Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 28736
b: refs/heads/master
c: 507279d
h: refs/heads/master
v: v3
  • Loading branch information
John Rose authored and Paul Mackerras committed Jun 9, 2006
1 parent 054ad9b commit 470ca53
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 92 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4a3ecc622465dbff7404139a8ad18bf4cb99f836
refs/heads/master: 507279db1819aacf4022e790b3fc8bc8cf56debf
30 changes: 16 additions & 14 deletions trunk/arch/powerpc/kernel/rtas-rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@
unsigned long __init rtas_get_boot_time(void)
{
int ret[8];
int error, wait_time;
int error;
unsigned int wait_time;
u64 max_wait_tb;

max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
do {
error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
wait_time = rtas_extended_busy_delay_time(error);

wait_time = rtas_busy_delay_time(error);
if (wait_time) {
/* This is boot time so we spin. */
udelay(wait_time*1000);
error = RTAS_CLOCK_BUSY;
}
} while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
} while (wait_time && (get_tb() < max_wait_tb));

if (error != 0 && printk_ratelimit()) {
printk(KERN_WARNING "error: reading the clock failed (%d)\n",
Expand All @@ -44,24 +45,25 @@ unsigned long __init rtas_get_boot_time(void)
void rtas_get_rtc_time(struct rtc_time *rtc_tm)
{
int ret[8];
int error, wait_time;
int error;
unsigned int wait_time;
u64 max_wait_tb;

max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
do {
error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {

wait_time = rtas_busy_delay_time(error);
if (wait_time) {
if (in_interrupt() && printk_ratelimit()) {
memset(rtc_tm, 0, sizeof(struct rtc_time));
printk(KERN_WARNING "error: reading clock"
" would delay interrupt\n");
return; /* delay not allowed */
}
wait_time = rtas_extended_busy_delay_time(error);
msleep(wait_time);
error = RTAS_CLOCK_BUSY;
}
} while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
} while (wait_time && (get_tb() < max_wait_tb));

if (error != 0 && printk_ratelimit()) {
printk(KERN_WARNING "error: reading the clock failed (%d)\n",
Expand All @@ -88,14 +90,14 @@ int rtas_set_rtc_time(struct rtc_time *tm)
tm->tm_year + 1900, tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min,
tm->tm_sec, 0);
if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {

wait_time = rtas_busy_delay_time(error);
if (wait_time) {
if (in_interrupt())
return 1; /* probably decrementer */
wait_time = rtas_extended_busy_delay_time(error);
msleep(wait_time);
error = RTAS_CLOCK_BUSY;
}
} while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
} while (wait_time && (get_tb() < max_wait_tb));

if (error != 0 && printk_ratelimit())
printk(KERN_WARNING "error: setting the clock failed (%d)\n",
Expand Down
85 changes: 35 additions & 50 deletions trunk/arch/powerpc/kernel/rtas.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,24 +370,36 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
return ret;
}

/* Given an RTAS status code of 990n compute the hinted delay of 10^n
* (last digit) milliseconds. For now we bound at n=5 (100 sec).
/* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status
* code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
*/
unsigned int rtas_extended_busy_delay_time(int status)
unsigned int rtas_busy_delay_time(int status)
{
int order = status - 9900;
unsigned long ms;
int order;
unsigned int ms = 0;

if (status == RTAS_BUSY) {
ms = 1;
} else if (status >= 9900 && status <= 9905) {
order = status - 9900;
for (ms = 1; order > 0; order--)
ms *= 10;
}

if (order < 0)
order = 0; /* RTC depends on this for -2 clock busy */
else if (order > 5)
order = 5; /* bound */
return ms;
}

/* Use microseconds for reasonable accuracy */
for (ms = 1; order > 0; order--)
ms *= 10;
/* For an RTAS busy status code, perform the hinted delay. */
unsigned int rtas_busy_delay(int status)
{
unsigned int ms;

return ms;
might_sleep();
ms = rtas_busy_delay_time(status);
if (ms)
msleep(ms);

return ms;
}

int rtas_error_rc(int rtas_rc)
Expand Down Expand Up @@ -438,22 +450,14 @@ int rtas_get_power_level(int powerdomain, int *level)
int rtas_set_power_level(int powerdomain, int level, int *setlevel)
{
int token = rtas_token("set-power-level");
unsigned int wait_time;
int rc;

if (token == RTAS_UNKNOWN_SERVICE)
return -ENOENT;

while (1) {
do {
rc = rtas_call(token, 2, 2, setlevel, powerdomain, level);
if (rc == RTAS_BUSY)
udelay(1);
else if (rtas_is_extended_busy(rc)) {
wait_time = rtas_extended_busy_delay_time(rc);
udelay(wait_time * 1000);
} else
break;
}
} while (rtas_busy_delay(rc));

if (rc < 0)
return rtas_error_rc(rc);
Expand All @@ -463,22 +467,14 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel)
int rtas_get_sensor(int sensor, int index, int *state)
{
int token = rtas_token("get-sensor-state");
unsigned int wait_time;
int rc;

if (token == RTAS_UNKNOWN_SERVICE)
return -ENOENT;

while (1) {
do {
rc = rtas_call(token, 2, 2, state, sensor, index);
if (rc == RTAS_BUSY)
udelay(1);
else if (rtas_is_extended_busy(rc)) {
wait_time = rtas_extended_busy_delay_time(rc);
udelay(wait_time * 1000);
} else
break;
}
} while (rtas_busy_delay(rc));

if (rc < 0)
return rtas_error_rc(rc);
Expand All @@ -488,23 +484,14 @@ int rtas_get_sensor(int sensor, int index, int *state)
int rtas_set_indicator(int indicator, int index, int new_value)
{
int token = rtas_token("set-indicator");
unsigned int wait_time;
int rc;

if (token == RTAS_UNKNOWN_SERVICE)
return -ENOENT;

while (1) {
do {
rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value);
if (rc == RTAS_BUSY)
udelay(1);
else if (rtas_is_extended_busy(rc)) {
wait_time = rtas_extended_busy_delay_time(rc);
udelay(wait_time * 1000);
}
else
break;
}
} while (rtas_busy_delay(rc));

if (rc < 0)
return rtas_error_rc(rc);
Expand Down Expand Up @@ -555,13 +542,11 @@ void rtas_os_term(char *str)
do {
status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
__pa(rtas_os_term_buf));
} while (rtas_busy_delay(status));

if (status == RTAS_BUSY)
udelay(1);
else if (status != 0)
printk(KERN_EMERG "ibm,os-term call failed %d\n",
if (status != 0)
printk(KERN_EMERG "ibm,os-term call failed %d\n",
status);
} while (status == RTAS_BUSY);
}

static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
Expand Down Expand Up @@ -789,7 +774,7 @@ EXPORT_SYMBOL(rtas_token);
EXPORT_SYMBOL(rtas_call);
EXPORT_SYMBOL(rtas_data_buf);
EXPORT_SYMBOL(rtas_data_buf_lock);
EXPORT_SYMBOL(rtas_extended_busy_delay_time);
EXPORT_SYMBOL(rtas_busy_delay_time);
EXPORT_SYMBOL(rtas_get_sensor);
EXPORT_SYMBOL(rtas_get_power_level);
EXPORT_SYMBOL(rtas_set_power_level);
Expand Down
25 changes: 4 additions & 21 deletions trunk/arch/powerpc/kernel/rtas_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,20 +365,12 @@ static int rtas_excl_release(struct inode *inode, struct file *file)

static void manage_flash(struct rtas_manage_flash_t *args_buf)
{
unsigned int wait_time;
s32 rc;

while (1) {
do {
rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1,
1, NULL, args_buf->op);
if (rc == RTAS_RC_BUSY)
udelay(1);
else if (rtas_is_extended_busy(rc)) {
wait_time = rtas_extended_busy_delay_time(rc);
udelay(wait_time * 1000);
} else
break;
}
} while (rtas_busy_delay(rc));

args_buf->status = rc;
}
Expand Down Expand Up @@ -451,27 +443,18 @@ static ssize_t manage_flash_write(struct file *file, const char __user *buf,
static void validate_flash(struct rtas_validate_flash_t *args_buf)
{
int token = rtas_token("ibm,validate-flash-image");
unsigned int wait_time;
int update_results;
s32 rc;

rc = 0;
while(1) {
do {
spin_lock(&rtas_data_buf_lock);
memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE);
rc = rtas_call(token, 2, 2, &update_results,
(u32) __pa(rtas_data_buf), args_buf->buf_size);
memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE);
spin_unlock(&rtas_data_buf_lock);

if (rc == RTAS_RC_BUSY)
udelay(1);
else if (rtas_is_extended_busy(rc)) {
wait_time = rtas_extended_busy_delay_time(rc);
udelay(wait_time * 1000);
} else
break;
}
} while (rtas_busy_delay(rc));

args_buf->status = rc;
args_buf->update_results = update_results;
Expand Down
8 changes: 2 additions & 6 deletions trunk/include/asm-powerpc/rtas.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,8 @@ extern unsigned long rtas_get_boot_time(void);
extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
extern int rtas_set_rtc_time(struct rtc_time *rtc_time);

/* Given an RTAS status code of 9900..9905 compute the hinted delay */
unsigned int rtas_extended_busy_delay_time(int status);
static inline int rtas_is_extended_busy(int status)
{
return status >= 9900 && status <= 9909;
}
extern unsigned int rtas_busy_delay_time(int status);
extern unsigned int rtas_busy_delay(int status);

extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);

Expand Down

0 comments on commit 470ca53

Please sign in to comment.