aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/atheros/patches-3.18/105-ar2315_pci.patch123
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;
+}