[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