aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci/pci.c
diff options
context:
space:
mode:
authorJohn Crispin <blogic@openwrt.org>2012-05-04 04:50:13 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-05-15 11:49:19 -0400
commita48cf37ac8a77ddd2370be3c9af411c622ebc425 (patch)
tree7326beae68f1fafd924b9436ec2c1551e36f94b8 /arch/mips/pci/pci.c
parent3572a2c37f667ee49333f8863722b8f43eac506b (diff)
MIPS: pci: parse memory ranges from devicetree
Implement pci_load_of_ranges on MIPS. Due to lack of test hardware only 32bit bus width is supported. This function is based on pci_process_bridge_OF_ranges from powerpc. Signed-off-by: John Crispin <blogic@openwrt.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/3729/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/pci/pci.c')
-rw-r--r--arch/mips/pci/pci.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 0514866fa925..271e8c4a54c7 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/of_address.h>
19 20
20#include <asm/cpu-info.h> 21#include <asm/cpu-info.h>
21 22
@@ -114,9 +115,63 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
114 pci_bus_assign_resources(bus); 115 pci_bus_assign_resources(bus);
115 pci_enable_bridges(bus); 116 pci_enable_bridges(bus);
116 } 117 }
118 bus->dev.of_node = hose->of_node;
117 } 119 }
118} 120}
119 121
122#ifdef CONFIG_OF
123void __devinit pci_load_of_ranges(struct pci_controller *hose,
124 struct device_node *node)
125{
126 const __be32 *ranges;
127 int rlen;
128 int pna = of_n_addr_cells(node);
129 int np = pna + 5;
130
131 pr_info("PCI host bridge %s ranges:\n", node->full_name);
132 ranges = of_get_property(node, "ranges", &rlen);
133 if (ranges == NULL)
134 return;
135 hose->of_node = node;
136
137 while ((rlen -= np * 4) >= 0) {
138 u32 pci_space;
139 struct resource *res = NULL;
140 u64 addr, size;
141
142 pci_space = be32_to_cpup(&ranges[0]);
143 addr = of_translate_address(node, ranges + 3);
144 size = of_read_number(ranges + pna + 3, 2);
145 ranges += np;
146 switch ((pci_space >> 24) & 0x3) {
147 case 1: /* PCI IO space */
148 pr_info(" IO 0x%016llx..0x%016llx\n",
149 addr, addr + size - 1);
150 hose->io_map_base =
151 (unsigned long)ioremap(addr, size);
152 res = hose->io_resource;
153 res->flags = IORESOURCE_IO;
154 break;
155 case 2: /* PCI Memory space */
156 case 3: /* PCI 64 bits Memory space */
157 pr_info(" MEM 0x%016llx..0x%016llx\n",
158 addr, addr + size - 1);
159 res = hose->mem_resource;
160 res->flags = IORESOURCE_MEM;
161 break;
162 }
163 if (res != NULL) {
164 res->start = addr;
165 res->name = node->full_name;
166 res->end = res->start + size - 1;
167 res->parent = NULL;
168 res->sibling = NULL;
169 res->child = NULL;
170 }
171 }
172}
173#endif
174
120static DEFINE_MUTEX(pci_scan_mutex); 175static DEFINE_MUTEX(pci_scan_mutex);
121 176
122void __devinit register_pci_controller(struct pci_controller *hose) 177void __devinit register_pci_controller(struct pci_controller *hose)