diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1286.c')
| -rw-r--r-- | drivers/rtc/rtc-ds1286.c | 114 |
1 files changed, 37 insertions, 77 deletions
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index 4fcb16bbff4..50e109b7825 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -18,14 +18,13 @@ #include <linux/bcd.h> #include <linux/ds1286.h> #include <linux/io.h> +#include <linux/slab.h> #define DRV_VERSION "1.0" struct ds1286_priv { struct rtc_device *rtc; u32 __iomem *rtcregs; - size_t size; - unsigned long baseaddr; spinlock_t lock; }; @@ -39,6 +38,26 @@ static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg) __raw_writel(data, &priv->rtcregs[reg]); } + +static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct ds1286_priv *priv = dev_get_drvdata(dev); + unsigned long flags; + unsigned char val; + + /* Allow or mask alarm interrupts */ + spin_lock_irqsave(&priv->lock, flags); + val = ds1286_rtc_read(priv, RTC_CMD); + if (enabled) + val &= ~RTC_TDM; + else + val |= RTC_TDM; + ds1286_rtc_write(priv, val, RTC_CMD); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + #ifdef CONFIG_RTC_INTF_DEV static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) @@ -48,22 +67,6 @@ static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) unsigned char val; switch (cmd) { - case RTC_AIE_OFF: - /* Mask alarm int. enab. bit */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val |= RTC_TDM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; - case RTC_AIE_ON: - /* Allow alarm interrupts. */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - val &= ~RTC_TDM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - break; case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ spin_lock_irqsave(&priv->lock, flags); @@ -265,7 +268,6 @@ static int ds1286_set_time(struct device *dev, struct rtc_time *tm) static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned char cmd; unsigned long flags; /* @@ -276,7 +278,7 @@ static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm) alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f; alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x1f; alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x07; - cmd = ds1286_rtc_read(priv, RTC_CMD); + ds1286_rtc_read(priv, RTC_CMD); spin_unlock_irqrestore(&priv->lock, flags); alm->time.tm_min = bcd2bin(alm->time.tm_min); @@ -315,69 +317,39 @@ static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm) } static const struct rtc_class_ops ds1286_ops = { - .ioctl = ds1286_ioctl, - .proc = ds1286_proc, + .ioctl = ds1286_ioctl, + .proc = ds1286_proc, .read_time = ds1286_read_time, .set_time = ds1286_set_time, .read_alarm = ds1286_read_alarm, .set_alarm = ds1286_set_alarm, + .alarm_irq_enable = ds1286_alarm_irq_enable, }; -static int __devinit ds1286_probe(struct platform_device *pdev) +static int ds1286_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct resource *res; struct ds1286_priv *priv; - int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; - priv = kzalloc(sizeof(struct ds1286_priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(struct ds1286_priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->size = res->end - res->start + 1; - if (!request_mem_region(res->start, priv->size, pdev->name)) { - ret = -EBUSY; - goto out; - } - priv->baseaddr = res->start; - priv->rtcregs = ioremap(priv->baseaddr, priv->size); - if (!priv->rtcregs) { - ret = -ENOMEM; - goto out; - } + priv->rtcregs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->rtcregs)) + return PTR_ERR(priv->rtcregs); + spin_lock_init(&priv->lock); - rtc = rtc_device_register("ds1286", &pdev->dev, - &ds1286_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto out; - } - priv->rtc = rtc; platform_set_drvdata(pdev, priv); - return 0; - -out: - if (priv->rtc) - rtc_device_unregister(priv->rtc); - if (priv->rtcregs) - iounmap(priv->rtcregs); - if (priv->baseaddr) - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); - return ret; -} - -static int __devexit ds1286_remove(struct platform_device *pdev) -{ - struct ds1286_priv *priv = platform_get_drvdata(pdev); - - rtc_device_unregister(priv->rtc); - iounmap(priv->rtcregs); - release_mem_region(priv->baseaddr, priv->size); - kfree(priv); + rtc = devm_rtc_device_register(&pdev->dev, "ds1286", &ds1286_ops, + THIS_MODULE); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + priv->rtc = rtc; return 0; } @@ -387,24 +359,12 @@ static struct platform_driver ds1286_platform_driver = { .owner = THIS_MODULE, }, .probe = ds1286_probe, - .remove = __devexit_p(ds1286_remove), }; -static int __init ds1286_init(void) -{ - return platform_driver_register(&ds1286_platform_driver); -} - -static void __exit ds1286_exit(void) -{ - platform_driver_unregister(&ds1286_platform_driver); -} +module_platform_driver(ds1286_platform_driver); MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); MODULE_DESCRIPTION("DS1286 RTC driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:rtc-ds1286"); - -module_init(ds1286_init); -module_exit(ds1286_exit); |
