diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-13 10:53:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-13 10:53:11 -0400 |
commit | 0e2ffbf650bf97499c02327719383818777651e6 (patch) | |
tree | 70cc80a7270ac6ee9e338e4c87a1f06c2432e79b | |
parent | 1b0f06d0b4860a8a73dc0b48540d82d8897ead71 (diff) | |
parent | a83f982313bc60dd3d87e50f8c88d6a169e8a5a0 (diff) |
Merge commit master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6 of HEAD
* HEAD:
[SPARC]: Fix OF register translations under sub-PCI busses.
[SPARC64]: Refine Sabre wsync logic.
[SERIAL] sunsu: Handle keyboard and mouse ports directly.
[SPARC64]: Fix 2 bugs in sabre_irq_build()
[SPARC64]: Update defconfig.
[SPARC64]: Fix make headers_install
[SPARC64]: of_device_register() error checking fix
-rw-r--r-- | arch/sparc/kernel/of_device.c | 173 | ||||
-rw-r--r-- | arch/sparc64/defconfig | 39 | ||||
-rw-r--r-- | arch/sparc64/kernel/of_device.c | 314 | ||||
-rw-r--r-- | arch/sparc64/kernel/prom.c | 51 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 35 | ||||
-rw-r--r-- | include/asm-sparc64/Kbuild | 2 |
6 files changed, 383 insertions, 231 deletions
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index bc956c530376..5a2faad5d043 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c | |||
@@ -183,7 +183,7 @@ struct bus_type of_bus_type = { | |||
183 | }; | 183 | }; |
184 | EXPORT_SYMBOL(of_bus_type); | 184 | EXPORT_SYMBOL(of_bus_type); |
185 | 185 | ||
186 | static inline u64 of_read_addr(u32 *cell, int size) | 186 | static inline u64 of_read_addr(const u32 *cell, int size) |
187 | { | 187 | { |
188 | u64 r = 0; | 188 | u64 r = 0; |
189 | while (size--) | 189 | while (size--) |
@@ -209,8 +209,8 @@ struct of_bus { | |||
209 | int (*match)(struct device_node *parent); | 209 | int (*match)(struct device_node *parent); |
210 | void (*count_cells)(struct device_node *child, | 210 | void (*count_cells)(struct device_node *child, |
211 | int *addrc, int *sizec); | 211 | int *addrc, int *sizec); |
212 | u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); | 212 | int (*map)(u32 *addr, const u32 *range, |
213 | int (*translate)(u32 *addr, u64 offset, int na); | 213 | int na, int ns, int pna); |
214 | unsigned int (*get_flags)(u32 *addr); | 214 | unsigned int (*get_flags)(u32 *addr); |
215 | }; | 215 | }; |
216 | 216 | ||
@@ -224,27 +224,49 @@ static void of_bus_default_count_cells(struct device_node *dev, | |||
224 | get_cells(dev, addrc, sizec); | 224 | get_cells(dev, addrc, sizec); |
225 | } | 225 | } |
226 | 226 | ||
227 | static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) | 227 | /* Make sure the least significant 64-bits are in-range. Even |
228 | * for 3 or 4 cell values it is a good enough approximation. | ||
229 | */ | ||
230 | static int of_out_of_range(const u32 *addr, const u32 *base, | ||
231 | const u32 *size, int na, int ns) | ||
228 | { | 232 | { |
229 | u64 cp, s, da; | 233 | u64 a = of_read_addr(addr, na); |
234 | u64 b = of_read_addr(base, na); | ||
235 | |||
236 | if (a < b) | ||
237 | return 1; | ||
230 | 238 | ||
231 | cp = of_read_addr(range, na); | 239 | b += of_read_addr(size, ns); |
232 | s = of_read_addr(range + na + pna, ns); | 240 | if (a >= b) |
233 | da = of_read_addr(addr, na); | 241 | return 1; |
234 | 242 | ||
235 | if (da < cp || da >= (cp + s)) | 243 | return 0; |
236 | return OF_BAD_ADDR; | ||
237 | return da - cp; | ||
238 | } | 244 | } |
239 | 245 | ||
240 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | 246 | static int of_bus_default_map(u32 *addr, const u32 *range, |
247 | int na, int ns, int pna) | ||
241 | { | 248 | { |
242 | u64 a = of_read_addr(addr, na); | 249 | u32 result[OF_MAX_ADDR_CELLS]; |
243 | memset(addr, 0, na * 4); | 250 | int i; |
244 | a += offset; | 251 | |
245 | if (na > 1) | 252 | if (ns > 2) { |
246 | addr[na - 2] = a >> 32; | 253 | printk("of_device: Cannot handle size cells (%d) > 2.", ns); |
247 | addr[na - 1] = a & 0xffffffffu; | 254 | return -EINVAL; |
255 | } | ||
256 | |||
257 | if (of_out_of_range(addr, range, range + na + pna, na, ns)) | ||
258 | return -EINVAL; | ||
259 | |||
260 | /* Start with the parent range base. */ | ||
261 | memcpy(result, range + na, pna * 4); | ||
262 | |||
263 | /* Add in the child address offset. */ | ||
264 | for (i = 0; i < na; i++) | ||
265 | result[pna - 1 - i] += | ||
266 | (addr[na - 1 - i] - | ||
267 | range[na - 1 - i]); | ||
268 | |||
269 | memcpy(addr, result, pna * 4); | ||
248 | 270 | ||
249 | return 0; | 271 | return 0; |
250 | } | 272 | } |
@@ -254,14 +276,26 @@ static unsigned int of_bus_default_get_flags(u32 *addr) | |||
254 | return IORESOURCE_MEM; | 276 | return IORESOURCE_MEM; |
255 | } | 277 | } |
256 | 278 | ||
257 | |||
258 | /* | 279 | /* |
259 | * PCI bus specific translator | 280 | * PCI bus specific translator |
260 | */ | 281 | */ |
261 | 282 | ||
262 | static int of_bus_pci_match(struct device_node *np) | 283 | static int of_bus_pci_match(struct device_node *np) |
263 | { | 284 | { |
264 | return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex"); | 285 | if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { |
286 | /* Do not do PCI specific frobbing if the | ||
287 | * PCI bridge lacks a ranges property. We | ||
288 | * want to pass it through up to the next | ||
289 | * parent as-is, not with the PCI translate | ||
290 | * method which chops off the top address cell. | ||
291 | */ | ||
292 | if (!of_find_property(np, "ranges", NULL)) | ||
293 | return 0; | ||
294 | |||
295 | return 1; | ||
296 | } | ||
297 | |||
298 | return 0; | ||
265 | } | 299 | } |
266 | 300 | ||
267 | static void of_bus_pci_count_cells(struct device_node *np, | 301 | static void of_bus_pci_count_cells(struct device_node *np, |
@@ -273,27 +307,32 @@ static void of_bus_pci_count_cells(struct device_node *np, | |||
273 | *sizec = 2; | 307 | *sizec = 2; |
274 | } | 308 | } |
275 | 309 | ||
276 | static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) | 310 | static int of_bus_pci_map(u32 *addr, const u32 *range, |
311 | int na, int ns, int pna) | ||
277 | { | 312 | { |
278 | u64 cp, s, da; | 313 | u32 result[OF_MAX_ADDR_CELLS]; |
314 | int i; | ||
279 | 315 | ||
280 | /* Check address type match */ | 316 | /* Check address type match */ |
281 | if ((addr[0] ^ range[0]) & 0x03000000) | 317 | if ((addr[0] ^ range[0]) & 0x03000000) |
282 | return OF_BAD_ADDR; | 318 | return -EINVAL; |
283 | 319 | ||
284 | /* Read address values, skipping high cell */ | 320 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, |
285 | cp = of_read_addr(range + 1, na - 1); | 321 | na - 1, ns)) |
286 | s = of_read_addr(range + na + pna, ns); | 322 | return -EINVAL; |
287 | da = of_read_addr(addr + 1, na - 1); | ||
288 | 323 | ||
289 | if (da < cp || da >= (cp + s)) | 324 | /* Start with the parent range base. */ |
290 | return OF_BAD_ADDR; | 325 | memcpy(result, range + na, pna * 4); |
291 | return da - cp; | ||
292 | } | ||
293 | 326 | ||
294 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | 327 | /* Add in the child address offset, skipping high cell. */ |
295 | { | 328 | for (i = 0; i < na - 1; i++) |
296 | return of_bus_default_translate(addr + 1, offset, na - 1); | 329 | result[pna - 1 - i] += |
330 | (addr[na - 1 - i] - | ||
331 | range[na - 1 - i]); | ||
332 | |||
333 | memcpy(addr, result, pna * 4); | ||
334 | |||
335 | return 0; | ||
297 | } | 336 | } |
298 | 337 | ||
299 | static unsigned int of_bus_pci_get_flags(u32 *addr) | 338 | static unsigned int of_bus_pci_get_flags(u32 *addr) |
@@ -332,16 +371,11 @@ static void of_bus_sbus_count_cells(struct device_node *child, | |||
332 | *sizec = 1; | 371 | *sizec = 1; |
333 | } | 372 | } |
334 | 373 | ||
335 | static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna) | 374 | static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) |
336 | { | 375 | { |
337 | return of_bus_default_map(addr, range, na, ns, pna); | 376 | return of_bus_default_map(addr, range, na, ns, pna); |
338 | } | 377 | } |
339 | 378 | ||
340 | static int of_bus_sbus_translate(u32 *addr, u64 offset, int na) | ||
341 | { | ||
342 | return of_bus_default_translate(addr, offset, na); | ||
343 | } | ||
344 | |||
345 | static unsigned int of_bus_sbus_get_flags(u32 *addr) | 379 | static unsigned int of_bus_sbus_get_flags(u32 *addr) |
346 | { | 380 | { |
347 | return IORESOURCE_MEM; | 381 | return IORESOURCE_MEM; |
@@ -360,7 +394,6 @@ static struct of_bus of_busses[] = { | |||
360 | .match = of_bus_pci_match, | 394 | .match = of_bus_pci_match, |
361 | .count_cells = of_bus_pci_count_cells, | 395 | .count_cells = of_bus_pci_count_cells, |
362 | .map = of_bus_pci_map, | 396 | .map = of_bus_pci_map, |
363 | .translate = of_bus_pci_translate, | ||
364 | .get_flags = of_bus_pci_get_flags, | 397 | .get_flags = of_bus_pci_get_flags, |
365 | }, | 398 | }, |
366 | /* SBUS */ | 399 | /* SBUS */ |
@@ -370,7 +403,6 @@ static struct of_bus of_busses[] = { | |||
370 | .match = of_bus_sbus_match, | 403 | .match = of_bus_sbus_match, |
371 | .count_cells = of_bus_sbus_count_cells, | 404 | .count_cells = of_bus_sbus_count_cells, |
372 | .map = of_bus_sbus_map, | 405 | .map = of_bus_sbus_map, |
373 | .translate = of_bus_sbus_translate, | ||
374 | .get_flags = of_bus_sbus_get_flags, | 406 | .get_flags = of_bus_sbus_get_flags, |
375 | }, | 407 | }, |
376 | /* Default */ | 408 | /* Default */ |
@@ -380,7 +412,6 @@ static struct of_bus of_busses[] = { | |||
380 | .match = NULL, | 412 | .match = NULL, |
381 | .count_cells = of_bus_default_count_cells, | 413 | .count_cells = of_bus_default_count_cells, |
382 | .map = of_bus_default_map, | 414 | .map = of_bus_default_map, |
383 | .translate = of_bus_default_translate, | ||
384 | .get_flags = of_bus_default_get_flags, | 415 | .get_flags = of_bus_default_get_flags, |
385 | }, | 416 | }, |
386 | }; | 417 | }; |
@@ -405,33 +436,34 @@ static int __init build_one_resource(struct device_node *parent, | |||
405 | u32 *ranges; | 436 | u32 *ranges; |
406 | unsigned int rlen; | 437 | unsigned int rlen; |
407 | int rone; | 438 | int rone; |
408 | u64 offset = OF_BAD_ADDR; | ||
409 | 439 | ||
410 | ranges = of_get_property(parent, "ranges", &rlen); | 440 | ranges = of_get_property(parent, "ranges", &rlen); |
411 | if (ranges == NULL || rlen == 0) { | 441 | if (ranges == NULL || rlen == 0) { |
412 | offset = of_read_addr(addr, na); | 442 | u32 result[OF_MAX_ADDR_CELLS]; |
413 | memset(addr, 0, pna * 4); | 443 | int i; |
414 | goto finish; | 444 | |
445 | memset(result, 0, pna * 4); | ||
446 | for (i = 0; i < na; i++) | ||
447 | result[pna - 1 - i] = | ||
448 | addr[na - 1 - i]; | ||
449 | |||
450 | memcpy(addr, result, pna * 4); | ||
451 | return 0; | ||
415 | } | 452 | } |
416 | 453 | ||
417 | /* Now walk through the ranges */ | 454 | /* Now walk through the ranges */ |
418 | rlen /= 4; | 455 | rlen /= 4; |
419 | rone = na + pna + ns; | 456 | rone = na + pna + ns; |
420 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | 457 | for (; rlen >= rone; rlen -= rone, ranges += rone) { |
421 | offset = bus->map(addr, ranges, na, ns, pna); | 458 | if (!bus->map(addr, ranges, na, ns, pna)) |
422 | if (offset != OF_BAD_ADDR) | 459 | return 0; |
423 | break; | ||
424 | } | 460 | } |
425 | if (offset == OF_BAD_ADDR) | ||
426 | return 1; | ||
427 | 461 | ||
428 | memcpy(addr, ranges + na, 4 * pna); | 462 | return 1; |
429 | |||
430 | finish: | ||
431 | /* Translate it into parent bus space */ | ||
432 | return pbus->translate(addr, offset, pna); | ||
433 | } | 463 | } |
434 | 464 | ||
465 | static int of_resource_verbose; | ||
466 | |||
435 | static void __init build_device_resources(struct of_device *op, | 467 | static void __init build_device_resources(struct of_device *op, |
436 | struct device *parent) | 468 | struct device *parent) |
437 | { | 469 | { |
@@ -497,7 +529,8 @@ static void __init build_device_resources(struct of_device *op, | |||
497 | pbus = of_match_bus(pp); | 529 | pbus = of_match_bus(pp); |
498 | pbus->count_cells(dp, &pna, &pns); | 530 | pbus->count_cells(dp, &pna, &pns); |
499 | 531 | ||
500 | if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna)) | 532 | if (build_one_resource(dp, bus, pbus, addr, |
533 | dna, dns, pna)) | ||
501 | break; | 534 | break; |
502 | 535 | ||
503 | dna = pna; | 536 | dna = pna; |
@@ -507,6 +540,12 @@ static void __init build_device_resources(struct of_device *op, | |||
507 | 540 | ||
508 | build_res: | 541 | build_res: |
509 | memset(r, 0, sizeof(*r)); | 542 | memset(r, 0, sizeof(*r)); |
543 | |||
544 | if (of_resource_verbose) | ||
545 | printk("%s reg[%d] -> %llx\n", | ||
546 | op->node->full_name, index, | ||
547 | result); | ||
548 | |||
510 | if (result != OF_BAD_ADDR) { | 549 | if (result != OF_BAD_ADDR) { |
511 | r->start = result & 0xffffffff; | 550 | r->start = result & 0xffffffff; |
512 | r->end = result + size - 1; | 551 | r->end = result + size - 1; |
@@ -643,6 +682,18 @@ static int __init of_bus_driver_init(void) | |||
643 | 682 | ||
644 | postcore_initcall(of_bus_driver_init); | 683 | postcore_initcall(of_bus_driver_init); |
645 | 684 | ||
685 | static int __init of_debug(char *str) | ||
686 | { | ||
687 | int val = 0; | ||
688 | |||
689 | get_option(&str, &val); | ||
690 | if (val & 1) | ||
691 | of_resource_verbose = 1; | ||
692 | return 1; | ||
693 | } | ||
694 | |||
695 | __setup("of_debug=", of_debug); | ||
696 | |||
646 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | 697 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) |
647 | { | 698 | { |
648 | /* initialize common driver fields */ | 699 | /* initialize common driver fields */ |
@@ -695,9 +746,11 @@ int of_device_register(struct of_device *ofdev) | |||
695 | if (rc) | 746 | if (rc) |
696 | return rc; | 747 | return rc; |
697 | 748 | ||
698 | device_create_file(&ofdev->dev, &dev_attr_devspec); | 749 | rc = device_create_file(&ofdev->dev, &dev_attr_devspec); |
750 | if (rc) | ||
751 | device_unregister(&ofdev->dev); | ||
699 | 752 | ||
700 | return 0; | 753 | return rc; |
701 | } | 754 | } |
702 | 755 | ||
703 | void of_device_unregister(struct of_device *ofdev) | 756 | void of_device_unregister(struct of_device *ofdev) |
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index b2f41147d0e4..38353621069e 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.17 | 3 | # Linux kernel version: 2.6.18-rc1 |
4 | # Fri Jun 23 23:17:09 2006 | 4 | # Wed Jul 12 14:00:58 2006 |
5 | # | 5 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
@@ -18,6 +18,7 @@ CONFIG_SECCOMP=y | |||
18 | CONFIG_HZ_250=y | 18 | CONFIG_HZ_250=y |
19 | # CONFIG_HZ_1000 is not set | 19 | # CONFIG_HZ_1000 is not set |
20 | CONFIG_HZ=250 | 20 | CONFIG_HZ=250 |
21 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
21 | 22 | ||
22 | # | 23 | # |
23 | # Code maturity level options | 24 | # Code maturity level options |
@@ -51,10 +52,12 @@ CONFIG_PRINTK=y | |||
51 | CONFIG_BUG=y | 52 | CONFIG_BUG=y |
52 | CONFIG_ELF_CORE=y | 53 | CONFIG_ELF_CORE=y |
53 | CONFIG_BASE_FULL=y | 54 | CONFIG_BASE_FULL=y |
55 | CONFIG_RT_MUTEXES=y | ||
54 | CONFIG_FUTEX=y | 56 | CONFIG_FUTEX=y |
55 | CONFIG_EPOLL=y | 57 | CONFIG_EPOLL=y |
56 | CONFIG_SHMEM=y | 58 | CONFIG_SHMEM=y |
57 | CONFIG_SLAB=y | 59 | CONFIG_SLAB=y |
60 | CONFIG_VM_EVENT_COUNTERS=y | ||
58 | # CONFIG_TINY_SHMEM is not set | 61 | # CONFIG_TINY_SHMEM is not set |
59 | CONFIG_BASE_SMALL=0 | 62 | CONFIG_BASE_SMALL=0 |
60 | # CONFIG_SLOB is not set | 63 | # CONFIG_SLOB is not set |
@@ -127,8 +130,8 @@ CONFIG_SPARSEMEM=y | |||
127 | CONFIG_HAVE_MEMORY_PRESENT=y | 130 | CONFIG_HAVE_MEMORY_PRESENT=y |
128 | # CONFIG_SPARSEMEM_STATIC is not set | 131 | # CONFIG_SPARSEMEM_STATIC is not set |
129 | CONFIG_SPARSEMEM_EXTREME=y | 132 | CONFIG_SPARSEMEM_EXTREME=y |
130 | CONFIG_MEMORY_HOTPLUG=y | ||
131 | CONFIG_SPLIT_PTLOCK_CPUS=4 | 133 | CONFIG_SPLIT_PTLOCK_CPUS=4 |
134 | CONFIG_RESOURCES_64BIT=y | ||
132 | CONFIG_GENERIC_ISA_DMA=y | 135 | CONFIG_GENERIC_ISA_DMA=y |
133 | CONFIG_SBUS=y | 136 | CONFIG_SBUS=y |
134 | CONFIG_SBUSCHAR=y | 137 | CONFIG_SBUSCHAR=y |
@@ -203,7 +206,6 @@ CONFIG_TCP_CONG_VEGAS=m | |||
203 | CONFIG_TCP_CONG_SCALABLE=m | 206 | CONFIG_TCP_CONG_SCALABLE=m |
204 | CONFIG_TCP_CONG_LP=m | 207 | CONFIG_TCP_CONG_LP=m |
205 | CONFIG_TCP_CONG_VENO=m | 208 | CONFIG_TCP_CONG_VENO=m |
206 | CONFIG_TCP_CONG_COMPOUND=m | ||
207 | CONFIG_IPV6=m | 209 | CONFIG_IPV6=m |
208 | CONFIG_IPV6_PRIVACY=y | 210 | CONFIG_IPV6_PRIVACY=y |
209 | CONFIG_IPV6_ROUTER_PREF=y | 211 | CONFIG_IPV6_ROUTER_PREF=y |
@@ -461,9 +463,8 @@ CONFIG_MD_LINEAR=m | |||
461 | CONFIG_MD_RAID0=m | 463 | CONFIG_MD_RAID0=m |
462 | CONFIG_MD_RAID1=m | 464 | CONFIG_MD_RAID1=m |
463 | CONFIG_MD_RAID10=m | 465 | CONFIG_MD_RAID10=m |
464 | CONFIG_MD_RAID5=m | 466 | CONFIG_MD_RAID456=m |
465 | # CONFIG_MD_RAID5_RESHAPE is not set | 467 | # CONFIG_MD_RAID5_RESHAPE is not set |
466 | CONFIG_MD_RAID6=m | ||
467 | CONFIG_MD_MULTIPATH=m | 468 | CONFIG_MD_MULTIPATH=m |
468 | # CONFIG_MD_FAULTY is not set | 469 | # CONFIG_MD_FAULTY is not set |
469 | CONFIG_BLK_DEV_DM=m | 470 | CONFIG_BLK_DEV_DM=m |
@@ -663,6 +664,7 @@ CONFIG_SERIO_RAW=m | |||
663 | CONFIG_VT=y | 664 | CONFIG_VT=y |
664 | CONFIG_VT_CONSOLE=y | 665 | CONFIG_VT_CONSOLE=y |
665 | CONFIG_HW_CONSOLE=y | 666 | CONFIG_HW_CONSOLE=y |
667 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
666 | # CONFIG_SERIAL_NONSTANDARD is not set | 668 | # CONFIG_SERIAL_NONSTANDARD is not set |
667 | 669 | ||
668 | # | 670 | # |
@@ -693,6 +695,7 @@ CONFIG_UNIX98_PTYS=y | |||
693 | # Watchdog Cards | 695 | # Watchdog Cards |
694 | # | 696 | # |
695 | # CONFIG_WATCHDOG is not set | 697 | # CONFIG_WATCHDOG is not set |
698 | # CONFIG_HW_RANDOM is not set | ||
696 | CONFIG_RTC=y | 699 | CONFIG_RTC=y |
697 | # CONFIG_DTLK is not set | 700 | # CONFIG_DTLK is not set |
698 | # CONFIG_R3964 is not set | 701 | # CONFIG_R3964 is not set |
@@ -839,12 +842,13 @@ CONFIG_VIDEO_V4L2=y | |||
839 | # | 842 | # |
840 | # Graphics support | 843 | # Graphics support |
841 | # | 844 | # |
845 | # CONFIG_FIRMWARE_EDID is not set | ||
842 | CONFIG_FB=y | 846 | CONFIG_FB=y |
843 | CONFIG_FB_CFB_FILLRECT=y | 847 | CONFIG_FB_CFB_FILLRECT=y |
844 | CONFIG_FB_CFB_COPYAREA=y | 848 | CONFIG_FB_CFB_COPYAREA=y |
845 | CONFIG_FB_CFB_IMAGEBLIT=y | 849 | CONFIG_FB_CFB_IMAGEBLIT=y |
846 | # CONFIG_FB_MACMODES is not set | 850 | # CONFIG_FB_MACMODES is not set |
847 | # CONFIG_FB_FIRMWARE_EDID is not set | 851 | # CONFIG_FB_BACKLIGHT is not set |
848 | CONFIG_FB_MODE_HELPERS=y | 852 | CONFIG_FB_MODE_HELPERS=y |
849 | CONFIG_FB_TILEBLITTING=y | 853 | CONFIG_FB_TILEBLITTING=y |
850 | # CONFIG_FB_CIRRUS is not set | 854 | # CONFIG_FB_CIRRUS is not set |
@@ -954,6 +958,18 @@ CONFIG_SND_ALI5451=m | |||
954 | # CONFIG_SND_CMIPCI is not set | 958 | # CONFIG_SND_CMIPCI is not set |
955 | # CONFIG_SND_CS4281 is not set | 959 | # CONFIG_SND_CS4281 is not set |
956 | # CONFIG_SND_CS46XX is not set | 960 | # CONFIG_SND_CS46XX is not set |
961 | # CONFIG_SND_DARLA20 is not set | ||
962 | # CONFIG_SND_GINA20 is not set | ||
963 | # CONFIG_SND_LAYLA20 is not set | ||
964 | # CONFIG_SND_DARLA24 is not set | ||
965 | # CONFIG_SND_GINA24 is not set | ||
966 | # CONFIG_SND_LAYLA24 is not set | ||
967 | # CONFIG_SND_MONA is not set | ||
968 | # CONFIG_SND_MIA is not set | ||
969 | # CONFIG_SND_ECHO3G is not set | ||
970 | # CONFIG_SND_INDIGO is not set | ||
971 | # CONFIG_SND_INDIGOIO is not set | ||
972 | # CONFIG_SND_INDIGODJ is not set | ||
957 | # CONFIG_SND_EMU10K1 is not set | 973 | # CONFIG_SND_EMU10K1 is not set |
958 | # CONFIG_SND_EMU10K1X is not set | 974 | # CONFIG_SND_EMU10K1X is not set |
959 | # CONFIG_SND_ENS1370 is not set | 975 | # CONFIG_SND_ENS1370 is not set |
@@ -1263,6 +1279,7 @@ CONFIG_RAMFS=y | |||
1263 | # CONFIG_NFSD is not set | 1279 | # CONFIG_NFSD is not set |
1264 | # CONFIG_SMB_FS is not set | 1280 | # CONFIG_SMB_FS is not set |
1265 | # CONFIG_CIFS is not set | 1281 | # CONFIG_CIFS is not set |
1282 | # CONFIG_CIFS_DEBUG2 is not set | ||
1266 | # CONFIG_NCP_FS is not set | 1283 | # CONFIG_NCP_FS is not set |
1267 | # CONFIG_CODA_FS is not set | 1284 | # CONFIG_CODA_FS is not set |
1268 | # CONFIG_AFS_FS is not set | 1285 | # CONFIG_AFS_FS is not set |
@@ -1331,14 +1348,19 @@ CONFIG_KPROBES=y | |||
1331 | # | 1348 | # |
1332 | CONFIG_PRINTK_TIME=y | 1349 | CONFIG_PRINTK_TIME=y |
1333 | CONFIG_MAGIC_SYSRQ=y | 1350 | CONFIG_MAGIC_SYSRQ=y |
1351 | # CONFIG_UNUSED_SYMBOLS is not set | ||
1334 | CONFIG_DEBUG_KERNEL=y | 1352 | CONFIG_DEBUG_KERNEL=y |
1335 | CONFIG_LOG_BUF_SHIFT=18 | 1353 | CONFIG_LOG_BUF_SHIFT=18 |
1336 | CONFIG_DETECT_SOFTLOCKUP=y | 1354 | CONFIG_DETECT_SOFTLOCKUP=y |
1337 | CONFIG_SCHEDSTATS=y | 1355 | CONFIG_SCHEDSTATS=y |
1338 | # CONFIG_DEBUG_SLAB is not set | 1356 | # CONFIG_DEBUG_SLAB is not set |
1339 | # CONFIG_DEBUG_MUTEXES is not set | 1357 | # CONFIG_DEBUG_RT_MUTEXES is not set |
1358 | # CONFIG_RT_MUTEX_TESTER is not set | ||
1340 | # CONFIG_DEBUG_SPINLOCK is not set | 1359 | # CONFIG_DEBUG_SPINLOCK is not set |
1360 | # CONFIG_DEBUG_MUTEXES is not set | ||
1361 | # CONFIG_DEBUG_RWSEMS is not set | ||
1341 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1362 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
1363 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
1342 | # CONFIG_DEBUG_KOBJECT is not set | 1364 | # CONFIG_DEBUG_KOBJECT is not set |
1343 | CONFIG_DEBUG_BUGVERBOSE=y | 1365 | CONFIG_DEBUG_BUGVERBOSE=y |
1344 | # CONFIG_DEBUG_INFO is not set | 1366 | # CONFIG_DEBUG_INFO is not set |
@@ -1402,3 +1424,4 @@ CONFIG_CRC32=y | |||
1402 | CONFIG_LIBCRC32C=m | 1424 | CONFIG_LIBCRC32C=m |
1403 | CONFIG_ZLIB_INFLATE=y | 1425 | CONFIG_ZLIB_INFLATE=y |
1404 | CONFIG_ZLIB_DEFLATE=y | 1426 | CONFIG_ZLIB_DEFLATE=y |
1427 | CONFIG_PLIST=y | ||
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 169b017eec0b..7064cee290ae 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -210,7 +210,7 @@ struct bus_type of_bus_type = { | |||
210 | }; | 210 | }; |
211 | EXPORT_SYMBOL(of_bus_type); | 211 | EXPORT_SYMBOL(of_bus_type); |
212 | 212 | ||
213 | static inline u64 of_read_addr(u32 *cell, int size) | 213 | static inline u64 of_read_addr(const u32 *cell, int size) |
214 | { | 214 | { |
215 | u64 r = 0; | 215 | u64 r = 0; |
216 | while (size--) | 216 | while (size--) |
@@ -236,8 +236,8 @@ struct of_bus { | |||
236 | int (*match)(struct device_node *parent); | 236 | int (*match)(struct device_node *parent); |
237 | void (*count_cells)(struct device_node *child, | 237 | void (*count_cells)(struct device_node *child, |
238 | int *addrc, int *sizec); | 238 | int *addrc, int *sizec); |
239 | u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); | 239 | int (*map)(u32 *addr, const u32 *range, |
240 | int (*translate)(u32 *addr, u64 offset, int na); | 240 | int na, int ns, int pna); |
241 | unsigned int (*get_flags)(u32 *addr); | 241 | unsigned int (*get_flags)(u32 *addr); |
242 | }; | 242 | }; |
243 | 243 | ||
@@ -251,27 +251,49 @@ static void of_bus_default_count_cells(struct device_node *dev, | |||
251 | get_cells(dev, addrc, sizec); | 251 | get_cells(dev, addrc, sizec); |
252 | } | 252 | } |
253 | 253 | ||
254 | static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) | 254 | /* Make sure the least significant 64-bits are in-range. Even |
255 | * for 3 or 4 cell values it is a good enough approximation. | ||
256 | */ | ||
257 | static int of_out_of_range(const u32 *addr, const u32 *base, | ||
258 | const u32 *size, int na, int ns) | ||
255 | { | 259 | { |
256 | u64 cp, s, da; | 260 | u64 a = of_read_addr(addr, na); |
261 | u64 b = of_read_addr(base, na); | ||
257 | 262 | ||
258 | cp = of_read_addr(range, na); | 263 | if (a < b) |
259 | s = of_read_addr(range + na + pna, ns); | 264 | return 1; |
260 | da = of_read_addr(addr, na); | ||
261 | 265 | ||
262 | if (da < cp || da >= (cp + s)) | 266 | b += of_read_addr(size, ns); |
263 | return OF_BAD_ADDR; | 267 | if (a >= b) |
264 | return da - cp; | 268 | return 1; |
269 | |||
270 | return 0; | ||
265 | } | 271 | } |
266 | 272 | ||
267 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | 273 | static int of_bus_default_map(u32 *addr, const u32 *range, |
274 | int na, int ns, int pna) | ||
268 | { | 275 | { |
269 | u64 a = of_read_addr(addr, na); | 276 | u32 result[OF_MAX_ADDR_CELLS]; |
270 | memset(addr, 0, na * 4); | 277 | int i; |
271 | a += offset; | 278 | |
272 | if (na > 1) | 279 | if (ns > 2) { |
273 | addr[na - 2] = a >> 32; | 280 | printk("of_device: Cannot handle size cells (%d) > 2.", ns); |
274 | addr[na - 1] = a & 0xffffffffu; | 281 | return -EINVAL; |
282 | } | ||
283 | |||
284 | if (of_out_of_range(addr, range, range + na + pna, na, ns)) | ||
285 | return -EINVAL; | ||
286 | |||
287 | /* Start with the parent range base. */ | ||
288 | memcpy(result, range + na, pna * 4); | ||
289 | |||
290 | /* Add in the child address offset. */ | ||
291 | for (i = 0; i < na; i++) | ||
292 | result[pna - 1 - i] += | ||
293 | (addr[na - 1 - i] - | ||
294 | range[na - 1 - i]); | ||
295 | |||
296 | memcpy(addr, result, pna * 4); | ||
275 | 297 | ||
276 | return 0; | 298 | return 0; |
277 | } | 299 | } |
@@ -287,7 +309,20 @@ static unsigned int of_bus_default_get_flags(u32 *addr) | |||
287 | 309 | ||
288 | static int of_bus_pci_match(struct device_node *np) | 310 | static int of_bus_pci_match(struct device_node *np) |
289 | { | 311 | { |
290 | return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex"); | 312 | if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { |
313 | /* Do not do PCI specific frobbing if the | ||
314 | * PCI bridge lacks a ranges property. We | ||
315 | * want to pass it through up to the next | ||
316 | * parent as-is, not with the PCI translate | ||
317 | * method which chops off the top address cell. | ||
318 | */ | ||
319 | if (!of_find_property(np, "ranges", NULL)) | ||
320 | return 0; | ||
321 | |||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | return 0; | ||
291 | } | 326 | } |
292 | 327 | ||
293 | static void of_bus_pci_count_cells(struct device_node *np, | 328 | static void of_bus_pci_count_cells(struct device_node *np, |
@@ -299,27 +334,32 @@ static void of_bus_pci_count_cells(struct device_node *np, | |||
299 | *sizec = 2; | 334 | *sizec = 2; |
300 | } | 335 | } |
301 | 336 | ||
302 | static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) | 337 | static int of_bus_pci_map(u32 *addr, const u32 *range, |
338 | int na, int ns, int pna) | ||
303 | { | 339 | { |
304 | u64 cp, s, da; | 340 | u32 result[OF_MAX_ADDR_CELLS]; |
341 | int i; | ||
305 | 342 | ||
306 | /* Check address type match */ | 343 | /* Check address type match */ |
307 | if ((addr[0] ^ range[0]) & 0x03000000) | 344 | if ((addr[0] ^ range[0]) & 0x03000000) |
308 | return OF_BAD_ADDR; | 345 | return -EINVAL; |
309 | 346 | ||
310 | /* Read address values, skipping high cell */ | 347 | if (of_out_of_range(addr + 1, range + 1, range + na + pna, |
311 | cp = of_read_addr(range + 1, na - 1); | 348 | na - 1, ns)) |
312 | s = of_read_addr(range + na + pna, ns); | 349 | return -EINVAL; |
313 | da = of_read_addr(addr + 1, na - 1); | ||
314 | 350 | ||
315 | if (da < cp || da >= (cp + s)) | 351 | /* Start with the parent range base. */ |
316 | return OF_BAD_ADDR; | 352 | memcpy(result, range + na, pna * 4); |
317 | return da - cp; | ||
318 | } | ||
319 | 353 | ||
320 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | 354 | /* Add in the child address offset, skipping high cell. */ |
321 | { | 355 | for (i = 0; i < na - 1; i++) |
322 | return of_bus_default_translate(addr + 1, offset, na - 1); | 356 | result[pna - 1 - i] += |
357 | (addr[na - 1 - i] - | ||
358 | range[na - 1 - i]); | ||
359 | |||
360 | memcpy(addr, result, pna * 4); | ||
361 | |||
362 | return 0; | ||
323 | } | 363 | } |
324 | 364 | ||
325 | static unsigned int of_bus_pci_get_flags(u32 *addr) | 365 | static unsigned int of_bus_pci_get_flags(u32 *addr) |
@@ -340,59 +380,6 @@ static unsigned int of_bus_pci_get_flags(u32 *addr) | |||
340 | } | 380 | } |
341 | 381 | ||
342 | /* | 382 | /* |
343 | * ISA bus specific translator | ||
344 | */ | ||
345 | |||
346 | static int of_bus_isa_match(struct device_node *np) | ||
347 | { | ||
348 | return !strcmp(np->name, "isa"); | ||
349 | } | ||
350 | |||
351 | static void of_bus_isa_count_cells(struct device_node *child, | ||
352 | int *addrc, int *sizec) | ||
353 | { | ||
354 | if (addrc) | ||
355 | *addrc = 2; | ||
356 | if (sizec) | ||
357 | *sizec = 1; | ||
358 | } | ||
359 | |||
360 | static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) | ||
361 | { | ||
362 | u64 cp, s, da; | ||
363 | |||
364 | /* Check address type match */ | ||
365 | if ((addr[0] ^ range[0]) & 0x00000001) | ||
366 | return OF_BAD_ADDR; | ||
367 | |||
368 | /* Read address values, skipping high cell */ | ||
369 | cp = of_read_addr(range + 1, na - 1); | ||
370 | s = of_read_addr(range + na + pna, ns); | ||
371 | da = of_read_addr(addr + 1, na - 1); | ||
372 | |||
373 | if (da < cp || da >= (cp + s)) | ||
374 | return OF_BAD_ADDR; | ||
375 | return da - cp; | ||
376 | } | ||
377 | |||
378 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | ||
379 | { | ||
380 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
381 | } | ||
382 | |||
383 | static unsigned int of_bus_isa_get_flags(u32 *addr) | ||
384 | { | ||
385 | unsigned int flags = 0; | ||
386 | u32 w = addr[0]; | ||
387 | |||
388 | if (w & 1) | ||
389 | flags |= IORESOURCE_IO; | ||
390 | else | ||
391 | flags |= IORESOURCE_MEM; | ||
392 | return flags; | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * SBUS bus specific translator | 383 | * SBUS bus specific translator |
397 | */ | 384 | */ |
398 | 385 | ||
@@ -411,16 +398,11 @@ static void of_bus_sbus_count_cells(struct device_node *child, | |||
411 | *sizec = 1; | 398 | *sizec = 1; |
412 | } | 399 | } |
413 | 400 | ||
414 | static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna) | 401 | static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) |
415 | { | 402 | { |
416 | return of_bus_default_map(addr, range, na, ns, pna); | 403 | return of_bus_default_map(addr, range, na, ns, pna); |
417 | } | 404 | } |
418 | 405 | ||
419 | static int of_bus_sbus_translate(u32 *addr, u64 offset, int na) | ||
420 | { | ||
421 | return of_bus_default_translate(addr, offset, na); | ||
422 | } | ||
423 | |||
424 | static unsigned int of_bus_sbus_get_flags(u32 *addr) | 406 | static unsigned int of_bus_sbus_get_flags(u32 *addr) |
425 | { | 407 | { |
426 | return IORESOURCE_MEM; | 408 | return IORESOURCE_MEM; |
@@ -439,19 +421,8 @@ static struct of_bus of_busses[] = { | |||
439 | .match = of_bus_pci_match, | 421 | .match = of_bus_pci_match, |
440 | .count_cells = of_bus_pci_count_cells, | 422 | .count_cells = of_bus_pci_count_cells, |
441 | .map = of_bus_pci_map, | 423 | .map = of_bus_pci_map, |
442 | .translate = of_bus_pci_translate, | ||
443 | .get_flags = of_bus_pci_get_flags, | 424 | .get_flags = of_bus_pci_get_flags, |
444 | }, | 425 | }, |
445 | /* ISA */ | ||
446 | { | ||
447 | .name = "isa", | ||
448 | .addr_prop_name = "reg", | ||
449 | .match = of_bus_isa_match, | ||
450 | .count_cells = of_bus_isa_count_cells, | ||
451 | .map = of_bus_isa_map, | ||
452 | .translate = of_bus_isa_translate, | ||
453 | .get_flags = of_bus_isa_get_flags, | ||
454 | }, | ||
455 | /* SBUS */ | 426 | /* SBUS */ |
456 | { | 427 | { |
457 | .name = "sbus", | 428 | .name = "sbus", |
@@ -459,7 +430,6 @@ static struct of_bus of_busses[] = { | |||
459 | .match = of_bus_sbus_match, | 430 | .match = of_bus_sbus_match, |
460 | .count_cells = of_bus_sbus_count_cells, | 431 | .count_cells = of_bus_sbus_count_cells, |
461 | .map = of_bus_sbus_map, | 432 | .map = of_bus_sbus_map, |
462 | .translate = of_bus_sbus_translate, | ||
463 | .get_flags = of_bus_sbus_get_flags, | 433 | .get_flags = of_bus_sbus_get_flags, |
464 | }, | 434 | }, |
465 | /* Default */ | 435 | /* Default */ |
@@ -469,7 +439,6 @@ static struct of_bus of_busses[] = { | |||
469 | .match = NULL, | 439 | .match = NULL, |
470 | .count_cells = of_bus_default_count_cells, | 440 | .count_cells = of_bus_default_count_cells, |
471 | .map = of_bus_default_map, | 441 | .map = of_bus_default_map, |
472 | .translate = of_bus_default_translate, | ||
473 | .get_flags = of_bus_default_get_flags, | 442 | .get_flags = of_bus_default_get_flags, |
474 | }, | 443 | }, |
475 | }; | 444 | }; |
@@ -494,33 +463,62 @@ static int __init build_one_resource(struct device_node *parent, | |||
494 | u32 *ranges; | 463 | u32 *ranges; |
495 | unsigned int rlen; | 464 | unsigned int rlen; |
496 | int rone; | 465 | int rone; |
497 | u64 offset = OF_BAD_ADDR; | ||
498 | 466 | ||
499 | ranges = of_get_property(parent, "ranges", &rlen); | 467 | ranges = of_get_property(parent, "ranges", &rlen); |
500 | if (ranges == NULL || rlen == 0) { | 468 | if (ranges == NULL || rlen == 0) { |
501 | offset = of_read_addr(addr, na); | 469 | u32 result[OF_MAX_ADDR_CELLS]; |
502 | memset(addr, 0, pna * 4); | 470 | int i; |
503 | goto finish; | 471 | |
472 | memset(result, 0, pna * 4); | ||
473 | for (i = 0; i < na; i++) | ||
474 | result[pna - 1 - i] = | ||
475 | addr[na - 1 - i]; | ||
476 | |||
477 | memcpy(addr, result, pna * 4); | ||
478 | return 0; | ||
504 | } | 479 | } |
505 | 480 | ||
506 | /* Now walk through the ranges */ | 481 | /* Now walk through the ranges */ |
507 | rlen /= 4; | 482 | rlen /= 4; |
508 | rone = na + pna + ns; | 483 | rone = na + pna + ns; |
509 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | 484 | for (; rlen >= rone; rlen -= rone, ranges += rone) { |
510 | offset = bus->map(addr, ranges, na, ns, pna); | 485 | if (!bus->map(addr, ranges, na, ns, pna)) |
511 | if (offset != OF_BAD_ADDR) | 486 | return 0; |
512 | break; | ||
513 | } | 487 | } |
514 | if (offset == OF_BAD_ADDR) | 488 | |
489 | return 1; | ||
490 | } | ||
491 | |||
492 | static int __init use_1to1_mapping(struct device_node *pp) | ||
493 | { | ||
494 | char *model; | ||
495 | |||
496 | /* If this is on the PMU bus, don't try to translate it even | ||
497 | * if a ranges property exists. | ||
498 | */ | ||
499 | if (!strcmp(pp->name, "pmu")) | ||
515 | return 1; | 500 | return 1; |
516 | 501 | ||
517 | memcpy(addr, ranges + na, 4 * pna); | 502 | /* If we have a ranges property in the parent, use it. */ |
503 | if (of_find_property(pp, "ranges", NULL) != NULL) | ||
504 | return 0; | ||
505 | |||
506 | /* If the parent is the dma node of an ISA bus, pass | ||
507 | * the translation up to the root. | ||
508 | */ | ||
509 | if (!strcmp(pp->name, "dma")) | ||
510 | return 0; | ||
511 | |||
512 | /* Similarly for Simba PCI bridges. */ | ||
513 | model = of_get_property(pp, "model", NULL); | ||
514 | if (model && !strcmp(model, "SUNW,simba")) | ||
515 | return 0; | ||
518 | 516 | ||
519 | finish: | 517 | return 1; |
520 | /* Translate it into parent bus space */ | ||
521 | return pbus->translate(addr, offset, pna); | ||
522 | } | 518 | } |
523 | 519 | ||
520 | static int of_resource_verbose; | ||
521 | |||
524 | static void __init build_device_resources(struct of_device *op, | 522 | static void __init build_device_resources(struct of_device *op, |
525 | struct device *parent) | 523 | struct device *parent) |
526 | { | 524 | { |
@@ -564,15 +562,7 @@ static void __init build_device_resources(struct of_device *op, | |||
564 | 562 | ||
565 | memcpy(addr, reg, na * 4); | 563 | memcpy(addr, reg, na * 4); |
566 | 564 | ||
567 | /* If the immediate parent has no ranges property to apply, | 565 | if (use_1to1_mapping(pp)) { |
568 | * just use a 1<->1 mapping. Unless it is the 'dma' child | ||
569 | * of an isa bus, which must be passed up towards the root. | ||
570 | * | ||
571 | * Also, don't try to translate PMU bus device registers. | ||
572 | */ | ||
573 | if ((of_find_property(pp, "ranges", NULL) == NULL && | ||
574 | strcmp(pp->name, "dma") != 0) || | ||
575 | !strcmp(pp->name, "pmu")) { | ||
576 | result = of_read_addr(addr, na); | 566 | result = of_read_addr(addr, na); |
577 | goto build_res; | 567 | goto build_res; |
578 | } | 568 | } |
@@ -591,7 +581,8 @@ static void __init build_device_resources(struct of_device *op, | |||
591 | pbus = of_match_bus(pp); | 581 | pbus = of_match_bus(pp); |
592 | pbus->count_cells(dp, &pna, &pns); | 582 | pbus->count_cells(dp, &pna, &pns); |
593 | 583 | ||
594 | if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna)) | 584 | if (build_one_resource(dp, bus, pbus, addr, |
585 | dna, dns, pna)) | ||
595 | break; | 586 | break; |
596 | 587 | ||
597 | dna = pna; | 588 | dna = pna; |
@@ -601,6 +592,12 @@ static void __init build_device_resources(struct of_device *op, | |||
601 | 592 | ||
602 | build_res: | 593 | build_res: |
603 | memset(r, 0, sizeof(*r)); | 594 | memset(r, 0, sizeof(*r)); |
595 | |||
596 | if (of_resource_verbose) | ||
597 | printk("%s reg[%d] -> %lx\n", | ||
598 | op->node->full_name, index, | ||
599 | result); | ||
600 | |||
604 | if (result != OF_BAD_ADDR) { | 601 | if (result != OF_BAD_ADDR) { |
605 | if (tlb_type == hypervisor) | 602 | if (tlb_type == hypervisor) |
606 | result &= 0x0fffffffffffffffUL; | 603 | result &= 0x0fffffffffffffffUL; |
@@ -684,6 +681,8 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp, | |||
684 | return ret; | 681 | return ret; |
685 | } | 682 | } |
686 | 683 | ||
684 | static int of_irq_verbose; | ||
685 | |||
687 | static unsigned int __init build_one_device_irq(struct of_device *op, | 686 | static unsigned int __init build_one_device_irq(struct of_device *op, |
688 | struct device *parent, | 687 | struct device *parent, |
689 | unsigned int irq) | 688 | unsigned int irq) |
@@ -698,10 +697,11 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
698 | if (dp->irq_trans) { | 697 | if (dp->irq_trans) { |
699 | irq = dp->irq_trans->irq_build(dp, irq, | 698 | irq = dp->irq_trans->irq_build(dp, irq, |
700 | dp->irq_trans->data); | 699 | dp->irq_trans->data); |
701 | #if 1 | 700 | |
702 | printk("%s: direct translate %x --> %x\n", | 701 | if (of_irq_verbose) |
703 | dp->full_name, orig_irq, irq); | 702 | printk("%s: direct translate %x --> %x\n", |
704 | #endif | 703 | dp->full_name, orig_irq, irq); |
704 | |||
705 | return irq; | 705 | return irq; |
706 | } | 706 | } |
707 | 707 | ||
@@ -728,12 +728,13 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
728 | iret = apply_interrupt_map(dp, pp, | 728 | iret = apply_interrupt_map(dp, pp, |
729 | imap, imlen, imsk, | 729 | imap, imlen, imsk, |
730 | &irq); | 730 | &irq); |
731 | #if 1 | 731 | |
732 | printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", | 732 | if (of_irq_verbose) |
733 | op->node->full_name, | 733 | printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", |
734 | pp->full_name, this_orig_irq, | 734 | op->node->full_name, |
735 | (iret ? iret->full_name : "NULL"), irq); | 735 | pp->full_name, this_orig_irq, |
736 | #endif | 736 | (iret ? iret->full_name : "NULL"), irq); |
737 | |||
737 | if (!iret) | 738 | if (!iret) |
738 | break; | 739 | break; |
739 | 740 | ||
@@ -747,11 +748,13 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
747 | unsigned int this_orig_irq = irq; | 748 | unsigned int this_orig_irq = irq; |
748 | 749 | ||
749 | irq = pci_irq_swizzle(dp, pp, irq); | 750 | irq = pci_irq_swizzle(dp, pp, irq); |
750 | #if 1 | 751 | if (of_irq_verbose) |
751 | printk("%s: PCI swizzle [%s] %x --> %x\n", | 752 | printk("%s: PCI swizzle [%s] " |
752 | op->node->full_name, | 753 | "%x --> %x\n", |
753 | pp->full_name, this_orig_irq, irq); | 754 | op->node->full_name, |
754 | #endif | 755 | pp->full_name, this_orig_irq, |
756 | irq); | ||
757 | |||
755 | } | 758 | } |
756 | 759 | ||
757 | if (pp->irq_trans) { | 760 | if (pp->irq_trans) { |
@@ -767,10 +770,9 @@ static unsigned int __init build_one_device_irq(struct of_device *op, | |||
767 | 770 | ||
768 | irq = ip->irq_trans->irq_build(op->node, irq, | 771 | irq = ip->irq_trans->irq_build(op->node, irq, |
769 | ip->irq_trans->data); | 772 | ip->irq_trans->data); |
770 | #if 1 | 773 | if (of_irq_verbose) |
771 | printk("%s: Apply IRQ trans [%s] %x --> %x\n", | 774 | printk("%s: Apply IRQ trans [%s] %x --> %x\n", |
772 | op->node->full_name, ip->full_name, orig_irq, irq); | 775 | op->node->full_name, ip->full_name, orig_irq, irq); |
773 | #endif | ||
774 | 776 | ||
775 | return irq; | 777 | return irq; |
776 | } | 778 | } |
@@ -870,6 +872,20 @@ static int __init of_bus_driver_init(void) | |||
870 | 872 | ||
871 | postcore_initcall(of_bus_driver_init); | 873 | postcore_initcall(of_bus_driver_init); |
872 | 874 | ||
875 | static int __init of_debug(char *str) | ||
876 | { | ||
877 | int val = 0; | ||
878 | |||
879 | get_option(&str, &val); | ||
880 | if (val & 1) | ||
881 | of_resource_verbose = 1; | ||
882 | if (val & 2) | ||
883 | of_irq_verbose = 1; | ||
884 | return 1; | ||
885 | } | ||
886 | |||
887 | __setup("of_debug=", of_debug); | ||
888 | |||
873 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | 889 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) |
874 | { | 890 | { |
875 | /* initialize common driver fields */ | 891 | /* initialize common driver fields */ |
@@ -922,9 +938,11 @@ int of_device_register(struct of_device *ofdev) | |||
922 | if (rc) | 938 | if (rc) |
923 | return rc; | 939 | return rc; |
924 | 940 | ||
925 | device_create_file(&ofdev->dev, &dev_attr_devspec); | 941 | rc = device_create_file(&ofdev->dev, &dev_attr_devspec); |
942 | if (rc) | ||
943 | device_unregister(&ofdev->dev); | ||
926 | 944 | ||
927 | return 0; | 945 | return rc; |
928 | } | 946 | } |
929 | 947 | ||
930 | void of_device_unregister(struct of_device *ofdev) | 948 | void of_device_unregister(struct of_device *ofdev) |
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 99daeee4209d..c86007a2aa3f 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c | |||
@@ -539,6 +539,45 @@ static unsigned long __sabre_onboard_imap_off[] = { | |||
539 | ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ | 539 | ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ |
540 | (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) | 540 | (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) |
541 | 541 | ||
542 | static int sabre_device_needs_wsync(struct device_node *dp) | ||
543 | { | ||
544 | struct device_node *parent = dp->parent; | ||
545 | char *parent_model, *parent_compat; | ||
546 | |||
547 | /* This traversal up towards the root is meant to | ||
548 | * handle two cases: | ||
549 | * | ||
550 | * 1) non-PCI bus sitting under PCI, such as 'ebus' | ||
551 | * 2) the PCI controller interrupts themselves, which | ||
552 | * will use the sabre_irq_build but do not need | ||
553 | * the DMA synchronization handling | ||
554 | */ | ||
555 | while (parent) { | ||
556 | if (!strcmp(parent->type, "pci")) | ||
557 | break; | ||
558 | parent = parent->parent; | ||
559 | } | ||
560 | |||
561 | if (!parent) | ||
562 | return 0; | ||
563 | |||
564 | parent_model = of_get_property(parent, | ||
565 | "model", NULL); | ||
566 | if (parent_model && | ||
567 | (!strcmp(parent_model, "SUNW,sabre") || | ||
568 | !strcmp(parent_model, "SUNW,simba"))) | ||
569 | return 0; | ||
570 | |||
571 | parent_compat = of_get_property(parent, | ||
572 | "compatible", NULL); | ||
573 | if (parent_compat && | ||
574 | (!strcmp(parent_compat, "pci108e,a000") || | ||
575 | !strcmp(parent_compat, "pci108e,a001"))) | ||
576 | return 0; | ||
577 | |||
578 | return 1; | ||
579 | } | ||
580 | |||
542 | static unsigned int sabre_irq_build(struct device_node *dp, | 581 | static unsigned int sabre_irq_build(struct device_node *dp, |
543 | unsigned int ino, | 582 | unsigned int ino, |
544 | void *_data) | 583 | void *_data) |
@@ -577,15 +616,17 @@ static unsigned int sabre_irq_build(struct device_node *dp, | |||
577 | 616 | ||
578 | virt_irq = build_irq(inofixup, iclr, imap); | 617 | virt_irq = build_irq(inofixup, iclr, imap); |
579 | 618 | ||
619 | /* If the parent device is a PCI<->PCI bridge other than | ||
620 | * APB, we have to install a pre-handler to ensure that | ||
621 | * all pending DMA is drained before the interrupt handler | ||
622 | * is run. | ||
623 | */ | ||
580 | regs = of_get_property(dp, "reg", NULL); | 624 | regs = of_get_property(dp, "reg", NULL); |
581 | if (regs && | 625 | if (regs && sabre_device_needs_wsync(dp)) { |
582 | ((regs->phys_hi >> 16) & 0xff) != irq_data->pci_first_busno) { | ||
583 | irq_install_pre_handler(virt_irq, | 626 | irq_install_pre_handler(virt_irq, |
584 | sabre_wsync_handler, | 627 | sabre_wsync_handler, |
585 | (void *) (long) regs->phys_hi, | 628 | (void *) (long) regs->phys_hi, |
586 | (void *) | 629 | (void *) irq_data); |
587 | controller_regs + | ||
588 | SABRE_WRSYNC); | ||
589 | } | 630 | } |
590 | 631 | ||
591 | return virt_irq; | 632 | return virt_irq; |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index f9013baba05b..93bdaa3169fc 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1406,25 +1406,35 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1406 | struct device_node *dp = op->node; | 1406 | struct device_node *dp = op->node; |
1407 | struct uart_sunsu_port *up; | 1407 | struct uart_sunsu_port *up; |
1408 | struct resource *rp; | 1408 | struct resource *rp; |
1409 | enum su_type type; | ||
1409 | int err; | 1410 | int err; |
1410 | 1411 | ||
1411 | if (inst >= UART_NR) | 1412 | type = su_get_type(dp); |
1412 | return -EINVAL; | 1413 | if (type == SU_PORT_PORT) { |
1414 | if (inst >= UART_NR) | ||
1415 | return -EINVAL; | ||
1416 | up = &sunsu_ports[inst]; | ||
1417 | } else { | ||
1418 | up = kzalloc(sizeof(*up), GFP_KERNEL); | ||
1419 | if (!up) | ||
1420 | return -ENOMEM; | ||
1421 | } | ||
1413 | 1422 | ||
1414 | up = &sunsu_ports[inst]; | ||
1415 | up->port.line = inst; | 1423 | up->port.line = inst; |
1416 | 1424 | ||
1417 | spin_lock_init(&up->port.lock); | 1425 | spin_lock_init(&up->port.lock); |
1418 | 1426 | ||
1419 | up->su_type = su_get_type(dp); | 1427 | up->su_type = type; |
1420 | 1428 | ||
1421 | rp = &op->resource[0]; | 1429 | rp = &op->resource[0]; |
1422 | up->port.mapbase = op->resource[0].start; | 1430 | up->port.mapbase = rp->start; |
1423 | |||
1424 | up->reg_size = (rp->end - rp->start) + 1; | 1431 | up->reg_size = (rp->end - rp->start) + 1; |
1425 | up->port.membase = of_ioremap(rp, 0, up->reg_size, "su"); | 1432 | up->port.membase = of_ioremap(rp, 0, up->reg_size, "su"); |
1426 | if (!up->port.membase) | 1433 | if (!up->port.membase) { |
1434 | if (type != SU_PORT_PORT) | ||
1435 | kfree(up); | ||
1427 | return -ENOMEM; | 1436 | return -ENOMEM; |
1437 | } | ||
1428 | 1438 | ||
1429 | up->port.irq = op->irqs[0]; | 1439 | up->port.irq = op->irqs[0]; |
1430 | 1440 | ||
@@ -1436,8 +1446,11 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1436 | err = 0; | 1446 | err = 0; |
1437 | if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { | 1447 | if (up->su_type == SU_PORT_KBD || up->su_type == SU_PORT_MS) { |
1438 | err = sunsu_kbd_ms_init(up); | 1448 | err = sunsu_kbd_ms_init(up); |
1439 | if (err) | 1449 | if (err) { |
1450 | kfree(up); | ||
1440 | goto out_unmap; | 1451 | goto out_unmap; |
1452 | } | ||
1453 | dev_set_drvdata(&op->dev, up); | ||
1441 | 1454 | ||
1442 | return 0; | 1455 | return 0; |
1443 | } | 1456 | } |
@@ -1476,8 +1489,12 @@ static int __devexit su_remove(struct of_device *dev) | |||
1476 | #ifdef CONFIG_SERIO | 1489 | #ifdef CONFIG_SERIO |
1477 | serio_unregister_port(&up->serio); | 1490 | serio_unregister_port(&up->serio); |
1478 | #endif | 1491 | #endif |
1479 | } else if (up->port.type != PORT_UNKNOWN) | 1492 | kfree(up); |
1493 | } else if (up->port.type != PORT_UNKNOWN) { | ||
1480 | uart_remove_one_port(&sunsu_reg, &up->port); | 1494 | uart_remove_one_port(&sunsu_reg, &up->port); |
1495 | } | ||
1496 | |||
1497 | dev_set_drvdata(&dev->dev, NULL); | ||
1481 | 1498 | ||
1482 | return 0; | 1499 | return 0; |
1483 | } | 1500 | } |
diff --git a/include/asm-sparc64/Kbuild b/include/asm-sparc64/Kbuild index c78d44bb195f..9284c3cb27ec 100644 --- a/include/asm-sparc64/Kbuild +++ b/include/asm-sparc64/Kbuild | |||
@@ -4,7 +4,7 @@ ALTARCH := sparc | |||
4 | ARCHDEF := defined __sparc__ && defined __arch64__ | 4 | ARCHDEF := defined __sparc__ && defined __arch64__ |
5 | ALTARCHDEF := defined __sparc__ && !defined __arch64__ | 5 | ALTARCHDEF := defined __sparc__ && !defined __arch64__ |
6 | 6 | ||
7 | unifdef-y := fbio.h perfctr.h | 7 | unifdef-y += fbio.h perfctr.h |
8 | header-y += apb.h asi.h bbc.h bpp.h display7seg.h envctrl.h floppy.h \ | 8 | header-y += apb.h asi.h bbc.h bpp.h display7seg.h envctrl.h floppy.h \ |
9 | ipc.h kdebug.h mostek.h openprom.h openpromio.h parport.h \ | 9 | ipc.h kdebug.h mostek.h openprom.h openpromio.h parport.h \ |
10 | pconf.h psrcompat.h pstate.h reg.h uctx.h utrap.h watchdog.h | 10 | pconf.h psrcompat.h pstate.h reg.h uctx.h utrap.h watchdog.h |