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

Suman Tripathi stripathi at apm.com
Fri May 8 12:13:49 PDT 2015


Hi Tejun

On Wed, May 6, 2015 at 12:51 AM, Suman Tripathi <stripathi at apm.com> wrote:
>
> This patch adds the support to handle HOST_IRQ_STAT as edge trigger
> latch.
>
> Signed-off-by: Suman Tripathi <stripathi at apm.com>
> ---
>  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



More information about the linux-arm-kernel mailing list