diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/linux/atheros/patches-3.18/105-ar2315_pci.patch | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch index c3456ed2a2..02074ddf76 100644 --- a/target/linux/atheros/patches-3.18/105-ar2315_pci.patch +++ b/target/linux/atheros/patches-3.18/105-ar2315_pci.patch @@ -10,7 +10,7 @@ obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o --- /dev/null +++ b/arch/mips/pci/pci-ar2315.c -@@ -0,0 +1,428 @@ +@@ -0,0 +1,445 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License @@ -172,10 +172,22 @@ +/* ??? access BAR */ +#define AR2315_PCI_HOST_MBAR2 0x30000000 + -+static void __iomem *ar2315_pci_cfg_mem; ++struct ar2315_pci_ctrl { ++ void __iomem *cfg_mem; ++ struct pci_controller pci_ctrl; ++ struct resource mem_res; ++ struct resource io_res; ++}; ++ ++static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus) ++{ ++ struct pci_controller *hose = bus->sysdata; ++ ++ return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl); ++} + -+static int ar2315_pci_cfg_access(int devfn, int where, int size, u32 *ptr, -+ bool write) ++static int ar2315_pci_cfg_access(struct ar2315_pci_ctrl *apc, unsigned devfn, ++ int where, int size, u32 *ptr, bool write) +{ + int func = PCI_FUNC(devfn); + int dev = PCI_SLOT(devfn); @@ -195,7 +207,7 @@ + + mb(); /* PCI must see space change before we begin */ + -+ value = __raw_readl(ar2315_pci_cfg_mem + addr); ++ value = __raw_readl(apc->cfg_mem + addr); + + isr = ar231x_read_reg(AR2315_PCI_ISR); + if (isr & AR2315_PCI_INT_ABORT) @@ -203,7 +215,7 @@ + + if (write) { + value = (value & ~(mask << sh)) | *ptr << sh; -+ __raw_writel(value, ar2315_pci_cfg_mem + addr); ++ __raw_writel(value, apc->cfg_mem + addr); + isr = ar231x_read_reg(AR2315_PCI_ISR); + if (isr & AR2315_PCI_INT_ABORT) + goto exit_err; @@ -226,32 +238,40 @@ + PCIBIOS_SUCCESSFUL; +} + -+static inline int ar2315_pci_local_cfg_rd(unsigned devfn, int where, u32 *val) ++static inline int ar2315_pci_local_cfg_rd(struct ar2315_pci_ctrl *apc, ++ unsigned devfn, int where, u32 *val) +{ -+ return ar2315_pci_cfg_access(devfn, where, sizeof(u32), val, false); ++ return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), val, ++ false); +} + -+static inline int ar2315_pci_local_cfg_wr(unsigned devfn, int where, u32 val) ++static inline int ar2315_pci_local_cfg_wr(struct ar2315_pci_ctrl *apc, ++ unsigned devfn, int where, u32 val) +{ -+ return ar2315_pci_cfg_access(devfn, where, sizeof(u32), &val, true); ++ return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), &val, ++ true); +} + -+static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 *value) ++static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned devfn, int where, ++ int size, u32 *value) +{ ++ struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); ++ + if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + return PCIBIOS_DEVICE_NOT_FOUND; + -+ return ar2315_pci_cfg_access(devfn, where, size, value, 0); ++ return ar2315_pci_cfg_access(apc, devfn, where, size, value, false); +} + -+static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 value) ++static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned devfn, int where, ++ int size, u32 value) +{ ++ struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); ++ + if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + return PCIBIOS_DEVICE_NOT_FOUND; + -+ return ar2315_pci_cfg_access(devfn, where, size, &value, 1); ++ return ar2315_pci_cfg_access(apc, devfn, where, size, &value, true); +} + +static struct pci_ops ar2315_pci_ops = { @@ -259,49 +279,26 @@ + .write = ar2315_pci_cfg_write, +}; + -+static struct resource ar2315_mem_resource = { -+ .name = "ar2315-pci-mem", -+ .start = AR2315_PCIEXT, -+ .end = AR2315_PCIEXT + AR2315_PCIEXT_SZ - 1, -+ .flags = IORESOURCE_MEM, -+}; -+ -+/* PCI controller does not support I/O ports */ -+static struct resource ar2315_io_resource = { -+ .name = "ar2315-pci-io", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_IO, -+}; -+ -+static struct pci_controller ar2315_pci_controller = { -+ .pci_ops = &ar2315_pci_ops, -+ .mem_resource = &ar2315_mem_resource, -+ .io_resource = &ar2315_io_resource, -+ .mem_offset = 0x00000000UL, -+ .io_offset = 0x00000000UL, -+}; -+ -+static int ar2315_pci_host_setup(void) ++static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc) +{ + unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0); + int res; + u32 id; + -+ res = ar2315_pci_local_cfg_rd(devfn, PCI_VENDOR_ID, &id); ++ res = ar2315_pci_local_cfg_rd(apc, devfn, PCI_VENDOR_ID, &id); + if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID) + return -ENODEV; + + /* Program MBARs */ -+ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_0, ++ ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_0, + AR2315_PCI_HOST_MBAR0); -+ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_1, ++ ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_1, + AR2315_PCI_HOST_MBAR1); -+ ar2315_pci_local_cfg_wr(devfn, PCI_BASE_ADDRESS_2, ++ ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_2, + AR2315_PCI_HOST_MBAR2); + + /* Run */ -+ ar2315_pci_local_cfg_wr(devfn, PCI_COMMAND, PCI_COMMAND_MEMORY | ++ ar2315_pci_local_cfg_wr(apc, devfn, PCI_COMMAND, PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL | + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | + PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); @@ -377,13 +374,23 @@ + +static int ar2315_pci_probe(struct platform_device *pdev) +{ ++ struct ar2315_pci_ctrl *apc; + struct device *dev = &pdev->dev; -+ int res; ++ int err; ++ ++ apc = devm_kzalloc(dev, sizeof(*apc), GFP_KERNEL); ++ if (!apc) ++ return -ENOMEM; ++ ++ apc->mem_res.name = "AR2315 PCI mem space"; ++ apc->mem_res.start = AR2315_PCIEXT; ++ apc->mem_res.end = AR2315_PCIEXT + AR2315_PCIEXT_SZ - 1; ++ apc->mem_res.flags = IORESOURCE_MEM; + + /* Remap PCI config space */ -+ ar2315_pci_cfg_mem = devm_ioremap_nocache(dev, AR2315_PCIEXT, -+ AR2315_PCI_CFG_SIZE); -+ if (!ar2315_pci_cfg_mem) { ++ apc->cfg_mem = devm_ioremap_nocache(dev, AR2315_PCIEXT, ++ AR2315_PCI_CFG_SIZE); ++ if (!apc->cfg_mem) { + dev_err(dev, "failed to remap PCI config space\n"); + return -ENOMEM; + } @@ -405,13 +412,23 @@ + + msleep(500); + -+ res = ar2315_pci_host_setup(); -+ if (res) -+ return res; ++ err = ar2315_pci_host_setup(apc); ++ if (err) ++ return err; + + ar2315_pci_irq_init(); + -+ register_pci_controller(&ar2315_pci_controller); ++ /* PCI controller does not support I/O ports */ ++ apc->io_res.name = "AR2315 IO space"; ++ apc->io_res.start = 0; ++ apc->io_res.end = 0; ++ apc->io_res.flags = IORESOURCE_IO, ++ ++ apc->pci_ctrl.pci_ops = &ar2315_pci_ops; ++ apc->pci_ctrl.mem_resource = &apc->mem_res, ++ apc->pci_ctrl.io_resource = &apc->io_res, ++ ++ register_pci_controller(&apc->pci_ctrl); + + return 0; +} |