imx: add initial version of 3.18 support
[openwrt.git] / target / linux / imx6 / patches-3.18 / 201-pci_imx6_ventana_fixup-for-IRQ-mismapping.patch
1 commit 2c0d0491438433a1f327f2e754c7b6b55fec51c4
2 Author: Tim Harvey <tharvey@gateworks.com>
3 Date:   Thu Feb 27 00:59:53 2014 -0800
4
5     PCI: imx6: ventana: fixup for IRQ mismapping
6     
7     The TI XIO2001 PCIe-to-PCI bridge used on several Ventana expansion boards
8     has its slot-to-bridge IRQ mapping reversed from the PCI specification:
9     
10       INTA->INTD
11       INTB->INTC
12       INTC->INTB
13       INTD->INTA
14     
15     Implement a custom swizzle function that does a fixup on the interrupt for
16     devices on a TI XIO2001 bridge.
17     
18     Signed-off-by: Tim Harvey <tharvey@gateworks.com>
19
20 --- a/drivers/pci/host/pci-imx6.c
21 +++ b/drivers/pci/host/pci-imx6.c
22 @@ -553,6 +553,39 @@ static int __init imx6_add_pcie_port(str
23         return 0;
24  }
25  
26 +/* TI XIO2001 PCIe-to-PCI bridge on GW16082 exp card has IRQs reversed */
27 +u8 ventana_swizzle(struct pci_dev *dev, u8 *pin)
28 +{
29 +       u8 i = 0;
30 +       struct pci_dev *pdev = dev;
31 +
32 +       /* count number of TI XIO2001 bridges on bus */
33 +       while (!pci_is_root_bus(pdev->bus)) {
34 +               if (pdev->bus && pdev->bus->self &&
35 +                   (pdev->bus->self->vendor == PCI_VENDOR_ID_TI) &&
36 +                   (pdev->bus->self->device == PCI_DEVICE_ID_TI_XIO2001)) {
37 +                       i++;
38 +               }
39 +               pdev = pdev->bus->self;
40 +       }
41 +       while (!pci_is_root_bus(dev->bus)) {
42 +               /* if we are directly downstream from 1st TI XIO2001 bridge */
43 +               if (dev->bus && dev->bus->self &&
44 +                   (dev->bus->self->vendor == PCI_VENDOR_ID_TI) &&
45 +                   (dev->bus->self->device == PCI_DEVICE_ID_TI_XIO2001)) {
46 +                       if (--i == 0) {
47 +                               /* swap IRQs and swizzle backwards */
48 +                               *pin = (15 - PCI_SLOT(dev->devfn)) + 1;
49 +                               dev = dev->bus->self;
50 +                               continue;
51 +                       }
52 +               }
53 +               *pin = pci_swizzle_interrupt_pin(dev, *pin);
54 +               dev = dev->bus->self;
55 +       }
56 +       return PCI_SLOT(dev->devfn);
57 +}
58 +
59  static int __init imx6_pcie_probe(struct platform_device *pdev)
60  {
61         struct imx6_pcie *imx6_pcie;
62 @@ -618,6 +651,9 @@ static int __init imx6_pcie_probe(struct
63                 return PTR_ERR(imx6_pcie->iomuxc_gpr);
64         }
65  
66 +       if (of_machine_is_compatible("gw,ventana"))
67 +               pp->swizzle = ventana_swizzle;
68 +
69         ret = imx6_add_pcie_port(pp, pdev);
70         if (ret < 0)
71                 return ret;
72 --- a/include/linux/pci_ids.h
73 +++ b/include/linux/pci_ids.h
74 @@ -827,6 +827,7 @@
75  #define PCI_DEVICE_ID_TI_XX12          0x8039
76  #define PCI_DEVICE_ID_TI_XX12_FM       0x803b
77  #define PCI_DEVICE_ID_TI_XIO2000A      0x8231
78 +#define PCI_DEVICE_ID_TI_XIO2001       0x8240
79  #define PCI_DEVICE_ID_TI_1130          0xac12
80  #define PCI_DEVICE_ID_TI_1031          0xac13
81  #define PCI_DEVICE_ID_TI_1131          0xac15