diff options
| -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 6a8221893256..a3d25da2f275 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 6 | #include <linux/smp_lock.h> | ||
| 7 | #include <linux/errno.h> | 6 | #include <linux/errno.h> |
| 8 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
| 9 | #include <linux/miscdevice.h> | 8 | #include <linux/miscdevice.h> |
| @@ -26,6 +25,7 @@ | |||
| 26 | static unsigned long anslcd_short_delay = 80; | 25 | static unsigned long anslcd_short_delay = 80; |
| 27 | static unsigned long anslcd_long_delay = 3280; | 26 | static unsigned long anslcd_long_delay = 3280; |
| 28 | static volatile unsigned char __iomem *anslcd_ptr; | 27 | static volatile unsigned char __iomem *anslcd_ptr; |
| 28 | static DEFINE_MUTEX(anslcd_mutex); | ||
| 29 | 29 | ||
| 30 | #undef DEBUG | 30 | #undef DEBUG |
| 31 | 31 | ||
| @@ -65,26 +65,31 @@ anslcd_write( struct file * file, const char __user * buf, | |||
| 65 | 65 | ||
| 66 | if (!access_ok(VERIFY_READ, buf, count)) | 66 | if (!access_ok(VERIFY_READ, buf, count)) |
| 67 | return -EFAULT; | 67 | return -EFAULT; |
| 68 | |||
| 69 | mutex_lock(&anslcd_mutex); | ||
| 68 | for ( i = *ppos; count > 0; ++i, ++p, --count ) | 70 | for ( i = *ppos; count > 0; ++i, ++p, --count ) |
| 69 | { | 71 | { |
| 70 | char c; | 72 | char c; |
| 71 | __get_user(c, p); | 73 | __get_user(c, p); |
| 72 | anslcd_write_byte_data( c ); | 74 | anslcd_write_byte_data( c ); |
| 73 | } | 75 | } |
| 76 | mutex_unlock(&anslcd_mutex); | ||
| 74 | *ppos = i; | 77 | *ppos = i; |
| 75 | return p - buf; | 78 | return p - buf; |
| 76 | } | 79 | } |
| 77 | 80 | ||
| 78 | static int | 81 | static long |
| 79 | anslcd_ioctl( struct inode * inode, struct file * file, | 82 | anslcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 80 | unsigned int cmd, unsigned long arg ) | ||
| 81 | { | 83 | { |
| 82 | char ch, __user *temp; | 84 | char ch, __user *temp; |
| 85 | long ret = 0; | ||
| 83 | 86 | ||
| 84 | #ifdef DEBUG | 87 | #ifdef DEBUG |
| 85 | printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg); | 88 | printk(KERN_DEBUG "LCD: ioctl(%d,%d)\n",cmd,arg); |
| 86 | #endif | 89 | #endif |
| 87 | 90 | ||
| 91 | mutex_lock(&anslcd_mutex); | ||
| 92 | |||
| 88 | switch ( cmd ) | 93 | switch ( cmd ) |
| 89 | { | 94 | { |
| 90 | case ANSLCD_CLEAR: | 95 | case ANSLCD_CLEAR: |
| @@ -93,7 +98,7 @@ anslcd_ioctl( struct inode * inode, struct file * file, | |||
| 93 | anslcd_write_byte_ctrl ( 0x06 ); | 98 | anslcd_write_byte_ctrl ( 0x06 ); |
| 94 | anslcd_write_byte_ctrl ( 0x01 ); | 99 | anslcd_write_byte_ctrl ( 0x01 ); |
| 95 | anslcd_write_byte_ctrl ( 0x02 ); | 100 | anslcd_write_byte_ctrl ( 0x02 ); |
| 96 | return 0; | 101 | break; |
| 97 | case ANSLCD_SENDCTRL: | 102 | case ANSLCD_SENDCTRL: |
| 98 | temp = (char __user *) arg; | 103 | temp = (char __user *) arg; |
| 99 | __get_user(ch, temp); | 104 | __get_user(ch, temp); |
| @@ -101,33 +106,37 @@ anslcd_ioctl( struct inode * inode, struct file * file, | |||
| 101 | anslcd_write_byte_ctrl ( ch ); | 106 | anslcd_write_byte_ctrl ( ch ); |
| 102 | __get_user(ch, temp); | 107 | __get_user(ch, temp); |
| 103 | } | 108 | } |
| 104 | return 0; | 109 | break; |
| 105 | case ANSLCD_SETSHORTDELAY: | 110 | case ANSLCD_SETSHORTDELAY: |
| 106 | if (!capable(CAP_SYS_ADMIN)) | 111 | if (!capable(CAP_SYS_ADMIN)) |
| 107 | return -EACCES; | 112 | ret =-EACCES; |
| 108 | anslcd_short_delay=arg; | 113 | else |
| 109 | return 0; | 114 | anslcd_short_delay=arg; |
| 115 | break; | ||
| 110 | case ANSLCD_SETLONGDELAY: | 116 | case ANSLCD_SETLONGDELAY: |
| 111 | if (!capable(CAP_SYS_ADMIN)) | 117 | if (!capable(CAP_SYS_ADMIN)) |
| 112 | return -EACCES; | 118 | ret = -EACCES; |
| 113 | anslcd_long_delay=arg; | 119 | else |
| 114 | return 0; | 120 | anslcd_long_delay=arg; |
| 121 | break; | ||
| 115 | default: | 122 | default: |
| 116 | return -EINVAL; | 123 | ret = -EINVAL; |
| 117 | } | 124 | } |
| 125 | |||
| 126 | mutex_unlock(&anslcd_mutex); | ||
| 127 | return ret; | ||
| 118 | } | 128 | } |
| 119 | 129 | ||
| 120 | static int | 130 | static int |
| 121 | anslcd_open( struct inode * inode, struct file * file ) | 131 | anslcd_open( struct inode * inode, struct file * file ) |
| 122 | { | 132 | { |
| 123 | cycle_kernel_lock(); | ||
| 124 | return 0; | 133 | return 0; |
| 125 | } | 134 | } |
| 126 | 135 | ||
| 127 | const struct file_operations anslcd_fops = { | 136 | const struct file_operations anslcd_fops = { |
| 128 | .write = anslcd_write, | 137 | .write = anslcd_write, |
| 129 | .ioctl = anslcd_ioctl, | 138 | .unlocked_ioctl = anslcd_ioctl, |
| 130 | .open = anslcd_open, | 139 | .open = anslcd_open, |
| 131 | }; | 140 | }; |
| 132 | 141 | ||
| 133 | static struct miscdevice anslcd_dev = { | 142 | static struct miscdevice anslcd_dev = { |
| @@ -168,6 +177,7 @@ anslcd_init(void) | |||
| 168 | printk(KERN_DEBUG "LCD: init\n"); | 177 | printk(KERN_DEBUG "LCD: init\n"); |
| 169 | #endif | 178 | #endif |
| 170 | 179 | ||
| 180 | mutex_lock(&anslcd_mutex); | ||
| 171 | anslcd_write_byte_ctrl ( 0x38 ); | 181 | anslcd_write_byte_ctrl ( 0x38 ); |
| 172 | anslcd_write_byte_ctrl ( 0x0c ); | 182 | anslcd_write_byte_ctrl ( 0x0c ); |
| 173 | anslcd_write_byte_ctrl ( 0x06 ); | 183 | anslcd_write_byte_ctrl ( 0x06 ); |
| @@ -176,6 +186,7 @@ anslcd_init(void) | |||
| 176 | for(a=0;a<80;a++) { | 186 | for(a=0;a<80;a++) { |
| 177 | anslcd_write_byte_data(anslcd_logo[a]); | 187 | anslcd_write_byte_data(anslcd_logo[a]); |
| 178 | } | 188 | } |
| 189 | mutex_unlock(&anslcd_mutex); | ||
| 179 | return 0; | 190 | return 0; |
| 180 | } | 191 | } |
| 181 | 192 | ||
