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: Suman Tripathi <stripathi@apm.com> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Родитель
a129db89d8
Коммит
5903b1643f
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче