hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
+
+ hpriv->irq = pdev->irq;
hpriv->flags |= (unsigned long)pi.private_data;
if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
acard_ahci_pci_print_info(host);
pci_set_master(pdev);
- return ahci_host_activate(host, pdev->irq, &acard_ahci_sht);
+ return ahci_host_activate(host, &acard_ahci_sht);
}
module_pci_driver(acard_ahci_pci_driver);
if (nvec > 1)
hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
- return nvec;
+ goto out;
single_msi:
+ nvec = 1;
+
rc = pci_enable_msi(pdev);
if (rc < 0)
return rc;
+out:
+ hpriv->irq = pdev->irq;
- return 1;
+ return nvec;
}
static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
/* lagacy intx interrupts */
pci_intx(pdev, 1);
+ hpriv->irq = pdev->irq;
return 0;
}
*/
n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
- ahci_init_interrupts(pdev, n_ports, hpriv);
-
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
if (!host)
return -ENOMEM;
host->private_data = hpriv;
+ ahci_init_interrupts(pdev, n_ports, hpriv);
+
if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN;
else
pci_set_master(pdev);
- return ahci_host_activate(host, pdev->irq, &ahci_sht);
+ return ahci_host_activate(host, &ahci_sht);
}
module_pci_driver(ahci_pci_driver);
struct phy **phys;
unsigned nports; /* Number of ports */
void *plat_data; /* Other platform data */
+ unsigned int irq; /* interrupt line */
/*
* Optional ahci_start_engine override, if not set this gets set to the
* default ahci_start_engine during ahci_save_initial_config, this can
struct ata_port_info *pi);
int ahci_reset_em(struct ata_host *host);
void ahci_print_info(struct ata_host *host, const char *scc_s);
-int ahci_host_activate(struct ata_host *host, int irq,
- struct scsi_host_template *sht);
+int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht);
void ahci_error_handler(struct ata_port *ap);
static inline void __iomem *__ahci_port_base(struct ata_host *host,
/*
* Switch to per-port locking in case each port has its own MSI vector.
*/
- if ((hpriv->flags & AHCI_HFLAG_MULTI_MSI)) {
+ if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) {
spin_lock_init(&pp->lock);
ap->lock = &pp->lock;
}
rc = ata_host_start(host);
if (rc)
return rc;
-
+ /*
+ * Requests IRQs according to AHCI-1.1 when multiple MSIs were
+ * allocated. That is one MSI per port, starting from @irq.
+ */
for (i = 0; i < host->n_ports; i++) {
struct ahci_port_priv *pp = host->ports[i]->private_data;
/**
* ahci_host_activate - start AHCI host, request IRQs and register it
* @host: target ATA host
- * @irq: base IRQ number to request
* @sht: scsi_host_template to use when registering the host
*
- * Similar to ata_host_activate, but requests IRQs according to AHCI-1.1
- * when multiple MSIs were allocated. That is one MSI per port, starting
- * from @irq.
- *
* LOCKING:
* Inherited from calling layer (may sleep).
*
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ahci_host_activate(struct ata_host *host, int irq,
- struct scsi_host_template *sht)
+int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
{
struct ahci_host_priv *hpriv = host->private_data;
+ int irq = hpriv->irq;
int rc;
if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
return -EINVAL;
}
+ hpriv->irq = irq;
+
/* prepare host */
pi.private_data = (void *)(unsigned long)hpriv->flags;
ahci_init_controller(host);
ahci_print_info(host, "platform");
- return ahci_host_activate(host, irq, sht);
+ return ahci_host_activate(host, sht);
}
EXPORT_SYMBOL_GPL(ahci_platform_init_host);
return -ENOMEM;
}
+ hpriv->irq = irq;
hpriv->flags |= (unsigned long)pi.private_data;
hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
ahci_init_controller(host);
ahci_print_info(host, "platform");
- rc = ahci_host_activate(host, irq, &ahci_highbank_platform_sht);
+ rc = ahci_host_activate(host, &ahci_highbank_platform_sht);
if (rc)
goto err0;