Commit 21bfd1aa authored by Robert Richter's avatar Robert Richter Committed by Tejun Heo

ahci: Store irq number in struct ahci_host_priv

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: default avatarRobert Richter <rrichter@cavium.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent a1c82311
...@@ -433,6 +433,8 @@ static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id ...@@ -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); hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv) if (!hpriv)
return -ENOMEM; return -ENOMEM;
hpriv->irq = pdev->irq;
hpriv->flags |= (unsigned long)pi.private_data; hpriv->flags |= (unsigned long)pi.private_data;
if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) 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 ...@@ -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); acard_ahci_pci_print_info(host);
pci_set_master(pdev); 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); module_pci_driver(acard_ahci_pci_driver);
......
...@@ -1237,14 +1237,18 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports, ...@@ -1237,14 +1237,18 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
if (nvec > 1) if (nvec > 1)
hpriv->flags |= AHCI_HFLAG_MULTI_MSI; hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
return nvec; goto out;
single_msi: single_msi:
nvec = 1;
rc = pci_enable_msi(pdev); rc = pci_enable_msi(pdev);
if (rc < 0) if (rc < 0)
return rc; return rc;
out:
hpriv->irq = pdev->irq;
return 1; return nvec;
} }
static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, 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, ...@@ -1258,6 +1262,7 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
/* lagacy intx interrupts */ /* lagacy intx interrupts */
pci_intx(pdev, 1); pci_intx(pdev, 1);
hpriv->irq = pdev->irq;
return 0; return 0;
} }
...@@ -1423,13 +1428,13 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -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)); 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); host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
if (!host) if (!host)
return -ENOMEM; return -ENOMEM;
host->private_data = hpriv; host->private_data = hpriv;
ahci_init_interrupts(pdev, n_ports, hpriv);
if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN; host->flags |= ATA_HOST_PARALLEL_SCAN;
else else
...@@ -1475,7 +1480,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1475,7 +1480,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev); 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); module_pci_driver(ahci_pci_driver);
......
...@@ -343,6 +343,7 @@ struct ahci_host_priv { ...@@ -343,6 +343,7 @@ struct ahci_host_priv {
struct phy **phys; struct phy **phys;
unsigned nports; /* Number of ports */ unsigned nports; /* Number of ports */
void *plat_data; /* Other platform data */ void *plat_data; /* Other platform data */
unsigned int irq; /* interrupt line */
/* /*
* Optional ahci_start_engine override, if not set this gets set to the * Optional ahci_start_engine override, if not set this gets set to the
* default ahci_start_engine during ahci_save_initial_config, this can * 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, ...@@ -395,8 +396,7 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
struct ata_port_info *pi); struct ata_port_info *pi);
int ahci_reset_em(struct ata_host *host); int ahci_reset_em(struct ata_host *host);
void ahci_print_info(struct ata_host *host, const char *scc_s); void ahci_print_info(struct ata_host *host, const char *scc_s);
int ahci_host_activate(struct ata_host *host, int irq, int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht);
struct scsi_host_template *sht);
void ahci_error_handler(struct ata_port *ap); void ahci_error_handler(struct ata_port *ap);
static inline void __iomem *__ahci_port_base(struct ata_host *host, static inline void __iomem *__ahci_port_base(struct ata_host *host,
......
...@@ -2344,7 +2344,7 @@ static int ahci_port_start(struct ata_port *ap) ...@@ -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. * 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); spin_lock_init(&pp->lock);
ap->lock = &pp->lock; ap->lock = &pp->lock;
} }
...@@ -2472,7 +2472,10 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq, ...@@ -2472,7 +2472,10 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq,
rc = ata_host_start(host); rc = ata_host_start(host);
if (rc) if (rc)
return 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++) { for (i = 0; i < host->n_ports; i++) {
struct ahci_port_priv *pp = host->ports[i]->private_data; struct ahci_port_priv *pp = host->ports[i]->private_data;
...@@ -2511,23 +2514,18 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq, ...@@ -2511,23 +2514,18 @@ static int ahci_host_activate_multi_irqs(struct ata_host *host, int irq,
/** /**
* ahci_host_activate - start AHCI host, request IRQs and register it * ahci_host_activate - start AHCI host, request IRQs and register it
* @host: target ATA host * @host: target ATA host
* @irq: base IRQ number to request
* @sht: scsi_host_template to use when registering the host * @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: * LOCKING:
* Inherited from calling layer (may sleep). * Inherited from calling layer (may sleep).
* *
* RETURNS: * RETURNS:
* 0 on success, -errno otherwise. * 0 on success, -errno otherwise.
*/ */
int ahci_host_activate(struct ata_host *host, int irq, int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
struct scsi_host_template *sht)
{ {
struct ahci_host_priv *hpriv = host->private_data; struct ahci_host_priv *hpriv = host->private_data;
int irq = hpriv->irq;
int rc; int rc;
if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) if (hpriv->flags & AHCI_HFLAG_MULTI_MSI)
......
...@@ -518,6 +518,8 @@ int ahci_platform_init_host(struct platform_device *pdev, ...@@ -518,6 +518,8 @@ int ahci_platform_init_host(struct platform_device *pdev,
return -EINVAL; return -EINVAL;
} }
hpriv->irq = irq;
/* prepare host */ /* prepare host */
pi.private_data = (void *)(unsigned long)hpriv->flags; pi.private_data = (void *)(unsigned long)hpriv->flags;
...@@ -588,7 +590,7 @@ int ahci_platform_init_host(struct platform_device *pdev, ...@@ -588,7 +590,7 @@ int ahci_platform_init_host(struct platform_device *pdev,
ahci_init_controller(host); ahci_init_controller(host);
ahci_print_info(host, "platform"); 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); EXPORT_SYMBOL_GPL(ahci_platform_init_host);
......
...@@ -499,6 +499,7 @@ static int ahci_highbank_probe(struct platform_device *pdev) ...@@ -499,6 +499,7 @@ static int ahci_highbank_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
hpriv->irq = irq;
hpriv->flags |= (unsigned long)pi.private_data; hpriv->flags |= (unsigned long)pi.private_data;
hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem)); hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
...@@ -568,7 +569,7 @@ static int ahci_highbank_probe(struct platform_device *pdev) ...@@ -568,7 +569,7 @@ static int ahci_highbank_probe(struct platform_device *pdev)
ahci_init_controller(host); ahci_init_controller(host);
ahci_print_info(host, "platform"); 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) if (rc)
goto err0; goto err0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment