/* NOTE: get_rtc_time will get an error if executed in interrupt context * and if a delay is needed to read the clock. In this case we just * silently return without updating rtc_tm. */ void pSeries_get_rtc_time(struct rtc_time *rtc_tm) { int ret[8]; int error, wait_time; unsigned long 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)) { if (in_interrupt()) { printk(KERN_WARNING "error: reading clock would delay interrupt\n"); return; /* delay not allowed */ } wait_time = rtas_extended_busy_delay_time(error); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(wait_time); error = RTAS_CLOCK_BUSY; } } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); if (error != 0) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", error); return; } rtc_tm->tm_sec = ret[5]; rtc_tm->tm_min = ret[4]; rtc_tm->tm_hour = ret[3]; rtc_tm->tm_mday = ret[2]; rtc_tm->tm_mon = ret[1] - 1; rtc_tm->tm_year = ret[0] - 1900; }
static void validate_flash(struct rtas_validate_flash_t *args_buf) { int token = rtas_token("ibm,validate-flash-image"); unsigned int wait_time; long update_results; s32 rc; rc = 0; while(1) { spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE); rc = (s32) rtas_call(token, 2, 2, &update_results, __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; } args_buf->status = rc; args_buf->update_results = (u32) update_results; }
int pSeries_set_rtc_time(struct rtc_time *tm) { int error, wait_time; unsigned long max_wait_tb; max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT; do { error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL, 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)) { if (in_interrupt()) return 1; /* probably decrementer */ wait_time = rtas_extended_busy_delay_time(error); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(wait_time); error = RTAS_CLOCK_BUSY; } } while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb)); if (error != 0) printk(KERN_WARNING "error: setting the clock failed (%d)\n", error); return 0; }
void pSeries_get_boot_time(struct rtc_time *rtc_tm) { int ret[8]; int error, wait_time; unsigned long 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); /* 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)); if (error != 0) { printk(KERN_WARNING "error: reading the clock failed (%d)\n", error); return; } rtc_tm->tm_sec = ret[5]; rtc_tm->tm_min = ret[4]; rtc_tm->tm_hour = ret[3]; rtc_tm->tm_mday = ret[2]; rtc_tm->tm_mon = ret[1] - 1; rtc_tm->tm_year = ret[0] - 1900; }
static void manage_flash(struct rtas_manage_flash_t *args_buf) { unsigned int wait_time; s32 rc; while (1) { rc = (s32) rtas_call(rtas_token("ibm,manage-flash-image"), 1, 1, NULL, (long) 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; } args_buf->status = rc; }
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 RTAS_UNKNOWN_OP; while (1) { 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; } return rc; }
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 RTAS_UNKNOWN_OP; while (1) { 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; } return rc; }
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 RTAS_UNKNOWN_OP; while (1) { 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; } return rc; }
static ssize_t scanlog_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct inode * inode = file->f_dentry->d_inode; struct proc_dir_entry *dp; unsigned int *data; int status; unsigned long len, off; unsigned int wait_time; dp = PDE(inode); data = (unsigned int *)dp->data; if (!data) { printk(KERN_ERR "scanlog: read failed no data\n"); return -EIO; } if (count > RTAS_DATA_BUF_SIZE) count = RTAS_DATA_BUF_SIZE; if (count < 1024) { /* This is the min supported by this RTAS call. Rather * than do all the buffering we insist the user code handle * larger reads. As long as cp works... :) */ printk(KERN_ERR "scanlog: cannot perform a small read (%ld)\n", count); return -EINVAL; } if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; for (;;) { wait_time = 500; /* default wait if no data */ spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, data, RTAS_DATA_BUF_SIZE); status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, (u32) __pa(rtas_data_buf), (u32) count); memcpy(data, rtas_data_buf, RTAS_DATA_BUF_SIZE); spin_unlock(&rtas_data_buf_lock); DEBUG("status=%d, data[0]=%x, data[1]=%x, data[2]=%x\n", status, data[0], data[1], data[2]); switch (status) { case SCANLOG_COMPLETE: DEBUG("hit eof\n"); return 0; case SCANLOG_HWERROR: DEBUG("hardware error reading scan log data\n"); return -EIO; case SCANLOG_CONTINUE: /* We may or may not have data yet */ len = data[1]; off = data[2]; if (len > 0) { if (copy_to_user(buf, ((char *)data)+off, len)) return -EFAULT; return len; } /* Break to sleep default time */ break; default: if (status > 9900 && status <= 9905) { wait_time = rtas_extended_busy_delay_time(status); } else { printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status); return -EIO; } } /* Apparently no data yet. Wait and try again. */ msleep_interruptible(wait_time); } /*NOTREACHED*/ }