Loading drivers/ata/ahci.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading drivers/ata/libahci.c +40 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading
drivers/ata/ahci.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
drivers/ata/libahci.c +40 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading