aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/rtas-rtc.c30
-rw-r--r--arch/powerpc/kernel/rtas.c85
-rw-r--r--arch/powerpc/kernel/rtas_flash.c25
-rw-r--r--include/asm-powerpc/rtas.h8
4 files changed, 57 insertions, 91 deletions
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c
index 34d073fb6091..77578c093dda 100644
--- a/arch/powerpc/kernel/rtas-rtc.c
+++ b/arch/powerpc/kernel/rtas-rtc.c
@@ -14,19 +14,20 @@
14unsigned long __init rtas_get_boot_time(void) 14unsigned long __init rtas_get_boot_time(void)
15{ 15{
16 int ret[8]; 16 int ret[8];
17 int error, wait_time; 17 int error;
18 unsigned int wait_time;
18 u64 max_wait_tb; 19 u64 max_wait_tb;
19 20
20 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; 21 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
21 do { 22 do {
22 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); 23 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
23 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { 24
24 wait_time = rtas_extended_busy_delay_time(error); 25 wait_time = rtas_busy_delay_time(error);
26 if (wait_time) {
25 /* This is boot time so we spin. */ 27 /* This is boot time so we spin. */
26 udelay(wait_time*1000); 28 udelay(wait_time*1000);
27 error = RTAS_CLOCK_BUSY;
28 } 29 }
29 } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); 30 } while (wait_time && (get_tb() < max_wait_tb));
30 31
31 if (error != 0 && printk_ratelimit()) { 32 if (error != 0 && printk_ratelimit()) {
32 printk(KERN_WARNING "error: reading the clock failed (%d)\n", 33 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
@@ -44,24 +45,25 @@ unsigned long __init rtas_get_boot_time(void)
44void rtas_get_rtc_time(struct rtc_time *rtc_tm) 45void rtas_get_rtc_time(struct rtc_time *rtc_tm)
45{ 46{
46 int ret[8]; 47 int ret[8];
47 int error, wait_time; 48 int error;
49 unsigned int wait_time;
48 u64 max_wait_tb; 50 u64 max_wait_tb;
49 51
50 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; 52 max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
51 do { 53 do {
52 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); 54 error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
53 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { 55
56 wait_time = rtas_busy_delay_time(error);
57 if (wait_time) {
54 if (in_interrupt() && printk_ratelimit()) { 58 if (in_interrupt() && printk_ratelimit()) {
55 memset(rtc_tm, 0, sizeof(struct rtc_time)); 59 memset(rtc_tm, 0, sizeof(struct rtc_time));
56 printk(KERN_WARNING "error: reading clock" 60 printk(KERN_WARNING "error: reading clock"
57 " would delay interrupt\n"); 61 " would delay interrupt\n");
58 return; /* delay not allowed */ 62 return; /* delay not allowed */
59 } 63 }
60 wait_time = rtas_extended_busy_delay_time(error);
61 msleep(wait_time); 64 msleep(wait_time);
62 error = RTAS_CLOCK_BUSY;
63 } 65 }
64 } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); 66 } while (wait_time && (get_tb() < max_wait_tb));
65 67
66 if (error != 0 && printk_ratelimit()) { 68 if (error != 0 && printk_ratelimit()) {
67 printk(KERN_WARNING "error: reading the clock failed (%d)\n", 69 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
@@ -88,14 +90,14 @@ int rtas_set_rtc_time(struct rtc_time *tm)
88 tm->tm_year + 1900, tm->tm_mon + 1, 90 tm->tm_year + 1900, tm->tm_mon + 1,
89 tm->tm_mday, tm->tm_hour, tm->tm_min, 91 tm->tm_mday, tm->tm_hour, tm->tm_min,
90 tm->tm_sec, 0); 92 tm->tm_sec, 0);
91 if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) { 93
94 wait_time = rtas_busy_delay_time(error);
95 if (wait_time) {
92 if (in_interrupt()) 96 if (in_interrupt())
93 return 1; /* probably decrementer */ 97 return 1; /* probably decrementer */
94 wait_time = rtas_extended_busy_delay_time(error);
95 msleep(wait_time); 98 msleep(wait_time);
96 error = RTAS_CLOCK_BUSY;
97 } 99 }
98 } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb)); 100 } while (wait_time && (get_tb() < max_wait_tb));
99 101
100 if (error != 0 && printk_ratelimit()) 102 if (error != 0 && printk_ratelimit())
101 printk(KERN_WARNING "error: setting the clock failed (%d)\n", 103 printk(KERN_WARNING "error: setting the clock failed (%d)\n",
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 0112318213ab..13496f319855 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -370,24 +370,36 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
370 return ret; 370 return ret;
371} 371}
372 372
373/* Given an RTAS status code of 990n compute the hinted delay of 10^n 373/* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status
374 * (last digit) milliseconds. For now we bound at n=5 (100 sec). 374 * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
375 */ 375 */
376unsigned int rtas_extended_busy_delay_time(int status) 376unsigned int rtas_busy_delay_time(int status)
377{ 377{
378 int order = status - 9900; 378 int order;
379 unsigned long ms; 379 unsigned int ms = 0;
380
381 if (status == RTAS_BUSY) {
382 ms = 1;
383 } else if (status >= 9900 && status <= 9905) {
384 order = status - 9900;
385 for (ms = 1; order > 0; order--)
386 ms *= 10;
387 }
380 388
381 if (order < 0) 389 return ms;
382 order = 0; /* RTC depends on this for -2 clock busy */ 390}
383 else if (order > 5)
384 order = 5; /* bound */
385 391
386 /* Use microseconds for reasonable accuracy */ 392/* For an RTAS busy status code, perform the hinted delay. */
387 for (ms = 1; order > 0; order--) 393unsigned int rtas_busy_delay(int status)
388 ms *= 10; 394{
395 unsigned int ms;
389 396
390 return ms; 397 might_sleep();
398 ms = rtas_busy_delay_time(status);
399 if (ms)
400 msleep(ms);
401
402 return ms;
391} 403}
392 404
393int rtas_error_rc(int rtas_rc) 405int rtas_error_rc(int rtas_rc)
@@ -438,22 +450,14 @@ int rtas_get_power_level(int powerdomain, int *level)
438int rtas_set_power_level(int powerdomain, int level, int *setlevel) 450int rtas_set_power_level(int powerdomain, int level, int *setlevel)
439{ 451{
440 int token = rtas_token("set-power-level"); 452 int token = rtas_token("set-power-level");
441 unsigned int wait_time;
442 int rc; 453 int rc;
443 454
444 if (token == RTAS_UNKNOWN_SERVICE) 455 if (token == RTAS_UNKNOWN_SERVICE)
445 return -ENOENT; 456 return -ENOENT;
446 457
447 while (1) { 458 do {
448 rc = rtas_call(token, 2, 2, setlevel, powerdomain, level); 459 rc = rtas_call(token, 2, 2, setlevel, powerdomain, level);
449 if (rc == RTAS_BUSY) 460 } while (rtas_busy_delay(rc));
450 udelay(1);
451 else if (rtas_is_extended_busy(rc)) {
452 wait_time = rtas_extended_busy_delay_time(rc);
453 udelay(wait_time * 1000);
454 } else
455 break;
456 }
457 461
458 if (rc < 0) 462 if (rc < 0)
459 return rtas_error_rc(rc); 463 return rtas_error_rc(rc);
@@ -463,22 +467,14 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel)
463int rtas_get_sensor(int sensor, int index, int *state) 467int rtas_get_sensor(int sensor, int index, int *state)
464{ 468{
465 int token = rtas_token("get-sensor-state"); 469 int token = rtas_token("get-sensor-state");
466 unsigned int wait_time;
467 int rc; 470 int rc;
468 471
469 if (token == RTAS_UNKNOWN_SERVICE) 472 if (token == RTAS_UNKNOWN_SERVICE)
470 return -ENOENT; 473 return -ENOENT;
471 474
472 while (1) { 475 do {
473 rc = rtas_call(token, 2, 2, state, sensor, index); 476 rc = rtas_call(token, 2, 2, state, sensor, index);
474 if (rc == RTAS_BUSY) 477 } while (rtas_busy_delay(rc));
475 udelay(1);
476 else if (rtas_is_extended_busy(rc)) {
477 wait_time = rtas_extended_busy_delay_time(rc);
478 udelay(wait_time * 1000);
479 } else
480 break;
481 }
482 478
483 if (rc < 0) 479 if (rc < 0)
484 return rtas_error_rc(rc); 480 return rtas_error_rc(rc);
@@ -488,23 +484,14 @@ int rtas_get_sensor(int sensor, int index, int *state)
488int rtas_set_indicator(int indicator, int index, int new_value) 484int rtas_set_indicator(int indicator, int index, int new_value)
489{ 485{
490 int token = rtas_token("set-indicator"); 486 int token = rtas_token("set-indicator");
491 unsigned int wait_time;
492 int rc; 487 int rc;
493 488
494 if (token == RTAS_UNKNOWN_SERVICE) 489 if (token == RTAS_UNKNOWN_SERVICE)
495 return -ENOENT; 490 return -ENOENT;
496 491
497 while (1) { 492 do {
498 rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value); 493 rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value);
499 if (rc == RTAS_BUSY) 494 } while (rtas_busy_delay(rc));
500 udelay(1);
501 else if (rtas_is_extended_busy(rc)) {
502 wait_time = rtas_extended_busy_delay_time(rc);
503 udelay(wait_time * 1000);
504 }
505 else
506 break;
507 }
508 495
509 if (rc < 0) 496 if (rc < 0)
510 return rtas_error_rc(rc); 497 return rtas_error_rc(rc);
@@ -555,13 +542,11 @@ void rtas_os_term(char *str)
555 do { 542 do {
556 status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL, 543 status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
557 __pa(rtas_os_term_buf)); 544 __pa(rtas_os_term_buf));
545 } while (rtas_busy_delay(status));
558 546
559 if (status == RTAS_BUSY) 547 if (status != 0)
560 udelay(1); 548 printk(KERN_EMERG "ibm,os-term call failed %d\n",
561 else if (status != 0)
562 printk(KERN_EMERG "ibm,os-term call failed %d\n",
563 status); 549 status);
564 } while (status == RTAS_BUSY);
565} 550}
566 551
567static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; 552static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
@@ -789,7 +774,7 @@ EXPORT_SYMBOL(rtas_token);
789EXPORT_SYMBOL(rtas_call); 774EXPORT_SYMBOL(rtas_call);
790EXPORT_SYMBOL(rtas_data_buf); 775EXPORT_SYMBOL(rtas_data_buf);
791EXPORT_SYMBOL(rtas_data_buf_lock); 776EXPORT_SYMBOL(rtas_data_buf_lock);
792EXPORT_SYMBOL(rtas_extended_busy_delay_time); 777EXPORT_SYMBOL(rtas_busy_delay_time);
793EXPORT_SYMBOL(rtas_get_sensor); 778EXPORT_SYMBOL(rtas_get_sensor);
794EXPORT_SYMBOL(rtas_get_power_level); 779EXPORT_SYMBOL(rtas_get_power_level);
795EXPORT_SYMBOL(rtas_set_power_level); 780EXPORT_SYMBOL(rtas_set_power_level);
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index aaf384c3f04a..1442b63a75da 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -365,20 +365,12 @@ static int rtas_excl_release(struct inode *inode, struct file *file)
365 365
366static void manage_flash(struct rtas_manage_flash_t *args_buf) 366static void manage_flash(struct rtas_manage_flash_t *args_buf)
367{ 367{
368 unsigned int wait_time;
369 s32 rc; 368 s32 rc;
370 369
371 while (1) { 370 do {
372 rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 371 rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1,
373 1, NULL, args_buf->op); 372 1, NULL, args_buf->op);
374 if (rc == RTAS_RC_BUSY) 373 } while (rtas_busy_delay(rc));
375 udelay(1);
376 else if (rtas_is_extended_busy(rc)) {
377 wait_time = rtas_extended_busy_delay_time(rc);
378 udelay(wait_time * 1000);
379 } else
380 break;
381 }
382 374
383 args_buf->status = rc; 375 args_buf->status = rc;
384} 376}
@@ -451,27 +443,18 @@ static ssize_t manage_flash_write(struct file *file, const char __user *buf,
451static void validate_flash(struct rtas_validate_flash_t *args_buf) 443static void validate_flash(struct rtas_validate_flash_t *args_buf)
452{ 444{
453 int token = rtas_token("ibm,validate-flash-image"); 445 int token = rtas_token("ibm,validate-flash-image");
454 unsigned int wait_time;
455 int update_results; 446 int update_results;
456 s32 rc; 447 s32 rc;
457 448
458 rc = 0; 449 rc = 0;
459 while(1) { 450 do {
460 spin_lock(&rtas_data_buf_lock); 451 spin_lock(&rtas_data_buf_lock);
461 memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE); 452 memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE);
462 rc = rtas_call(token, 2, 2, &update_results, 453 rc = rtas_call(token, 2, 2, &update_results,
463 (u32) __pa(rtas_data_buf), args_buf->buf_size); 454 (u32) __pa(rtas_data_buf), args_buf->buf_size);
464 memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE); 455 memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE);
465 spin_unlock(&rtas_data_buf_lock); 456 spin_unlock(&rtas_data_buf_lock);
466 457 } while (rtas_busy_delay(rc));
467 if (rc == RTAS_RC_BUSY)
468 udelay(1);
469 else if (rtas_is_extended_busy(rc)) {
470 wait_time = rtas_extended_busy_delay_time(rc);
471 udelay(wait_time * 1000);
472 } else
473 break;
474 }
475 458
476 args_buf->status = rc; 459 args_buf->status = rc;
477 args_buf->update_results = update_results; 460 args_buf->update_results = update_results;
diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h
index f43c6835e62a..a3b4e55569c7 100644
--- a/include/asm-powerpc/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -177,12 +177,8 @@ extern unsigned long rtas_get_boot_time(void);
177extern void rtas_get_rtc_time(struct rtc_time *rtc_time); 177extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
178extern int rtas_set_rtc_time(struct rtc_time *rtc_time); 178extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
179 179
180/* Given an RTAS status code of 9900..9905 compute the hinted delay */ 180extern unsigned int rtas_busy_delay_time(int status);
181unsigned int rtas_extended_busy_delay_time(int status); 181extern unsigned int rtas_busy_delay(int status);
182static inline int rtas_is_extended_busy(int status)
183{
184 return status >= 9900 && status <= 9909;
185}
186 182
187extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal); 183extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
188 184