|
@@ -113,6 +113,9 @@ 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);
|
|
|
static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
|
|
@@ -512,6 +515,11 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
|
|
|
|
|
|
if (!hpriv->start_engine)
|
|
|
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;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ahci_save_initial_config);
|
|
|
|
|
@@ -1846,7 +1854,7 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance)
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
-static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
|
|
|
+u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
|
|
|
{
|
|
|
unsigned int i, handled = 0;
|
|
|
|
|
@@ -1872,6 +1880,7 @@ static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
|
|
|
|
|
|
return handled;
|
|
|
}
|
|
|
+EXPORT_SYMBOL_GPL(ahci_handle_port_intr);
|
|
|
|
|
|
static irqreturn_t ahci_single_edge_irq_intr(int irq, void *dev_instance)
|
|
|
{
|
|
@@ -2535,14 +2544,18 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
|
|
|
int irq = hpriv->irq;
|
|
|
int rc;
|
|
|
|
|
|
- if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX))
|
|
|
+ if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX)) {
|
|
|
+ if (hpriv->irq_handler)
|
|
|
+ dev_warn(host->dev, "both AHCI_HFLAG_MULTI_MSI flag set \
|
|
|
+ and custom irq handler implemented\n");
|
|
|
+
|
|
|
rc = ahci_host_activate_multi_irqs(host, 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,
|
|
|
+ } else {
|
|
|
+ rc = ata_host_activate(host, irq, hpriv->irq_handler,
|
|
|
IRQF_SHARED, sht);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
return rc;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ahci_host_activate);
|