Commit 5903b164 authored by Suman Tripathi's avatar Suman Tripathi Committed by Tejun Heo

libahci: Add support to handle HOST_IRQ_STAT as edge trigger latch.

This patch adds the support to handle HOST_IRQ_STAT as edge trigger
latch.
Signed-off-by: default avatarSuman Tripathi <stripathi@apm.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent a129db89
...@@ -238,6 +238,8 @@ enum { ...@@ -238,6 +238,8 @@ enum {
AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */ AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */
AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */
AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */ AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */
AHCI_HFLAG_EDGE_IRQ = (1 << 19), /* HOST_IRQ_STAT behaves as
Edge Triggered */
/* ap->flags bits */ /* ap->flags bits */
......
...@@ -1853,6 +1853,43 @@ static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked) ...@@ -1853,6 +1853,43 @@ static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
return handled; return handled;
} }
static irqreturn_t ahci_single_edge_irq_intr(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
struct ahci_host_priv *hpriv;
unsigned int rc = 0;
void __iomem *mmio;
u32 irq_stat, irq_masked;
VPRINTK("ENTER\n");
hpriv = host->private_data;
mmio = hpriv->mmio;
/* sigh. 0xffffffff is a valid return from h/w */
irq_stat = readl(mmio + HOST_IRQ_STAT);
if (!irq_stat)
return IRQ_NONE;
irq_masked = irq_stat & hpriv->port_map;
spin_lock(&host->lock);
/*
* HOST_IRQ_STAT behaves as edge triggered latch meaning that
* it should be cleared before all the port events are cleared.
*/
writel(irq_stat, mmio + HOST_IRQ_STAT);
rc = ahci_handle_port_intr(host, irq_masked);
spin_unlock(&host->lock);
VPRINTK("EXIT\n");
return IRQ_RETVAL(rc);
}
static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance) static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance)
{ {
struct ata_host *host = dev_instance; struct ata_host *host = dev_instance;
...@@ -2495,6 +2532,9 @@ int ahci_host_activate(struct ata_host *host, int irq, ...@@ -2495,6 +2532,9 @@ int ahci_host_activate(struct ata_host *host, int irq,
if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
rc = ahci_host_activate_multi_irqs(host, irq, sht); rc = ahci_host_activate_multi_irqs(host, irq, sht);
else if (hpriv->flags & AHCI_HFLAG_EDGE_IRQ)
rc = ata_host_activate(host, irq, ahci_single_edge_irq_intr,
IRQF_SHARED, sht);
else else
rc = ata_host_activate(host, irq, ahci_single_level_irq_intr, rc = ata_host_activate(host, irq, ahci_single_level_irq_intr,
IRQF_SHARED, sht); IRQF_SHARED, sht);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment