From: Robert Picco I eliminated the request_irq brain damage, chopped off procfs support (didn't care for it too much in the first place and it was adopted from rtc.c), made the check for FMODE_WRITE in hpet_open and responded to a few other suggestions. Signed-off-by: Andrew Morton --- 25-akpm/Documentation/devices.txt | 1 25-akpm/Documentation/filesystems/proc.txt | 2 25-akpm/Documentation/hpet.txt | 6 - 25-akpm/arch/i386/kernel/time_hpet.c | 7 -- 25-akpm/drivers/char/hpet.c | 96 +++-------------------------- 25-akpm/include/linux/hpet.h | 2 25-akpm/include/linux/miscdevice.h | 2 7 files changed, 21 insertions(+), 95 deletions(-) diff -puN arch/i386/kernel/time_hpet.c~hpet-fixes arch/i386/kernel/time_hpet.c --- 25/arch/i386/kernel/time_hpet.c~hpet-fixes Wed Jun 23 14:20:42 2004 +++ 25-akpm/arch/i386/kernel/time_hpet.c Wed Jun 23 14:20:42 2004 @@ -155,10 +155,9 @@ int __init hpet_enable(void) hd.hd_address = hpet_virt_address; hd.hd_nirqs = ntimer; hd.hd_flags = HPET_DATA_PLATFORM; -#ifndef CONFIG_HPET_EMULATE_RTC - hd.hd_state = 0x1; -#else - hd.hd_state = 0x3; + HD_STATE(&hd, 0); +#ifdef CONFIG_HPET_EMULATE_RTC + HD_STATE(&hd, 1); #endif hd.hd_irq[0] = HPET_LEGACY_8254; hd.hd_irq[1] = HPET_LEGACY_RTC; diff -puN Documentation/devices.txt~hpet-fixes Documentation/devices.txt --- 25/Documentation/devices.txt~hpet-fixes Wed Jun 23 14:20:42 2004 +++ 25-akpm/Documentation/devices.txt Wed Jun 23 14:20:42 2004 @@ -434,6 +434,7 @@ Your cooperation is appreciated. 225 = /dev/pps Pulse Per Second driver 226 = /dev/systrace Systrace device 227 = /dev/mcelog X86_64 Machine Check Exception driver + 228 = /dev/hpet HPET driver 240-254 Reserved for local use 255 Reserved for MISC_DYNAMIC_MINOR diff -puN Documentation/filesystems/proc.txt~hpet-fixes Documentation/filesystems/proc.txt --- 25/Documentation/filesystems/proc.txt~hpet-fixes Wed Jun 23 14:20:42 2004 +++ 25-akpm/Documentation/filesystems/proc.txt Wed Jun 23 14:20:42 2004 @@ -201,7 +201,7 @@ Table 1-3: Kernel info in /proc devices Available devices (block and character) dma Used DMS channels filesystems Supported filesystems - driver Various drivers grouped here, currently rtc (2.4) and hpet (2.6) + driver Various drivers grouped here, currently rtc (2.4) execdomains Execdomains, related to security (2.4) fb Frame Buffer devices (2.4) fs File system parameters, currently nfs/exports (2.4) diff -puN Documentation/hpet.txt~hpet-fixes Documentation/hpet.txt --- 25/Documentation/hpet.txt~hpet-fixes Wed Jun 23 14:20:42 2004 +++ 25-akpm/Documentation/hpet.txt Wed Jun 23 14:20:42 2004 @@ -103,7 +103,7 @@ hpet_open_close(int argc, const char **a return; } - fd = open(argv[0], O_RDWR); + fd = open(argv[0], O_RDONLY); if (fd < 0) fprintf(stderr, "hpet_open_close: open failed\n"); else @@ -136,7 +136,7 @@ hpet_poll(int argc, const char **argv) freq = atoi(argv[1]); iterations = atoi(argv[2]); - fd = open(argv[0], O_RDWR); + fd = open(argv[0], O_RDONLY); if (fd < 0) { fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]); @@ -230,7 +230,7 @@ hpet_fasync(int argc, const char **argv) goto out; } - fd = open(argv[0], O_RDWR); + fd = open(argv[0], O_RDONLY); if (fd < 0) { fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]); diff -puN drivers/char/hpet.c~hpet-fixes drivers/char/hpet.c --- 25/drivers/char/hpet.c~hpet-fixes Wed Jun 23 14:20:42 2004 +++ 25-akpm/drivers/char/hpet.c Wed Jun 23 14:20:42 2004 @@ -50,6 +50,8 @@ static spinlock_t hpet_lock = SPIN_LOCK_ /* A lock for concurrent intermodule access to hpet and isr hpet activity. */ static spinlock_t hpet_task_lock = SPIN_LOCK_UNLOCKED; +#define HPET_DEV_NAME (7) + struct hpet_dev { struct hpets *hd_hpets; struct hpet *hd_hpet; @@ -62,6 +64,7 @@ struct hpet_dev { unsigned int hd_flags; unsigned int hd_irq; unsigned int hd_hdwirq; + char hd_name[HPET_DEV_NAME]; }; struct hpets { @@ -148,6 +151,9 @@ static int hpet_open(struct inode *inode struct hpets *hpetp; int i; + if (file->f_mode & FMODE_WRITE) + return -EINVAL; + spin_lock_irq(&hpet_lock); for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) @@ -191,8 +197,6 @@ hpet_read(struct file *file, char *buf, add_wait_queue(&devp->hd_waitqueue, &wait); do { - __set_current_state(TASK_INTERRUPTIBLE); - spin_lock_irq(&hpet_lock); data = devp->hd_irqdata; devp->hd_irqdata = 0; @@ -208,6 +212,7 @@ hpet_read(struct file *file, char *buf, goto out; } + set_current_state(TASK_INTERRUPTIBLE); schedule(); } while (1); @@ -255,9 +260,6 @@ static int hpet_mmap(struct file *file, if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) return -EINVAL; - if (vma->vm_flags & VM_WRITE) - return -EPERM; - devp = file->private_data; addr = (unsigned long)devp->hd_hpet; @@ -371,12 +373,10 @@ static int hpet_ioctl_ieon(struct hpet_d irq = devp->hd_hdwirq; if (irq) { - char name[7]; - - sprintf(name, "hpet%d", (int)(devp - hpetp->hp_dev)); + sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); if (request_irq - (irq, hpet_interrupt, SA_INTERRUPT, name, (void *)devp)) { + (irq, hpet_interrupt, SA_INTERRUPT, devp->hd_name, (void *)devp)) { printk(KERN_ERR "hpet: IRQ %d is not free\n", irq); irq = 0; } @@ -731,73 +731,6 @@ static ctl_table dev_root[] = { static struct ctl_table_header *sysctl_header; -static void *hpet_start(struct seq_file *s, loff_t * pos) -{ - struct hpets *hpetp; - loff_t n; - - for (n = *pos, hpetp = hpets; hpetp; hpetp = hpetp->hp_next) - if (!n--) - return hpetp; - - return 0; -} - -static void *hpet_next(struct seq_file *s, void *v, loff_t * pos) -{ - struct hpets *hpetp; - - hpetp = v; - ++*pos; - return hpetp->hp_next; -} - -static void hpet_stop(struct seq_file *s, void *v) -{ - return; -} - -static int hpet_show(struct seq_file *s, void *v) -{ - struct hpets *hpetp; - struct hpet *hpet; - u64 cap, vendor, period; - - hpetp = v; - hpet = hpetp->hp_hpet; - - cap = readq(&hpet->hpet_cap); - period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >> - HPET_COUNTER_CLK_PERIOD_SHIFT; - vendor = (cap & HPET_VENDOR_ID_MASK) >> HPET_VENDOR_ID_SHIFT; - - seq_printf(s, - "HPET%d period = %d 10**-15 vendor = 0x%x number timer = %d\n", - hpetp->hp_which, (u32) period, (u32) vendor, - hpetp->hp_ntimer); - - return 0; -} - -static struct seq_operations hpet_seq_ops = { - .start = hpet_start, - .next = hpet_next, - .stop = hpet_stop, - .show = hpet_show -}; - -static int hpet_proc_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &hpet_seq_ops); -} - -static struct file_operations hpet_proc_fops = { - .open = hpet_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release -}; - /* * Adjustment for when arming the timer with * initial conditions. That is, main counter @@ -1025,19 +958,12 @@ static struct miscdevice hpet_misc = { H static int __init hpet_init(void) { - struct proc_dir_entry *entry; - (void)acpi_bus_register_driver(&hpet_acpi_driver); if (hpets) { if (misc_register(&hpet_misc)) return -ENODEV; - entry = create_proc_entry("driver/hpet", 0, 0); - - if (entry) - entry->proc_fops = &hpet_proc_fops; - sysctl_header = register_sysctl_table(dev_root, 0); #ifdef CONFIG_TIME_INTERPOLATION @@ -1062,10 +988,8 @@ static void __exit hpet_exit(void) { acpi_bus_unregister_driver(&hpet_acpi_driver); - if (hpets) { + if (hpets) unregister_sysctl_table(sysctl_header); - remove_proc_entry("driver/hpet", NULL); - } return; } diff -puN include/linux/hpet.h~hpet-fixes include/linux/hpet.h --- 25/include/linux/hpet.h~hpet-fixes Wed Jun 23 14:20:42 2004 +++ 25-akpm/include/linux/hpet.h Wed Jun 23 14:20:42 2004 @@ -115,6 +115,8 @@ struct hpet_task { void *ht_opaque; }; +#define HD_STATE(HD, TIMER) (HD)->hd_state |= (1 << TIMER) + struct hpet_data { unsigned long hd_address; unsigned short hd_nirqs; diff -puN include/linux/miscdevice.h~hpet-fixes include/linux/miscdevice.h --- 25/include/linux/miscdevice.h~hpet-fixes Wed Jun 23 14:20:42 2004 +++ 25-akpm/include/linux/miscdevice.h Wed Jun 23 14:20:42 2004 @@ -33,9 +33,9 @@ #define SGI_STREAMS_KEYBOARD 150 /* drivers/sgi/char/usema.c */ #define SGI_USEMACLONE 151 -#define HPET_MINOR 152 #define TUN_MINOR 200 +#define HPET_MINOR 228 struct device; _