aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-22 22:12:03 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:28 -0400
commit690c8fd31f1e35985d0f35772fde514da59ec9d1 (patch)
tree8a5a0036b3780a9eb315ea2201a2562570de1ebe /arch
parentde8d28b16f5614aeb12bb69c8f9a38578b8d3ada (diff)
[SPARC64]: Use in-kernel PROM tree for EBUS and ISA.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc64/kernel/auxio.c2
-rw-r--r--arch/sparc64/kernel/ebus.c141
-rw-r--r--arch/sparc64/kernel/isa.c144
-rw-r--r--arch/sparc64/kernel/power.c20
-rw-r--r--arch/sparc64/kernel/prom.c1
-rw-r--r--arch/sparc64/kernel/time.c368
6 files changed, 338 insertions, 338 deletions
diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
index 8852c20c8d99..db36b66a4e3c 100644
--- a/arch/sparc64/kernel/auxio.c
+++ b/arch/sparc64/kernel/auxio.c
@@ -136,7 +136,7 @@ found_sdev:
136 136
137 for_each_ebus(ebus) { 137 for_each_ebus(ebus) {
138 for_each_ebusdev(edev, ebus) { 138 for_each_ebusdev(edev, ebus) {
139 if (!strcmp(edev->prom_name, "auxio")) 139 if (!strcmp(edev->prom_node->name, "auxio"))
140 goto ebus_done; 140 goto ebus_done;
141 } 141 }
142 } 142 }
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 3125a5b49775..919a91d9e5de 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -285,36 +285,38 @@ static inline void *ebus_alloc(size_t size)
285 285
286static void __init ebus_ranges_init(struct linux_ebus *ebus) 286static void __init ebus_ranges_init(struct linux_ebus *ebus)
287{ 287{
288 int success; 288 struct linux_prom_ebus_ranges *rngs;
289 int len;
289 290
290 ebus->num_ebus_ranges = 0; 291 ebus->num_ebus_ranges = 0;
291 success = prom_getproperty(ebus->prom_node, "ranges", 292 rngs = of_get_property(ebus->prom_node, "ranges", &len);
292 (char *)ebus->ebus_ranges, 293 if (rngs) {
293 sizeof(ebus->ebus_ranges)); 294 memcpy(ebus->ebus_ranges, rngs, len);
294 if (success != -1) 295 ebus->num_ebus_ranges =
295 ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges)); 296 (len / sizeof(struct linux_prom_ebus_ranges));
297 }
296} 298}
297 299
298static void __init ebus_intmap_init(struct linux_ebus *ebus) 300static void __init ebus_intmap_init(struct linux_ebus *ebus)
299{ 301{
300 int success; 302 struct linux_prom_ebus_intmap *imap;
303 struct linux_prom_ebus_intmask *imask;
304 int len;
301 305
302 ebus->num_ebus_intmap = 0; 306 ebus->num_ebus_intmap = 0;
303 success = prom_getproperty(ebus->prom_node, "interrupt-map", 307 imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
304 (char *)ebus->ebus_intmap, 308 if (!imap)
305 sizeof(ebus->ebus_intmap));
306 if (success == -1)
307 return; 309 return;
308 310
309 ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap)); 311 memcpy(ebus->ebus_intmap, imap, len);
312 ebus->num_ebus_intmap = (len / sizeof(struct linux_prom_ebus_intmap));
310 313
311 success = prom_getproperty(ebus->prom_node, "interrupt-map-mask", 314 imask = of_get_property(ebus->prom_node, "interrupt-map-mask", &len);
312 (char *)&ebus->ebus_intmask, 315 if (!imask) {
313 sizeof(ebus->ebus_intmask)); 316 prom_printf("EBUS: can't get interrupt-map-mask\n");
314 if (success == -1) {
315 prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
316 prom_halt(); 317 prom_halt();
317 } 318 }
319 memcpy(&ebus->ebus_intmask, imask, sizeof(ebus->ebus_intmask));
318} 320}
319 321
320int __init ebus_intmap_match(struct linux_ebus *ebus, 322int __init ebus_intmap_match(struct linux_ebus *ebus,
@@ -341,19 +343,23 @@ int __init ebus_intmap_match(struct linux_ebus *ebus,
341 return -1; 343 return -1;
342} 344}
343 345
344void __init fill_ebus_child(int node, struct linux_prom_registers *preg, 346void __init fill_ebus_child(struct device_node *dp,
345 struct linux_ebus_child *dev, int non_standard_regs) 347 struct linux_prom_registers *preg,
348 struct linux_ebus_child *dev,
349 int non_standard_regs)
346{ 350{
347 int regs[PROMREG_MAX]; 351 int *regs;
348 int irqs[PROMREG_MAX]; 352 int *irqs;
349 int i, len; 353 int i, len;
350 354
351 dev->prom_node = node; 355 dev->prom_node = dp;
352 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); 356 printk(" (%s)", dp->name);
353 printk(" (%s)", dev->prom_name);
354 357
355 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 358 regs = of_get_property(dp, "reg", &len);
356 dev->num_addrs = len / sizeof(regs[0]); 359 if (!regs)
360 dev->num_addrs = 0;
361 else
362 dev->num_addrs = len / sizeof(regs[0]);
357 363
358 if (non_standard_regs) { 364 if (non_standard_regs) {
359 /* This is to handle reg properties which are not 365 /* This is to handle reg properties which are not
@@ -370,21 +376,21 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
370 int rnum = regs[i]; 376 int rnum = regs[i];
371 if (rnum >= dev->parent->num_addrs) { 377 if (rnum >= dev->parent->num_addrs) {
372 prom_printf("UGH: property for %s was %d, need < %d\n", 378 prom_printf("UGH: property for %s was %d, need < %d\n",
373 dev->prom_name, len, dev->parent->num_addrs); 379 dp->name, len, dev->parent->num_addrs);
374 panic(__FUNCTION__); 380 prom_halt();
375 } 381 }
376 dev->resource[i].start = dev->parent->resource[i].start; 382 dev->resource[i].start = dev->parent->resource[i].start;
377 dev->resource[i].end = dev->parent->resource[i].end; 383 dev->resource[i].end = dev->parent->resource[i].end;
378 dev->resource[i].flags = IORESOURCE_MEM; 384 dev->resource[i].flags = IORESOURCE_MEM;
379 dev->resource[i].name = dev->prom_name; 385 dev->resource[i].name = dp->name;
380 } 386 }
381 } 387 }
382 388
383 for (i = 0; i < PROMINTR_MAX; i++) 389 for (i = 0; i < PROMINTR_MAX; i++)
384 dev->irqs[i] = PCI_IRQ_NONE; 390 dev->irqs[i] = PCI_IRQ_NONE;
385 391
386 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 392 irqs = of_get_property(dp, "interrupts", &len);
387 if ((len == -1) || (len == 0)) { 393 if (!irqs) {
388 dev->num_irqs = 0; 394 dev->num_irqs = 0;
389 /* 395 /*
390 * Oh, well, some PROMs don't export interrupts 396 * Oh, well, some PROMs don't export interrupts
@@ -392,8 +398,8 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
392 * 398 *
393 * Be smart about PS/2 keyboard and mouse. 399 * Be smart about PS/2 keyboard and mouse.
394 */ 400 */
395 if (!strcmp(dev->parent->prom_name, "8042")) { 401 if (!strcmp(dev->parent->prom_node->name, "8042")) {
396 if (!strcmp(dev->prom_name, "kb_ps2")) { 402 if (!strcmp(dev->prom_node->name, "kb_ps2")) {
397 dev->num_irqs = 1; 403 dev->num_irqs = 1;
398 dev->irqs[0] = dev->parent->irqs[0]; 404 dev->irqs[0] = dev->parent->irqs[0];
399 } else { 405 } else {
@@ -423,32 +429,32 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
423 429
424static int __init child_regs_nonstandard(struct linux_ebus_device *dev) 430static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
425{ 431{
426 if (!strcmp(dev->prom_name, "i2c") || 432 if (!strcmp(dev->prom_node->name, "i2c") ||
427 !strcmp(dev->prom_name, "SUNW,lombus")) 433 !strcmp(dev->prom_node->name, "SUNW,lombus"))
428 return 1; 434 return 1;
429 return 0; 435 return 0;
430} 436}
431 437
432void __init fill_ebus_device(int node, struct linux_ebus_device *dev) 438void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
433{ 439{
434 struct linux_prom_registers regs[PROMREG_MAX]; 440 struct linux_prom_registers *regs;
435 struct linux_ebus_child *child; 441 struct linux_ebus_child *child;
436 int irqs[PROMINTR_MAX]; 442 int *irqs;
437 int i, n, len; 443 int i, n, len;
438 444
439 dev->prom_node = node; 445 dev->prom_node = dp;
440 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
441 printk(" [%s", dev->prom_name);
442 446
443 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 447 printk(" [%s", dp->name);
444 if (len == -1) { 448
449 regs = of_get_property(dp, "reg", &len);
450 if (!regs) {
445 dev->num_addrs = 0; 451 dev->num_addrs = 0;
446 goto probe_interrupts; 452 goto probe_interrupts;
447 } 453 }
448 454
449 if (len % sizeof(struct linux_prom_registers)) { 455 if (len % sizeof(struct linux_prom_registers)) {
450 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", 456 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
451 dev->prom_name, len, 457 dev->prom_node->name, len,
452 (int)sizeof(struct linux_prom_registers)); 458 (int)sizeof(struct linux_prom_registers));
453 prom_halt(); 459 prom_halt();
454 } 460 }
@@ -466,7 +472,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
466 dev->resource[i].end = 472 dev->resource[i].end =
467 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL); 473 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
468 dev->resource[i].flags = IORESOURCE_MEM; 474 dev->resource[i].flags = IORESOURCE_MEM;
469 dev->resource[i].name = dev->prom_name; 475 dev->resource[i].name = dev->prom_node->name;
470 request_resource(&dev->bus->self->resource[n], 476 request_resource(&dev->bus->self->resource[n],
471 &dev->resource[i]); 477 &dev->resource[i]);
472 } 478 }
@@ -475,8 +481,8 @@ probe_interrupts:
475 for (i = 0; i < PROMINTR_MAX; i++) 481 for (i = 0; i < PROMINTR_MAX; i++)
476 dev->irqs[i] = PCI_IRQ_NONE; 482 dev->irqs[i] = PCI_IRQ_NONE;
477 483
478 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 484 irqs = of_get_property(dp, "interrupts", &len);
479 if ((len == -1) || (len == 0)) { 485 if (!irqs) {
480 dev->num_irqs = 0; 486 dev->num_irqs = 0;
481 } else { 487 } else {
482 dev->num_irqs = len / sizeof(irqs[0]); 488 dev->num_irqs = len / sizeof(irqs[0]);
@@ -497,7 +503,8 @@ probe_interrupts:
497 } 503 }
498 } 504 }
499 505
500 if ((node = prom_getchild(node))) { 506 dp = dp->child;
507 if (dp) {
501 printk(" ->"); 508 printk(" ->");
502 dev->children = ebus_alloc(sizeof(struct linux_ebus_child)); 509 dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
503 510
@@ -505,18 +512,18 @@ probe_interrupts:
505 child->next = NULL; 512 child->next = NULL;
506 child->parent = dev; 513 child->parent = dev;
507 child->bus = dev->bus; 514 child->bus = dev->bus;
508 fill_ebus_child(node, &regs[0], 515 fill_ebus_child(dp, regs, child,
509 child, child_regs_nonstandard(dev)); 516 child_regs_nonstandard(dev));
510 517
511 while ((node = prom_getsibling(node)) != 0) { 518 while ((dp = dp->sibling) != NULL) {
512 child->next = ebus_alloc(sizeof(struct linux_ebus_child)); 519 child->next = ebus_alloc(sizeof(struct linux_ebus_child));
513 520
514 child = child->next; 521 child = child->next;
515 child->next = NULL; 522 child->next = NULL;
516 child->parent = dev; 523 child->parent = dev;
517 child->bus = dev->bus; 524 child->bus = dev->bus;
518 fill_ebus_child(node, &regs[0], 525 fill_ebus_child(dp, regs, child,
519 child, child_regs_nonstandard(dev)); 526 child_regs_nonstandard(dev));
520 } 527 }
521 } 528 }
522 printk("]"); 529 printk("]");
@@ -543,7 +550,8 @@ void __init ebus_init(void)
543 struct linux_ebus *ebus; 550 struct linux_ebus *ebus;
544 struct pci_dev *pdev; 551 struct pci_dev *pdev;
545 struct pcidev_cookie *cookie; 552 struct pcidev_cookie *cookie;
546 int nd, ebusnd, is_rio; 553 struct device_node *dp;
554 int is_rio;
547 int num_ebus = 0; 555 int num_ebus = 0;
548 556
549 pdev = find_next_ebus(NULL, &is_rio); 557 pdev = find_next_ebus(NULL, &is_rio);
@@ -553,20 +561,22 @@ void __init ebus_init(void)
553 } 561 }
554 562
555 cookie = pdev->sysdata; 563 cookie = pdev->sysdata;
556 ebusnd = cookie->prom_node->node; 564 dp = cookie->prom_node;
557 565
558 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); 566 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
559 ebus->next = NULL; 567 ebus->next = NULL;
560 ebus->is_rio = is_rio; 568 ebus->is_rio = is_rio;
561 569
562 while (ebusnd) { 570 while (dp) {
571 struct device_node *child;
572
563 /* SUNW,pci-qfe uses four empty ebuses on it. 573 /* SUNW,pci-qfe uses four empty ebuses on it.
564 I think we should not consider them here, 574 I think we should not consider them here,
565 as they have half of the properties this 575 as they have half of the properties this
566 code expects and once we do PCI hot-plug, 576 code expects and once we do PCI hot-plug,
567 we'd have to tweak with the ebus_chain 577 we'd have to tweak with the ebus_chain
568 in the runtime after initialization. -jj */ 578 in the runtime after initialization. -jj */
569 if (!prom_getchild (ebusnd)) { 579 if (!dp->child) {
570 pdev = find_next_ebus(pdev, &is_rio); 580 pdev = find_next_ebus(pdev, &is_rio);
571 if (!pdev) { 581 if (!pdev) {
572 if (ebus == ebus_chain) { 582 if (ebus == ebus_chain) {
@@ -578,22 +588,21 @@ void __init ebus_init(void)
578 } 588 }
579 ebus->is_rio = is_rio; 589 ebus->is_rio = is_rio;
580 cookie = pdev->sysdata; 590 cookie = pdev->sysdata;
581 ebusnd = cookie->prom_node->node; 591 dp = cookie->prom_node;
582 continue; 592 continue;
583 } 593 }
584 printk("ebus%d:", num_ebus); 594 printk("ebus%d:", num_ebus);
585 595
586 prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
587 ebus->index = num_ebus; 596 ebus->index = num_ebus;
588 ebus->prom_node = ebusnd; 597 ebus->prom_node = dp;
589 ebus->self = pdev; 598 ebus->self = pdev;
590 ebus->parent = pbm = cookie->pbm; 599 ebus->parent = pbm = cookie->pbm;
591 600
592 ebus_ranges_init(ebus); 601 ebus_ranges_init(ebus);
593 ebus_intmap_init(ebus); 602 ebus_intmap_init(ebus);
594 603
595 nd = prom_getchild(ebusnd); 604 child = dp->child;
596 if (!nd) 605 if (!child)
597 goto next_ebus; 606 goto next_ebus;
598 607
599 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); 608 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
@@ -602,16 +611,16 @@ void __init ebus_init(void)
602 dev->next = NULL; 611 dev->next = NULL;
603 dev->children = NULL; 612 dev->children = NULL;
604 dev->bus = ebus; 613 dev->bus = ebus;
605 fill_ebus_device(nd, dev); 614 fill_ebus_device(child, dev);
606 615
607 while ((nd = prom_getsibling(nd)) != 0) { 616 while ((child = child->sibling) != NULL) {
608 dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); 617 dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
609 618
610 dev = dev->next; 619 dev = dev->next;
611 dev->next = NULL; 620 dev->next = NULL;
612 dev->children = NULL; 621 dev->children = NULL;
613 dev->bus = ebus; 622 dev->bus = ebus;
614 fill_ebus_device(nd, dev); 623 fill_ebus_device(child, dev);
615 } 624 }
616 625
617 next_ebus: 626 next_ebus:
@@ -622,7 +631,7 @@ void __init ebus_init(void)
622 break; 631 break;
623 632
624 cookie = pdev->sysdata; 633 cookie = pdev->sysdata;
625 ebusnd = cookie->prom_node->node; 634 dp = cookie->prom_node;
626 635
627 ebus->next = ebus_alloc(sizeof(struct linux_ebus)); 636 ebus->next = ebus_alloc(sizeof(struct linux_ebus));
628 ebus = ebus->next; 637 ebus = ebus->next;
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index ae02c3820eab..8c8c5a491ad6 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -15,23 +15,19 @@ static void __init fatal_err(const char *reason)
15static void __init report_dev(struct sparc_isa_device *isa_dev, int child) 15static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
16{ 16{
17 if (child) 17 if (child)
18 printk(" (%s)", isa_dev->prom_name); 18 printk(" (%s)", isa_dev->prom_node->name);
19 else 19 else
20 printk(" [%s", isa_dev->prom_name); 20 printk(" [%s", isa_dev->prom_node->name);
21} 21}
22 22
23static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev, 23static struct linux_prom_registers * __init
24 struct linux_prom_registers *pregs, 24isa_dev_get_resource(struct sparc_isa_device *isa_dev)
25 int pregs_size)
26{ 25{
26 struct linux_prom_registers *pregs;
27 unsigned long base, len; 27 unsigned long base, len;
28 int prop_len; 28 int prop_len;
29 29
30 prop_len = prom_getproperty(isa_dev->prom_node, "reg", 30 pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
31 (char *) pregs, pregs_size);
32
33 if (prop_len <= 0)
34 return;
35 31
36 /* Only the first one is interesting. */ 32 /* Only the first one is interesting. */
37 len = pregs[0].reg_size; 33 len = pregs[0].reg_size;
@@ -42,10 +38,12 @@ static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev,
42 isa_dev->resource.start = base; 38 isa_dev->resource.start = base;
43 isa_dev->resource.end = (base + len - 1UL); 39 isa_dev->resource.end = (base + len - 1UL);
44 isa_dev->resource.flags = IORESOURCE_IO; 40 isa_dev->resource.flags = IORESOURCE_IO;
45 isa_dev->resource.name = isa_dev->prom_name; 41 isa_dev->resource.name = isa_dev->prom_node->name;
46 42
47 request_resource(&isa_dev->bus->parent->io_space, 43 request_resource(&isa_dev->bus->parent->io_space,
48 &isa_dev->resource); 44 &isa_dev->resource);
45
46 return pregs;
49} 47}
50 48
51/* I can't believe they didn't put a real INO in the isa device 49/* I can't believe they didn't put a real INO in the isa device
@@ -98,8 +96,8 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
98{ 96{
99 int irq_prop; 97 int irq_prop;
100 98
101 irq_prop = prom_getintdefault(isa_dev->prom_node, 99 irq_prop = of_getintprop_default(isa_dev->prom_node,
102 "interrupts", -1); 100 "interrupts", -1);
103 if (irq_prop <= 0) { 101 if (irq_prop <= 0) {
104 goto no_irq; 102 goto no_irq;
105 } else { 103 } else {
@@ -141,16 +139,15 @@ no_irq:
141 139
142static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) 140static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
143{ 141{
144 int node = prom_getchild(parent_isa_dev->prom_node); 142 struct device_node *dp = parent_isa_dev->prom_node->child;
145 143
146 if (node == 0) 144 if (!dp)
147 return; 145 return;
148 146
149 printk(" ->"); 147 printk(" ->");
150 while (node != 0) { 148 while (dp) {
151 struct linux_prom_registers regs[PROMREG_MAX]; 149 struct linux_prom_registers *regs;
152 struct sparc_isa_device *isa_dev; 150 struct sparc_isa_device *isa_dev;
153 int prop_len;
154 151
155 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); 152 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
156 if (!isa_dev) { 153 if (!isa_dev) {
@@ -165,40 +162,24 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
165 parent_isa_dev->child = isa_dev; 162 parent_isa_dev->child = isa_dev;
166 163
167 isa_dev->bus = parent_isa_dev->bus; 164 isa_dev->bus = parent_isa_dev->bus;
168 isa_dev->prom_node = node; 165 isa_dev->prom_node = dp;
169 prop_len = prom_getproperty(node, "name",
170 (char *) isa_dev->prom_name,
171 sizeof(isa_dev->prom_name));
172 if (prop_len <= 0) {
173 fatal_err("cannot get child isa_dev OBP node name");
174 prom_halt();
175 }
176
177 prop_len = prom_getproperty(node, "compatible",
178 (char *) isa_dev->compatible,
179 sizeof(isa_dev->compatible));
180 166
181 /* Not having this is OK. */ 167 regs = isa_dev_get_resource(isa_dev);
182 if (prop_len <= 0)
183 isa_dev->compatible[0] = '\0';
184
185 isa_dev_get_resource(isa_dev, regs, sizeof(regs));
186 isa_dev_get_irq(isa_dev, regs); 168 isa_dev_get_irq(isa_dev, regs);
187 169
188 report_dev(isa_dev, 1); 170 report_dev(isa_dev, 1);
189 171
190 node = prom_getsibling(node); 172 dp = dp->sibling;
191 } 173 }
192} 174}
193 175
194static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) 176static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
195{ 177{
196 int node = prom_getchild(isa_br->prom_node); 178 struct device_node *dp = isa_br->prom_node->child;
197 179
198 while (node != 0) { 180 while (dp) {
199 struct linux_prom_registers regs[PROMREG_MAX]; 181 struct linux_prom_registers *regs;
200 struct sparc_isa_device *isa_dev; 182 struct sparc_isa_device *isa_dev;
201 int prop_len;
202 183
203 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); 184 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
204 if (!isa_dev) { 185 if (!isa_dev) {
@@ -222,24 +203,9 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
222 } 203 }
223 204
224 isa_dev->bus = isa_br; 205 isa_dev->bus = isa_br;
225 isa_dev->prom_node = node; 206 isa_dev->prom_node = dp;
226 prop_len = prom_getproperty(node, "name",
227 (char *) isa_dev->prom_name,
228 sizeof(isa_dev->prom_name));
229 if (prop_len <= 0) {
230 fatal_err("cannot get isa_dev OBP node name");
231 prom_halt();
232 }
233
234 prop_len = prom_getproperty(node, "compatible",
235 (char *) isa_dev->compatible,
236 sizeof(isa_dev->compatible));
237
238 /* Not having this is OK. */
239 if (prop_len <= 0)
240 isa_dev->compatible[0] = '\0';
241 207
242 isa_dev_get_resource(isa_dev, regs, sizeof(regs)); 208 regs = isa_dev_get_resource(isa_dev);
243 isa_dev_get_irq(isa_dev, regs); 209 isa_dev_get_irq(isa_dev, regs);
244 210
245 report_dev(isa_dev, 0); 211 report_dev(isa_dev, 0);
@@ -248,10 +214,40 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
248 214
249 printk("]"); 215 printk("]");
250 216
251 node = prom_getsibling(node); 217 dp = dp->sibling;
252 } 218 }
253} 219}
254 220
221static void __init get_bridge_props(struct sparc_isa_bridge *isa_br)
222{
223 struct device_node *dp = isa_br->prom_node;
224 void *pval;
225 int len;
226
227 pval = of_get_property(dp, "ranges", &len);
228 if (pval) {
229 memcpy(isa_br->isa_ranges, pval, len);
230 isa_br->num_isa_ranges =
231 len / sizeof(struct linux_prom_isa_ranges);
232 } else {
233 isa_br->num_isa_ranges = 0;
234 }
235
236 pval = of_get_property(dp, "interrupt-map", &len);
237 if (pval) {
238 memcpy(isa_br->isa_intmap, pval, len);
239 isa_br->num_isa_intmap =
240 (len / sizeof(struct linux_prom_isa_intmap));
241 } else {
242 isa_br->num_isa_intmap = 0;
243 }
244
245 pval = of_get_property(dp, "interrupt-map-mask", &len);
246 if (pval)
247 memcpy(&isa_br->isa_intmask, pval,
248 sizeof(isa_br->isa_intmask));
249}
250
255void __init isa_init(void) 251void __init isa_init(void)
256{ 252{
257 struct pci_dev *pdev; 253 struct pci_dev *pdev;
@@ -266,7 +262,6 @@ void __init isa_init(void)
266 struct pcidev_cookie *pdev_cookie; 262 struct pcidev_cookie *pdev_cookie;
267 struct pci_pbm_info *pbm; 263 struct pci_pbm_info *pbm;
268 struct sparc_isa_bridge *isa_br; 264 struct sparc_isa_bridge *isa_br;
269 int prop_len;
270 265
271 pdev_cookie = pdev->sysdata; 266 pdev_cookie = pdev->sysdata;
272 if (!pdev_cookie) { 267 if (!pdev_cookie) {
@@ -291,34 +286,9 @@ void __init isa_init(void)
291 isa_br->parent = pbm; 286 isa_br->parent = pbm;
292 isa_br->self = pdev; 287 isa_br->self = pdev;
293 isa_br->index = index++; 288 isa_br->index = index++;
294 isa_br->prom_node = pdev_cookie->prom_node->node; 289 isa_br->prom_node = pdev_cookie->prom_node;
295 strncpy(isa_br->prom_name, pdev_cookie->prom_node->name, 290
296 sizeof(isa_br->prom_name)); 291 get_bridge_props(isa_br);
297
298 prop_len = prom_getproperty(isa_br->prom_node,
299 "ranges",
300 (char *) isa_br->isa_ranges,
301 sizeof(isa_br->isa_ranges));
302 if (prop_len <= 0)
303 isa_br->num_isa_ranges = 0;
304 else
305 isa_br->num_isa_ranges =
306 (prop_len / sizeof(struct linux_prom_isa_ranges));
307
308 prop_len = prom_getproperty(isa_br->prom_node,
309 "interrupt-map",
310 (char *) isa_br->isa_intmap,
311 sizeof(isa_br->isa_intmap));
312 if (prop_len <= 0)
313 isa_br->num_isa_intmap = 0;
314 else
315 isa_br->num_isa_intmap =
316 (prop_len / sizeof(struct linux_prom_isa_intmap));
317
318 prop_len = prom_getproperty(isa_br->prom_node,
319 "interrupt-map-mask",
320 (char *) &(isa_br->isa_intmask),
321 sizeof(isa_br->isa_intmask));
322 292
323 printk("isa%d:", isa_br->index); 293 printk("isa%d:", isa_br->index);
324 294
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 30bcaf58e3ab..75159a7843f1 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -105,24 +105,24 @@ again:
105 return 0; 105 return 0;
106} 106}
107 107
108static int __init has_button_interrupt(unsigned int irq, int prom_node) 108static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
109{ 109{
110 if (irq == PCI_IRQ_NONE) 110 if (irq == PCI_IRQ_NONE)
111 return 0; 111 return 0;
112 if (!prom_node_has_property(prom_node, "button")) 112 if (!of_find_property(dp, "button", NULL))
113 return 0; 113 return 0;
114 114
115 return 1; 115 return 1;
116} 116}
117 117
118static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p) 118static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p)
119{ 119{
120 struct linux_ebus *ebus; 120 struct linux_ebus *ebus;
121 struct linux_ebus_device *edev; 121 struct linux_ebus_device *edev;
122 122
123 for_each_ebus(ebus) { 123 for_each_ebus(ebus) {
124 for_each_ebusdev(edev, ebus) { 124 for_each_ebusdev(edev, ebus) {
125 if (!strcmp(edev->prom_name, "power")) { 125 if (!strcmp(edev->prom_node->name, "power")) {
126 *resp = &edev->resource[0]; 126 *resp = &edev->resource[0];
127 *irq_p = edev->irqs[0]; 127 *irq_p = edev->irqs[0];
128 *prom_node_p = edev->prom_node; 128 *prom_node_p = edev->prom_node;
@@ -133,14 +133,14 @@ static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p,
133 return -ENODEV; 133 return -ENODEV;
134} 134}
135 135
136static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p) 136static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, struct device_node **prom_node_p)
137{ 137{
138 struct sparc_isa_bridge *isa_bus; 138 struct sparc_isa_bridge *isa_bus;
139 struct sparc_isa_device *isa_dev; 139 struct sparc_isa_device *isa_dev;
140 140
141 for_each_isa(isa_bus) { 141 for_each_isa(isa_bus) {
142 for_each_isadev(isa_dev, isa_bus) { 142 for_each_isadev(isa_dev, isa_bus) {
143 if (!strcmp(isa_dev->prom_name, "power")) { 143 if (!strcmp(isa_dev->prom_node->name, "power")) {
144 *resp = &isa_dev->resource; 144 *resp = &isa_dev->resource;
145 *irq_p = isa_dev->irq; 145 *irq_p = isa_dev->irq;
146 *prom_node_p = isa_dev->prom_node; 146 *prom_node_p = isa_dev->prom_node;
@@ -155,17 +155,17 @@ void __init power_init(void)
155{ 155{
156 struct resource *res = NULL; 156 struct resource *res = NULL;
157 unsigned int irq; 157 unsigned int irq;
158 int prom_node; 158 struct device_node *dp;
159 static int invoked; 159 static int invoked;
160 160
161 if (invoked) 161 if (invoked)
162 return; 162 return;
163 invoked = 1; 163 invoked = 1;
164 164
165 if (!power_probe_ebus(&res, &irq, &prom_node)) 165 if (!power_probe_ebus(&res, &irq, &dp))
166 goto found; 166 goto found;
167 167
168 if (!power_probe_isa(&res, &irq, &prom_node)) 168 if (!power_probe_isa(&res, &irq, &dp))
169 goto found; 169 goto found;
170 170
171 return; 171 return;
@@ -174,7 +174,7 @@ found:
174 power_reg = ioremap(res->start, 0x4); 174 power_reg = ioremap(res->start, 0x4);
175 printk("power: Control reg at %p ... ", power_reg); 175 printk("power: Control reg at %p ... ", power_reg);
176 poweroff_method = machine_halt; /* able to use the standard halt */ 176 poweroff_method = machine_halt; /* able to use the standard halt */
177 if (has_button_interrupt(irq, prom_node)) { 177 if (has_button_interrupt(irq, dp)) {
178 if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { 178 if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
179 printk("Failed to start power daemon.\n"); 179 printk("Failed to start power daemon.\n");
180 return; 180 return;
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index fb112c3c0485..7809100034b0 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -63,6 +63,7 @@ struct device_node *of_find_node_by_path(const char *path)
63 63
64 return np; 64 return np;
65} 65}
66EXPORT_SYMBOL(of_find_node_by_path);
66 67
67struct device_node *of_find_node_by_phandle(phandle handle) 68struct device_node *of_find_node_by_phandle(phandle handle)
68{ 69{
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index aa5438a4fd50..d072b8632ccd 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -756,24 +756,200 @@ retry:
756 return -EOPNOTSUPP; 756 return -EOPNOTSUPP;
757} 757}
758 758
759void __init clock_probe(void) 759static int __init clock_model_matches(char *model)
760{
761 if (strcmp(model, "mk48t02") &&
762 strcmp(model, "mk48t08") &&
763 strcmp(model, "mk48t59") &&
764 strcmp(model, "m5819") &&
765 strcmp(model, "m5819p") &&
766 strcmp(model, "m5823") &&
767 strcmp(model, "ds1287"))
768 return 0;
769
770 return 1;
771}
772
773static void __init __clock_assign_common(void __iomem *addr, char *model)
774{
775 if (model[5] == '0' && model[6] == '2') {
776 mstk48t02_regs = addr;
777 } else if(model[5] == '0' && model[6] == '8') {
778 mstk48t08_regs = addr;
779 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
780 } else {
781 mstk48t59_regs = addr;
782 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
783 }
784}
785
786static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
787 char *model)
788{
789 unsigned long addr;
790
791 addr = ((unsigned long) clk_reg[0].phys_addr |
792 (((unsigned long) clk_reg[0].which_io) << 32UL));
793
794 __clock_assign_common((void __iomem *) addr, model);
795}
796
797static int __init clock_probe_central(void)
760{ 798{
761 struct linux_prom_registers clk_reg[2]; 799 struct linux_prom_registers clk_reg[2];
762 char model[128]; 800 char model[64];
763 int node, busnd = -1, err; 801 int node;
764 unsigned long flags; 802
765 struct linux_central *cbus; 803 if (!central_bus)
804 return 0;
805
806 /* Get Central FHC's prom node. */
807 node = central_bus->child->prom_node;
808
809 /* Then get the first child device below it. */
810 node = prom_getchild(node);
811
812 while (node) {
813 prom_getstring(node, "model", model, sizeof(model));
814 if (!clock_model_matches(model))
815 goto next_sibling;
816
817 prom_getproperty(node, "reg", (char *)clk_reg,
818 sizeof(clk_reg));
819
820 apply_fhc_ranges(central_bus->child, clk_reg, 1);
821 apply_central_ranges(central_bus, clk_reg, 1);
822
823 clock_assign_clk_reg(clk_reg, model);
824 return 1;
825
826 next_sibling:
827 node = prom_getsibling(node);
828 }
829
830 return 0;
831}
832
766#ifdef CONFIG_PCI 833#ifdef CONFIG_PCI
767 struct linux_ebus *ebus = NULL; 834static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
768 struct sparc_isa_bridge *isa_br = NULL; 835{
836 if (!strcmp(model, "ds1287") ||
837 !strcmp(model, "m5819") ||
838 !strcmp(model, "m5819p") ||
839 !strcmp(model, "m5823")) {
840 ds1287_regs = res->start;
841 } else {
842 mstk48t59_regs = (void __iomem *) res->start;
843 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
844 }
845}
846
847static int __init clock_probe_one_ebus_dev(struct linux_ebus_device *edev)
848{
849 struct device_node *dp = edev->prom_node;
850 char *model;
851
852 model = of_get_property(dp, "model", NULL);
853 if (!clock_model_matches(model))
854 return 0;
855
856 clock_isa_ebus_assign_regs(&edev->resource[0], model);
857
858 return 1;
859}
860
861static int __init clock_probe_ebus(void)
862{
863 struct linux_ebus *ebus;
864
865 for_each_ebus(ebus) {
866 struct linux_ebus_device *edev;
867
868 for_each_ebusdev(edev, ebus) {
869 if (clock_probe_one_ebus_dev(edev))
870 return 1;
871 }
872 }
873
874 return 0;
875}
876
877static int __init clock_probe_one_isa_dev(struct sparc_isa_device *idev)
878{
879 struct device_node *dp = idev->prom_node;
880 char *model;
881
882 model = of_get_property(dp, "model", NULL);
883 if (!clock_model_matches(model))
884 return 0;
885
886 clock_isa_ebus_assign_regs(&idev->resource, model);
887
888 return 1;
889}
890
891static int __init clock_probe_isa(void)
892{
893 struct sparc_isa_bridge *isa_br;
894
895 for_each_isa(isa_br) {
896 struct sparc_isa_device *isa_dev;
897
898 for_each_isadev(isa_dev, isa_br) {
899 if (clock_probe_one_isa_dev(isa_dev))
900 return 1;
901 }
902 }
903
904 return 0;
905}
906#endif /* CONFIG_PCI */
907
908#ifdef CONFIG_SBUS
909static int __init clock_probe_one_sbus_dev(struct sbus_bus *sbus, struct sbus_dev *sdev)
910{
911 struct resource *res;
912 char model[64];
913 void __iomem *addr;
914
915 prom_getstring(sdev->prom_node, "model", model, sizeof(model));
916 if (!clock_model_matches(model))
917 return 0;
918
919 res = &sdev->resource[0];
920 addr = sbus_ioremap(res, 0, 0x800UL, "eeprom");
921
922 __clock_assign_common(addr, model);
923
924 return 1;
925}
926
927static int __init clock_probe_sbus(void)
928{
929 struct sbus_bus *sbus;
930
931 for_each_sbus(sbus) {
932 struct sbus_dev *sdev;
933
934 for_each_sbusdev(sdev, sbus) {
935 if (clock_probe_one_sbus_dev(sbus, sdev))
936 return 1;
937 }
938 }
939
940 return 0;
941}
769#endif 942#endif
943
944void __init clock_probe(void)
945{
770 static int invoked; 946 static int invoked;
947 unsigned long flags;
771 948
772 if (invoked) 949 if (invoked)
773 return; 950 return;
774 invoked = 1; 951 invoked = 1;
775 952
776
777 if (this_is_starfire) { 953 if (this_is_starfire) {
778 xtime.tv_sec = starfire_get_time(); 954 xtime.tv_sec = starfire_get_time();
779 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 955 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
@@ -789,183 +965,27 @@ void __init clock_probe(void)
789 return; 965 return;
790 } 966 }
791 967
792 local_irq_save(flags);
793
794 cbus = central_bus;
795 if (cbus != NULL)
796 busnd = central_bus->child->prom_node;
797
798 /* Check FHC Central then EBUSs then ISA bridges then SBUSs. 968 /* Check FHC Central then EBUSs then ISA bridges then SBUSs.
799 * That way we handle the presence of multiple properly. 969 * That way we handle the presence of multiple properly.
800 * 970 *
801 * As a special case, machines with Central must provide the 971 * As a special case, machines with Central must provide the
802 * timer chip there. 972 * timer chip there.
803 */ 973 */
974 if (!clock_probe_central() &&
804#ifdef CONFIG_PCI 975#ifdef CONFIG_PCI
805 if (ebus_chain != NULL) { 976 !clock_probe_ebus() &&
806 ebus = ebus_chain; 977 !clock_probe_isa() &&
807 if (busnd == -1)
808 busnd = ebus->prom_node;
809 }
810 if (isa_chain != NULL) {
811 isa_br = isa_chain;
812 if (busnd == -1)
813 busnd = isa_br->prom_node;
814 }
815#endif
816 if (sbus_root != NULL && busnd == -1)
817 busnd = sbus_root->prom_node;
818
819 if (busnd == -1) {
820 prom_printf("clock_probe: problem, cannot find bus to search.\n");
821 prom_halt();
822 }
823
824 node = prom_getchild(busnd);
825
826 while (1) {
827 if (!node)
828 model[0] = 0;
829 else
830 prom_getstring(node, "model", model, sizeof(model));
831 if (strcmp(model, "mk48t02") &&
832 strcmp(model, "mk48t08") &&
833 strcmp(model, "mk48t59") &&
834 strcmp(model, "m5819") &&
835 strcmp(model, "m5819p") &&
836 strcmp(model, "m5823") &&
837 strcmp(model, "ds1287")) {
838 if (cbus != NULL) {
839 prom_printf("clock_probe: Central bus lacks timer chip.\n");
840 prom_halt();
841 }
842
843 if (node != 0)
844 node = prom_getsibling(node);
845#ifdef CONFIG_PCI
846 while ((node == 0) && ebus != NULL) {
847 ebus = ebus->next;
848 if (ebus != NULL) {
849 busnd = ebus->prom_node;
850 node = prom_getchild(busnd);
851 }
852 }
853 while ((node == 0) && isa_br != NULL) {
854 isa_br = isa_br->next;
855 if (isa_br != NULL) {
856 busnd = isa_br->prom_node;
857 node = prom_getchild(busnd);
858 }
859 }
860#endif 978#endif
861 if (node == 0) { 979#ifdef CONFIG_SBUS
862 prom_printf("clock_probe: Cannot find timer chip\n"); 980 !clock_probe_sbus()
863 prom_halt();
864 }
865 continue;
866 }
867
868 err = prom_getproperty(node, "reg", (char *)clk_reg,
869 sizeof(clk_reg));
870 if(err == -1) {
871 prom_printf("clock_probe: Cannot get Mostek reg property\n");
872 prom_halt();
873 }
874
875 if (cbus != NULL) {
876 apply_fhc_ranges(central_bus->child, clk_reg, 1);
877 apply_central_ranges(central_bus, clk_reg, 1);
878 }
879#ifdef CONFIG_PCI
880 else if (ebus != NULL) {
881 struct linux_ebus_device *edev;
882
883 for_each_ebusdev(edev, ebus)
884 if (edev->prom_node == node)
885 break;
886 if (edev == NULL) {
887 if (isa_chain != NULL)
888 goto try_isa_clock;
889 prom_printf("%s: Mostek not probed by EBUS\n",
890 __FUNCTION__);
891 prom_halt();
892 }
893
894 if (!strcmp(model, "ds1287") ||
895 !strcmp(model, "m5819") ||
896 !strcmp(model, "m5819p") ||
897 !strcmp(model, "m5823")) {
898 ds1287_regs = edev->resource[0].start;
899 } else {
900 mstk48t59_regs = (void __iomem *)
901 edev->resource[0].start;
902 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
903 }
904 break;
905 }
906 else if (isa_br != NULL) {
907 struct sparc_isa_device *isadev;
908
909try_isa_clock:
910 for_each_isadev(isadev, isa_br)
911 if (isadev->prom_node == node)
912 break;
913 if (isadev == NULL) {
914 prom_printf("%s: Mostek not probed by ISA\n");
915 prom_halt();
916 }
917 if (!strcmp(model, "ds1287") ||
918 !strcmp(model, "m5819") ||
919 !strcmp(model, "m5819p") ||
920 !strcmp(model, "m5823")) {
921 ds1287_regs = isadev->resource.start;
922 } else {
923 mstk48t59_regs = (void __iomem *)
924 isadev->resource.start;
925 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
926 }
927 break;
928 }
929#endif 981#endif
930 else { 982 ) {
931 if (sbus_root->num_sbus_ranges) { 983 printk(KERN_WARNING "No clock chip found.\n");
932 int nranges = sbus_root->num_sbus_ranges; 984 return;
933 int rngc;
934
935 for (rngc = 0; rngc < nranges; rngc++)
936 if (clk_reg[0].which_io ==
937 sbus_root->sbus_ranges[rngc].ot_child_space)
938 break;
939 if (rngc == nranges) {
940 prom_printf("clock_probe: Cannot find ranges for "
941 "clock regs.\n");
942 prom_halt();
943 }
944 clk_reg[0].which_io =
945 sbus_root->sbus_ranges[rngc].ot_parent_space;
946 clk_reg[0].phys_addr +=
947 sbus_root->sbus_ranges[rngc].ot_parent_base;
948 }
949 }
950
951 if(model[5] == '0' && model[6] == '2') {
952 mstk48t02_regs = (void __iomem *)
953 (((u64)clk_reg[0].phys_addr) |
954 (((u64)clk_reg[0].which_io)<<32UL));
955 } else if(model[5] == '0' && model[6] == '8') {
956 mstk48t08_regs = (void __iomem *)
957 (((u64)clk_reg[0].phys_addr) |
958 (((u64)clk_reg[0].which_io)<<32UL));
959 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
960 } else {
961 mstk48t59_regs = (void __iomem *)
962 (((u64)clk_reg[0].phys_addr) |
963 (((u64)clk_reg[0].which_io)<<32UL));
964 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
965 }
966 break;
967 } 985 }
968 986
987 local_irq_save(flags);
988
969 if (mstk48t02_regs != NULL) { 989 if (mstk48t02_regs != NULL) {
970 /* Report a low battery voltage condition. */ 990 /* Report a low battery voltage condition. */
971 if (has_low_battery()) 991 if (has_low_battery())