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
--- /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 int ar2315_pci_cfg_access(int devfn, int where, int size, u32 *ptr,
+ bool write)
+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(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,
+ apc->cfg_mem = devm_ioremap_nocache(dev, AR2315_PCIEXT,
+ AR2315_PCI_CFG_SIZE);
+ if (!ar2315_pci_cfg_mem) {
+ 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;
+}