diff options
Diffstat (limited to 'drivers/char/toshiba.c')
| -rw-r--r-- | drivers/char/toshiba.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index dd36fd04a84..014c9d90d29 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c @@ -58,7 +58,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/sched.h> #include <linux/types.h> #include <linux/fcntl.h> #include <linux/miscdevice.h> @@ -68,7 +67,8 @@ #include <linux/init.h> #include <linux/stat.h> #include <linux/proc_fs.h> - +#include <linux/seq_file.h> +#include <linux/mutex.h> #include <linux/toshiba.h> #define TOSH_MINOR_DEV 181 @@ -78,6 +78,7 @@ MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); MODULE_DESCRIPTION("Toshiba laptop SMM driver"); MODULE_SUPPORTED_DEVICE("toshiba"); +static DEFINE_MUTEX(tosh_mutex); static int tosh_fn; module_param_named(fn, tosh_fn, int, 0); MODULE_PARM_DESC(fn, "User specified Fn key detection port"); @@ -88,13 +89,14 @@ static int tosh_date; static int tosh_sci; static int tosh_fan; -static int tosh_ioctl(struct inode *, struct file *, unsigned int, +static long tosh_ioctl(struct file *, unsigned int, unsigned long); static const struct file_operations tosh_fops = { .owner = THIS_MODULE, - .ioctl = tosh_ioctl, + .unlocked_ioctl = tosh_ioctl, + .llseek = noop_llseek, }; static struct miscdevice tosh_device = { @@ -249,10 +251,10 @@ int tosh_smm(SMMRegisters *regs) return eax; } +EXPORT_SYMBOL(tosh_smm); -static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, - unsigned long arg) +static long tosh_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) { SMMRegisters regs; SMMRegisters __user *argp = (SMMRegisters __user *)arg; @@ -274,13 +276,16 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, return -EINVAL; /* do we need to emulate the fan ? */ + mutex_lock(&tosh_mutex); if (tosh_fan==1) { if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) { err = tosh_emulate_fan(®s); + mutex_unlock(&tosh_mutex); break; } } err = tosh_smm(®s); + mutex_unlock(&tosh_mutex); break; default: return -EINVAL; @@ -297,12 +302,10 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, * Print the information for /proc/toshiba */ #ifdef CONFIG_PROC_FS -static int tosh_get_info(char *buffer, char **start, off_t fpos, int length) +static int proc_toshiba_show(struct seq_file *m, void *v) { - char *temp; int key; - temp = buffer; key = tosh_fn_status(); /* Arguments @@ -313,8 +316,7 @@ static int tosh_get_info(char *buffer, char **start, off_t fpos, int length) 4) BIOS date (in SCI date format) 5) Fn Key status */ - - temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n", + seq_printf(m, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n", tosh_id, (tosh_sci & 0xff00)>>8, tosh_sci & 0xff, @@ -322,9 +324,21 @@ static int tosh_get_info(char *buffer, char **start, off_t fpos, int length) tosh_bios & 0xff, tosh_date, key); + return 0; +} - return temp-buffer; +static int proc_toshiba_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_toshiba_show, NULL); } + +static const struct file_operations proc_toshiba_fops = { + .owner = THIS_MODULE, + .open = proc_toshiba_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif @@ -416,7 +430,7 @@ static int tosh_probe(void) int i,major,minor,day,year,month,flag; unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 }; SMMRegisters regs; - void __iomem *bios = ioremap(0xf0000, 0x10000); + void __iomem *bios = ioremap_cache(0xf0000, 0x10000); if (!bios) return -ENOMEM; @@ -495,7 +509,7 @@ static int __init toshiba_init(void) if (tosh_probe()) return -ENODEV; - printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n"); + printk(KERN_INFO "Toshiba System Management Mode driver v" TOSH_VERSION "\n"); /* set the port to use for Fn status if not specified as a parameter */ if (tosh_fn==0x00) @@ -507,10 +521,14 @@ static int __init toshiba_init(void) return retval; #ifdef CONFIG_PROC_FS - /* register the proc entry */ - if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) { - misc_deregister(&tosh_device); - return -ENOMEM; + { + struct proc_dir_entry *pde; + + pde = proc_create("toshiba", 0, NULL, &proc_toshiba_fops); + if (!pde) { + misc_deregister(&tosh_device); + return -ENOMEM; + } } #endif |
