Commit 31e824ed authored by Dan Williams's avatar Dan Williams

isci: rely on irq core for intx multiplexing, and silence screaming intx

Remove the extra logic to poll each controller for interrupts, that's
the core's job for shared interrupts.

While testing noticed that a number of interrupts fire while waiting for
the completion tasklet to run, so added an irq-ack.
Reported-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent e2023b87
...@@ -77,23 +77,19 @@ irqreturn_t isci_msix_isr(int vec, void *data) ...@@ -77,23 +77,19 @@ irqreturn_t isci_msix_isr(int vec, void *data)
irqreturn_t isci_intx_isr(int vec, void *data) irqreturn_t isci_intx_isr(int vec, void *data)
{ {
struct pci_dev *pdev = data;
struct isci_host *ihost;
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
int i; struct isci_host *ihost = data;
struct scic_sds_controller *scic = ihost->core_controller;
for_each_isci_host(i, ihost, pdev) { if (scic_sds_controller_isr(scic)) {
struct scic_sds_controller *scic = ihost->core_controller; writel(SMU_ISR_COMPLETION, &scic->smu_registers->interrupt_status);
tasklet_schedule(&ihost->completion_tasklet);
if (scic_sds_controller_isr(scic)) { ret = IRQ_HANDLED;
tasklet_schedule(&ihost->completion_tasklet); } else if (scic_sds_controller_error_isr(scic)) {
ret = IRQ_HANDLED; spin_lock(&ihost->scic_lock);
} else if (scic_sds_controller_error_isr(scic)) { scic_sds_controller_error_handler(scic);
spin_lock(&ihost->scic_lock); spin_unlock(&ihost->scic_lock);
scic_sds_controller_error_handler(scic); ret = IRQ_HANDLED;
spin_unlock(&ihost->scic_lock);
ret = IRQ_HANDLED;
}
} }
return ret; return ret;
......
...@@ -335,6 +335,7 @@ static int num_controllers(struct pci_dev *pdev) ...@@ -335,6 +335,7 @@ static int num_controllers(struct pci_dev *pdev)
static int isci_setup_interrupts(struct pci_dev *pdev) static int isci_setup_interrupts(struct pci_dev *pdev)
{ {
int err, i, num_msix; int err, i, num_msix;
struct isci_host *ihost;
struct isci_pci_info *pci_info = to_pci_info(pdev); struct isci_pci_info *pci_info = to_pci_info(pdev);
/* /*
...@@ -353,9 +354,9 @@ static int isci_setup_interrupts(struct pci_dev *pdev) ...@@ -353,9 +354,9 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
for (i = 0; i < num_msix; i++) { for (i = 0; i < num_msix; i++) {
int id = i / SCI_NUM_MSI_X_INT; int id = i / SCI_NUM_MSI_X_INT;
struct msix_entry *msix = &pci_info->msix_entries[i]; struct msix_entry *msix = &pci_info->msix_entries[i];
struct isci_host *isci_host = pci_info->hosts[id];
irq_handler_t isr; irq_handler_t isr;
ihost = pci_info->hosts[id];
/* odd numbered vectors are error interrupts */ /* odd numbered vectors are error interrupts */
if (i & 1) if (i & 1)
isr = isci_error_isr; isr = isci_error_isr;
...@@ -363,16 +364,16 @@ static int isci_setup_interrupts(struct pci_dev *pdev) ...@@ -363,16 +364,16 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
isr = isci_msix_isr; isr = isci_msix_isr;
err = devm_request_irq(&pdev->dev, msix->vector, isr, 0, err = devm_request_irq(&pdev->dev, msix->vector, isr, 0,
DRV_NAME"-msix", isci_host); DRV_NAME"-msix", ihost);
if (!err) if (!err)
continue; continue;
dev_info(&pdev->dev, "msix setup failed falling back to intx\n"); dev_info(&pdev->dev, "msix setup failed falling back to intx\n");
while (i--) { while (i--) {
id = i / SCI_NUM_MSI_X_INT; id = i / SCI_NUM_MSI_X_INT;
isci_host = pci_info->hosts[id]; ihost = pci_info->hosts[id];
msix = &pci_info->msix_entries[i]; msix = &pci_info->msix_entries[i];
devm_free_irq(&pdev->dev, msix->vector, isci_host); devm_free_irq(&pdev->dev, msix->vector, ihost);
} }
pci_disable_msix(pdev); pci_disable_msix(pdev);
goto intx; goto intx;
...@@ -380,8 +381,12 @@ static int isci_setup_interrupts(struct pci_dev *pdev) ...@@ -380,8 +381,12 @@ static int isci_setup_interrupts(struct pci_dev *pdev)
return 0; return 0;
intx: intx:
err = devm_request_irq(&pdev->dev, pdev->irq, isci_intx_isr, for_each_isci_host(i, ihost, pdev) {
IRQF_SHARED, DRV_NAME"-intx", pdev); err = devm_request_irq(&pdev->dev, pdev->irq, isci_intx_isr,
IRQF_SHARED, DRV_NAME"-intx", ihost);
if (err)
break;
}
return err; return err;
} }
......
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