Thread (1 message) 1 message, 1 author, 2015-05-08

[PATCH v5 2/3] libahci: Add support to handle HOST_IRQ_STAT as edge trigger latch.

From: Suman Tripathi <hidden>
Date: 2015-05-08 19:13:49
Also in: linux-devicetree, linux-ide, linux-scsi

Hi Tejun

On Wed, May 6, 2015 at 12:51 AM, Suman Tripathi [off-list ref] wrote:
quoted hunk
This patch adds the support to handle HOST_IRQ_STAT as edge trigger
latch.

Signed-off-by: Suman Tripathi <redacted>
---
 drivers/ata/ahci.h    |  2 ++
 drivers/ata/libahci.c | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index 71262e0..f442960 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -238,6 +238,8 @@ enum {
        AHCI_HFLAG_MULTI_MSI            = (1 << 16), /* multiple PCI MSIs */
        AHCI_HFLAG_NO_DEVSLP            = (1 << 17), /* no device sleep */
        AHCI_HFLAG_NO_FBS               = (1 << 18), /* no FBS */
+       AHCI_HFLAG_EDGE_IRQ             = (1 << 19), /* HOST_IRQ_STAT behaves as
+                                                       Edge Triggered */

        /* ap->flags bits */
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index aa89c8e..1add5ba 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1853,6 +1853,43 @@ static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
        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)
 {
        struct ata_host *host = dev_instance;
@@ -2495,6 +2532,9 @@ int ahci_host_activate(struct ata_host *host, int irq,

        if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
                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
                rc = ata_host_activate(host, irq, ahci_single_level_irq_intr,
                                       IRQF_SHARED, sht);
--
1.8.2.1
Any comments on this version ??

-- 
Thanks,
with regards,
Suman Tripathi
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help