Skip to content

Commit b4608e9

Browse files
Thangaraj Samynathanbroonie
authored andcommitted
spi: spi-pci1xxxx: Fix Probe failure with Dual SPI instance with INTx interrupts
Fixes a probe failure that occurs when dual SPI controllers are enabled and INTx interrupts are used. Reduces the minimum required number of interrupt vectors to 1 and registers a shared ISR when the allocated vectors are fewer than the number of controllers. This change ensures that the probe succeeds even with limited vectors, restoring INTx functionality when multiple SPI controllers are present. Signed-off-by: Thangaraj Samynathan <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent b00d686 commit b4608e9

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

drivers/spi/spi-pci1xxxx.c

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,17 @@ static irqreturn_t pci1xxxx_spi_isr(int irq, void *dev)
685685
return pci1xxxx_spi_isr_io(irq, dev);
686686
}
687687

688+
static irqreturn_t pci1xxxx_spi_shared_isr(int irq, void *dev)
689+
{
690+
struct pci1xxxx_spi *par = dev;
691+
u8 i = 0;
692+
693+
for (i = 0; i < par->total_hw_instances; i++)
694+
pci1xxxx_spi_isr(irq, par->spi_int[i]);
695+
696+
return IRQ_HANDLED;
697+
}
698+
688699
static bool pci1xxxx_spi_can_dma(struct spi_controller *host,
689700
struct spi_device *spi,
690701
struct spi_transfer *xfer)
@@ -702,6 +713,7 @@ static int pci1xxxx_spi_probe(struct pci_dev *pdev, const struct pci_device_id *
702713
struct device *dev = &pdev->dev;
703714
struct pci1xxxx_spi *spi_bus;
704715
struct spi_controller *spi_host;
716+
int num_vector = 0;
705717
u32 regval;
706718
int ret;
707719

@@ -749,9 +761,9 @@ static int pci1xxxx_spi_probe(struct pci_dev *pdev, const struct pci_device_id *
749761
if (!spi_bus->reg_base)
750762
return -EINVAL;
751763

752-
ret = pci_alloc_irq_vectors(pdev, hw_inst_cnt, hw_inst_cnt,
753-
PCI_IRQ_ALL_TYPES);
754-
if (ret < 0) {
764+
num_vector = pci_alloc_irq_vectors(pdev, 1, hw_inst_cnt,
765+
PCI_IRQ_ALL_TYPES);
766+
if (num_vector < 0) {
755767
dev_err(&pdev->dev, "Error allocating MSI vectors\n");
756768
return ret;
757769
}
@@ -765,9 +777,15 @@ static int pci1xxxx_spi_probe(struct pci_dev *pdev, const struct pci_device_id *
765777
SPI_MST_EVENT_MASK_REG_OFFSET(spi_sub_ptr->hw_inst));
766778
spi_sub_ptr->irq = pci_irq_vector(pdev, 0);
767779

768-
ret = devm_request_irq(&pdev->dev, spi_sub_ptr->irq,
769-
pci1xxxx_spi_isr, PCI1XXXX_IRQ_FLAGS,
770-
pci_name(pdev), spi_sub_ptr);
780+
if (num_vector >= hw_inst_cnt)
781+
ret = devm_request_irq(&pdev->dev, spi_sub_ptr->irq,
782+
pci1xxxx_spi_isr, PCI1XXXX_IRQ_FLAGS,
783+
pci_name(pdev), spi_sub_ptr);
784+
else
785+
ret = devm_request_irq(&pdev->dev, spi_sub_ptr->irq,
786+
pci1xxxx_spi_shared_isr,
787+
PCI1XXXX_IRQ_FLAGS | IRQF_SHARED,
788+
pci_name(pdev), spi_bus);
771789
if (ret < 0) {
772790
dev_err(&pdev->dev, "Unable to request irq : %d",
773791
spi_sub_ptr->irq);
@@ -798,14 +816,16 @@ static int pci1xxxx_spi_probe(struct pci_dev *pdev, const struct pci_device_id *
798816
regval &= ~SPI_INTR;
799817
writel(regval, spi_bus->reg_base +
800818
SPI_MST_EVENT_MASK_REG_OFFSET(spi_sub_ptr->hw_inst));
801-
spi_sub_ptr->irq = pci_irq_vector(pdev, iter);
802-
ret = devm_request_irq(&pdev->dev, spi_sub_ptr->irq,
803-
pci1xxxx_spi_isr, PCI1XXXX_IRQ_FLAGS,
804-
pci_name(pdev), spi_sub_ptr);
805-
if (ret < 0) {
806-
dev_err(&pdev->dev, "Unable to request irq : %d",
807-
spi_sub_ptr->irq);
808-
return -ENODEV;
819+
if (num_vector >= hw_inst_cnt) {
820+
spi_sub_ptr->irq = pci_irq_vector(pdev, iter);
821+
ret = devm_request_irq(&pdev->dev, spi_sub_ptr->irq,
822+
pci1xxxx_spi_isr, PCI1XXXX_IRQ_FLAGS,
823+
pci_name(pdev), spi_sub_ptr);
824+
if (ret < 0) {
825+
dev_err(&pdev->dev, "Unable to request irq : %d",
826+
spi_sub_ptr->irq);
827+
return -ENODEV;
828+
}
809829
}
810830
}
811831

0 commit comments

Comments
 (0)