diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1305.c')
| -rw-r--r-- | drivers/rtc/rtc-ds1305.c | 153 |
1 files changed, 56 insertions, 97 deletions
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 9630e7d3314..129add77065 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -11,11 +11,13 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/bcd.h> +#include <linux/slab.h> #include <linux/rtc.h> #include <linux/workqueue.h> #include <linux/spi/spi.h> #include <linux/spi/ds1305.h> +#include <linux/module.h> /* @@ -138,49 +140,32 @@ static u8 hour2bcd(bool hr12, int hour) * Interface to RTC framework */ -#ifdef CONFIG_RTC_INTF_DEV - -/* - * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) - */ -static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) +static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct ds1305 *ds1305 = dev_get_drvdata(dev); u8 buf[2]; - int status = -ENOIOCTLCMD; + long err = -EINVAL; buf[0] = DS1305_WRITE | DS1305_CONTROL; buf[1] = ds1305->ctrl[0]; - switch (cmd) { - case RTC_AIE_OFF: - status = 0; - if (!(buf[1] & DS1305_AEI0)) - goto done; - buf[1] &= ~DS1305_AEI0; - break; - - case RTC_AIE_ON: - status = 0; + if (enabled) { if (ds1305->ctrl[0] & DS1305_AEI0) goto done; buf[1] |= DS1305_AEI0; - break; - } - if (status == 0) { - status = spi_write_then_read(ds1305->spi, buf, sizeof buf, - NULL, 0); - if (status >= 0) - ds1305->ctrl[0] = buf[1]; + } else { + if (!(buf[1] & DS1305_AEI0)) + goto done; + buf[1] &= ~DS1305_AEI0; } - + err = spi_write_then_read(ds1305->spi, buf, sizeof(buf), NULL, 0); + if (err >= 0) + ds1305->ctrl[0] = buf[1]; done: - return status; + return err; + } -#else -#define ds1305_ioctl NULL -#endif /* * Get/set of date and time is pretty normal. @@ -196,8 +181,8 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time) /* Use write-then-read to get all the date/time registers * since dma from stack is nonportable */ - status = spi_write_then_read(ds1305->spi, &addr, sizeof addr, - buf, sizeof buf); + status = spi_write_then_read(ds1305->spi, &addr, sizeof(addr), + buf, sizeof(buf)); if (status < 0) return status; @@ -252,7 +237,7 @@ static int ds1305_set_time(struct device *dev, struct rtc_time *time) buf[4], buf[5], buf[6], buf[7]); /* use write-then-read since dma from stack is nonportable */ - return spi_write_then_read(ds1305->spi, buf, sizeof buf, + return spi_write_then_read(ds1305->spi, buf, sizeof(buf), NULL, 0); } @@ -301,8 +286,8 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) * of EFI status is at best fragile anyway (given IRQ handlers). */ addr = DS1305_CONTROL; - status = spi_write_then_read(spi, &addr, sizeof addr, - ds1305->ctrl, sizeof ds1305->ctrl); + status = spi_write_then_read(spi, &addr, sizeof(addr), + ds1305->ctrl, sizeof(ds1305->ctrl)); if (status < 0) return status; @@ -311,8 +296,8 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) /* get and check ALM0 registers */ addr = DS1305_ALM0(DS1305_SEC); - status = spi_write_then_read(spi, &addr, sizeof addr, - buf, sizeof buf); + status = spi_write_then_read(spi, &addr, sizeof(addr), + buf, sizeof(buf)); if (status < 0) return status; @@ -396,7 +381,7 @@ static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm) "alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN], buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]); - status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); + status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0); if (status < 0) return status; @@ -459,12 +444,12 @@ done: #endif static const struct rtc_class_ops ds1305_ops = { - .ioctl = ds1305_ioctl, .read_time = ds1305_get_time, .set_time = ds1305_set_time, .read_alarm = ds1305_get_alarm, .set_alarm = ds1305_set_alarm, .proc = ds1305_proc, + .alarm_irq_enable = ds1305_alarm_irq_enable, }; static void ds1305_work(struct work_struct *work) @@ -489,7 +474,7 @@ static void ds1305_work(struct work_struct *work) buf[1] = ds1305->ctrl[0]; buf[2] = 0; - status = spi_write_then_read(spi, buf, sizeof buf, + status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0); if (status < 0) dev_dbg(&spi->dev, "clear irq --> %d\n", status); @@ -541,7 +526,8 @@ static void msg_init(struct spi_message *m, struct spi_transfer *x, } static ssize_t -ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; @@ -571,7 +557,8 @@ ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr, } static ssize_t -ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, +ds1305_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct spi_device *spi; @@ -614,12 +601,12 @@ static struct bin_attribute nvram = { * Interface to SPI stack */ -static int __devinit ds1305_probe(struct spi_device *spi) +static int ds1305_probe(struct spi_device *spi) { struct ds1305 *ds1305; int status; u8 addr, value; - struct ds1305_platform_data *pdata = spi->dev.platform_data; + struct ds1305_platform_data *pdata = dev_get_platdata(&spi->dev); bool write_ctrl = false; /* Sanity check board setup data. This may be hooked up @@ -632,7 +619,7 @@ static int __devinit ds1305_probe(struct spi_device *spi) return -EINVAL; /* set up driver data */ - ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL); + ds1305 = devm_kzalloc(&spi->dev, sizeof(*ds1305), GFP_KERNEL); if (!ds1305) return -ENOMEM; ds1305->spi = spi; @@ -640,17 +627,15 @@ static int __devinit ds1305_probe(struct spi_device *spi) /* read and cache control registers */ addr = DS1305_CONTROL; - status = spi_write_then_read(spi, &addr, sizeof addr, - ds1305->ctrl, sizeof ds1305->ctrl); + status = spi_write_then_read(spi, &addr, sizeof(addr), + ds1305->ctrl, sizeof(ds1305->ctrl)); if (status < 0) { dev_dbg(&spi->dev, "can't %s, %d\n", "read", status); - goto fail0; + return status; } - dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", - "read", ds1305->ctrl[0], - ds1305->ctrl[1], ds1305->ctrl[2]); + dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "read", ds1305->ctrl); /* Sanity check register values ... partially compensating for the * fact that SPI has no device handshake. A pullup on MISO would @@ -659,8 +644,7 @@ static int __devinit ds1305_probe(struct spi_device *spi) */ if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) { dev_dbg(&spi->dev, "RTC chip is not present\n"); - status = -ENODEV; - goto fail0; + return -ENODEV; } if (ds1305->ctrl[2] == 0) dev_dbg(&spi->dev, "chip may not be present\n"); @@ -675,11 +659,11 @@ static int __devinit ds1305_probe(struct spi_device *spi) buf[0] = DS1305_WRITE | DS1305_CONTROL; buf[1] = ds1305->ctrl[0]; - status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); + status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0); dev_dbg(&spi->dev, "clear WP --> %d\n", status); if (status < 0) - goto fail0; + return status; } /* on DS1305, maybe start oscillator; like most low power @@ -729,25 +713,23 @@ static int __devinit ds1305_probe(struct spi_device *spi) buf[1] = ds1305->ctrl[0]; buf[2] = ds1305->ctrl[1]; buf[3] = ds1305->ctrl[2]; - status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0); + status = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0); if (status < 0) { dev_dbg(&spi->dev, "can't %s, %d\n", "write", status); - goto fail0; + return status; } - dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n", - "write", ds1305->ctrl[0], - ds1305->ctrl[1], ds1305->ctrl[2]); + dev_dbg(&spi->dev, "ctrl %s: %3ph\n", "write", ds1305->ctrl); } /* see if non-Linux software set up AM/PM mode */ addr = DS1305_HOUR; - status = spi_write_then_read(spi, &addr, sizeof addr, - &value, sizeof value); + status = spi_write_then_read(spi, &addr, sizeof(addr), + &value, sizeof(value)); if (status < 0) { dev_dbg(&spi->dev, "read HOUR --> %d\n", status); - goto fail0; + return status; } ds1305->hr12 = (DS1305_HR_12 & value) != 0; @@ -755,12 +737,12 @@ static int __devinit ds1305_probe(struct spi_device *spi) dev_dbg(&spi->dev, "AM/PM\n"); /* register RTC ... from here on, ds1305->ctrl needs locking */ - ds1305->rtc = rtc_device_register("ds1305", &spi->dev, + ds1305->rtc = devm_rtc_device_register(&spi->dev, "ds1305", &ds1305_ops, THIS_MODULE); if (IS_ERR(ds1305->rtc)) { status = PTR_ERR(ds1305->rtc); dev_dbg(&spi->dev, "register rtc --> %d\n", status); - goto fail0; + return status; } /* Maybe set up alarm IRQ; be ready to handle it triggering right @@ -771,36 +753,26 @@ static int __devinit ds1305_probe(struct spi_device *spi) */ if (spi->irq) { INIT_WORK(&ds1305->work, ds1305_work); - status = request_irq(spi->irq, ds1305_irq, + status = devm_request_irq(&spi->dev, spi->irq, ds1305_irq, 0, dev_name(&ds1305->rtc->dev), ds1305); if (status < 0) { - dev_dbg(&spi->dev, "request_irq %d --> %d\n", + dev_err(&spi->dev, "request_irq %d --> %d\n", spi->irq, status); - goto fail1; + } else { + device_set_wakeup_capable(&spi->dev, 1); } - - device_set_wakeup_capable(&spi->dev, 1); } /* export NVRAM */ status = sysfs_create_bin_file(&spi->dev.kobj, &nvram); if (status < 0) { - dev_dbg(&spi->dev, "register nvram --> %d\n", status); - goto fail2; + dev_err(&spi->dev, "register nvram --> %d\n", status); } return 0; - -fail2: - free_irq(spi->irq, ds1305); -fail1: - rtc_device_unregister(ds1305->rtc); -fail0: - kfree(ds1305); - return status; } -static int __devexit ds1305_remove(struct spi_device *spi) +static int ds1305_remove(struct spi_device *spi) { struct ds1305 *ds1305 = spi_get_drvdata(spi); @@ -809,13 +781,10 @@ static int __devexit ds1305_remove(struct spi_device *spi) /* carefully shut down irq and workqueue, if present */ if (spi->irq) { set_bit(FLAG_EXITING, &ds1305->flags); - free_irq(spi->irq, ds1305); - flush_scheduled_work(); + devm_free_irq(&spi->dev, spi->irq, ds1305); + cancel_work_sync(&ds1305->work); } - rtc_device_unregister(ds1305->rtc); - spi_set_drvdata(spi, NULL); - kfree(ds1305); return 0; } @@ -823,21 +792,11 @@ static struct spi_driver ds1305_driver = { .driver.name = "rtc-ds1305", .driver.owner = THIS_MODULE, .probe = ds1305_probe, - .remove = __devexit_p(ds1305_remove), + .remove = ds1305_remove, /* REVISIT add suspend/resume */ }; -static int __init ds1305_init(void) -{ - return spi_register_driver(&ds1305_driver); -} -module_init(ds1305_init); - -static void __exit ds1305_exit(void) -{ - spi_unregister_driver(&ds1305_driver); -} -module_exit(ds1305_exit); +module_spi_driver(ds1305_driver); MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips"); MODULE_LICENSE("GPL"); |
