diff options
Diffstat (limited to 'drivers/macintosh')
-rw-r--r-- | drivers/macintosh/ans-lcd.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index 6a822189325..a3d25da2f27 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c @@ -3,7 +3,6 @@ */ #include <linux/types.h> -#include <linux/smp_lock.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/miscdevice.h> @@ -26,6 +25,7 @@ static unsigned long anslcd_short_delay = 80; static unsigned long anslcd_long_delay = 3280; static volatile unsigned char __iomem *anslcd_ptr; +static DEFINE_MUTEX(anslcd_mutex); #undef DEBUG @@ -65,26 +65,31 @@ anslcd_write( struct file * file, const char __user * buf, if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; + + mutex_lock(&anslcd_mutex); for ( i = *ppos; count > 0; ++i, ++p, --count ) { char c; __get_user(c, p); anslcd_write_byte_data( c ); } + mutex_unlock(&anslcd_mutex); *ppos = i; return p - buf; } -static int -anslcd_ioctl( struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg ) +static long +anslcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { char ch, __user *temp; + long ret = 0; #ifdef DEBUG printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg); #endif + mutex_lock(&anslcd_mutex); + switch ( cmd ) { case ANSLCD_CLEAR: @@ -93,7 +98,7 @@ anslcd_ioctl( struct inode * inode, struct file * file, anslcd_write_byte_ctrl ( 0x06 ); anslcd_write_byte_ctrl ( 0x01 ); anslcd_write_byte_ctrl ( 0x02 ); - return 0; + break; case ANSLCD_SENDCTRL: temp = (char __user *) arg; __get_user(ch, temp); @@ -101,33 +106,37 @@ anslcd_ioctl( struct inode * inode, struct file * file, anslcd_write_byte_ctrl ( ch ); __get_user(ch, temp); } - return 0; + break; case ANSLCD_SETSHORTDELAY: if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - anslcd_short_delay=arg; - return 0; + ret =-EACCES; + else + anslcd_short_delay=arg; + break; case ANSLCD_SETLONGDELAY: if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - anslcd_long_delay=arg; - return 0; + ret = -EACCES; + else + anslcd_long_delay=arg; + break; default: - return -EINVAL; + ret = -EINVAL; } + + mutex_unlock(&anslcd_mutex); + return ret; } static int anslcd_open( struct inode * inode, struct file * file ) { - cycle_kernel_lock(); return 0; } const struct file_operations anslcd_fops = { - .write = anslcd_write, - .ioctl = anslcd_ioctl, - .open = anslcd_open, + .write = anslcd_write, + .unlocked_ioctl = anslcd_ioctl, + .open = anslcd_open, }; static struct miscdevice anslcd_dev = { @@ -168,6 +177,7 @@ anslcd_init(void) printk(KERN_DEBUG "LCD: init\n"); #endif + mutex_lock(&anslcd_mutex); anslcd_write_byte_ctrl ( 0x38 ); anslcd_write_byte_ctrl ( 0x0c ); anslcd_write_byte_ctrl ( 0x06 ); @@ -176,6 +186,7 @@ anslcd_init(void) for(a=0;a<80;a++) { anslcd_write_byte_data(anslcd_logo[a]); } + mutex_unlock(&anslcd_mutex); return 0; } |