int rtas_set_rtc_time(struct rtc_time *tm)
{
	int error, 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("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);

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

	if (error != 0)
		printk_ratelimited(KERN_WARNING
				   "error: setting the clock failed (%d)\n",
				   error);

        return 0;
}
unsigned long __init rtas_get_boot_time(void)
{
	int ret[8];
	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);

		wait_time = rtas_busy_delay_time(error);
		if (wait_time) {
			/*                               */
			udelay(wait_time*1000);
		}
	} while (wait_time && (get_tb() < max_wait_tb));

	if (error != 0) {
		printk_ratelimited(KERN_WARNING
				   "error: reading the clock failed (%d)\n",
				   error);
		return 0;
	}

	return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
}
Exemple #3
0
/* For an RTAS busy status code, perform the hinted delay. */
unsigned int rtas_busy_delay(int status)
{
	unsigned int ms;

	might_sleep();
	ms = rtas_busy_delay_time(status);
	if (ms && need_resched())
		msleep(ms);

	return ms;
}
void rtas_get_rtc_time(struct rtc_time *rtc_tm)
{
        int ret[8];
	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);

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

	if (error != 0) {
		printk_ratelimited(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;
}
Exemple #5
0
static ssize_t scanlog_read(struct file *file, char __user *buf,
			    size_t count, loff_t *ppos)
{
	unsigned int *data = scanlog_buffer;
	int status;
	unsigned long len, off;
	unsigned int wait_time;

	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);

		pr_debug("scanlog: status=%d, data[0]=%x, data[1]=%x, " \
			 "data[2]=%x\n", status, data[0], data[1], data[2]);
		switch (status) {
		    case SCANLOG_COMPLETE:
			pr_debug("scanlog: hit eof\n");
			return 0;
		    case SCANLOG_HWERROR:
			pr_debug("scanlog: hardware error reading 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:
			/* Assume extended busy */
			wait_time = rtas_busy_delay_time(status);
			if (!wait_time) {
				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*/
}