mirror of https://github.com/hak5/openwrt-owl.git
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: 44719owl
parent
6d7e75fd99
commit
862a89b8f7
|
@ -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;
|
||||
+}
|
||||
|
|
Loading…
Reference in New Issue