aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-29 00:02:58 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 01:59:10 -0400
commite3c71a32915fabb095de7108c22672e457631a08 (patch)
tree86461d9740df55f8377dabc4248ee88661e256da /arch/sparc64/kernel
parent66e4f8c076f8803e83879d986a7803a918b2129e (diff)
sparc: Fix resource flags for PCI children in OF device tree.
When a device is under an EBUS or ISA bus, the resource flags don't get set properly. Fix this by re-evaluating the resource flags at each level of bus as we apply ranges on the way to the root. And let PCI override any existing flags setting, but don't let the default flags calculator make such overrides. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/of_device.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index f8b50cbf4bf7..f845f150f565 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -96,7 +96,7 @@ struct of_bus {
96 int *addrc, int *sizec); 96 int *addrc, int *sizec);
97 int (*map)(u32 *addr, const u32 *range, 97 int (*map)(u32 *addr, const u32 *range,
98 int na, int ns, int pna); 98 int na, int ns, int pna);
99 unsigned int (*get_flags)(const u32 *addr); 99 unsigned long (*get_flags)(const u32 *addr, unsigned long);
100}; 100};
101 101
102/* 102/*
@@ -156,8 +156,10 @@ static int of_bus_default_map(u32 *addr, const u32 *range,
156 return 0; 156 return 0;
157} 157}
158 158
159static unsigned int of_bus_default_get_flags(const u32 *addr) 159static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long flags)
160{ 160{
161 if (flags)
162 return flags;
161 return IORESOURCE_MEM; 163 return IORESOURCE_MEM;
162} 164}
163 165
@@ -249,17 +251,21 @@ static int of_bus_pci_map(u32 *addr, const u32 *range,
249 return 0; 251 return 0;
250} 252}
251 253
252static unsigned int of_bus_pci_get_flags(const u32 *addr) 254static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags)
253{ 255{
254 unsigned int flags = 0;
255 u32 w = addr[0]; 256 u32 w = addr[0];
256 257
258 /* For PCI, we override whatever child busses may have used. */
259 flags = 0;
257 switch((w >> 24) & 0x03) { 260 switch((w >> 24) & 0x03) {
258 case 0x01: 261 case 0x01:
259 flags |= IORESOURCE_IO; 262 flags |= IORESOURCE_IO;
263 break;
264
260 case 0x02: /* 32 bits */ 265 case 0x02: /* 32 bits */
261 case 0x03: /* 64 bits */ 266 case 0x03: /* 64 bits */
262 flags |= IORESOURCE_MEM; 267 flags |= IORESOURCE_MEM;
268 break;
263 } 269 }
264 if (w & 0x40000000) 270 if (w & 0x40000000)
265 flags |= IORESOURCE_PREFETCH; 271 flags |= IORESOURCE_PREFETCH;
@@ -478,10 +484,10 @@ static void __init build_device_resources(struct of_device *op,
478 int pna, pns; 484 int pna, pns;
479 485
480 size = of_read_addr(reg + na, ns); 486 size = of_read_addr(reg + na, ns);
481 flags = bus->get_flags(reg);
482
483 memcpy(addr, reg, na * 4); 487 memcpy(addr, reg, na * 4);
484 488
489 flags = bus->get_flags(addr, 0);
490
485 if (use_1to1_mapping(pp)) { 491 if (use_1to1_mapping(pp)) {
486 result = of_read_addr(addr, na); 492 result = of_read_addr(addr, na);
487 goto build_res; 493 goto build_res;
@@ -506,6 +512,8 @@ static void __init build_device_resources(struct of_device *op,
506 dna, dns, pna)) 512 dna, dns, pna))
507 break; 513 break;
508 514
515 flags = pbus->get_flags(addr, flags);
516
509 dna = pna; 517 dna = pna;
510 dns = pns; 518 dns = pns;
511 dbus = pbus; 519 dbus = pbus;