diff -urN -X dontdiff linux-2.6.15-rc6-git4.org/drivers/char/tlclk.c linux-2.6.15-rc6-git4/drivers/char/tlclk.c --- linux-2.6.15-rc6-git4.org/drivers/char/tlclk.c 2005-12-23 12:52:42.000000000 -0800 +++ linux-2.6.15-rc6-git4/drivers/char/tlclk.c 2005-12-23 14:25:55.000000000 -0800 @@ -34,7 +34,6 @@ #include /* printk() */ #include /* everything... */ #include /* error codes */ -#include /* udelay */ #include #include #include @@ -165,7 +164,7 @@ filter_select : hardware_switching : hardware_switching_mode : -interrupt_switch : +telclock_version : mode_select : refalign : reset : @@ -173,7 +172,6 @@ select_amcb2_transmit_clock : select_redundant_clock : select_ref_frequency : -test_mode : All sysfs interfaces are integers in hex format, i.e echo 99 > refalign has the same effect as echo 0x99 > refalign. @@ -202,6 +200,11 @@ { int result; + alarm_events = kzalloc(sizeof(struct tlclk_alarms), GFP_KERNEL); + if (!alarm_events) + return -ENOMEM; + + init_timer(&switchover_timer); /* Make sure there is no interrupt pending while * initialising interrupt handler */ inb(TLCLK_REG6); @@ -212,6 +215,8 @@ SA_INTERRUPT, "telco_clock", tlclk_interrupt); if (result == -EBUSY) { printk(KERN_ERR "telco_clock: Interrupt can't be reserved!\n"); + kfree(alarm_events); + alarm_events = NULL; return -EBUSY; } inb(TLCLK_REG6); /* Clear interrupt events */ @@ -222,11 +227,14 @@ static int tlclk_release(struct inode *inode, struct file *filp) { free_irq(telclk_interrupt, tlclk_interrupt); + del_timer_sync(&switchover_timer); + kfree(alarm_events); + alarm_events = NULL; return 0; } -ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, +static ssize_t tlclk_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { if (count < sizeof(struct tlclk_alarms)) @@ -242,7 +250,7 @@ return sizeof(struct tlclk_alarms); } -ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, +static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { return 0; @@ -278,21 +286,21 @@ static DEVICE_ATTR(current_ref, S_IRUGO, show_current_ref, NULL); -static ssize_t show_interrupt_switch(struct device *d, +static ssize_t show_telclock_version(struct device *d, struct device_attribute *attr, char *buf) { unsigned long ret_val; unsigned long flags; spin_lock_irqsave(&event_lock, flags); - ret_val = inb(TLCLK_REG6); + ret_val = inb(TLCLK_REG5); spin_unlock_irqrestore(&event_lock, flags); return sprintf(buf, "0x%lX\n", ret_val); } -static DEVICE_ATTR(interrupt_switch, S_IRUGO, - show_interrupt_switch, NULL); +static DEVICE_ATTR(telclock_version, S_IRUGO, + show_telclock_version, NULL); static ssize_t show_alarms(struct device *d, struct device_attribute *attr, char *buf) @@ -436,26 +444,6 @@ static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, store_enable_clka0_output); -static ssize_t store_test_mode(struct device *d, - struct device_attribute *attr, const char *buf, size_t count) -{ - unsigned long flags; - unsigned long tmp; - unsigned char val; - - sscanf(buf, "%lX", &tmp); - dev_dbg(d, "tmp = 0x%lX\n", tmp); - - val = (unsigned char)tmp; - spin_lock_irqsave(&event_lock, flags); - SET_PORT_BITS(TLCLK_REG4, 0xfd, 2); - spin_unlock_irqrestore(&event_lock, flags); - - return strnlen(buf, count); -} - -static DEVICE_ATTR(test_mode, S_IWUGO, NULL, store_test_mode); - static ssize_t store_select_amcb2_transmit_clock(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { @@ -475,7 +463,7 @@ SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38); switch (val) { case CLK_8_592MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); + SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); break; case CLK_11_184MHz: SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); @@ -484,7 +472,7 @@ SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); break; case CLK_44_736MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); + SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); break; } } else @@ -653,9 +641,7 @@ dev_dbg(d, "tmp = 0x%lX\n", tmp); spin_lock_irqsave(&event_lock, flags); SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); - udelay(2); SET_PORT_BITS(TLCLK_REG0, 0xf7, 0x08); - udelay(2); SET_PORT_BITS(TLCLK_REG0, 0xf7, 0); spin_unlock_irqrestore(&event_lock, flags); @@ -706,7 +692,7 @@ static struct attribute *tlclk_sysfs_entries[] = { &dev_attr_current_ref.attr, - &dev_attr_interrupt_switch.attr, + &dev_attr_telclock_version.attr, &dev_attr_alarms.attr, &dev_attr_enable_clk3a_output.attr, &dev_attr_enable_clk3b_output.attr, @@ -714,7 +700,6 @@ &dev_attr_enable_clka1_output.attr, &dev_attr_enable_clkb0_output.attr, &dev_attr_enable_clka0_output.attr, - &dev_attr_test_mode.attr, &dev_attr_select_amcb1_transmit_clock.attr, &dev_attr_select_amcb2_transmit_clock.attr, &dev_attr_select_redundant_clock.attr, @@ -744,16 +729,13 @@ printk(KERN_ERR "telco_clock: can't get major! %d\n", tlclk_major); return ret; } - alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); - if (!alarm_events) - goto out1; /* Read telecom clock IRQ number (Set by BIOS) */ if (!request_region(TLCLK_BASE, 8, "telco_clock")) { printk(KERN_ERR "tlclk: request_region failed! 0x%X\n", TLCLK_BASE); ret = -EBUSY; - goto out2; + goto out1; } telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); @@ -761,16 +743,14 @@ printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw\n", telclk_interrupt); ret = -ENXIO; - goto out3; + goto out2; } - init_timer(&switchover_timer); - ret = misc_register(&tlclk_miscdev); if (ret < 0) { printk(KERN_ERR " misc_register retruns %d\n", ret); ret = -EBUSY; - goto out3; + goto out2; } tlclk_device = platform_device_register_simple("telco_clock", @@ -779,7 +759,7 @@ printk(KERN_ERR " platform_device_register retruns 0x%X\n", (unsigned int) tlclk_device); ret = -EBUSY; - goto out4; + goto out3; } ret = sysfs_create_group(&tlclk_device->dev.kobj, @@ -788,18 +768,16 @@ printk(KERN_ERR "failed to create sysfs device attributes\n"); sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group); - goto out5; + goto out4; } return 0; -out5: - platform_device_unregister(tlclk_device); out4: - misc_deregister(&tlclk_miscdev); + platform_device_unregister(tlclk_device); out3: - release_region(TLCLK_BASE, 8); + misc_deregister(&tlclk_miscdev); out2: - kfree(alarm_events); + release_region(TLCLK_BASE, 8); out1: unregister_chrdev(tlclk_major, "telco_clock"); return ret; @@ -813,9 +791,6 @@ unregister_chrdev(tlclk_major, "telco_clock"); release_region(TLCLK_BASE, 8); - del_timer_sync(&switchover_timer); - kfree(alarm_events); - } static void switchover_timeout(unsigned long data)