ahci: Store irq number in struct ahci_host_priv
authorRobert Richter <rrichter@cavium.com>
Sun, 31 May 2015 11:55:18 +0000 (13:55 +0200)
committerTejun Heo <tj@kernel.org>
Wed, 3 Jun 2015 05:37:49 +0000 (01:37 -0400)
Currently, ahci supports only msi and intx. To also support msix the
handling of the irq number need to be changed. The irq number for msix
devices is taken from msi_list instead of pci_dev. Thus, the irq
number of a device needs to be stored in struct ahci_host_priv now.
This allows the host controller to be activated in a generic way.

This change is only intended for ahci drivers. For that reason the irq
number is stored in struct ahci_host_priv used only by ahci drivers.
Thus, the ABI changes only for ahci_host_activate(), but existing ata
drivers (about 50) are unaffected and keep unchanged. All users of
ahci_host_activate() have been updated.

While touching drivers/ata/libahci.c, doing a small code cleanup in
ahci_port_start().

Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
drivers/ata/acard-ahci.c
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/libahci.c
drivers/ata/libahci_platform.c
drivers/ata/sata_highbank.c

index 12489ce863c4bf06c06a38aa182124785346e365..ed6a30cd681a047276e5f782aa603ca9c47c3315 100644 (file)
@@ -433,6 +433,8 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id
        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))
@@ -498,7 +500,7 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id
        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);
index 7ba5332476c6f9061917d951ba594121717e7c04..a3c66c3bb76ebc4c4dc4d59342942d443371bd05 100644 (file)
@@ -1237,14 +1237,18 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
        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,
@@ -1258,6 +1262,7 @@ 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;
 }
@@ -1423,13 +1428,13 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
         */
        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
@@ -1475,7 +1480,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        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);
index f4429600e2bfb8d6f9dd3962c2dfa99ac9bd55f4..5b8e8a0fab487a8fdce58066c347df6759b31bee 100644 (file)
@@ -343,6 +343,7 @@ struct ahci_host_priv {
        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
@@ -395,8 +396,7 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
                          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,
index 1add5baec58483c1c2ba6870962a79ed7aff7772..1c99402a1017a3d6209746b6c2059525fa672262 100644 (file)
@@ -2344,7 +2344,7 @@ static int ahci_port_start(struct ata_port *ap)
        /*
         * 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;
        }
@@ -2472,7 +2472,10 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq,
        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;
 
@@ -2511,23 +2514,18 @@ out_free_irqs:
 /**
  *     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)
index d89305d289f63f8a4afcb78773a19e42088790ba..aaa761b9081cc02a75792302c741f7b54ebd9823 100644 (file)
@@ -518,6 +518,8 @@ int ahci_platform_init_host(struct platform_device *pdev,
                return -EINVAL;
        }
 
+       hpriv->irq = irq;
+
        /* prepare host */
        pi.private_data = (void *)(unsigned long)hpriv->flags;
 
@@ -588,7 +590,7 @@ int ahci_platform_init_host(struct platform_device *pdev,
        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);
 
index 24e311fe2c1c3ebf90431b99f67e5ac09cb2c572..8638d575b2b99baef3d9a429e99fbc5287b4f1e1 100644 (file)
@@ -499,6 +499,7 @@ static int ahci_highbank_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       hpriv->irq = irq;
        hpriv->flags |= (unsigned long)pi.private_data;
 
        hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
@@ -568,7 +569,7 @@ static int ahci_highbank_probe(struct platform_device *pdev)
        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;