]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/ppc64/kernel/scanlog.c
ppc64: move stack switching up in interrupt processing
[karo-tx-linux.git] / arch / ppc64 / kernel / scanlog.c
index 189b81a419871ac9653ed42201788b30d865d278..2edc947f7c44b2a9908f43ad098633018dc38bf6 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/rtas.h>
 #include <asm/prom.h>
@@ -43,7 +44,7 @@ static int scanlog_debug;
 static unsigned int ibm_scan_log_dump;                 /* RTAS token */
 static struct proc_dir_entry *proc_ppc64_scan_log_dump;        /* The proc file */
 
-static ssize_t scanlog_read(struct file *file, char *buf,
+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;
@@ -77,7 +78,7 @@ static ssize_t scanlog_read(struct file *file, char *buf,
                return -EFAULT;
 
        for (;;) {
-               wait_time = HZ/2;       /* default wait if no data */
+               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,
@@ -107,29 +108,19 @@ static ssize_t scanlog_read(struct file *file, char *buf,
                        break;
                    default:
                        if (status > 9900 && status <= 9905) {
-                               /* No data.  RTAS is hinting at a delay required
-                                * between 1-100000 milliseconds
-                                */
-                               int ms = 1;
-                               for (; status > 9900; status--)
-                                       ms = ms * 10;
-                               /* Use microseconds for reasonable accuracy */
-                               ms *= 1000;
-                               wait_time = ms / (1000000/HZ); /* round down is fine */
-                               /* Fall through to sleep */
+                               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. */
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(wait_time);
+               msleep_interruptible(wait_time);
        }
        /*NOTREACHED*/
 }
 
-static ssize_t scanlog_write(struct file * file, const char * buf,
+static ssize_t scanlog_write(struct file * file, const char __user * buf,
                             size_t count, loff_t *ppos)
 {
        char stkbuf[20];
@@ -234,8 +225,7 @@ int __init scanlog_init(void)
 void __exit scanlog_cleanup(void)
 {
        if (proc_ppc64_scan_log_dump) {
-               if (proc_ppc64_scan_log_dump->data)
-                       kfree(proc_ppc64_scan_log_dump->data);
+               kfree(proc_ppc64_scan_log_dump->data);
                remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
        }
 }