[PATCH 1/3] PCI: designware: add legacy PCI interrupt mapping

Tim Harvey tharvey at gateworks.com
Thu Feb 27 23:24:40 EST 2014


On Thu, Feb 27, 2014 at 6:00 PM, Jingoo Han <jg1.han at samsung.com> wrote:
> On Friday, February 28, 2014 10:20 AM, Tim Harvey wrote:
>>
>> The IMX6 maps INTA/B/C/D to ARM GIC IRQ 155/154/153/152 respectively.
>> This allows a PCIe-to-PCI bridge to function properly.
>>
>> The irq field of the pcie_host struct is expanded to 4 interrupts to
>> allow for INTA/B/C/D and the IMX6 PCIe host driver will populate them
>> all from devicetree.  I'm not clear if the Exynos driver has this
>> capability so it places the same interrupt in all 4 slots.
>
> (+cc Marek Vasut, Pratyush Anand, Kishon Vijay Abraham I, Mohit KUMAR DCG)
>
> In the case of Exynos,
> 'INTA/B/C/D' are mapped to only one interrupt (<0 20 0>).
> Thus, the current code works properly on Exynos platform.
>
> There are three interrupts for Exynos PCIe; INTx, MSI, PHY Link,
> respectively as below.
>
> ./arch/arm/boot/dts/exynos5440.dtsi
>         interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
>
> <0 20 0>: PCIe RC0 pulse interrupt,
>              INTA, INTB, INTC and INTD, etc
> <0 21 0>: PCIe RC0 level interrupt,
>              MSI, etc
> <0 22 0>: PCIe RC0 special interrupt,
>              PHY Link related interrupts, etc
>
> Of course, legacy INTx is handled as message only.
>
> Mohit, Kishon,
> How about the other SoCs? INTx is mapped to single interrupt
> such as Exynos, or separate interrupts such as i.MX6?

Jingoo,

Ok - so at least the I.MX6 and Exynos, which both use the designware
IP need different IRQ mappings.  It seems to me then that the map_irq
should be moved out of drivers/pci/host/pcie-designware.c and into the
SoC specific host controller drivers (pci-imx.c and pci-exynos.c).  If
that becomes the consensus I can submit a patch that does that.

Thanks,

Tim

>
> Best regards,
> Jingoo Han
>
>>
>> Signed-off-by: Tim Harvey <tharvey at gateworks.com>
>> Cc: Bjorn Helgaas <bhelgaas at google.com>
>> Cc: Richard Zhu <r65037 at freescale.com>
>> Cc: Shawn Guo <shawn.guo at linaro.org>
>> Cc: Lucas Stach <l.stach at pengutronix.de>
>> Cc: Sean Cross <xobs at kosagi.com>
>> Cc: Jingoo Han <jg1.han at samsung.com>
>> ---
>>  arch/arm/boot/dts/imx6qdl.dtsi     |  2 +-
>>  drivers/pci/host/pci-exynos.c      |  7 +++++--
>>  drivers/pci/host/pci-imx6.c        | 11 +++++++----
>>  drivers/pci/host/pcie-designware.c |  8 +++++++-
>>  drivers/pci/host/pcie-designware.h |  2 +-
>>  5 files changed, 21 insertions(+), 9 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
>> index eed6897..fad8d90 100644
>> --- a/arch/arm/boot/dts/imx6qdl.dtsi
>> +++ b/arch/arm/boot/dts/imx6qdl.dtsi
>> @@ -126,7 +126,7 @@
>>                                 0x81000000 0 0          0x01f80000 0 0x00010000 /* downstream I/O */
>>                                 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable
>> memory */
>>                       num-lanes = <1>;
>> -                     interrupts = <0 123 0x04>;
>> +                     interrupts = <0 123 0x04>, <0 122 0x04>, <0 121 0x04>, <0 120 0x04>;
>>                       clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>;
>>                       clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
>>                       status = "disabled";
>> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
>> index 3de6bfb..d85dcb0 100644
>> --- a/drivers/pci/host/pci-exynos.c
>> +++ b/drivers/pci/host/pci-exynos.c
>> @@ -515,11 +515,14 @@ static int add_pcie_port(struct pcie_port *pp, struct platform_device *pdev)
>>  {
>>       int ret;
>>
>> -     pp->irq = platform_get_irq(pdev, 1);
>> -     if (!pp->irq) {
>> +     pp->irq[0] = platform_get_irq(pdev, 1);
>> +     if (!pp->irq[0]) {
>>               dev_err(&pdev->dev, "failed to get irq\n");
>>               return -ENODEV;
>>       }
>> +     pp->irq[1] = pp->irq[0];
>> +     pp->irq[2] = pp->irq[0];
>> +     pp->irq[3] = pp->irq[0];
>>       ret = devm_request_irq(&pdev->dev, pp->irq, exynos_pcie_irq_handler,
>>                               IRQF_SHARED, "exynos-pcie", pp);
>>       if (ret) {
>> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
>> index e8663a8..aaa05c8 100644
>> --- a/drivers/pci/host/pci-imx6.c
>> +++ b/drivers/pci/host/pci-imx6.c
>> @@ -470,11 +470,14 @@ static int imx6_add_pcie_port(struct pcie_port *pp,
>>                       struct platform_device *pdev)
>>  {
>>       int ret;
>> +     int i;
>>
>> -     pp->irq = platform_get_irq(pdev, 0);
>> -     if (!pp->irq) {
>> -             dev_err(&pdev->dev, "failed to get irq\n");
>> -             return -ENODEV;
>> +     for (i = 0; i < 4; i++) {
>> +             pp->irq[i] = platform_get_irq(pdev, i);
>> +             if (!pp->irq[i]) {
>> +                     dev_err(&pdev->dev, "failed to get irq%d\n", i);
>> +                     return -ENODEV;
>> +             }
>>       }
>>
>>       pp->root_bus_nr = -1;
>> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
>> index 17ce88f..5808177 100644
>> --- a/drivers/pci/host/pcie-designware.c
>> +++ b/drivers/pci/host/pcie-designware.c
>> @@ -738,8 +738,14 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
>>  static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
>>  {
>>       struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
>> +     int irq = -1;
>>
>> -     return pp->irq;
>> +     if (pin > 0 && pin < 5)
>> +             irq = pp->irq[pin - 1];
>> +     dev_info(&dev->dev, "map_irq: %04x:%04x slot%d pin%d irq%d\n",
>> +             dev->vendor, dev->device, slot, pin, irq);
>> +
>> +     return irq;
>>  }
>>
>>  static void dw_pcie_add_bus(struct pci_bus *bus)
>> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
>> index 3063b35..5c596c0 100644
>> --- a/drivers/pci/host/pcie-designware.h
>> +++ b/drivers/pci/host/pcie-designware.h
>> @@ -46,7 +46,7 @@ struct pcie_port {
>>       struct resource         io;
>>       struct resource         mem;
>>       struct pcie_port_info   config;
>> -     int                     irq;
>> +     int                     irq[4];
>>       u32                     lanes;
>>       struct pcie_host_ops    *ops;
>>       int                     msi_irq;
>> --
>> 1.8.3.2
>



More information about the linux-arm-kernel mailing list