atheros: v3.18: add context container for PCI driver

Add container and place all context specific variables and structure to
it.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>

SVN-Revision: 44719
owl
Felix Fietkau 2015-03-13 03:00:19 +00:00
parent 6d7e75fd99
commit 862a89b8f7
1 changed files with 70 additions and 53 deletions

View File

@ -10,7 +10,7 @@
obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
--- /dev/null --- /dev/null
+++ b/arch/mips/pci/pci-ar2315.c +++ 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 + * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License + * modify it under the terms of the GNU General Public License
@ -172,10 +172,22 @@
+/* ??? access BAR */ +/* ??? access BAR */
+#define AR2315_PCI_HOST_MBAR2 0x30000000 +#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 int ar2315_pci_cfg_access(int devfn, int where, int size, u32 *ptr, +static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus)
+ bool write) +{
+ struct pci_controller *hose = bus->sysdata;
+
+ return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl);
+}
+
+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 func = PCI_FUNC(devfn);
+ int dev = PCI_SLOT(devfn); + int dev = PCI_SLOT(devfn);
@ -195,7 +207,7 @@
+ +
+ mb(); /* PCI must see space change before we begin */ + 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); + isr = ar231x_read_reg(AR2315_PCI_ISR);
+ if (isr & AR2315_PCI_INT_ABORT) + if (isr & AR2315_PCI_INT_ABORT)
@ -203,7 +215,7 @@
+ +
+ if (write) { + if (write) {
+ value = (value & ~(mask << sh)) | *ptr << sh; + 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); + isr = ar231x_read_reg(AR2315_PCI_ISR);
+ if (isr & AR2315_PCI_INT_ABORT) + if (isr & AR2315_PCI_INT_ABORT)
+ goto exit_err; + goto exit_err;
@ -226,32 +238,40 @@
+ PCIBIOS_SUCCESSFUL; + 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, +static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned devfn, int where,
+ int where, int size, u32 *value) + int size, u32 *value)
+{ +{
+ struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus);
+
+ if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT)
+ return PCIBIOS_DEVICE_NOT_FOUND; + 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, +static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned devfn, int where,
+ int where, int size, u32 value) + int size, u32 value)
+{ +{
+ struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus);
+
+ if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) + if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT)
+ return PCIBIOS_DEVICE_NOT_FOUND; + 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 = { +static struct pci_ops ar2315_pci_ops = {
@ -259,49 +279,26 @@
+ .write = ar2315_pci_cfg_write, + .write = ar2315_pci_cfg_write,
+}; +};
+ +
+static struct resource ar2315_mem_resource = { +static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc)
+ .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)
+{ +{
+ unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0); + unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0);
+ int res; + int res;
+ u32 id; + 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) + if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID)
+ return -ENODEV; + return -ENODEV;
+ +
+ /* Program MBARs */ + /* 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_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_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); + AR2315_PCI_HOST_MBAR2);
+ +
+ /* Run */ + /* 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_MASTER | PCI_COMMAND_SPECIAL |
+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
+ PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); + PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);
@ -377,13 +374,23 @@
+ +
+static int ar2315_pci_probe(struct platform_device *pdev) +static int ar2315_pci_probe(struct platform_device *pdev)
+{ +{
+ struct ar2315_pci_ctrl *apc;
+ struct device *dev = &pdev->dev; + 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 */ + /* Remap PCI config space */
+ ar2315_pci_cfg_mem = devm_ioremap_nocache(dev, AR2315_PCIEXT, + apc->cfg_mem = devm_ioremap_nocache(dev, AR2315_PCIEXT,
+ AR2315_PCI_CFG_SIZE); + AR2315_PCI_CFG_SIZE);
+ if (!ar2315_pci_cfg_mem) { + if (!apc->cfg_mem) {
+ dev_err(dev, "failed to remap PCI config space\n"); + dev_err(dev, "failed to remap PCI config space\n");
+ return -ENOMEM; + return -ENOMEM;
+ } + }
@ -405,13 +412,23 @@
+ +
+ msleep(500); + msleep(500);
+ +
+ res = ar2315_pci_host_setup(); + err = ar2315_pci_host_setup(apc);
+ if (res) + if (err)
+ return res; + return err;
+ +
+ ar2315_pci_irq_init(); + 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; + return 0;
+} +}