Skip to content

Commit

Permalink
ata: Remove the AHCI_HFLAG_EDGE_IRQ support from libahci.
Browse files Browse the repository at this point in the history
The flexibility to override the irq handles in the LLD's are already
present, so controllers implementing a edge trigger latch can
implement their own interrupt handler inside the driver.  This patch
removes the AHCI_HFLAG_EDGE_IRQ support from libahci and moves edge
irq handling to ahci_xgene.

tj: Minor update to description.

Signed-off-by: Suman Tripathi <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
suman-tripathi authored and htejun committed Feb 11, 2016
1 parent f070d67 commit d867b95
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 45 deletions.
3 changes: 1 addition & 2 deletions drivers/ata/ahci.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,7 @@ enum {
error-handling stage) */
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 */

#ifdef CONFIG_PCI_MSI
AHCI_HFLAG_MULTI_MSI = (1 << 20), /* multiple PCI MSIs */
AHCI_HFLAG_MULTI_MSIX = (1 << 21), /* per-port MSI-X */
Expand Down
40 changes: 39 additions & 1 deletion drivers/ata/ahci_xgene.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,43 @@ static int xgene_ahci_softreset(struct ata_link *link, unsigned int *class,
return rc;
}

static irqreturn_t xgene_ahci_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 struct ata_port_operations xgene_ahci_v1_ops = {
.inherits = &ahci_ops,
.host_stop = xgene_ahci_host_stop,
Expand Down Expand Up @@ -779,7 +816,8 @@ static int xgene_ahci_probe(struct platform_device *pdev)
hpriv->flags = AHCI_HFLAG_NO_NCQ;
break;
case XGENE_AHCI_V2:
hpriv->flags |= AHCI_HFLAG_YES_FBS | AHCI_HFLAG_EDGE_IRQ;
hpriv->flags |= AHCI_HFLAG_YES_FBS;
hpriv->irq_handler = xgene_ahci_irq_intr;
break;
default:
break;
Expand Down
43 changes: 1 addition & 42 deletions drivers/ata/libahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,6 @@ static ssize_t ahci_store_em_buffer(struct device *dev,
const char *buf, size_t size);
static ssize_t ahci_show_em_supported(struct device *dev,
struct device_attribute *attr, char *buf);
static irqreturn_t ahci_single_edge_irq_intr(int irq, void *dev_instance);

static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance);

static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
Expand Down Expand Up @@ -517,9 +515,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
hpriv->start_engine = ahci_start_engine;

if (!hpriv->irq_handler)
hpriv->irq_handler = (hpriv->flags & AHCI_HFLAG_EDGE_IRQ) ?
ahci_single_edge_irq_intr :
ahci_single_level_irq_intr;
hpriv->irq_handler = ahci_single_level_irq_intr;
}
EXPORT_SYMBOL_GPL(ahci_save_initial_config);

Expand Down Expand Up @@ -1882,43 +1878,6 @@ u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
}
EXPORT_SYMBOL_GPL(ahci_handle_port_intr);

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;
Expand Down

0 comments on commit d867b95

Please sign in to comment.