diff options
Diffstat (limited to 'arch/sparc')
| -rw-r--r-- | arch/sparc/kernel/devices.c | 25 | ||||
| -rw-r--r-- | arch/sparc/kernel/irq.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/of_device.c | 207 | ||||
| -rw-r--r-- | arch/sparc/kernel/prom.c | 9 | ||||
| -rw-r--r-- | arch/sparc/kernel/setup.c | 2 | ||||
| -rw-r--r-- | arch/sparc/kernel/smp.c | 96 | ||||
| -rw-r--r-- | arch/sparc/kernel/sparc_ksyms.c | 1 | ||||
| -rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 103 | ||||
| -rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 18 | ||||
| -rw-r--r-- | arch/sparc/mm/io-unit.c | 1 | ||||
| -rw-r--r-- | arch/sparc/prom/tree.c | 18 |
11 files changed, 290 insertions, 192 deletions
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index adba9dfee35e..af90a5f9ab57 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
| 17 | #include <asm/oplib.h> | 17 | #include <asm/oplib.h> |
| 18 | #include <asm/prom.h> | ||
| 18 | #include <asm/smp.h> | 19 | #include <asm/smp.h> |
| 19 | #include <asm/system.h> | 20 | #include <asm/system.h> |
| 20 | #include <asm/cpudata.h> | 21 | #include <asm/cpudata.h> |
| @@ -34,12 +35,6 @@ static int check_cpu_node(int nd, int *cur_inst, | |||
| 34 | int (*compare)(int, int, void *), void *compare_arg, | 35 | int (*compare)(int, int, void *), void *compare_arg, |
| 35 | int *prom_node, int *mid) | 36 | int *prom_node, int *mid) |
| 36 | { | 37 | { |
| 37 | char node_str[128]; | ||
| 38 | |||
| 39 | prom_getstring(nd, "device_type", node_str, sizeof(node_str)); | ||
| 40 | if (strcmp(node_str, "cpu")) | ||
| 41 | return -ENODEV; | ||
| 42 | |||
| 43 | if (!compare(nd, *cur_inst, compare_arg)) { | 38 | if (!compare(nd, *cur_inst, compare_arg)) { |
| 44 | if (prom_node) | 39 | if (prom_node) |
| 45 | *prom_node = nd; | 40 | *prom_node = nd; |
| @@ -59,20 +54,14 @@ static int check_cpu_node(int nd, int *cur_inst, | |||
| 59 | static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, | 54 | static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, |
| 60 | int *prom_node, int *mid) | 55 | int *prom_node, int *mid) |
| 61 | { | 56 | { |
| 62 | int nd, cur_inst, err; | 57 | struct device_node *dp; |
| 58 | int cur_inst; | ||
| 63 | 59 | ||
| 64 | nd = prom_root_node; | ||
| 65 | cur_inst = 0; | 60 | cur_inst = 0; |
| 66 | 61 | for_each_node_by_type(dp, "cpu") { | |
| 67 | err = check_cpu_node(nd, &cur_inst, compare, compare_arg, | 62 | int err = check_cpu_node(dp->node, &cur_inst, |
| 68 | prom_node, mid); | 63 | compare, compare_arg, |
| 69 | if (!err) | 64 | prom_node, mid); |
| 70 | return 0; | ||
| 71 | |||
| 72 | nd = prom_getchild(nd); | ||
| 73 | while ((nd = prom_getsibling(nd)) != 0) { | ||
| 74 | err = check_cpu_node(nd, &cur_inst, compare, compare_arg, | ||
| 75 | prom_node, mid); | ||
| 76 | if (!err) | 65 | if (!err) |
| 77 | return 0; | 66 | return 0; |
| 78 | } | 67 | } |
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index cde73327ca96..72f0201051a0 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c | |||
| @@ -329,7 +329,7 @@ void handler_irq(int irq, struct pt_regs * regs) | |||
| 329 | disable_pil_irq(irq); | 329 | disable_pil_irq(irq); |
| 330 | #ifdef CONFIG_SMP | 330 | #ifdef CONFIG_SMP |
| 331 | /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */ | 331 | /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */ |
| 332 | if(irq < 10) | 332 | if((sparc_cpu_model==sun4m) && (irq < 10)) |
| 333 | smp4m_irq_rotate(cpu); | 333 | smp4m_irq_rotate(cpu); |
| 334 | #endif | 334 | #endif |
| 335 | action = sparc_irq[irq].action; | 335 | action = sparc_irq[irq].action; |
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index bc956c530376..97bf87e8cdde 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); | ||
| 230 | 235 | ||
| 231 | cp = of_read_addr(range, na); | 236 | if (a < b) |
| 232 | s = of_read_addr(range + na + pna, ns); | 237 | return 1; |
| 233 | da = of_read_addr(addr, na); | ||
| 234 | 238 | ||
| 235 | if (da < cp || da >= (cp + s)) | 239 | b += of_read_addr(size, ns); |
| 236 | return OF_BAD_ADDR; | 240 | if (a >= b) |
| 237 | return da - cp; | 241 | return 1; |
| 242 | |||
| 243 | return 0; | ||
| 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; |
| @@ -557,14 +596,41 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
| 557 | static int pil_to_sbus[] = { | 596 | static int pil_to_sbus[] = { |
| 558 | 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, | 597 | 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, |
| 559 | }; | 598 | }; |
| 560 | struct device_node *busp = dp->parent; | 599 | struct device_node *io_unit, *sbi = dp->parent; |
| 561 | struct linux_prom_registers *regs; | 600 | struct linux_prom_registers *regs; |
| 562 | int board = of_getintprop_default(busp, "board#", 0); | 601 | int board, slot; |
| 563 | int slot; | 602 | |
| 603 | while (sbi) { | ||
| 604 | if (!strcmp(sbi->name, "sbi")) | ||
| 605 | break; | ||
| 606 | |||
| 607 | sbi = sbi->parent; | ||
| 608 | } | ||
| 609 | if (!sbi) | ||
| 610 | goto build_resources; | ||
| 564 | 611 | ||
| 565 | regs = of_get_property(dp, "reg", NULL); | 612 | regs = of_get_property(dp, "reg", NULL); |
| 613 | if (!regs) | ||
| 614 | goto build_resources; | ||
| 615 | |||
| 566 | slot = regs->which_io; | 616 | slot = regs->which_io; |
| 567 | 617 | ||
| 618 | /* If SBI's parent is not io-unit or the io-unit lacks | ||
| 619 | * a "board#" property, something is very wrong. | ||
| 620 | */ | ||
| 621 | if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { | ||
| 622 | printk("%s: Error, parent is not io-unit.\n", | ||
| 623 | sbi->full_name); | ||
| 624 | goto build_resources; | ||
| 625 | } | ||
| 626 | io_unit = sbi->parent; | ||
| 627 | board = of_getintprop_default(io_unit, "board#", -1); | ||
| 628 | if (board == -1) { | ||
| 629 | printk("%s: Error, lacks board# property.\n", | ||
| 630 | io_unit->full_name); | ||
| 631 | goto build_resources; | ||
| 632 | } | ||
| 633 | |||
| 568 | for (i = 0; i < op->num_irqs; i++) { | 634 | for (i = 0; i < op->num_irqs; i++) { |
| 569 | int this_irq = op->irqs[i]; | 635 | int this_irq = op->irqs[i]; |
| 570 | int sbusl = pil_to_sbus[this_irq]; | 636 | int sbusl = pil_to_sbus[this_irq]; |
| @@ -578,6 +644,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, | |||
| 578 | } | 644 | } |
| 579 | } | 645 | } |
| 580 | 646 | ||
| 647 | build_resources: | ||
| 581 | build_device_resources(op, parent); | 648 | build_device_resources(op, parent); |
| 582 | 649 | ||
| 583 | op->dev.parent = parent; | 650 | op->dev.parent = parent; |
| @@ -643,6 +710,18 @@ static int __init of_bus_driver_init(void) | |||
| 643 | 710 | ||
| 644 | postcore_initcall(of_bus_driver_init); | 711 | postcore_initcall(of_bus_driver_init); |
| 645 | 712 | ||
| 713 | static int __init of_debug(char *str) | ||
| 714 | { | ||
| 715 | int val = 0; | ||
| 716 | |||
| 717 | get_option(&str, &val); | ||
| 718 | if (val & 1) | ||
| 719 | of_resource_verbose = 1; | ||
| 720 | return 1; | ||
| 721 | } | ||
| 722 | |||
| 723 | __setup("of_debug=", of_debug); | ||
| 724 | |||
| 646 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | 725 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) |
| 647 | { | 726 | { |
| 648 | /* initialize common driver fields */ | 727 | /* initialize common driver fields */ |
| @@ -695,9 +774,11 @@ int of_device_register(struct of_device *ofdev) | |||
| 695 | if (rc) | 774 | if (rc) |
| 696 | return rc; | 775 | return rc; |
| 697 | 776 | ||
| 698 | device_create_file(&ofdev->dev, &dev_attr_devspec); | 777 | rc = device_create_file(&ofdev->dev, &dev_attr_devspec); |
| 778 | if (rc) | ||
| 779 | device_unregister(&ofdev->dev); | ||
| 699 | 780 | ||
| 700 | return 0; | 781 | return rc; |
| 701 | } | 782 | } |
| 702 | 783 | ||
| 703 | void of_device_unregister(struct of_device *ofdev) | 784 | void of_device_unregister(struct of_device *ofdev) |
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 4b06dcb00ebd..4ca9e5fc97f4 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c | |||
| @@ -444,6 +444,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s | |||
| 444 | static struct property *tmp = NULL; | 444 | static struct property *tmp = NULL; |
| 445 | struct property *p; | 445 | struct property *p; |
| 446 | int len; | 446 | int len; |
| 447 | const char *name; | ||
| 447 | 448 | ||
| 448 | if (tmp) { | 449 | if (tmp) { |
| 449 | p = tmp; | 450 | p = tmp; |
| @@ -456,19 +457,21 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s | |||
| 456 | 457 | ||
| 457 | p->name = (char *) (p + 1); | 458 | p->name = (char *) (p + 1); |
| 458 | if (special_name) { | 459 | if (special_name) { |
| 460 | strcpy(p->name, special_name); | ||
| 459 | p->length = special_len; | 461 | p->length = special_len; |
| 460 | p->value = prom_early_alloc(special_len); | 462 | p->value = prom_early_alloc(special_len); |
| 461 | memcpy(p->value, special_val, special_len); | 463 | memcpy(p->value, special_val, special_len); |
| 462 | } else { | 464 | } else { |
| 463 | if (prev == NULL) { | 465 | if (prev == NULL) { |
| 464 | prom_firstprop(node, p->name); | 466 | name = prom_firstprop(node, NULL); |
| 465 | } else { | 467 | } else { |
| 466 | prom_nextprop(node, prev, p->name); | 468 | name = prom_nextprop(node, prev, NULL); |
| 467 | } | 469 | } |
| 468 | if (strlen(p->name) == 0) { | 470 | if (strlen(name) == 0) { |
| 469 | tmp = p; | 471 | tmp = p; |
| 470 | return NULL; | 472 | return NULL; |
| 471 | } | 473 | } |
| 474 | strcpy(p->name, name); | ||
| 472 | p->length = prom_getproplen(node, p->name); | 475 | p->length = prom_getproplen(node, p->name); |
| 473 | if (p->length <= 0) { | 476 | if (p->length <= 0) { |
| 474 | p->length = 0; | 477 | p->length = 0; |
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 8606ef4e52e9..35488d6c7457 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <asm/smp.h> | 17 | #include <asm/smp.h> |
| 18 | #include <linux/user.h> | 18 | #include <linux/user.h> |
| 19 | #include <linux/a.out.h> | 19 | #include <linux/a.out.h> |
| 20 | #include <linux/tty.h> | 20 | #include <linux/screen_info.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
| 23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 6135d4faeeeb..e311ade1b490 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c | |||
| @@ -87,6 +87,7 @@ void __cpuinit smp_store_cpu_info(int id) | |||
| 87 | void __init smp_cpus_done(unsigned int max_cpus) | 87 | void __init smp_cpus_done(unsigned int max_cpus) |
| 88 | { | 88 | { |
| 89 | extern void smp4m_smp_done(void); | 89 | extern void smp4m_smp_done(void); |
| 90 | extern void smp4d_smp_done(void); | ||
| 90 | unsigned long bogosum = 0; | 91 | unsigned long bogosum = 0; |
| 91 | int cpu, num; | 92 | int cpu, num; |
| 92 | 93 | ||
| @@ -100,8 +101,34 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
| 100 | num, bogosum/(500000/HZ), | 101 | num, bogosum/(500000/HZ), |
| 101 | (bogosum/(5000/HZ))%100); | 102 | (bogosum/(5000/HZ))%100); |
| 102 | 103 | ||
| 103 | BUG_ON(sparc_cpu_model != sun4m); | 104 | switch(sparc_cpu_model) { |
| 104 | smp4m_smp_done(); | 105 | case sun4: |
| 106 | printk("SUN4\n"); | ||
| 107 | BUG(); | ||
| 108 | break; | ||
| 109 | case sun4c: | ||
| 110 | printk("SUN4C\n"); | ||
| 111 | BUG(); | ||
| 112 | break; | ||
| 113 | case sun4m: | ||
| 114 | smp4m_smp_done(); | ||
| 115 | break; | ||
| 116 | case sun4d: | ||
| 117 | smp4d_smp_done(); | ||
| 118 | break; | ||
| 119 | case sun4e: | ||
| 120 | printk("SUN4E\n"); | ||
| 121 | BUG(); | ||
| 122 | break; | ||
| 123 | case sun4u: | ||
| 124 | printk("SUN4U\n"); | ||
| 125 | BUG(); | ||
| 126 | break; | ||
| 127 | default: | ||
| 128 | printk("UNKNOWN!\n"); | ||
| 129 | BUG(); | ||
| 130 | break; | ||
| 131 | }; | ||
| 105 | } | 132 | } |
| 106 | 133 | ||
| 107 | void cpu_panic(void) | 134 | void cpu_panic(void) |
| @@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier) | |||
| 267 | void __init smp_prepare_cpus(unsigned int max_cpus) | 294 | void __init smp_prepare_cpus(unsigned int max_cpus) |
| 268 | { | 295 | { |
| 269 | extern void smp4m_boot_cpus(void); | 296 | extern void smp4m_boot_cpus(void); |
| 297 | extern void smp4d_boot_cpus(void); | ||
| 270 | int i, cpuid, extra; | 298 | int i, cpuid, extra; |
| 271 | 299 | ||
| 272 | BUG_ON(sparc_cpu_model != sun4m); | ||
| 273 | printk("Entering SMP Mode...\n"); | 300 | printk("Entering SMP Mode...\n"); |
| 274 | 301 | ||
| 275 | extra = 0; | 302 | extra = 0; |
| @@ -283,7 +310,34 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
| 283 | 310 | ||
| 284 | smp_store_cpu_info(boot_cpu_id); | 311 | smp_store_cpu_info(boot_cpu_id); |
| 285 | 312 | ||
| 286 | smp4m_boot_cpus(); | 313 | switch(sparc_cpu_model) { |
| 314 | case sun4: | ||
| 315 | printk("SUN4\n"); | ||
| 316 | BUG(); | ||
| 317 | break; | ||
| 318 | case sun4c: | ||
| 319 | printk("SUN4C\n"); | ||
| 320 | BUG(); | ||
| 321 | break; | ||
| 322 | case sun4m: | ||
| 323 | smp4m_boot_cpus(); | ||
| 324 | break; | ||
| 325 | case sun4d: | ||
| 326 | smp4d_boot_cpus(); | ||
| 327 | break; | ||
| 328 | case sun4e: | ||
| 329 | printk("SUN4E\n"); | ||
| 330 | BUG(); | ||
| 331 | break; | ||
| 332 | case sun4u: | ||
| 333 | printk("SUN4U\n"); | ||
| 334 | BUG(); | ||
| 335 | break; | ||
| 336 | default: | ||
| 337 | printk("UNKNOWN!\n"); | ||
| 338 | BUG(); | ||
| 339 | break; | ||
| 340 | }; | ||
| 287 | } | 341 | } |
| 288 | 342 | ||
| 289 | /* Set this up early so that things like the scheduler can init | 343 | /* Set this up early so that things like the scheduler can init |
| @@ -323,9 +377,37 @@ void __init smp_prepare_boot_cpu(void) | |||
| 323 | int __cpuinit __cpu_up(unsigned int cpu) | 377 | int __cpuinit __cpu_up(unsigned int cpu) |
| 324 | { | 378 | { |
| 325 | extern int smp4m_boot_one_cpu(int); | 379 | extern int smp4m_boot_one_cpu(int); |
| 326 | int ret; | 380 | extern int smp4d_boot_one_cpu(int); |
| 327 | 381 | int ret=0; | |
| 328 | ret = smp4m_boot_one_cpu(cpu); | 382 | |
| 383 | switch(sparc_cpu_model) { | ||
| 384 | case sun4: | ||
| 385 | printk("SUN4\n"); | ||
| 386 | BUG(); | ||
| 387 | break; | ||
| 388 | case sun4c: | ||
| 389 | printk("SUN4C\n"); | ||
| 390 | BUG(); | ||
| 391 | break; | ||
| 392 | case sun4m: | ||
| 393 | ret = smp4m_boot_one_cpu(cpu); | ||
| 394 | break; | ||
| 395 | case sun4d: | ||
| 396 | ret = smp4d_boot_one_cpu(cpu); | ||
| 397 | break; | ||
| 398 | case sun4e: | ||
| 399 | printk("SUN4E\n"); | ||
| 400 | BUG(); | ||
| 401 | break; | ||
| 402 | case sun4u: | ||
| 403 | printk("SUN4U\n"); | ||
| 404 | BUG(); | ||
| 405 | break; | ||
| 406 | default: | ||
| 407 | printk("UNKNOWN!\n"); | ||
| 408 | BUG(); | ||
| 409 | break; | ||
| 410 | }; | ||
| 329 | 411 | ||
| 330 | if (!ret) { | 412 | if (!ret) { |
| 331 | cpu_set(cpu, smp_commenced_mask); | 413 | cpu_set(cpu, smp_commenced_mask); |
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 5fb987fc3d63..4d441a554d35 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c | |||
| @@ -237,7 +237,6 @@ EXPORT_SYMBOL(prom_node_has_property); | |||
| 237 | EXPORT_SYMBOL(prom_setprop); | 237 | EXPORT_SYMBOL(prom_setprop); |
| 238 | EXPORT_SYMBOL(saved_command_line); | 238 | EXPORT_SYMBOL(saved_command_line); |
| 239 | EXPORT_SYMBOL(prom_apply_obio_ranges); | 239 | EXPORT_SYMBOL(prom_apply_obio_ranges); |
| 240 | EXPORT_SYMBOL(prom_getname); | ||
| 241 | EXPORT_SYMBOL(prom_feval); | 240 | EXPORT_SYMBOL(prom_feval); |
| 242 | EXPORT_SYMBOL(prom_getbool); | 241 | EXPORT_SYMBOL(prom_getbool); |
| 243 | EXPORT_SYMBOL(prom_getstring); | 242 | EXPORT_SYMBOL(prom_getstring); |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index b141b7ee6717..ba843f6a2832 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
| @@ -43,15 +43,10 @@ extern ctxd_t *srmmu_ctx_table_phys; | |||
| 43 | extern void calibrate_delay(void); | 43 | extern void calibrate_delay(void); |
| 44 | 44 | ||
| 45 | extern volatile int smp_processors_ready; | 45 | extern volatile int smp_processors_ready; |
| 46 | extern int smp_num_cpus; | ||
| 47 | static int smp_highest_cpu; | 46 | static int smp_highest_cpu; |
| 48 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; | 47 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; |
| 49 | extern cpuinfo_sparc cpu_data[NR_CPUS]; | 48 | extern cpuinfo_sparc cpu_data[NR_CPUS]; |
| 50 | extern unsigned char boot_cpu_id; | 49 | extern unsigned char boot_cpu_id; |
| 51 | extern int smp_activated; | ||
| 52 | extern volatile int __cpu_number_map[NR_CPUS]; | ||
| 53 | extern volatile int __cpu_logical_map[NR_CPUS]; | ||
| 54 | extern volatile unsigned long ipi_count; | ||
| 55 | extern volatile int smp_process_available; | 50 | extern volatile int smp_process_available; |
| 56 | 51 | ||
| 57 | extern cpumask_t smp_commenced_mask; | 52 | extern cpumask_t smp_commenced_mask; |
| @@ -144,6 +139,8 @@ void __init smp4d_callin(void) | |||
| 144 | spin_lock_irqsave(&sun4d_imsk_lock, flags); | 139 | spin_lock_irqsave(&sun4d_imsk_lock, flags); |
| 145 | cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ | 140 | cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ |
| 146 | spin_unlock_irqrestore(&sun4d_imsk_lock, flags); | 141 | spin_unlock_irqrestore(&sun4d_imsk_lock, flags); |
| 142 | cpu_set(cpuid, cpu_online_map); | ||
| 143 | |||
| 147 | } | 144 | } |
| 148 | 145 | ||
| 149 | extern void init_IRQ(void); | 146 | extern void init_IRQ(void); |
| @@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[]; | |||
| 160 | 157 | ||
| 161 | void __init smp4d_boot_cpus(void) | 158 | void __init smp4d_boot_cpus(void) |
| 162 | { | 159 | { |
| 163 | int cpucount = 0; | ||
| 164 | int i, mid; | ||
| 165 | |||
| 166 | printk("Entering SMP Mode...\n"); | ||
| 167 | |||
| 168 | if (boot_cpu_id) | 160 | if (boot_cpu_id) |
| 169 | current_set[0] = NULL; | 161 | current_set[0] = NULL; |
| 170 | |||
| 171 | local_irq_enable(); | ||
| 172 | cpus_clear(cpu_present_map); | ||
| 173 | |||
| 174 | /* XXX This whole thing has to go. See sparc64. */ | ||
| 175 | for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++) | ||
| 176 | cpu_set(mid, cpu_present_map); | ||
| 177 | SMP_PRINTK(("cpu_present_map %08lx\n", cpus_addr(cpu_present_map)[0])); | ||
| 178 | for(i=0; i < NR_CPUS; i++) | ||
| 179 | __cpu_number_map[i] = -1; | ||
| 180 | for(i=0; i < NR_CPUS; i++) | ||
| 181 | __cpu_logical_map[i] = -1; | ||
| 182 | __cpu_number_map[boot_cpu_id] = 0; | ||
| 183 | __cpu_logical_map[0] = boot_cpu_id; | ||
| 184 | current_thread_info()->cpu = boot_cpu_id; | ||
| 185 | smp_store_cpu_info(boot_cpu_id); | ||
| 186 | smp_setup_percpu_timer(); | 162 | smp_setup_percpu_timer(); |
| 187 | local_flush_cache_all(); | 163 | local_flush_cache_all(); |
| 188 | if (cpu_find_by_instance(1, NULL, NULL)) | 164 | } |
| 189 | return; /* Not an MP box. */ | 165 | |
| 190 | SMP_PRINTK(("Iterating over CPUs\n")); | 166 | int smp4d_boot_one_cpu(int i) |
| 191 | for(i = 0; i < NR_CPUS; i++) { | 167 | { |
| 192 | if(i == boot_cpu_id) | ||
| 193 | continue; | ||
| 194 | |||
| 195 | if (cpu_isset(i, cpu_present_map)) { | ||
| 196 | extern unsigned long sun4d_cpu_startup; | 168 | extern unsigned long sun4d_cpu_startup; |
| 197 | unsigned long *entry = &sun4d_cpu_startup; | 169 | unsigned long *entry = &sun4d_cpu_startup; |
| 198 | struct task_struct *p; | 170 | struct task_struct *p; |
| 199 | int timeout; | 171 | int timeout; |
| 200 | int no; | 172 | int cpu_node; |
| 201 | 173 | ||
| 174 | cpu_find_by_instance(i, &cpu_node,NULL); | ||
| 202 | /* Cook up an idler for this guy. */ | 175 | /* Cook up an idler for this guy. */ |
| 203 | p = fork_idle(i); | 176 | p = fork_idle(i); |
| 204 | cpucount++; | ||
| 205 | current_set[i] = task_thread_info(p); | 177 | current_set[i] = task_thread_info(p); |
| 206 | for (no = 0; !cpu_find_by_instance(no, NULL, &mid) | ||
| 207 | && mid != i; no++) ; | ||
| 208 | 178 | ||
| 209 | /* | 179 | /* |
| 210 | * Initialize the contexts table | 180 | * Initialize the contexts table |
| @@ -216,9 +186,9 @@ void __init smp4d_boot_cpus(void) | |||
| 216 | smp_penguin_ctable.reg_size = 0; | 186 | smp_penguin_ctable.reg_size = 0; |
| 217 | 187 | ||
| 218 | /* whirrr, whirrr, whirrrrrrrrr... */ | 188 | /* whirrr, whirrr, whirrrrrrrrr... */ |
| 219 | SMP_PRINTK(("Starting CPU %d at %p task %d node %08x\n", i, entry, cpucount, cpu_data(no).prom_node)); | 189 | SMP_PRINTK(("Starting CPU %d at %p \n", i, entry)); |
| 220 | local_flush_cache_all(); | 190 | local_flush_cache_all(); |
| 221 | prom_startcpu(cpu_data(no).prom_node, | 191 | prom_startcpu(cpu_node, |
| 222 | &smp_penguin_ctable, 0, (char *)entry); | 192 | &smp_penguin_ctable, 0, (char *)entry); |
| 223 | 193 | ||
| 224 | SMP_PRINTK(("prom_startcpu returned :)\n")); | 194 | SMP_PRINTK(("prom_startcpu returned :)\n")); |
| @@ -230,39 +200,30 @@ void __init smp4d_boot_cpus(void) | |||
| 230 | udelay(200); | 200 | udelay(200); |
| 231 | } | 201 | } |
| 232 | 202 | ||
| 233 | if(cpu_callin_map[i]) { | 203 | if (!(cpu_callin_map[i])) { |
| 234 | /* Another "Red Snapper". */ | 204 | printk("Processor %d is stuck.\n", i); |
| 235 | __cpu_number_map[i] = cpucount; | 205 | return -ENODEV; |
| 236 | __cpu_logical_map[cpucount] = i; | 206 | |
| 237 | } else { | ||
| 238 | cpucount--; | ||
| 239 | printk("Processor %d is stuck.\n", i); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | if(!(cpu_callin_map[i])) { | ||
| 243 | cpu_clear(i, cpu_present_map); | ||
| 244 | __cpu_number_map[i] = -1; | ||
| 245 | } | ||
| 246 | } | 207 | } |
| 247 | local_flush_cache_all(); | 208 | local_flush_cache_all(); |
| 248 | if(cpucount == 0) { | 209 | return 0; |
| 249 | printk("Error: only one Processor found.\n"); | 210 | } |
| 250 | cpu_present_map = cpumask_of_cpu(hard_smp4d_processor_id()); | 211 | |
| 251 | } else { | 212 | void __init smp4d_smp_done(void) |
| 252 | unsigned long bogosum = 0; | 213 | { |
| 253 | 214 | int i, first; | |
| 254 | for_each_present_cpu(i) { | 215 | int *prev; |
| 255 | bogosum += cpu_data(i).udelay_val; | 216 | |
| 256 | smp_highest_cpu = i; | 217 | /* setup cpu list for irq rotation */ |
| 218 | first = 0; | ||
| 219 | prev = &first; | ||
| 220 | for (i = 0; i < NR_CPUS; i++) | ||
| 221 | if (cpu_online(i)) { | ||
| 222 | *prev = i; | ||
| 223 | prev = &cpu_data(i).next; | ||
| 257 | } | 224 | } |
| 258 | SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100)); | 225 | *prev = first; |
| 259 | printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", | 226 | local_flush_cache_all(); |
| 260 | cpucount + 1, | ||
| 261 | bogosum/(500000/HZ), | ||
| 262 | (bogosum/(5000/HZ))%100); | ||
| 263 | smp_activated = 1; | ||
| 264 | smp_num_cpus = cpucount + 1; | ||
| 265 | } | ||
| 266 | 227 | ||
| 267 | /* Free unneeded trap tables */ | 228 | /* Free unneeded trap tables */ |
| 268 | ClearPageReserved(virt_to_page(trapbase_cpu1)); | 229 | ClearPageReserved(virt_to_page(trapbase_cpu1)); |
| @@ -334,7 +295,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, | |||
| 334 | register int i; | 295 | register int i; |
| 335 | 296 | ||
| 336 | mask = cpumask_of_cpu(hard_smp4d_processor_id()); | 297 | mask = cpumask_of_cpu(hard_smp4d_processor_id()); |
| 337 | cpus_andnot(mask, cpu_present_map, mask); | 298 | cpus_andnot(mask, cpu_online_map, mask); |
| 338 | for(i = 0; i <= high; i++) { | 299 | for(i = 0; i <= high; i++) { |
| 339 | if (cpu_isset(i, mask)) { | 300 | if (cpu_isset(i, mask)) { |
| 340 | ccall_info.processors_in[i] = 0; | 301 | ccall_info.processors_in[i] = 0; |
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 0cdfc9d294b4..a41c8a5c2007 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c | |||
| @@ -465,21 +465,21 @@ sys_rt_sigaction(int sig, | |||
| 465 | 465 | ||
| 466 | asmlinkage int sys_getdomainname(char __user *name, int len) | 466 | asmlinkage int sys_getdomainname(char __user *name, int len) |
| 467 | { | 467 | { |
| 468 | int nlen; | 468 | int nlen, err; |
| 469 | int err = -EFAULT; | ||
| 470 | 469 | ||
| 470 | if (len < 0 || len > __NEW_UTS_LEN) | ||
| 471 | return -EINVAL; | ||
| 472 | |||
| 471 | down_read(&uts_sem); | 473 | down_read(&uts_sem); |
| 472 | 474 | ||
| 473 | nlen = strlen(system_utsname.domainname) + 1; | 475 | nlen = strlen(system_utsname.domainname) + 1; |
| 474 | |||
| 475 | if (nlen < len) | 476 | if (nlen < len) |
| 476 | len = nlen; | 477 | len = nlen; |
| 477 | if (len > __NEW_UTS_LEN) | 478 | |
| 478 | goto done; | 479 | err = -EFAULT; |
| 479 | if (copy_to_user(name, system_utsname.domainname, len)) | 480 | if (!copy_to_user(name, system_utsname.domainname, len)) |
| 480 | goto done; | 481 | err = 0; |
| 481 | err = 0; | 482 | |
| 482 | done: | ||
| 483 | up_read(&uts_sem); | 483 | up_read(&uts_sem); |
| 484 | return err; | 484 | return err; |
| 485 | } | 485 | } |
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 42c1c700c0a7..2bb1309003dd 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c | |||
| @@ -64,6 +64,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) | |||
| 64 | 64 | ||
| 65 | sbus->iommu = (struct iommu_struct *)iounit; | 65 | sbus->iommu = (struct iommu_struct *)iounit; |
| 66 | iounit->page_table = xpt; | 66 | iounit->page_table = xpt; |
| 67 | spin_lock_init(&iounit->lock); | ||
| 67 | 68 | ||
| 68 | for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t); | 69 | for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t); |
| 69 | xpt < xptend;) | 70 | xpt < xptend;) |
diff --git a/arch/sparc/prom/tree.c b/arch/sparc/prom/tree.c index 2bf03ee8cde5..5ec246573a98 100644 --- a/arch/sparc/prom/tree.c +++ b/arch/sparc/prom/tree.c | |||
| @@ -205,24 +205,6 @@ int prom_searchsiblings(int node_start, char *nodename) | |||
| 205 | return 0; | 205 | return 0; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | /* Gets name in the form prom v2+ uses it (name@x,yyyyy or name (if no reg)) */ | ||
| 209 | int prom_getname (int node, char *buffer, int len) | ||
| 210 | { | ||
| 211 | int i; | ||
| 212 | struct linux_prom_registers reg[PROMREG_MAX]; | ||
| 213 | |||
| 214 | i = prom_getproperty (node, "name", buffer, len); | ||
| 215 | if (i <= 0) return -1; | ||
| 216 | buffer [i] = 0; | ||
| 217 | len -= i; | ||
| 218 | i = prom_getproperty (node, "reg", (char *)reg, sizeof (reg)); | ||
| 219 | if (i <= 0) return 0; | ||
| 220 | if (len < 11) return -1; | ||
| 221 | buffer = strchr (buffer, 0); | ||
| 222 | sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr); | ||
| 223 | return 0; | ||
| 224 | } | ||
| 225 | |||
| 226 | /* Interal version of nextprop that does not alter return values. */ | 208 | /* Interal version of nextprop that does not alter return values. */ |
| 227 | char * __prom_nextprop(int node, char * oprop) | 209 | char * __prom_nextprop(int node, char * oprop) |
| 228 | { | 210 | { |
