diff options
Diffstat (limited to 'drivers/char/tlclk.c')
| -rw-r--r-- | drivers/char/tlclk.c | 157 |
1 files changed, 72 insertions, 85 deletions
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index e95e0ab0bd87..b381ea7e85d2 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -42,11 +42,12 @@ #include <linux/sysfs.h> #include <linux/device.h> #include <linux/miscdevice.h> -#include <linux/platform_device.h> +#include <linux/device/faux.h> #include <asm/io.h> /* inb/outb */ -#include <asm/uaccess.h> +#include <linux/uaccess.h> MODULE_AUTHOR("Sebastien Bouchard <sebastien.bouchard@ca.kontron.com>"); +MODULE_DESCRIPTION("Telecom Clock driver for Intel NetStructure(tm) MPCBL0010"); MODULE_LICENSE("GPL"); /*Hardware Reset of the PLL */ @@ -184,9 +185,8 @@ static unsigned int telclk_interrupt; static int int_events; /* Event that generate a interrupt */ static int got_event; /* if events processing have been done */ -static void switchover_timeout(unsigned long data); -static struct timer_list switchover_timer = - TIMER_INITIALIZER(switchover_timeout , 0, 0); +static void switchover_timeout(struct timer_list *t); +static struct timer_list switchover_timer; static unsigned long tlclk_timer_data; static struct tlclk_alarms *alarm_events; @@ -222,7 +222,7 @@ static int tlclk_open(struct inode *inode, struct file *filp) /* This device is wired through the FPGA IO space of the ATCA blade * we can't share this IRQ */ result = request_irq(telclk_interrupt, &tlclk_interrupt, - IRQF_DISABLED, "telco_clock", tlclk_interrupt); + 0, "telco_clock", tlclk_interrupt); if (result == -EBUSY) printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n"); else @@ -507,28 +507,28 @@ static ssize_t store_select_amcb2_transmit_clock(struct device *d, val = (unsigned char)tmp; spin_lock_irqsave(&event_lock, flags); - if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { - SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28); - SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); - } else if (val >= CLK_8_592MHz) { - SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38); - switch (val) { - case CLK_8_592MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); - break; - case CLK_11_184MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); - break; - case CLK_34_368MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); - break; - case CLK_44_736MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); - break; - } - } else - SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3); - + if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { + SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x28); + SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); + } else if (val >= CLK_8_592MHz) { + SET_PORT_BITS(TLCLK_REG3, 0xc7, 0x38); + switch (val) { + case CLK_8_592MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); + break; + case CLK_11_184MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); + break; + case CLK_34_368MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); + break; + case CLK_44_736MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); + break; + } + } else { + SET_PORT_BITS(TLCLK_REG3, 0xc7, val << 3); + } spin_unlock_irqrestore(&event_lock, flags); return strnlen(buf, count); @@ -549,27 +549,28 @@ static ssize_t store_select_amcb1_transmit_clock(struct device *d, val = (unsigned char)tmp; spin_lock_irqsave(&event_lock, flags); - if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { - SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5); - SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); - } else if (val >= CLK_8_592MHz) { - SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7); - switch (val) { - case CLK_8_592MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); - break; - case CLK_11_184MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); - break; - case CLK_34_368MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); - break; - case CLK_44_736MHz: - SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); - break; - } - } else - SET_PORT_BITS(TLCLK_REG3, 0xf8, val); + if ((val == CLK_8kHz) || (val == CLK_16_384MHz)) { + SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x5); + SET_PORT_BITS(TLCLK_REG1, 0xfb, ~val); + } else if (val >= CLK_8_592MHz) { + SET_PORT_BITS(TLCLK_REG3, 0xf8, 0x7); + switch (val) { + case CLK_8_592MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 2); + break; + case CLK_11_184MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 0); + break; + case CLK_34_368MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 3); + break; + case CLK_44_736MHz: + SET_PORT_BITS(TLCLK_REG0, 0xfc, 1); + break; + } + } else { + SET_PORT_BITS(TLCLK_REG3, 0xf8, val); + } spin_unlock_irqrestore(&event_lock, flags); return strnlen(buf, count); @@ -741,7 +742,7 @@ static ssize_t store_reset (struct device *d, static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset); -static struct attribute *tlclk_sysfs_entries[] = { +static struct attribute *tlclk_attrs[] = { &dev_attr_current_ref.attr, &dev_attr_telclock_version.attr, &dev_attr_alarms.attr, @@ -765,29 +766,29 @@ static struct attribute *tlclk_sysfs_entries[] = { &dev_attr_reset.attr, NULL }; +ATTRIBUTE_GROUPS(tlclk); -static struct attribute_group tlclk_attribute_group = { - .name = NULL, /* put in device directory */ - .attrs = tlclk_sysfs_entries, -}; - -static struct platform_device *tlclk_device; +static struct faux_device *tlclk_device; static int __init tlclk_init(void) { int ret; + telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); + + alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); + if (!alarm_events) { + ret = -ENOMEM; + goto out1; + } + ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops); if (ret < 0) { printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major); + kfree(alarm_events); return ret; } tlclk_major = ret; - alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); - if (!alarm_events) { - ret = -ENOMEM; - goto out1; - } /* Read telecom clock IRQ number (Set by BIOS) */ if (!request_region(TLCLK_BASE, 8, "telco_clock")) { @@ -796,7 +797,6 @@ static int __init tlclk_init(void) ret = -EBUSY; goto out2; } - telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */ printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n", @@ -805,7 +805,7 @@ static int __init tlclk_init(void) goto out3; } - init_timer(&switchover_timer); + timer_setup(&switchover_timer, switchover_timeout, 0); ret = misc_register(&tlclk_miscdev); if (ret < 0) { @@ -813,51 +813,39 @@ static int __init tlclk_init(void) goto out3; } - tlclk_device = platform_device_register_simple("telco_clock", - -1, NULL, 0); - if (IS_ERR(tlclk_device)) { - printk(KERN_ERR "tlclk: platform_device_register failed.\n"); - ret = PTR_ERR(tlclk_device); + tlclk_device = faux_device_create_with_groups("telco_clock", NULL, NULL, tlclk_groups); + if (!tlclk_device) { + ret = -ENODEV; goto out4; } - ret = sysfs_create_group(&tlclk_device->dev.kobj, - &tlclk_attribute_group); - if (ret) { - printk(KERN_ERR "tlclk: failed to create sysfs device attributes.\n"); - goto out5; - } - return 0; -out5: - platform_device_unregister(tlclk_device); out4: misc_deregister(&tlclk_miscdev); out3: release_region(TLCLK_BASE, 8); out2: kfree(alarm_events); -out1: unregister_chrdev(tlclk_major, "telco_clock"); +out1: return ret; } static void __exit tlclk_cleanup(void) { - sysfs_remove_group(&tlclk_device->dev.kobj, &tlclk_attribute_group); - platform_device_unregister(tlclk_device); + faux_device_destroy(tlclk_device); misc_deregister(&tlclk_miscdev); unregister_chrdev(tlclk_major, "telco_clock"); release_region(TLCLK_BASE, 8); - del_timer_sync(&switchover_timer); + timer_delete_sync(&switchover_timer); kfree(alarm_events); } -static void switchover_timeout(unsigned long data) +static void switchover_timeout(struct timer_list *unused) { - unsigned long flags = *(unsigned long *) data; + unsigned long flags = tlclk_timer_data; if ((flags & 1)) { if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08)) @@ -868,7 +856,7 @@ static void switchover_timeout(unsigned long data) } /* Alarm processing is done, wake up read task */ - del_timer(&switchover_timer); + timer_delete(&switchover_timer); got_event = 1; wake_up(&wq); } @@ -922,7 +910,6 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id) /* TIMEOUT in ~10ms */ switchover_timer.expires = jiffies + msecs_to_jiffies(10); tlclk_timer_data = inb(TLCLK_REG1); - switchover_timer.data = (unsigned long) &tlclk_timer_data; mod_timer(&switchover_timer, switchover_timer.expires); } else { got_event = 1; |
