diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 10:22:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 10:22:27 -0700 |
commit | fbe173e3ffbd897b5a859020d714c0eaf4af2a1a (patch) | |
tree | 602fd9da34454d934fcee56b8a74ebed05ba7d1c /drivers/rtc/rtc-cmos.c | |
parent | 5e630afdcb82779f5bf03fd4a5e86adc56fe7c8a (diff) | |
parent | 1485991c024603b2fb4ae77beb7a0d741128a48e (diff) | |
download | linux-fbe173e3ffbd897b5a859020d714c0eaf4af2a1a.tar.bz2 |
Merge tag 'rtc-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"This contains a few series that have been in preparation for a while
and that will help systems with RTCs that will fail in 2038, 2069 or
2100.
Subsystem:
- Add tracepoints
- Rework of the RTC/nvmem API to allow drivers to discard struct
nvmem_config after registration
- New range API, drivers can now expose the useful range of the RTC
- New offset API the core is now able to add an offset to the RTC
time, modifying the supported range.
- Multiple rtc_time64_to_tm fixes
- Handle time_t overflow on 32 bit platforms in the core instead of
letting drivers do crazy things.
- remove rtc_control API
New driver:
- Intersil ISL12026
Drivers:
- Drivers exposing the RTC non volatile memory have been converted to
use nvmem
- Removed useless time and date validation
- Removed an indirection pattern that was a cargo cult from ancient
drivers
- Removed VLA usage
- Fixed a possible race condition in probe functions
- AB8540 support is dropped from ab8500
- pcf85363 now has alarm support"
* tag 'rtc-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (128 commits)
rtc: snvs: Fix usage of snvs_rtc_enable
rtc: mt7622: fix module autoloading for OF platform drivers
rtc: isl12022: use true and false for boolean values
rtc: ab8500: Drop AB8540 support
rtc: remove a warning during scripts/kernel-doc step
rtc: 88pm860x: remove artificial limitation
rtc: 88pm80x: remove artificial limitation
rtc: st-lpc: remove artificial limitation
rtc: mrst: remove artificial limitation
rtc: mv: remove artificial limitation
rtc: hctosys: Ensure system time doesn't overflow time_t
parisc: time: stop validating rtc_time in .read_time
rtc: pcf85063: fix clearing bits in pcf85063_start_clock
rtc: at91sam9: Set name of regmap_config
rtc: s5m: Remove VLA usage
rtc: s5m: Move enum from rtc.h to rtc-s5m.c
rtc: remove VLA usage
rtc: Add useful timestamp definitions
rtc: Add one offset seconds to expand RTC range
rtc: Factor out the RTC range validation into rtc_valid_range()
...
Diffstat (limited to 'drivers/rtc/rtc-cmos.c')
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 87 |
1 files changed, 33 insertions, 54 deletions
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index f7c0f72abb56..1b3738a11702 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -541,11 +541,10 @@ static const struct rtc_class_ops cmos_rtc_ops = { #define NVRAM_OFFSET (RTC_REG_D + 1) -static ssize_t -cmos_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static int cmos_nvram_read(void *priv, unsigned int off, void *val, + size_t count) { + unsigned char *buf = val; int retval; off += NVRAM_OFFSET; @@ -563,16 +562,13 @@ cmos_nvram_read(struct file *filp, struct kobject *kobj, return retval; } -static ssize_t -cmos_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static int cmos_nvram_write(void *priv, unsigned int off, void *val, + size_t count) { - struct cmos_rtc *cmos; + struct cmos_rtc *cmos = priv; + unsigned char *buf = val; int retval; - cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); - /* NOTE: on at least PCs and Ataris, the boot firmware uses a * checksum on part of the NVRAM data. That's currently ignored * here. If userspace is smart enough to know what fields of @@ -598,17 +594,6 @@ cmos_nvram_write(struct file *filp, struct kobject *kobj, return retval; } -static struct bin_attribute nvram = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - - .read = cmos_nvram_read, - .write = cmos_nvram_write, - /* size gets set up later */ -}; - /*----------------------------------------------------------------*/ static struct cmos_rtc cmos_rtc; @@ -675,6 +660,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) unsigned char rtc_control; unsigned address_space; u32 flags = 0; + struct nvmem_config nvmem_cfg = { + .name = "cmos_nvram", + .word_size = 1, + .stride = 1, + .reg_read = cmos_nvram_read, + .reg_write = cmos_nvram_write, + .priv = &cmos_rtc, + }; /* there can be only one ... */ if (cmos_rtc.dev) @@ -751,8 +744,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) cmos_rtc.dev = dev; dev_set_drvdata(dev, &cmos_rtc); - cmos_rtc.rtc = rtc_device_register(driver_name, dev, - &cmos_rtc_ops, THIS_MODULE); + cmos_rtc.rtc = devm_rtc_allocate_device(dev); if (IS_ERR(cmos_rtc.rtc)) { retval = PTR_ERR(cmos_rtc.rtc); goto cleanup0; @@ -814,22 +806,25 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) } } - /* export at least the first block of NVRAM */ - nvram.size = address_space - NVRAM_OFFSET; - retval = sysfs_create_bin_file(&dev->kobj, &nvram); - if (retval < 0) { - dev_dbg(dev, "can't create nvram file? %d\n", retval); + cmos_rtc.rtc->ops = &cmos_rtc_ops; + cmos_rtc.rtc->nvram_old_abi = true; + retval = rtc_register_device(cmos_rtc.rtc); + if (retval) goto cleanup2; - } - dev_info(dev, "%s%s, %zd bytes nvram%s\n", - !is_valid_irq(rtc_irq) ? "no alarms" : - cmos_rtc.mon_alrm ? "alarms up to one year" : - cmos_rtc.day_alrm ? "alarms up to one month" : - "alarms up to one day", - cmos_rtc.century ? ", y3k" : "", - nvram.size, - is_hpet_enabled() ? ", hpet irqs" : ""); + /* export at least the first block of NVRAM */ + nvmem_cfg.size = address_space - NVRAM_OFFSET; + if (rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg)) + dev_err(dev, "nvmem registration failed\n"); + + dev_info(dev, "%s%s, %d bytes nvram%s\n", + !is_valid_irq(rtc_irq) ? "no alarms" : + cmos_rtc.mon_alrm ? "alarms up to one year" : + cmos_rtc.day_alrm ? "alarms up to one month" : + "alarms up to one day", + cmos_rtc.century ? ", y3k" : "", + nvmem_cfg.size, + is_hpet_enabled() ? ", hpet irqs" : ""); return 0; @@ -838,7 +833,6 @@ cleanup2: free_irq(rtc_irq, cmos_rtc.rtc); cleanup1: cmos_rtc.dev = NULL; - rtc_device_unregister(cmos_rtc.rtc); cleanup0: if (RTC_IOMAPPED) release_region(ports->start, resource_size(ports)); @@ -862,14 +856,11 @@ static void cmos_do_remove(struct device *dev) cmos_do_shutdown(cmos->irq); - sysfs_remove_bin_file(&dev->kobj, &nvram); - if (is_valid_irq(cmos->irq)) { free_irq(cmos->irq, cmos->rtc); hpet_unregister_irq_handler(cmos_interrupt); } - rtc_device_unregister(cmos->rtc); cmos->rtc = NULL; ports = cmos->iomem; @@ -1271,8 +1262,6 @@ MODULE_DEVICE_TABLE(of, of_cmos_match); static __init void cmos_of_init(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct rtc_time time; - int ret; const __be32 *val; if (!node) @@ -1285,16 +1274,6 @@ static __init void cmos_of_init(struct platform_device *pdev) val = of_get_property(node, "freq-reg", NULL); if (val) CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); - - cmos_read_time(&pdev->dev, &time); - ret = rtc_valid_tm(&time); - if (ret) { - struct rtc_time def_time = { - .tm_year = 1, - .tm_mday = 1, - }; - cmos_set_time(&pdev->dev, &def_time); - } } #else static inline void cmos_of_init(struct platform_device *pdev) {} |