X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Flcd.c;h=d649abbf08574595d2e270cd488ea478c2405ac9;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=64837783d180510512a27e36ad631a798850a593;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 64837783d..d649abbf0 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -14,7 +14,6 @@ #define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ -#include #include #include #include @@ -24,6 +23,7 @@ #include #include #include +#include #include #include @@ -32,11 +32,14 @@ #include "lcd.h" +static DEFINE_SPINLOCK(lcd_lock); + static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -static int lcd_present = 1; +static unsigned int lcd_present = 1; +/* used in arch/mips/cobalt/reset.c */ int led_state = 0; #if defined(CONFIG_TULIP) && 0 @@ -62,7 +65,6 @@ static int lcd_ioctl(struct inode *inode, struct file *file, { struct lcd_display button_display; unsigned long address, a; - int index; switch (cmd) { case LCD_On: @@ -219,6 +221,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, case LCD_Write:{ struct lcd_display display; + unsigned int index; if (copy_from_user @@ -315,7 +318,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, // set only bit led_display.leds case LED_Bit_Set:{ - int i; + unsigned int i; int bit = 1; struct lcd_display led_display; @@ -337,7 +340,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, // clear only bit led_display.leds case LED_Bit_Clear:{ - int i; + unsigned int i; int bit = 1; struct lcd_display led_display; @@ -412,6 +415,10 @@ static int lcd_ioctl(struct inode *inode, struct file *file, int ctr = 0; + if ( !capable(CAP_SYS_ADMIN) ) return -EPERM; + + pr_info(LCD "Erasing Flash\n"); + // Chip Erase Sequence WRITE_FLASH(kFlash_Addr1, kFlash_Data1); WRITE_FLASH(kFlash_Addr2, kFlash_Data2); @@ -420,21 +427,15 @@ static int lcd_ioctl(struct inode *inode, struct file *file, WRITE_FLASH(kFlash_Addr2, kFlash_Data2); WRITE_FLASH(kFlash_Addr1, kFlash_Erase6); - printk("Erasing Flash.\n"); - while ((!dqpoll(0x00000000, 0xFF)) && (!timeout(0x00000000))) { ctr++; } - printk("\n"); - printk("\n"); - printk("\n"); - if (READ_FLASH(0x07FFF0) == 0xFF) { - printk("Erase Successful\r\n"); + pr_info(LCD "Erase Successful\n"); } else if (timeout) { - printk("Erase Timed Out\r\n"); + pr_info(LCD "Erase Timed Out\n"); } break; @@ -446,31 +447,35 @@ static int lcd_ioctl(struct inode *inode, struct file *file, volatile unsigned long burn_addr; unsigned long flags; - int i; + unsigned int i, index; unsigned char *rom; struct lcd_display display; + if ( !capable(CAP_SYS_ADMIN) ) return -EPERM; + if (copy_from_user (&display, (struct lcd_display *) arg, sizeof(struct lcd_display))) return -EFAULT; - rom = (unsigned char *) kmalloc((128), GFP_ATOMIC); + rom = kmalloc((128), GFP_ATOMIC); if (rom == NULL) { - printk("broken\n"); - return 1; + printk(KERN_ERR LCD "kmalloc() failed in %s\n", + __FUNCTION__); + return -ENOMEM; } - printk("Churning and Burning -"); - save_flags(flags); + pr_info(LCD "Starting Flash burn\n"); for (i = 0; i < FLASH_SIZE; i = i + 128) { if (copy_from_user - (rom, display.RomImage + i, 128)) + (rom, display.RomImage + i, 128)) { + kfree(rom); return -EFAULT; + } burn_addr = kFlashBase + i; - cli(); + spin_lock_irqsave(&lcd_lock, flags); for (index = 0; index < (128); index++) { WRITE_FLASH(kFlash_Addr1, @@ -479,32 +484,30 @@ static int lcd_ioctl(struct inode *inode, struct file *file, kFlash_Data2); WRITE_FLASH(kFlash_Addr1, kFlash_Prog); - *((volatile unsigned char *) - burn_addr) = - (volatile unsigned char) rom[index]; - - while ((!dqpoll - (burn_addr, - (volatile unsigned char) - rom[index])) - && (!timeout(burn_addr))) { - } + *((volatile unsigned char *)burn_addr) = + (volatile unsigned char) rom[index]; + + while ((!dqpoll (burn_addr, + (volatile unsigned char) + rom[index])) && + (!timeout(burn_addr))) { } burn_addr++; } - restore_flags(flags); - if (* - ((volatile unsigned char *) (burn_addr - - 1)) == - (volatile unsigned char) rom[index - - 1]) { + spin_unlock_irqrestore(&lcd_lock, flags); + if (* ((volatile unsigned char *) + (burn_addr - 1)) == + (volatile unsigned char) + rom[index - 1]) { } else if (timeout) { - printk("Program timed out\r\n"); + pr_info(LCD "Flash burn timed out\n"); } } kfree(rom); + pr_info(LCD "Flash successfully burned\n"); + break; } @@ -514,7 +517,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned char *user_bytes; volatile unsigned long read_addr; - int i; + unsigned int i; user_bytes = &(((struct lcd_display *) arg)->RomImage[0]); @@ -523,7 +526,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, (VERIFY_WRITE, user_bytes, FLASH_SIZE)) return -EFAULT; - printk("Reading Flash"); + pr_info(LCD "Reading Flash"); for (i = 0; i < FLASH_SIZE; i++) { unsigned char tmp_byte; read_addr = kFlashBase + i; @@ -539,8 +542,7 @@ static int lcd_ioctl(struct inode *inode, struct file *file, } default: - return 0; - break; + return -EINVAL; } @@ -572,8 +574,8 @@ static inline int button_pressed(void) static int lcd_waiters = 0; -static long lcd_read(struct inode *inode, struct file *file, char *buf, - unsigned long count) +static ssize_t lcd_read(struct file *file, char *buf, + size_t count, loff_t *ofs) { long buttons_now; @@ -583,8 +585,7 @@ static long lcd_read(struct inode *inode, struct file *file, char *buf, lcd_waiters++; while (((buttons_now = (long) button_pressed()) == 0) && !(signal_pending(current))) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(2 * HZ); + msleep_interruptible(2000); } lcd_waiters--; @@ -597,7 +598,7 @@ static long lcd_read(struct inode *inode, struct file *file, char *buf, * The various file operations we support. */ -static struct file_operations lcd_fops = { +static const struct file_operations lcd_fops = { .read = lcd_read, .ioctl = lcd_ioctl, .open = lcd_open, @@ -611,10 +612,15 @@ static struct miscdevice lcd_dev = { static int lcd_init(void) { + int ret; unsigned long data; - printk("%s\n", LCD_DRIVER); - misc_register(&lcd_dev); + pr_info("%s\n", LCD_DRIVER); + ret = misc_register(&lcd_dev); + if (ret) { + printk(KERN_WARNING LCD "Unable to register misc device.\n"); + return ret; + } /* Check region? Naaah! Just snarf it up. */ /* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/ @@ -623,7 +629,7 @@ static int lcd_init(void) data = LCDReadData; if ((data & 0x000000FF) == (0x00)) { lcd_present = 0; - printk("LCD Not Present\n"); + pr_info(LCD "LCD Not Present\n"); } else { lcd_present = 1; WRITE_GAL(kGal_DevBank2PReg, kGal_DevBank2Cfg);