Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: mt7621-pci: fix PCIe interrupt mapping

MT7621 has three assigned interrupts for the pcie. This
interrupts should properly being mapped taking into account
which devices are finally connected in which bus according
to link status. So the irq mappings should be as follows
according to link status (three bits indicating which devices
are link up):

* For PCIe Bus 1 slot 0:
- status = 0x2 || status = 0x6 => IRQ = pcie1_irq (24).
- status = 0x4 => IRQ = pcie2_irq (25).
- default => IRQ = pcie0_irq (23).
* For PCIe Bus 2 slot 0:
- status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25).
- default => IRQ = pcie1_irq (24).
* For PCIe Bus 2 slot 1:
- status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25).
- default => IRQ = pcie1_irq (24).
* For PCIe Bus 3 any slot:
- default => IRQ = pcie2_irq (25).

Because of this, the function 'of_irq_parse_and_map_pci' cannot
be used and we need to change device tree information from using
the 'interrupt-map' and 'interrupt-map-mask' properties into an
'interrupts' property to be able to get irq information from the
ports using the 'platform_get_irq' and storing an 'irq-map' into
the pcie driver data node to properly map correct irq using a
new 'mt7621_map_irq' function where this map will be read and the
correct irq returned.

Fixes: 46d093124df4 ("staging: mt7621-pci: improve interrupt mapping")
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
Link: https://lore.kernel.org/r/20200413055942.2714-1-sergio.paracuellos@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Sergio Paracuellos and committed by
Greg Kroah-Hartman
fab6710e be3d9b68

+38 -7
+4 -5
drivers/staging/mt7621-dts/mt7621.dtsi
··· 523 523 0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */ 524 524 >; 525 525 526 - #interrupt-cells = <1>; 527 - interrupt-map-mask = <0xF0000 0 0 1>; 528 - interrupt-map = <0x10000 0 0 1 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, 529 - <0x20000 0 0 1 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, 530 - <0x30000 0 0 1 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; 526 + interrupt-parent = <&gic>; 527 + interrupts = <GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH 528 + GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH 529 + GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; 531 530 532 531 status = "disabled"; 533 532
+34 -2
drivers/staging/mt7621-pci/pci-mt7621.c
··· 97 97 * @pcie_rst: pointer to port reset control 98 98 * @gpio_rst: gpio reset 99 99 * @slot: port slot 100 + * @irq: GIC irq 100 101 * @enabled: indicates if port is enabled 101 102 */ 102 103 struct mt7621_pcie_port { ··· 108 107 struct reset_control *pcie_rst; 109 108 struct gpio_desc *gpio_rst; 110 109 u32 slot; 110 + int irq; 111 111 bool enabled; 112 112 }; 113 113 ··· 122 120 * @dev: Pointer to PCIe device 123 121 * @io_map_base: virtual memory base address for io 124 122 * @ports: pointer to PCIe port information 123 + * @irq_map: irq mapping info according pcie link status 125 124 * @resets_inverted: depends on chip revision 126 125 * reset lines are inverted. 127 126 */ ··· 138 135 } offset; 139 136 unsigned long io_map_base; 140 137 struct list_head ports; 138 + int irq_map[PCIE_P2P_MAX]; 141 139 bool resets_inverted; 142 140 }; 143 141 ··· 283 279 } 284 280 } 285 281 282 + static int mt7621_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) 283 + { 284 + struct mt7621_pcie *pcie = pdev->bus->sysdata; 285 + struct device *dev = pcie->dev; 286 + int irq = pcie->irq_map[slot]; 287 + 288 + dev_info(dev, "bus=%d slot=%d irq=%d\n", pdev->bus->number, slot, irq); 289 + return irq; 290 + } 291 + 286 292 static int mt7621_pci_parse_request_of_pci_ranges(struct mt7621_pcie *pcie) 287 293 { 288 294 struct device *dev = pcie->dev; ··· 344 330 { 345 331 struct mt7621_pcie_port *port; 346 332 struct device *dev = pcie->dev; 333 + struct platform_device *pdev = to_platform_device(dev); 347 334 struct device_node *pnode = dev->of_node; 348 335 struct resource regs; 349 336 char name[10]; ··· 385 370 386 371 port->slot = slot; 387 372 port->pcie = pcie; 373 + 374 + port->irq = platform_get_irq(pdev, slot); 375 + if (port->irq < 0) { 376 + dev_err(dev, "Failed to get IRQ for PCIe%d\n", slot); 377 + return -ENXIO; 378 + } 388 379 389 380 INIT_LIST_HEAD(&port->list); 390 381 list_add_tail(&port->list, &pcie->ports); ··· 606 585 { 607 586 u32 pcie_link_status = 0; 608 587 u32 n; 609 - int i; 588 + int i = 0; 610 589 u32 p2p_br_devnum[PCIE_P2P_MAX]; 590 + int irqs[PCIE_P2P_MAX]; 611 591 struct mt7621_pcie_port *port; 612 592 613 593 list_for_each_entry(port, &pcie->ports, list) { 614 594 u32 slot = port->slot; 615 595 596 + irqs[i++] = port->irq; 616 597 if (port->enabled) 617 598 pcie_link_status |= BIT(slot); 618 599 } ··· 636 613 (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) | 637 614 (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) | 638 615 (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT)); 616 + 617 + /* Assign IRQs */ 618 + n = 0; 619 + for (i = 0; i < PCIE_P2P_MAX; i++) 620 + if (pcie_link_status & BIT(i)) 621 + pcie->irq_map[n++] = irqs[i]; 622 + 623 + for (i = n; i < PCIE_P2P_MAX; i++) 624 + pcie->irq_map[i] = -1; 639 625 640 626 return 0; 641 627 } ··· 670 638 host->busnr = pcie->busn.start; 671 639 host->dev.parent = pcie->dev; 672 640 host->ops = &mt7621_pci_ops; 673 - host->map_irq = of_irq_parse_and_map_pci; 641 + host->map_irq = mt7621_map_irq; 674 642 host->swizzle_irq = pci_common_swizzle; 675 643 host->sysdata = pcie; 676 644