Message ID | 1415177111-28730-1-git-send-email-Minghuan.Lian@freescale.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
On Wednesday 05 November 2014 16:45:11 Minghuan Lian wrote: > Add support for Freescale Layerscape PCIe controller. This driver > re-uses the designware core code. > > Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> > Acked-by: Arnd Bergmann <arnd@arndb.de> -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Nov 05, 2014 at 04:45:11PM +0800, Minghuan Lian wrote: > Add support for Freescale Layerscape PCIe controller. This driver > re-uses the designware core code. > > Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> Applied with Arnd's ack to pci/host-layerscape for v3.19, thanks! > --- > Based on pci-next branch > > Change log: > v6: > 1. remove MSI support. MSI driver will be implemented in a separate file > 2. remove bitrev() because SCFG is set bit reverse mode as default. > > v5: > 1. Add MAINTAINERS information > 2. Remove unnecessary NULL pointer check > 3. Use dev_dbg instead of dev_err in ls_pcie_msi_irq_handler() > > v4: > 1. Add 'depends on OF' to Kconfig > > v3: > 1. Add prefechable mem region and adjust mem region > 2. Rename 'pcie-scfg' to 'fsl,pcie-scfg' > 3. Change MSI interrupt handler > 4. Use module_platform_driver_probe instead of subsys_initcall > > v2: > 1. Add pcie-scfg to link scfg device node and remove "fsl, ls-pcie" compatible > 2. Use regmap API to access scfg. > 3. remove ls1021 PCI device ID. > 4. remove unused irq pme_irq and ls_pcie_list. > 5. Do not set scfg bit reverse mode > > .../devicetree/bindings/pci/layerscape-pci.txt | 42 +++++ > MAINTAINERS | 10 ++ > drivers/pci/host/Kconfig | 8 + > drivers/pci/host/Makefile | 1 + > drivers/pci/host/pci-layerscape.c | 179 +++++++++++++++++++++ > 5 files changed, 240 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci.txt > create mode 100644 drivers/pci/host/pci-layerscape.c > > diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt > new file mode 100644 > index 0000000..40749eb > --- /dev/null > +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt > @@ -0,0 +1,42 @@ > +Freescale Layerscape PCIe controller > + > +This PCIe host controller is based on the Synopsis Designware PCIe IP > +and thus inherits all the common properties defined in designware-pcie.txt. > + > +Required properties: > +- compatible: should contain the platform identifier such as "fsl,ls1021a-pcie" > +- reg: base addresses and lengths of the PCIe controller > +- interrupts: A list of interrupt outputs of the controller. Must contain an > + entry for each entry in the interrupt-names property. > +- interrupt-names: Must include the following entries: > + "intr": The interrupt that is asserted for controller interrupts > +- fsl,pcie-scfg: Must include two entries. > + The first entry must be a link to the SCFG device node > + The second entry must be '0' or '1' based on physical PCIe controller index. > + used to get SCFG PEXN registers > + > +Example: > + > + pcie@3400000 { > + compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; > + reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ > + 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ > + reg-names = "regs", "config"; > + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ > + interrupt-names = "intr"; > + fsl,pcie-scfg = <&scfg 0>; > + #address-cells = <3>; > + #size-cells = <2>; > + device_type = "pci"; > + num-lanes = <4>; > + bus-range = <0x0 0xff>; > + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ > + 0xc2000000 0x0 0x20000000 0x40 0x20000000 0x0 0x20000000 /* prefetchable memory */ > + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ > + #interrupt-cells = <1>; > + interrupt-map-mask = <0 0 0 7>; > + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, > + <0000 0 0 2 &gic GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, > + <0000 0 0 3 &gic GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, > + <0000 0 0 4 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; > + }; > diff --git a/MAINTAINERS b/MAINTAINERS > index a20df9b..7853d1b 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6983,6 +6983,16 @@ S: Maintained > F: Documentation/devicetree/bindings/pci/xgene-pci.txt > F: drivers/pci/host/pci-xgene.c > > +PCIe DRIVER FOR FREESCALE LAYERSCAPE > +M: Minghuan Lian <minghuan.Lian@freescale.com> > +M: Mingkai Hu <mingkai.hu@freescale.com> > +M: Roy Zang <tie-fei.zang@freescale.com> > +L: linuxppc-dev@lists.ozlabs.org > +L: linux-pci@vger.kernel.org > +L: linux-arm-kernel@lists.infradead.org > +S: Maintained > +F: drivers/pci/host/pci-layerscape.c > + > PCI DRIVER FOR IMX6 > M: Richard Zhu <r65037@freescale.com> > M: Lucas Stach <l.stach@pengutronix.de> > diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig > index 3dc25fa..8ac69aa 100644 > --- a/drivers/pci/host/Kconfig > +++ b/drivers/pci/host/Kconfig > @@ -91,4 +91,12 @@ config PCI_XGENE > There are 5 internal PCIe ports available. Each port is GEN3 capable > and have varied lanes from x1 to x8. > > +config PCI_LAYERSCAPE > + bool "Freescale Layerscape PCIe controller" > + depends on OF > + select PCIE_DW > + select MFD_SYSCON > + help > + Say Y here if you want PCIe controller support on Layerscape SoCs. > + > endmenu > diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile > index 26b3461..44c2699 100644 > --- a/drivers/pci/host/Makefile > +++ b/drivers/pci/host/Makefile > @@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o > obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o > obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o > obj-$(CONFIG_PCI_XGENE) += pci-xgene.o > +obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o > diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c > new file mode 100644 > index 0000000..6697b1a > --- /dev/null > +++ b/drivers/pci/host/pci-layerscape.c > @@ -0,0 +1,179 @@ > +/* > + * PCIe host controller driver for Freescale Layerscape SoCs > + * > + * Copyright (C) 2014 Freescale Semiconductor. > + * > + * Author: Minghuan Lian <Minghuan.Lian@freescale.com> > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#include <linux/kernel.h> > +#include <linux/delay.h> > +#include <linux/interrupt.h> > +#include <linux/module.h> > +#include <linux/of_pci.h> > +#include <linux/of_platform.h> > +#include <linux/of_irq.h> > +#include <linux/of_address.h> > +#include <linux/pci.h> > +#include <linux/platform_device.h> > +#include <linux/resource.h> > +#include <linux/mfd/syscon.h> > +#include <linux/regmap.h> > + > +#include "pcie-designware.h" > + > +/* PEX1/2 Misc Ports Status Register */ > +#define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4) > +#define LTSSM_STATE_SHIFT 20 > +#define LTSSM_STATE_MASK 0x3f > +#define LTSSM_PCIE_L0 0x11 /* L0 state */ > + > +/* Symbol Timer Register and Filter Mask Register 1 */ > +#define PCIE_STRFMR1 0x71c > + > +struct ls_pcie { > + struct list_head node; > + struct device *dev; > + struct pci_bus *bus; > + void __iomem *dbi; > + struct regmap *scfg; > + struct pcie_port pp; > + int index; > + int msi_irq; > +}; > + > +#define to_ls_pcie(x) container_of(x, struct ls_pcie, pp) > + > +static int ls_pcie_link_up(struct pcie_port *pp) > +{ > + u32 state; > + struct ls_pcie *pcie = to_ls_pcie(pp); > + > + regmap_read(pcie->scfg, SCFG_PEXMSCPORTSR(pcie->index), &state); > + state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK; > + > + if (state < LTSSM_PCIE_L0) > + return 0; > + > + return 1; > +} > + > +static void ls_pcie_host_init(struct pcie_port *pp) > +{ > + struct ls_pcie *pcie = to_ls_pcie(pp); > + int count = 0; > + u32 val; > + > + dw_pcie_setup_rc(pp); > + > + while (!ls_pcie_link_up(pp)) { > + usleep_range(100, 1000); > + count++; > + if (count >= 200) { > + dev_err(pp->dev, "phy link never came up\n"); > + return; > + } > + } > + > + /* > + * LS1021A Workaround for internal TKT228622 > + * to fix the INTx hang issue > + */ > + val = ioread32(pcie->dbi + PCIE_STRFMR1); > + val &= 0xffff; > + iowrite32(val, pcie->dbi + PCIE_STRFMR1); > +} > + > +static struct pcie_host_ops ls_pcie_host_ops = { > + .link_up = ls_pcie_link_up, > + .host_init = ls_pcie_host_init, > +}; > + > +static int ls_add_pcie_port(struct ls_pcie *pcie) > +{ > + struct pcie_port *pp; > + int ret; > + > + pp = &pcie->pp; > + pp->dev = pcie->dev; > + pp->dbi_base = pcie->dbi; > + pp->root_bus_nr = -1; > + pp->ops = &ls_pcie_host_ops; > + > + ret = dw_pcie_host_init(pp); > + if (ret) { > + dev_err(pp->dev, "failed to initialize host\n"); > + return ret; > + } > + > + return 0; > +} > + > +static int __init ls_pcie_probe(struct platform_device *pdev) > +{ > + struct ls_pcie *pcie; > + struct resource *dbi_base; > + u32 index[2]; > + int ret; > + > + pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); > + if (!pcie) > + return -ENOMEM; > + > + pcie->dev = &pdev->dev; > + > + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); > + if (!dbi_base) { > + dev_err(&pdev->dev, "missing *regs* space\n"); > + return -ENODEV; > + } > + > + pcie->dbi = devm_ioremap_resource(&pdev->dev, dbi_base); > + if (IS_ERR(pcie->dbi)) > + return PTR_ERR(pcie->dbi); > + > + pcie->scfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, > + "fsl,pcie-scfg"); > + if (IS_ERR(pcie->scfg)) { > + dev_err(&pdev->dev, "No syscfg phandle specified\n"); > + return PTR_ERR(pcie->scfg); > + } > + > + ret = of_property_read_u32_array(pdev->dev.of_node, > + "fsl,pcie-scfg", index, 2); > + if (ret) > + return ret; > + pcie->index = index[1]; > + > + ret = ls_add_pcie_port(pcie); > + if (ret < 0) > + return ret; > + > + platform_set_drvdata(pdev, pcie); > + > + return 0; > +} > + > +static const struct of_device_id ls_pcie_of_match[] = { > + { .compatible = "fsl,ls1021a-pcie" }, > + { }, > +}; > +MODULE_DEVICE_TABLE(of, ls_pcie_of_match); > + > +static struct platform_driver ls_pcie_driver = { > + .driver = { > + .name = "layerscape-pcie", > + .owner = THIS_MODULE, > + .of_match_table = ls_pcie_of_match, > + }, > +}; > + > +module_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); > + > +MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>"); > +MODULE_DESCRIPTION("Freescale Layerscape PCIe host controller driver"); > +MODULE_LICENSE("GPL v2"); > -- > 1.9.1 > -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thursday 13 November 2014 09:38:33 Bjorn Helgaas wrote: > On Wed, Nov 05, 2014 at 04:45:11PM +0800, Minghuan Lian wrote: > > Add support for Freescale Layerscape PCIe controller. This driver > > re-uses the designware core code. > > > > Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> > > Applied with Arnd's ack to pci/host-layerscape for v3.19, thanks! > the build bot just came back with an error: make.cross ARCH=xtensa All error/warnings: >> drivers/pci/host/pcie-designware.c:168:52: warning: 'struct pci_sys_data' declared inside parameter list static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) ^ >> drivers/pci/host/pcie-designware.c:168:52: warning: its scope is only this definition or declaration, which is probably not what you want drivers/pci/host/pcie-designware.c: In function 'sys_to_pcie': drivers/pci/host/pcie-designware.c:170:12: error: dereferencing pointer to incomplete type return sys->private_data; ^ drivers/pci/host/pcie-designware.c: At top level: >> drivers/pci/host/pcie-designware.c:397:45: warning: 'struct pci_sys_data' declared inside parameter list The new Kconfig symbol evidently needs a 'depends on ARM'. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt new file mode 100644 index 0000000..40749eb --- /dev/null +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -0,0 +1,42 @@ +Freescale Layerscape PCIe controller + +This PCIe host controller is based on the Synopsis Designware PCIe IP +and thus inherits all the common properties defined in designware-pcie.txt. + +Required properties: +- compatible: should contain the platform identifier such as "fsl,ls1021a-pcie" +- reg: base addresses and lengths of the PCIe controller +- interrupts: A list of interrupt outputs of the controller. Must contain an + entry for each entry in the interrupt-names property. +- interrupt-names: Must include the following entries: + "intr": The interrupt that is asserted for controller interrupts +- fsl,pcie-scfg: Must include two entries. + The first entry must be a link to the SCFG device node + The second entry must be '0' or '1' based on physical PCIe controller index. + used to get SCFG PEXN registers + +Example: + + pcie@3400000 { + compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; + reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ + 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; /* controller interrupt */ + interrupt-names = "intr"; + fsl,pcie-scfg = <&scfg 0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + num-lanes = <4>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0xc2000000 0x0 0x20000000 0x40 0x20000000 0x0 0x20000000 /* prefetchable memory */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index a20df9b..7853d1b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6983,6 +6983,16 @@ S: Maintained F: Documentation/devicetree/bindings/pci/xgene-pci.txt F: drivers/pci/host/pci-xgene.c +PCIe DRIVER FOR FREESCALE LAYERSCAPE +M: Minghuan Lian <minghuan.Lian@freescale.com> +M: Mingkai Hu <mingkai.hu@freescale.com> +M: Roy Zang <tie-fei.zang@freescale.com> +L: linuxppc-dev@lists.ozlabs.org +L: linux-pci@vger.kernel.org +L: linux-arm-kernel@lists.infradead.org +S: Maintained +F: drivers/pci/host/pci-layerscape.c + PCI DRIVER FOR IMX6 M: Richard Zhu <r65037@freescale.com> M: Lucas Stach <l.stach@pengutronix.de> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 3dc25fa..8ac69aa 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -91,4 +91,12 @@ config PCI_XGENE There are 5 internal PCIe ports available. Each port is GEN3 capable and have varied lanes from x1 to x8. +config PCI_LAYERSCAPE + bool "Freescale Layerscape PCIe controller" + depends on OF + select PCIE_DW + select MFD_SYSCON + help + Say Y here if you want PCIe controller support on Layerscape SoCs. + endmenu diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 26b3461..44c2699 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o obj-$(CONFIG_PCI_XGENE) += pci-xgene.o +obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c new file mode 100644 index 0000000..6697b1a --- /dev/null +++ b/drivers/pci/host/pci-layerscape.c @@ -0,0 +1,179 @@ +/* + * PCIe host controller driver for Freescale Layerscape SoCs + * + * Copyright (C) 2014 Freescale Semiconductor. + * + * Author: Minghuan Lian <Minghuan.Lian@freescale.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of_pci.h> +#include <linux/of_platform.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/resource.h> +#include <linux/mfd/syscon.h> +#include <linux/regmap.h> + +#include "pcie-designware.h" + +/* PEX1/2 Misc Ports Status Register */ +#define SCFG_PEXMSCPORTSR(pex_idx) (0x94 + (pex_idx) * 4) +#define LTSSM_STATE_SHIFT 20 +#define LTSSM_STATE_MASK 0x3f +#define LTSSM_PCIE_L0 0x11 /* L0 state */ + +/* Symbol Timer Register and Filter Mask Register 1 */ +#define PCIE_STRFMR1 0x71c + +struct ls_pcie { + struct list_head node; + struct device *dev; + struct pci_bus *bus; + void __iomem *dbi; + struct regmap *scfg; + struct pcie_port pp; + int index; + int msi_irq; +}; + +#define to_ls_pcie(x) container_of(x, struct ls_pcie, pp) + +static int ls_pcie_link_up(struct pcie_port *pp) +{ + u32 state; + struct ls_pcie *pcie = to_ls_pcie(pp); + + regmap_read(pcie->scfg, SCFG_PEXMSCPORTSR(pcie->index), &state); + state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK; + + if (state < LTSSM_PCIE_L0) + return 0; + + return 1; +} + +static void ls_pcie_host_init(struct pcie_port *pp) +{ + struct ls_pcie *pcie = to_ls_pcie(pp); + int count = 0; + u32 val; + + dw_pcie_setup_rc(pp); + + while (!ls_pcie_link_up(pp)) { + usleep_range(100, 1000); + count++; + if (count >= 200) { + dev_err(pp->dev, "phy link never came up\n"); + return; + } + } + + /* + * LS1021A Workaround for internal TKT228622 + * to fix the INTx hang issue + */ + val = ioread32(pcie->dbi + PCIE_STRFMR1); + val &= 0xffff; + iowrite32(val, pcie->dbi + PCIE_STRFMR1); +} + +static struct pcie_host_ops ls_pcie_host_ops = { + .link_up = ls_pcie_link_up, + .host_init = ls_pcie_host_init, +}; + +static int ls_add_pcie_port(struct ls_pcie *pcie) +{ + struct pcie_port *pp; + int ret; + + pp = &pcie->pp; + pp->dev = pcie->dev; + pp->dbi_base = pcie->dbi; + pp->root_bus_nr = -1; + pp->ops = &ls_pcie_host_ops; + + ret = dw_pcie_host_init(pp); + if (ret) { + dev_err(pp->dev, "failed to initialize host\n"); + return ret; + } + + return 0; +} + +static int __init ls_pcie_probe(struct platform_device *pdev) +{ + struct ls_pcie *pcie; + struct resource *dbi_base; + u32 index[2]; + int ret; + + pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); + if (!pcie) + return -ENOMEM; + + pcie->dev = &pdev->dev; + + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); + if (!dbi_base) { + dev_err(&pdev->dev, "missing *regs* space\n"); + return -ENODEV; + } + + pcie->dbi = devm_ioremap_resource(&pdev->dev, dbi_base); + if (IS_ERR(pcie->dbi)) + return PTR_ERR(pcie->dbi); + + pcie->scfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "fsl,pcie-scfg"); + if (IS_ERR(pcie->scfg)) { + dev_err(&pdev->dev, "No syscfg phandle specified\n"); + return PTR_ERR(pcie->scfg); + } + + ret = of_property_read_u32_array(pdev->dev.of_node, + "fsl,pcie-scfg", index, 2); + if (ret) + return ret; + pcie->index = index[1]; + + ret = ls_add_pcie_port(pcie); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, pcie); + + return 0; +} + +static const struct of_device_id ls_pcie_of_match[] = { + { .compatible = "fsl,ls1021a-pcie" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ls_pcie_of_match); + +static struct platform_driver ls_pcie_driver = { + .driver = { + .name = "layerscape-pcie", + .owner = THIS_MODULE, + .of_match_table = ls_pcie_of_match, + }, +}; + +module_platform_driver_probe(ls_pcie_driver, ls_pcie_probe); + +MODULE_AUTHOR("Minghuan Lian <Minghuan.Lian@freescale.com>"); +MODULE_DESCRIPTION("Freescale Layerscape PCIe host controller driver"); +MODULE_LICENSE("GPL v2");
Add support for Freescale Layerscape PCIe controller. This driver re-uses the designware core code. Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> --- Based on pci-next branch Change log: v6: 1. remove MSI support. MSI driver will be implemented in a separate file 2. remove bitrev() because SCFG is set bit reverse mode as default. v5: 1. Add MAINTAINERS information 2. Remove unnecessary NULL pointer check 3. Use dev_dbg instead of dev_err in ls_pcie_msi_irq_handler() v4: 1. Add 'depends on OF' to Kconfig v3: 1. Add prefechable mem region and adjust mem region 2. Rename 'pcie-scfg' to 'fsl,pcie-scfg' 3. Change MSI interrupt handler 4. Use module_platform_driver_probe instead of subsys_initcall v2: 1. Add pcie-scfg to link scfg device node and remove "fsl, ls-pcie" compatible 2. Use regmap API to access scfg. 3. remove ls1021 PCI device ID. 4. remove unused irq pme_irq and ls_pcie_list. 5. Do not set scfg bit reverse mode .../devicetree/bindings/pci/layerscape-pci.txt | 42 +++++ MAINTAINERS | 10 ++ drivers/pci/host/Kconfig | 8 + drivers/pci/host/Makefile | 1 + drivers/pci/host/pci-layerscape.c | 179 +++++++++++++++++++++ 5 files changed, 240 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/layerscape-pci.txt create mode 100644 drivers/pci/host/pci-layerscape.c