diff options
Diffstat (limited to 'drivers/rtc/rtc-m48t59.c')
| -rw-r--r-- | drivers/rtc/rtc-m48t59.c | 168 |
1 files changed, 61 insertions, 107 deletions
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index d99a705bec07..4e608bc8bbd3 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ST M48T59 RTC driver * * Copyright (c) 2007 Wind River Systems, Inc. * * Author: Mark Zhan <rongkai.zhan@windriver.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/kernel.h> @@ -47,8 +44,7 @@ struct m48t59_private { static void m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); writeb(val, m48t59->ioaddr+ofs); } @@ -56,8 +52,7 @@ m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val) static u8 m48t59_mem_readb(struct device *dev, u32 ofs) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); return readb(m48t59->ioaddr+ofs); } @@ -67,9 +62,8 @@ m48t59_mem_readb(struct device *dev, u32 ofs) */ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_plat_data *pdata = dev_get_platdata(dev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); unsigned long flags; u8 val; @@ -77,7 +71,7 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) /* Issue the READ command */ M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); - tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); + tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)) + pdata->yy_offset; /* tm_mon is 0-11 */ tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; tm->tm_mday = bcd2bin(M48T59_READ(M48T59_MDAY)); @@ -88,10 +82,6 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) dev_dbg(dev, "Century bit is enabled\n"); tm->tm_year += 100; /* one century */ } -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - tm->tm_year += 68; -#endif tm->tm_wday = bcd2bin(val & 0x07); tm->tm_hour = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F); @@ -102,25 +92,17 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL); spin_unlock_irqrestore(&m48t59->lock, flags); - dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n", - tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - return rtc_valid_tm(tm); + dev_dbg(dev, "RTC read time %ptR\n", tm); + return 0; } static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_plat_data *pdata = dev_get_platdata(dev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); unsigned long flags; u8 val = 0; - int year = tm->tm_year; - -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - year -= 68; -#endif + int year = tm->tm_year - pdata->yy_offset; dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n", year + 1900, tm->tm_mon, tm->tm_mday, @@ -141,7 +123,7 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH); M48T59_WRITE(bin2bcd(year % 100), M48T59_YEAR); - if (pdata->type == M48T59RTC_TYPE_M48T59 && (year / 100)) + if (pdata->type == M48T59RTC_TYPE_M48T59 && (year >= 100)) val = (M48T59_WDAY_CEB | M48T59_WDAY_CB); val |= (bin2bcd(tm->tm_wday) & 0x07); M48T59_WRITE(val, M48T59_WDAY); @@ -157,9 +139,8 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) */ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_plat_data *pdata = dev_get_platdata(dev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); struct rtc_time *tm = &alrm->time; unsigned long flags; u8 val; @@ -172,11 +153,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) /* Issue the READ command */ M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); - tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - tm->tm_year += 68; -#endif + tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)) + pdata->yy_offset; /* tm_mon is 0-11 */ tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; @@ -193,9 +170,7 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL); spin_unlock_irqrestore(&m48t59->lock, flags); - dev_dbg(dev, "RTC read alarm time %04d-%02d-%02d %02d/%02d/%02d\n", - tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); + dev_dbg(dev, "RTC read alarm time %ptR\n", tm); return rtc_valid_tm(tm); } @@ -204,18 +179,12 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) */ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_plat_data *pdata = dev_get_platdata(dev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); struct rtc_time *tm = &alrm->time; u8 mday, hour, min, sec; unsigned long flags; - int year = tm->tm_year; - -#ifdef CONFIG_SPARC - /* Sun SPARC machines count years since 1968 */ - year -= 68; -#endif + int year = tm->tm_year - pdata->yy_offset; /* If no irq, we don't support ALARM */ if (m48t59->irq == NO_IRQ) @@ -265,9 +234,8 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) */ static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_plat_data *pdata = dev_get_platdata(dev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); unsigned long flags; spin_lock_irqsave(&m48t59->lock, flags); @@ -282,9 +250,8 @@ static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) { - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_plat_data *pdata = dev_get_platdata(dev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); unsigned long flags; u8 val; @@ -303,9 +270,8 @@ static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id) { struct device *dev = (struct device *)dev_id; - struct platform_device *pdev = to_platform_device(dev); - struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct m48t59_private *m48t59 = platform_get_drvdata(pdev); + struct m48t59_plat_data *pdata = dev_get_platdata(dev); + struct m48t59_private *m48t59 = dev_get_drvdata(dev); u8 event; spin_lock(&m48t59->lock); @@ -329,21 +295,16 @@ static const struct rtc_class_ops m48t59_rtc_ops = { .alarm_irq_enable = m48t59_rtc_alarm_irq_enable, }; -static const struct rtc_class_ops m48t02_rtc_ops = { - .read_time = m48t59_rtc_read_time, - .set_time = m48t59_rtc_set_time, -}; - -static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int m48t59_nvram_read(void *priv, unsigned int offset, void *val, + size_t size) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); + struct platform_device *pdev = priv; + struct device *dev = &pdev->dev; struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = platform_get_drvdata(pdev); ssize_t cnt = 0; unsigned long flags; + u8 *buf = val; spin_lock_irqsave(&m48t59->lock, flags); @@ -352,19 +313,19 @@ static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, spin_unlock_irqrestore(&m48t59->lock, flags); - return cnt; + return 0; } -static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int m48t59_nvram_write(void *priv, unsigned int offset, void *val, + size_t size) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); + struct platform_device *pdev = priv; + struct device *dev = &pdev->dev; struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = platform_get_drvdata(pdev); ssize_t cnt = 0; unsigned long flags; + u8 *buf = val; spin_lock_irqsave(&m48t59->lock, flags); @@ -373,26 +334,23 @@ static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, spin_unlock_irqrestore(&m48t59->lock, flags); - return cnt; + return 0; } -static struct bin_attribute m48t59_nvram_attr = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - .read = m48t59_nvram_read, - .write = m48t59_nvram_write, -}; - static int m48t59_rtc_probe(struct platform_device *pdev) { struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = NULL; struct resource *res; int ret = -ENOMEM; - char *name; - const struct rtc_class_ops *ops; + struct nvmem_config nvmem_cfg = { + .name = "m48t59-", + .word_size = 1, + .stride = 1, + .reg_read = m48t59_nvram_read, + .reg_write = m48t59_nvram_write, + .priv = pdev, + }; /* This chip could be memory-mapped or I/O-mapped */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -445,7 +403,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev) /* Try to get irq number. We also can work in * the mode without IRQ. */ - m48t59->irq = platform_get_irq(pdev, 0); + m48t59->irq = platform_get_irq_optional(pdev, 0); if (m48t59->irq <= 0) m48t59->irq = NO_IRQ; @@ -456,20 +414,21 @@ static int m48t59_rtc_probe(struct platform_device *pdev) if (ret) return ret; } + + m48t59->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(m48t59->rtc)) + return PTR_ERR(m48t59->rtc); + switch (pdata->type) { case M48T59RTC_TYPE_M48T59: - name = "m48t59"; - ops = &m48t59_rtc_ops; pdata->offset = 0x1ff0; break; case M48T59RTC_TYPE_M48T02: - name = "m48t02"; - ops = &m48t02_rtc_ops; + clear_bit(RTC_FEATURE_ALARM, m48t59->rtc->features); pdata->offset = 0x7f0; break; case M48T59RTC_TYPE_M48T08: - name = "m48t08"; - ops = &m48t02_rtc_ops; + clear_bit(RTC_FEATURE_ALARM, m48t59->rtc->features); pdata->offset = 0x1ff0; break; default: @@ -480,23 +439,19 @@ static int m48t59_rtc_probe(struct platform_device *pdev) spin_lock_init(&m48t59->lock); platform_set_drvdata(pdev, m48t59); - m48t59->rtc = devm_rtc_device_register(&pdev->dev, name, ops, - THIS_MODULE); - if (IS_ERR(m48t59->rtc)) - return PTR_ERR(m48t59->rtc); - - m48t59_nvram_attr.size = pdata->offset; + m48t59->rtc->ops = &m48t59_rtc_ops; + m48t59->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900; + m48t59->rtc->range_max = RTC_TIMESTAMP_END_2099; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); + nvmem_cfg.size = pdata->offset; + ret = devm_rtc_nvmem_register(m48t59->rtc, &nvmem_cfg); if (ret) return ret; - return 0; -} + ret = devm_rtc_register_device(m48t59->rtc); + if (ret) + return ret; -static int m48t59_rtc_remove(struct platform_device *pdev) -{ - sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); return 0; } @@ -508,7 +463,6 @@ static struct platform_driver m48t59_rtc_driver = { .name = "rtc-m48t59", }, .probe = m48t59_rtc_probe, - .remove = m48t59_rtc_remove, }; module_platform_driver(m48t59_rtc_driver); |
