diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/isa-bridge.c | 271 | ||||
-rw-r--r-- | arch/powerpc/kernel/of_platform.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/pci_64.c | 358 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 7 |
5 files changed, 400 insertions, 246 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 3e779f07f21b..08ce7de7c768 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -65,7 +65,7 @@ obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o | |||
65 | module-$(CONFIG_PPC64) += module_64.o | 65 | module-$(CONFIG_PPC64) += module_64.o |
66 | obj-$(CONFIG_MODULES) += $(module-y) | 66 | obj-$(CONFIG_MODULES) += $(module-y) |
67 | 67 | ||
68 | pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o | 68 | pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o isa-bridge.o |
69 | pci32-$(CONFIG_PPC32) := pci_32.o | 69 | pci32-$(CONFIG_PPC32) := pci_32.o |
70 | obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) | 70 | obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) |
71 | obj-$(CONFIG_PCI_MSI) += msi.o | 71 | obj-$(CONFIG_PCI_MSI) += msi.o |
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c new file mode 100644 index 000000000000..f0f49d1be3d5 --- /dev/null +++ b/arch/powerpc/kernel/isa-bridge.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | * Routines for tracking a legacy ISA bridge | ||
3 | * | ||
4 | * Copyrigh 2007 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. | ||
5 | * | ||
6 | * Some bits and pieces moved over from pci_64.c | ||
7 | * | ||
8 | * Copyrigh 2003 Anton Blanchard <anton@au.ibm.com>, IBM Corp. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version | ||
13 | * 2 of the License, or (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #define DEBUG | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/notifier.h> | ||
24 | |||
25 | #include <asm/processor.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <asm/prom.h> | ||
28 | #include <asm/pci-bridge.h> | ||
29 | #include <asm/machdep.h> | ||
30 | #include <asm/ppc-pci.h> | ||
31 | #include <asm/firmware.h> | ||
32 | |||
33 | unsigned long isa_io_base; /* NULL if no ISA bus */ | ||
34 | EXPORT_SYMBOL(isa_io_base); | ||
35 | |||
36 | /* Cached ISA bridge dev. */ | ||
37 | static struct device_node *isa_bridge_devnode; | ||
38 | struct pci_dev *isa_bridge_pcidev; | ||
39 | EXPORT_SYMBOL_GPL(isa_bridge_pcidev); | ||
40 | |||
41 | #define ISA_SPACE_MASK 0x1 | ||
42 | #define ISA_SPACE_IO 0x1 | ||
43 | |||
44 | static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, | ||
45 | unsigned long phb_io_base_phys) | ||
46 | { | ||
47 | /* We should get some saner parsing here and remove these structs */ | ||
48 | struct pci_address { | ||
49 | u32 a_hi; | ||
50 | u32 a_mid; | ||
51 | u32 a_lo; | ||
52 | }; | ||
53 | |||
54 | struct isa_address { | ||
55 | u32 a_hi; | ||
56 | u32 a_lo; | ||
57 | }; | ||
58 | |||
59 | struct isa_range { | ||
60 | struct isa_address isa_addr; | ||
61 | struct pci_address pci_addr; | ||
62 | unsigned int size; | ||
63 | }; | ||
64 | |||
65 | const struct isa_range *range; | ||
66 | unsigned long pci_addr; | ||
67 | unsigned int isa_addr; | ||
68 | unsigned int size; | ||
69 | int rlen = 0; | ||
70 | |||
71 | range = of_get_property(isa_node, "ranges", &rlen); | ||
72 | if (range == NULL || (rlen < sizeof(struct isa_range))) | ||
73 | goto inval_range; | ||
74 | |||
75 | /* From "ISA Binding to 1275" | ||
76 | * The ranges property is laid out as an array of elements, | ||
77 | * each of which comprises: | ||
78 | * cells 0 - 1: an ISA address | ||
79 | * cells 2 - 4: a PCI address | ||
80 | * (size depending on dev->n_addr_cells) | ||
81 | * cell 5: the size of the range | ||
82 | */ | ||
83 | if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO) { | ||
84 | range++; | ||
85 | rlen -= sizeof(struct isa_range); | ||
86 | if (rlen < sizeof(struct isa_range)) | ||
87 | goto inval_range; | ||
88 | } | ||
89 | if ((range->isa_addr.a_hi && ISA_SPACE_MASK) != ISA_SPACE_IO) | ||
90 | goto inval_range; | ||
91 | |||
92 | isa_addr = range->isa_addr.a_lo; | ||
93 | pci_addr = (unsigned long) range->pci_addr.a_mid << 32 | | ||
94 | range->pci_addr.a_lo; | ||
95 | |||
96 | /* Assume these are both zero. Note: We could fix that and | ||
97 | * do a proper parsing instead ... oh well, that will do for | ||
98 | * now as nobody uses fancy mappings for ISA bridges | ||
99 | */ | ||
100 | if ((pci_addr != 0) || (isa_addr != 0)) { | ||
101 | printk(KERN_ERR "unexpected isa to pci mapping: %s\n", | ||
102 | __FUNCTION__); | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | /* Align size and make sure it's cropped to 64K */ | ||
107 | size = PAGE_ALIGN(range->size); | ||
108 | if (size > 0x10000) | ||
109 | size = 0x10000; | ||
110 | |||
111 | printk(KERN_ERR "no ISA IO ranges or unexpected isa range," | ||
112 | "mapping 64k\n"); | ||
113 | |||
114 | __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE, | ||
115 | size, _PAGE_NO_CACHE|_PAGE_GUARDED); | ||
116 | return; | ||
117 | |||
118 | inval_range: | ||
119 | printk(KERN_ERR "no ISA IO ranges or unexpected isa range," | ||
120 | "mapping 64k\n"); | ||
121 | __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE, | ||
122 | 0x10000, _PAGE_NO_CACHE|_PAGE_GUARDED); | ||
123 | } | ||
124 | |||
125 | |||
126 | /** | ||
127 | * isa_bridge_find_early - Find and map the ISA IO space early before | ||
128 | * main PCI discovery. This is optionally called by | ||
129 | * the arch code when adding PCI PHBs to get early | ||
130 | * access to ISA IO ports | ||
131 | */ | ||
132 | void __init isa_bridge_find_early(struct pci_controller *hose) | ||
133 | { | ||
134 | struct device_node *np, *parent = NULL, *tmp; | ||
135 | |||
136 | /* If we already have an ISA bridge, bail off */ | ||
137 | if (isa_bridge_devnode != NULL) | ||
138 | return; | ||
139 | |||
140 | /* For each "isa" node in the system. Note : we do a search by | ||
141 | * type and not by name. It might be better to do by name but that's | ||
142 | * what the code used to do and I don't want to break too much at | ||
143 | * once. We can look into changing that separately | ||
144 | */ | ||
145 | for_each_node_by_type(np, "isa") { | ||
146 | /* Look for our hose being a parent */ | ||
147 | for (parent = of_get_parent(np); parent;) { | ||
148 | if (parent == hose->arch_data) { | ||
149 | of_node_put(parent); | ||
150 | break; | ||
151 | } | ||
152 | tmp = parent; | ||
153 | parent = of_get_parent(parent); | ||
154 | of_node_put(tmp); | ||
155 | } | ||
156 | if (parent != NULL) | ||
157 | break; | ||
158 | } | ||
159 | if (np == NULL) | ||
160 | return; | ||
161 | isa_bridge_devnode = np; | ||
162 | |||
163 | /* Now parse the "ranges" property and setup the ISA mapping */ | ||
164 | pci_process_ISA_OF_ranges(np, hose->io_base_phys); | ||
165 | |||
166 | /* Set the global ISA io base to indicate we have an ISA bridge */ | ||
167 | isa_io_base = ISA_IO_BASE; | ||
168 | |||
169 | pr_debug("ISA bridge (early) is %s\n", np->full_name); | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * isa_bridge_find_late - Find and map the ISA IO space upon discovery of | ||
174 | * a new ISA bridge | ||
175 | */ | ||
176 | static void __devinit isa_bridge_find_late(struct pci_dev *pdev, | ||
177 | struct device_node *devnode) | ||
178 | { | ||
179 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | ||
180 | |||
181 | /* Store ISA device node and PCI device */ | ||
182 | isa_bridge_devnode = of_node_get(devnode); | ||
183 | isa_bridge_pcidev = pdev; | ||
184 | |||
185 | /* Now parse the "ranges" property and setup the ISA mapping */ | ||
186 | pci_process_ISA_OF_ranges(devnode, hose->io_base_phys); | ||
187 | |||
188 | /* Set the global ISA io base to indicate we have an ISA bridge */ | ||
189 | isa_io_base = ISA_IO_BASE; | ||
190 | |||
191 | pr_debug("ISA bridge (late) is %s on %s\n", | ||
192 | devnode->full_name, pci_name(pdev)); | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * isa_bridge_remove - Remove/unmap an ISA bridge | ||
197 | */ | ||
198 | static void isa_bridge_remove(void) | ||
199 | { | ||
200 | pr_debug("ISA bridge removed !\n"); | ||
201 | |||
202 | /* Clear the global ISA io base to indicate that we have no more | ||
203 | * ISA bridge. Note that drivers don't quite handle that, though | ||
204 | * we should probably do something about it. But do we ever really | ||
205 | * have ISA bridges being removed on machines using legacy devices ? | ||
206 | */ | ||
207 | isa_io_base = ISA_IO_BASE; | ||
208 | |||
209 | /* Clear references to the bridge */ | ||
210 | of_node_put(isa_bridge_devnode); | ||
211 | isa_bridge_devnode = NULL; | ||
212 | isa_bridge_pcidev = NULL; | ||
213 | |||
214 | /* Unmap the ISA area */ | ||
215 | __iounmap_at((void *)ISA_IO_BASE, 0x10000); | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * isa_bridge_notify - Get notified of PCI devices addition/removal | ||
220 | */ | ||
221 | static int __devinit isa_bridge_notify(struct notifier_block *nb, | ||
222 | unsigned long action, void *data) | ||
223 | { | ||
224 | struct device *dev = data; | ||
225 | struct pci_dev *pdev = to_pci_dev(dev); | ||
226 | struct device_node *devnode = pci_device_to_OF_node(pdev); | ||
227 | |||
228 | switch(action) { | ||
229 | case BUS_NOTIFY_ADD_DEVICE: | ||
230 | /* Check if we have an early ISA device, without PCI dev */ | ||
231 | if (isa_bridge_devnode && isa_bridge_devnode == devnode && | ||
232 | !isa_bridge_pcidev) { | ||
233 | pr_debug("ISA bridge PCI attached: %s\n", | ||
234 | pci_name(pdev)); | ||
235 | isa_bridge_pcidev = pdev; | ||
236 | } | ||
237 | |||
238 | /* Check if we have no ISA device, and this happens to be one, | ||
239 | * register it as such if it has an OF device | ||
240 | */ | ||
241 | if (!isa_bridge_devnode && devnode && devnode->type && | ||
242 | !strcmp(devnode->type, "isa")) | ||
243 | isa_bridge_find_late(pdev, devnode); | ||
244 | |||
245 | return 0; | ||
246 | case BUS_NOTIFY_DEL_DEVICE: | ||
247 | /* Check if this our existing ISA device */ | ||
248 | if (pdev == isa_bridge_pcidev || | ||
249 | (devnode && devnode == isa_bridge_devnode)) | ||
250 | isa_bridge_remove(); | ||
251 | return 0; | ||
252 | } | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static struct notifier_block isa_bridge_notifier = { | ||
257 | .notifier_call = isa_bridge_notify | ||
258 | }; | ||
259 | |||
260 | /** | ||
261 | * isa_bridge_init - register to be notified of ISA bridge addition/removal | ||
262 | * | ||
263 | */ | ||
264 | static int __init isa_bridge_init(void) | ||
265 | { | ||
266 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
267 | return 0; | ||
268 | bus_register_notifier(&pci_bus_type, &isa_bridge_notifier); | ||
269 | return 0; | ||
270 | } | ||
271 | arch_initcall(isa_bridge_init); | ||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index d454f61c9c7c..9536ed7f247c 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
@@ -427,14 +427,6 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, | |||
427 | /* Process "ranges" property */ | 427 | /* Process "ranges" property */ |
428 | pci_process_bridge_OF_ranges(phb, dev->node, 0); | 428 | pci_process_bridge_OF_ranges(phb, dev->node, 0); |
429 | 429 | ||
430 | /* Setup IO space. We use the non-dynamic version of that code here, | ||
431 | * which doesn't quite support unplugging. Next kernel release will | ||
432 | * have a better fix for this. | ||
433 | * Note also that we don't do ISA, this will also be fixed with a | ||
434 | * more massive rework. | ||
435 | */ | ||
436 | pci_setup_phb_io(phb, pci_io_base == 0); | ||
437 | |||
438 | /* Init pci_dn data structures */ | 430 | /* Init pci_dn data structures */ |
439 | pci_devs_phb_init_dynamic(phb); | 431 | pci_devs_phb_init_dynamic(phb); |
440 | 432 | ||
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 249cca27a9b8..6ae67ebfab4d 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -11,7 +11,7 @@ | |||
11 | * 2 of the License, or (at your option) any later version. | 11 | * 2 of the License, or (at your option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #undef DEBUG | 14 | #define DEBUG |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/syscalls.h> | 23 | #include <linux/syscalls.h> |
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/vmalloc.h> | ||
25 | 26 | ||
26 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
@@ -41,35 +42,26 @@ | |||
41 | 42 | ||
42 | unsigned long pci_probe_only = 1; | 43 | unsigned long pci_probe_only = 1; |
43 | int pci_assign_all_buses = 0; | 44 | int pci_assign_all_buses = 0; |
44 | static int pci_initial_scan_done; | ||
45 | 45 | ||
46 | static void fixup_resource(struct resource *res, struct pci_dev *dev); | 46 | static void fixup_resource(struct resource *res, struct pci_dev *dev); |
47 | static void do_bus_setup(struct pci_bus *bus); | 47 | static void do_bus_setup(struct pci_bus *bus); |
48 | static void phbs_remap_io(void); | ||
49 | 48 | ||
50 | /* pci_io_base -- the base address from which io bars are offsets. | 49 | /* pci_io_base -- the base address from which io bars are offsets. |
51 | * This is the lowest I/O base address (so bar values are always positive), | 50 | * This is the lowest I/O base address (so bar values are always positive), |
52 | * and it *must* be the start of ISA space if an ISA bus exists because | 51 | * and it *must* be the start of ISA space if an ISA bus exists because |
53 | * ISA drivers use hard coded offsets. If no ISA bus exists a dummy | 52 | * ISA drivers use hard coded offsets. If no ISA bus exists nothing |
54 | * page is mapped and isa_io_limit prevents access to it. | 53 | * is mapped on the first 64K of IO space |
55 | */ | 54 | */ |
56 | unsigned long isa_io_base; /* NULL if no ISA bus */ | 55 | unsigned long pci_io_base = ISA_IO_BASE; |
57 | EXPORT_SYMBOL(isa_io_base); | ||
58 | unsigned long pci_io_base; | ||
59 | EXPORT_SYMBOL(pci_io_base); | 56 | EXPORT_SYMBOL(pci_io_base); |
60 | 57 | ||
61 | void iSeries_pcibios_init(void); | ||
62 | |||
63 | LIST_HEAD(hose_list); | 58 | LIST_HEAD(hose_list); |
64 | 59 | ||
65 | static struct dma_mapping_ops *pci_dma_ops; | 60 | static struct dma_mapping_ops *pci_dma_ops; |
66 | 61 | ||
62 | /* XXX kill that some day ... */ | ||
67 | int global_phb_number; /* Global phb counter */ | 63 | int global_phb_number; /* Global phb counter */ |
68 | 64 | ||
69 | /* Cached ISA bridge dev. */ | ||
70 | struct pci_dev *ppc64_isabridge_dev = NULL; | ||
71 | EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); | ||
72 | |||
73 | void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) | 65 | void set_pci_dma_ops(struct dma_mapping_ops *dma_ops) |
74 | { | 66 | { |
75 | pci_dma_ops = dma_ops; | 67 | pci_dma_ops = dma_ops; |
@@ -100,7 +92,7 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region | |||
100 | return; | 92 | return; |
101 | 93 | ||
102 | if (res->flags & IORESOURCE_IO) | 94 | if (res->flags & IORESOURCE_IO) |
103 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | 95 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; |
104 | 96 | ||
105 | if (res->flags & IORESOURCE_MEM) | 97 | if (res->flags & IORESOURCE_MEM) |
106 | offset = hose->pci_mem_offset; | 98 | offset = hose->pci_mem_offset; |
@@ -119,7 +111,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | |||
119 | return; | 111 | return; |
120 | 112 | ||
121 | if (res->flags & IORESOURCE_IO) | 113 | if (res->flags & IORESOURCE_IO) |
122 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | 114 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; |
123 | 115 | ||
124 | if (res->flags & IORESOURCE_MEM) | 116 | if (res->flags & IORESOURCE_MEM) |
125 | offset = hose->pci_mem_offset; | 117 | offset = hose->pci_mem_offset; |
@@ -156,7 +148,7 @@ void pcibios_align_resource(void *data, struct resource *res, | |||
156 | 148 | ||
157 | if (res->flags & IORESOURCE_IO) { | 149 | if (res->flags & IORESOURCE_IO) { |
158 | unsigned long offset = (unsigned long)hose->io_base_virt - | 150 | unsigned long offset = (unsigned long)hose->io_base_virt - |
159 | pci_io_base; | 151 | _IO_BASE; |
160 | /* Make sure we start at our min on all hoses */ | 152 | /* Make sure we start at our min on all hoses */ |
161 | if (start - offset < PCIBIOS_MIN_IO) | 153 | if (start - offset < PCIBIOS_MIN_IO) |
162 | start = PCIBIOS_MIN_IO + offset; | 154 | start = PCIBIOS_MIN_IO + offset; |
@@ -535,10 +527,16 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
535 | bus->secondary = hose->first_busno; | 527 | bus->secondary = hose->first_busno; |
536 | hose->bus = bus; | 528 | hose->bus = bus; |
537 | 529 | ||
530 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
531 | pcibios_map_io_space(bus); | ||
532 | |||
538 | bus->resource[0] = res = &hose->io_resource; | 533 | bus->resource[0] = res = &hose->io_resource; |
539 | if (res->flags && request_resource(&ioport_resource, res)) | 534 | if (res->flags && request_resource(&ioport_resource, res)) { |
540 | printk(KERN_ERR "Failed to request PCI IO region " | 535 | printk(KERN_ERR "Failed to request PCI IO region " |
541 | "on PCI domain %04x\n", hose->global_number); | 536 | "on PCI domain %04x\n", hose->global_number); |
537 | DBG("res->start = 0x%016lx, res->end = 0x%016lx\n", | ||
538 | res->start, res->end); | ||
539 | } | ||
542 | 540 | ||
543 | for (i = 0; i < 3; ++i) { | 541 | for (i = 0; i < 3; ++i) { |
544 | res = &hose->mem_resources[i]; | 542 | res = &hose->mem_resources[i]; |
@@ -596,17 +594,6 @@ static int __init pcibios_init(void) | |||
596 | if (ppc_md.pcibios_fixup) | 594 | if (ppc_md.pcibios_fixup) |
597 | ppc_md.pcibios_fixup(); | 595 | ppc_md.pcibios_fixup(); |
598 | 596 | ||
599 | /* Cache the location of the ISA bridge (if we have one) */ | ||
600 | ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); | ||
601 | if (ppc64_isabridge_dev != NULL) | ||
602 | printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); | ||
603 | |||
604 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | ||
605 | /* map in PCI I/O space */ | ||
606 | phbs_remap_io(); | ||
607 | |||
608 | pci_initial_scan_done = 1; | ||
609 | |||
610 | printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); | 597 | printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); |
611 | 598 | ||
612 | return 0; | 599 | return 0; |
@@ -711,7 +698,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
711 | #endif | 698 | #endif |
712 | res_bit = IORESOURCE_MEM; | 699 | res_bit = IORESOURCE_MEM; |
713 | } else { | 700 | } else { |
714 | io_offset = (unsigned long)hose->io_base_virt - pci_io_base; | 701 | io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; |
715 | *offset += io_offset; | 702 | *offset += io_offset; |
716 | res_bit = IORESOURCE_IO; | 703 | res_bit = IORESOURCE_IO; |
717 | } | 704 | } |
@@ -881,76 +868,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev) | |||
881 | device_create_file(&pdev->dev, &dev_attr_devspec); | 868 | device_create_file(&pdev->dev, &dev_attr_devspec); |
882 | } | 869 | } |
883 | 870 | ||
884 | #define ISA_SPACE_MASK 0x1 | ||
885 | #define ISA_SPACE_IO 0x1 | ||
886 | |||
887 | static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, | ||
888 | unsigned long phb_io_base_phys, | ||
889 | void __iomem * phb_io_base_virt) | ||
890 | { | ||
891 | /* Remove these asap */ | ||
892 | |||
893 | struct pci_address { | ||
894 | u32 a_hi; | ||
895 | u32 a_mid; | ||
896 | u32 a_lo; | ||
897 | }; | ||
898 | |||
899 | struct isa_address { | ||
900 | u32 a_hi; | ||
901 | u32 a_lo; | ||
902 | }; | ||
903 | |||
904 | struct isa_range { | ||
905 | struct isa_address isa_addr; | ||
906 | struct pci_address pci_addr; | ||
907 | unsigned int size; | ||
908 | }; | ||
909 | |||
910 | const struct isa_range *range; | ||
911 | unsigned long pci_addr; | ||
912 | unsigned int isa_addr; | ||
913 | unsigned int size; | ||
914 | int rlen = 0; | ||
915 | |||
916 | range = of_get_property(isa_node, "ranges", &rlen); | ||
917 | if (range == NULL || (rlen < sizeof(struct isa_range))) { | ||
918 | printk(KERN_ERR "no ISA ranges or unexpected isa range size," | ||
919 | "mapping 64k\n"); | ||
920 | __ioremap_explicit(phb_io_base_phys, | ||
921 | (unsigned long)phb_io_base_virt, | ||
922 | 0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
923 | return; | ||
924 | } | ||
925 | |||
926 | /* From "ISA Binding to 1275" | ||
927 | * The ranges property is laid out as an array of elements, | ||
928 | * each of which comprises: | ||
929 | * cells 0 - 1: an ISA address | ||
930 | * cells 2 - 4: a PCI address | ||
931 | * (size depending on dev->n_addr_cells) | ||
932 | * cell 5: the size of the range | ||
933 | */ | ||
934 | if ((range->isa_addr.a_hi && ISA_SPACE_MASK) == ISA_SPACE_IO) { | ||
935 | isa_addr = range->isa_addr.a_lo; | ||
936 | pci_addr = (unsigned long) range->pci_addr.a_mid << 32 | | ||
937 | range->pci_addr.a_lo; | ||
938 | |||
939 | /* Assume these are both zero */ | ||
940 | if ((pci_addr != 0) || (isa_addr != 0)) { | ||
941 | printk(KERN_ERR "unexpected isa to pci mapping: %s\n", | ||
942 | __FUNCTION__); | ||
943 | return; | ||
944 | } | ||
945 | |||
946 | size = PAGE_ALIGN(range->size); | ||
947 | |||
948 | __ioremap_explicit(phb_io_base_phys, | ||
949 | (unsigned long) phb_io_base_virt, | ||
950 | size, _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
951 | } | ||
952 | } | ||
953 | |||
954 | void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | 871 | void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, |
955 | struct device_node *dev, int prim) | 872 | struct device_node *dev, int prim) |
956 | { | 873 | { |
@@ -1045,155 +962,122 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
1045 | } | 962 | } |
1046 | } | 963 | } |
1047 | 964 | ||
1048 | void __devinit pci_setup_phb_io(struct pci_controller *hose, int primary) | 965 | #ifdef CONFIG_HOTPLUG |
966 | |||
967 | int pcibios_unmap_io_space(struct pci_bus *bus) | ||
1049 | { | 968 | { |
1050 | unsigned long size = hose->pci_io_size; | 969 | struct pci_controller *hose; |
1051 | unsigned long io_virt_offset; | ||
1052 | struct resource *res; | ||
1053 | struct device_node *isa_dn; | ||
1054 | 970 | ||
1055 | if (size == 0) | 971 | WARN_ON(bus == NULL); |
1056 | return; | ||
1057 | 972 | ||
1058 | hose->io_base_virt = reserve_phb_iospace(size); | 973 | /* If this is not a PHB, we only flush the hash table over |
1059 | DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", | 974 | * the area mapped by this bridge. We don't play with the PTE |
1060 | hose->global_number, hose->io_base_phys, | 975 | * mappings since we might have to deal with sub-page alignemnts |
1061 | (unsigned long) hose->io_base_virt); | 976 | * so flushing the hash table is the only sane way to make sure |
1062 | 977 | * that no hash entries are covering that removed bridge area | |
1063 | if (primary) { | 978 | * while still allowing other busses overlapping those pages |
1064 | pci_io_base = (unsigned long)hose->io_base_virt; | 979 | */ |
1065 | isa_dn = of_find_node_by_type(NULL, "isa"); | 980 | if (bus->self) { |
1066 | if (isa_dn) { | 981 | struct resource *res = bus->resource[0]; |
1067 | isa_io_base = pci_io_base; | ||
1068 | pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys, | ||
1069 | hose->io_base_virt); | ||
1070 | of_node_put(isa_dn); | ||
1071 | } | ||
1072 | } | ||
1073 | 982 | ||
1074 | io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; | 983 | DBG("IO unmapping for PCI-PCI bridge %s\n", |
1075 | res = &hose->io_resource; | 984 | pci_name(bus->self)); |
1076 | res->start += io_virt_offset; | ||
1077 | res->end += io_virt_offset; | ||
1078 | 985 | ||
1079 | /* If this is called after the initial PCI scan, then we need to | 986 | __flush_hash_table_range(&init_mm, res->start + _IO_BASE, |
1080 | * proceed to IO mappings now | 987 | res->end - res->start + 1); |
1081 | */ | 988 | return 0; |
1082 | if (pci_initial_scan_done) | 989 | } |
1083 | __ioremap_explicit(hose->io_base_phys, | ||
1084 | (unsigned long)hose->io_base_virt, | ||
1085 | hose->pci_io_size, | ||
1086 | _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
1087 | } | ||
1088 | 990 | ||
1089 | void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose, | 991 | /* Get the host bridge */ |
1090 | int primary) | 992 | hose = pci_bus_to_host(bus); |
1091 | { | ||
1092 | unsigned long size = hose->pci_io_size; | ||
1093 | unsigned long io_virt_offset; | ||
1094 | struct resource *res; | ||
1095 | 993 | ||
1096 | if (size == 0) | 994 | /* Check if we have IOs allocated */ |
1097 | return; | 995 | if (hose->io_base_alloc == 0) |
996 | return 0; | ||
1098 | 997 | ||
1099 | hose->io_base_virt = __ioremap(hose->io_base_phys, size, | 998 | DBG("IO unmapping for PHB %s\n", |
1100 | _PAGE_NO_CACHE | _PAGE_GUARDED); | 999 | ((struct device_node *)hose->arch_data)->full_name); |
1101 | DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n", | 1000 | DBG(" alloc=0x%p\n", hose->io_base_alloc); |
1102 | hose->global_number, hose->io_base_phys, | ||
1103 | (unsigned long) hose->io_base_virt); | ||
1104 | 1001 | ||
1105 | if (primary) | 1002 | /* This is a PHB, we fully unmap the IO area */ |
1106 | pci_io_base = (unsigned long)hose->io_base_virt; | 1003 | vunmap(hose->io_base_alloc); |
1107 | 1004 | ||
1108 | io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base; | 1005 | return 0; |
1109 | res = &hose->io_resource; | ||
1110 | res->start += io_virt_offset; | ||
1111 | res->end += io_virt_offset; | ||
1112 | } | 1006 | } |
1007 | EXPORT_SYMBOL_GPL(pcibios_unmap_io_space); | ||
1113 | 1008 | ||
1009 | #endif /* CONFIG_HOTPLUG */ | ||
1114 | 1010 | ||
1115 | static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys, | 1011 | int __devinit pcibios_map_io_space(struct pci_bus *bus) |
1116 | unsigned long *start_virt, unsigned long *size) | ||
1117 | { | 1012 | { |
1118 | struct pci_controller *hose = pci_bus_to_host(bus); | 1013 | struct vm_struct *area; |
1119 | struct resource *res; | 1014 | unsigned long phys_page; |
1120 | 1015 | unsigned long size_page; | |
1121 | if (bus->self) | 1016 | unsigned long io_virt_offset; |
1122 | res = bus->resource[0]; | 1017 | struct pci_controller *hose; |
1123 | else | ||
1124 | /* Root Bus */ | ||
1125 | res = &hose->io_resource; | ||
1126 | |||
1127 | if (res->end == 0 && res->start == 0) | ||
1128 | return 1; | ||
1129 | 1018 | ||
1130 | *start_virt = pci_io_base + res->start; | 1019 | WARN_ON(bus == NULL); |
1131 | *start_phys = *start_virt + hose->io_base_phys | ||
1132 | - (unsigned long) hose->io_base_virt; | ||
1133 | 1020 | ||
1134 | if (res->end > res->start) | 1021 | /* If this not a PHB, nothing to do, page tables still exist and |
1135 | *size = res->end - res->start + 1; | 1022 | * thus HPTEs will be faulted in when needed |
1136 | else { | 1023 | */ |
1137 | printk("%s(): unexpected region 0x%lx->0x%lx\n", | 1024 | if (bus->self) { |
1138 | __FUNCTION__, res->start, res->end); | 1025 | DBG("IO mapping for PCI-PCI bridge %s\n", |
1139 | return 1; | 1026 | pci_name(bus->self)); |
1027 | DBG(" virt=0x%016lx...0x%016lx\n", | ||
1028 | bus->resource[0]->start + _IO_BASE, | ||
1029 | bus->resource[0]->end + _IO_BASE); | ||
1030 | return 0; | ||
1140 | } | 1031 | } |
1141 | 1032 | ||
1142 | return 0; | 1033 | /* Get the host bridge */ |
1143 | } | 1034 | hose = pci_bus_to_host(bus); |
1144 | 1035 | phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE); | |
1145 | int unmap_bus_range(struct pci_bus *bus) | 1036 | size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE); |
1146 | { | ||
1147 | unsigned long start_phys; | ||
1148 | unsigned long start_virt; | ||
1149 | unsigned long size; | ||
1150 | |||
1151 | if (!bus) { | ||
1152 | printk(KERN_ERR "%s() expected bus\n", __FUNCTION__); | ||
1153 | return 1; | ||
1154 | } | ||
1155 | |||
1156 | if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) | ||
1157 | return 1; | ||
1158 | if (__iounmap_explicit((void __iomem *) start_virt, size)) | ||
1159 | return 1; | ||
1160 | 1037 | ||
1161 | return 0; | 1038 | /* Make sure IO area address is clear */ |
1162 | } | 1039 | hose->io_base_alloc = NULL; |
1163 | EXPORT_SYMBOL(unmap_bus_range); | ||
1164 | 1040 | ||
1165 | int remap_bus_range(struct pci_bus *bus) | 1041 | /* If there's no IO to map on that bus, get away too */ |
1166 | { | 1042 | if (hose->pci_io_size == 0 || hose->io_base_phys == 0) |
1167 | unsigned long start_phys; | 1043 | return 0; |
1168 | unsigned long start_virt; | ||
1169 | unsigned long size; | ||
1170 | 1044 | ||
1171 | if (!bus) { | 1045 | /* Let's allocate some IO space for that guy. We don't pass |
1172 | printk(KERN_ERR "%s() expected bus\n", __FUNCTION__); | 1046 | * VM_IOREMAP because we don't care about alignment tricks that |
1173 | return 1; | 1047 | * the core does in that case. Maybe we should due to stupid card |
1174 | } | 1048 | * with incomplete address decoding but I'd rather not deal with |
1175 | 1049 | * those outside of the reserved 64K legacy region. | |
1176 | 1050 | */ | |
1177 | if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) | 1051 | area = __get_vm_area(size_page, 0, PHB_IO_BASE, PHB_IO_END); |
1178 | return 1; | 1052 | if (area == NULL) |
1179 | if (start_phys == 0) | 1053 | return -ENOMEM; |
1180 | return 1; | 1054 | hose->io_base_alloc = area->addr; |
1181 | printk(KERN_DEBUG "mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size); | 1055 | hose->io_base_virt = (void __iomem *)(area->addr + |
1182 | if (__ioremap_explicit(start_phys, start_virt, size, | 1056 | hose->io_base_phys - phys_page); |
1183 | _PAGE_NO_CACHE | _PAGE_GUARDED)) | 1057 | |
1184 | return 1; | 1058 | DBG("IO mapping for PHB %s\n", |
1059 | ((struct device_node *)hose->arch_data)->full_name); | ||
1060 | DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", | ||
1061 | hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); | ||
1062 | DBG(" size=0x%016lx (alloc=0x%016lx)\n", | ||
1063 | hose->pci_io_size, size_page); | ||
1064 | |||
1065 | /* Establish the mapping */ | ||
1066 | if (__ioremap_at(phys_page, area->addr, size_page, | ||
1067 | _PAGE_NO_CACHE | _PAGE_GUARDED) == NULL) | ||
1068 | return -ENOMEM; | ||
1069 | |||
1070 | /* Fixup hose IO resource */ | ||
1071 | io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
1072 | hose->io_resource.start += io_virt_offset; | ||
1073 | hose->io_resource.end += io_virt_offset; | ||
1074 | |||
1075 | DBG(" hose->io_resource=0x%016lx...0x%016lx\n", | ||
1076 | hose->io_resource.start, hose->io_resource.end); | ||
1185 | 1077 | ||
1186 | return 0; | 1078 | return 0; |
1187 | } | 1079 | } |
1188 | EXPORT_SYMBOL(remap_bus_range); | 1080 | EXPORT_SYMBOL_GPL(pcibios_map_io_space); |
1189 | |||
1190 | static void phbs_remap_io(void) | ||
1191 | { | ||
1192 | struct pci_controller *hose, *tmp; | ||
1193 | |||
1194 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | ||
1195 | remap_bus_range(hose->bus); | ||
1196 | } | ||
1197 | 1081 | ||
1198 | static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) | 1082 | static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) |
1199 | { | 1083 | { |
@@ -1201,8 +1085,7 @@ static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) | |||
1201 | unsigned long offset; | 1085 | unsigned long offset; |
1202 | 1086 | ||
1203 | if (res->flags & IORESOURCE_IO) { | 1087 | if (res->flags & IORESOURCE_IO) { |
1204 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | 1088 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; |
1205 | |||
1206 | res->start += offset; | 1089 | res->start += offset; |
1207 | res->end += offset; | 1090 | res->end += offset; |
1208 | } else if (res->flags & IORESOURCE_MEM) { | 1091 | } else if (res->flags & IORESOURCE_MEM) { |
@@ -1217,9 +1100,20 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, | |||
1217 | /* Update device resources. */ | 1100 | /* Update device resources. */ |
1218 | int i; | 1101 | int i; |
1219 | 1102 | ||
1220 | for (i = 0; i < PCI_NUM_RESOURCES; i++) | 1103 | DBG("%s: Fixup resources:\n", pci_name(dev)); |
1221 | if (dev->resource[i].flags) | 1104 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { |
1222 | fixup_resource(&dev->resource[i], dev); | 1105 | struct resource *res = &dev->resource[i]; |
1106 | if (!res->flags) | ||
1107 | continue; | ||
1108 | |||
1109 | DBG(" 0x%02x < %08lx:0x%016lx...0x%016lx\n", | ||
1110 | i, res->flags, res->start, res->end); | ||
1111 | |||
1112 | fixup_resource(res, dev); | ||
1113 | |||
1114 | DBG(" > %08lx:0x%016lx...0x%016lx\n", | ||
1115 | res->flags, res->start, res->end); | ||
1116 | } | ||
1223 | } | 1117 | } |
1224 | EXPORT_SYMBOL(pcibios_fixup_device_resources); | 1118 | EXPORT_SYMBOL(pcibios_fixup_device_resources); |
1225 | 1119 | ||
@@ -1360,7 +1254,7 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
1360 | return; | 1254 | return; |
1361 | 1255 | ||
1362 | if (rsrc->flags & IORESOURCE_IO) | 1256 | if (rsrc->flags & IORESOURCE_IO) |
1363 | offset = (unsigned long)hose->io_base_virt - pci_io_base; | 1257 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; |
1364 | 1258 | ||
1365 | /* We pass a fully fixed up address to userland for MMIO instead of | 1259 | /* We pass a fully fixed up address to userland for MMIO instead of |
1366 | * a BAR value because X is lame and expects to be able to use that | 1260 | * a BAR value because X is lame and expects to be able to use that |
@@ -1410,7 +1304,7 @@ unsigned long pci_address_to_pio(phys_addr_t address) | |||
1410 | if (address >= hose->io_base_phys && | 1304 | if (address >= hose->io_base_phys && |
1411 | address < (hose->io_base_phys + hose->pci_io_size)) { | 1305 | address < (hose->io_base_phys + hose->pci_io_size)) { |
1412 | unsigned long base = | 1306 | unsigned long base = |
1413 | (unsigned long)hose->io_base_virt - pci_io_base; | 1307 | (unsigned long)hose->io_base_virt - _IO_BASE; |
1414 | return base + (address - hose->io_base_phys); | 1308 | return base + (address - hose->io_base_phys); |
1415 | } | 1309 | } |
1416 | } | 1310 | } |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index f2286822be09..a5de6211b97a 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -278,10 +278,8 @@ void __init find_and_init_phbs(void) | |||
278 | { | 278 | { |
279 | struct device_node *node; | 279 | struct device_node *node; |
280 | struct pci_controller *phb; | 280 | struct pci_controller *phb; |
281 | unsigned int index; | ||
282 | struct device_node *root = of_find_node_by_path("/"); | 281 | struct device_node *root = of_find_node_by_path("/"); |
283 | 282 | ||
284 | index = 0; | ||
285 | for (node = of_get_next_child(root, NULL); | 283 | for (node = of_get_next_child(root, NULL); |
286 | node != NULL; | 284 | node != NULL; |
287 | node = of_get_next_child(root, node)) { | 285 | node = of_get_next_child(root, node)) { |
@@ -295,8 +293,7 @@ void __init find_and_init_phbs(void) | |||
295 | continue; | 293 | continue; |
296 | rtas_setup_phb(phb); | 294 | rtas_setup_phb(phb); |
297 | pci_process_bridge_OF_ranges(phb, node, 0); | 295 | pci_process_bridge_OF_ranges(phb, node, 0); |
298 | pci_setup_phb_io(phb, index == 0); | 296 | isa_bridge_find_early(phb); |
299 | index++; | ||
300 | } | 297 | } |
301 | 298 | ||
302 | of_node_put(root); | 299 | of_node_put(root); |
@@ -335,7 +332,7 @@ int pcibios_remove_root_bus(struct pci_controller *phb) | |||
335 | return 1; | 332 | return 1; |
336 | } | 333 | } |
337 | 334 | ||
338 | rc = unmap_bus_range(b); | 335 | rc = pcibios_unmap_io_space(b); |
339 | if (rc) { | 336 | if (rc) { |
340 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", | 337 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", |
341 | __FUNCTION__, b->name); | 338 | __FUNCTION__, b->name); |