Commit 3a00be19 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'rtc-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "Here is the pull-request for the RTC subsystem for 4.13.

  Subsystem:

   - expose non volatile RAM using nvmem instead of open coding in many
     drivers. Unfortunately, this option has to be enabled by default to
     not break existing users.

   - rtctest can now test for cutoff dates, showing when an RTC will
     start failing to properly save time and date.

   - new RTC registration functions to remove race conditions in drivers

  Newly supported RTCs:

   - Broadcom STB wake-timer

   - Epson RX8130CE

   - Maxim IC DS1308

   - STMicroelectronics STM32H7

  Drivers:

   - ds1307: use regmap, use nvmem, more cleanups

   - ds3232: temperature reading support

   - gemini: renamed to ftrtc010

   - m41t80: use CCF to expose the clock

   - rv8803: use nvmem

   - s3c: many cleanups

   - st-lpc: fix y2106 bug"

* tag 'rtc-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (51 commits)
  rtc: Remove wrong deprecation comment
  nvmem: include linux/err.h from header
  rtc: st-lpc: make it robust against y2038/2106 bug
  rtc: rtctest: add check for problematic dates
  tools: timer: add rtctest_setdate
  rtc: ds1307: remove ds1307_remove
  rtc: ds1307: use generic nvmem
  rtc: ds1307: switch to rtc_register_device
  rtc: rv8803: remove rv8803_remove
  rtc: rv8803: use generic nvmem support
  rtc: rv8803: switch to rtc_register_device
  rtc: add generic nvmem support
  rtc: at91rm9200: remove race condition
  rtc: introduce new registration method
  rtc: class separate id allocation from registration
  rtc: class separate device allocation from registration
  rtc: stm32: add STM32H7 RTC support
  dt-bindings: rtc: stm32: add support for STM32H7
  rtc: ds1307: add ds1308 variant
  rtc: ds3232: add temperature support
  ...
parents b5e16170 40bf6a35
Broadcom STB wake-up Timer
The Broadcom STB wake-up timer provides a 27Mhz resolution timer, with the
ability to wake up the system from low-power suspend/standby modes.
Required properties:
- compatible : should contain "brcm,brcmstb-waketimer"
- reg : the register start and length for the WKTMR block
- interrupts : The TIMER interrupt
- interrupt-parent: The phandle to the Always-On (AON) Power Management (PM) L2
interrupt controller node
- clocks : The phandle to the UPG fixed clock (27Mhz domain)
Example:
waketimer@f0411580 {
compatible = "brcm,brcmstb-waketimer";
reg = <0xf0411580 0x14>;
interrupts = <0x3>;
interrupt-parent = <&aon_pm_l2_intc>;
clocks = <&upg_fixed>;
};
* Cortina Systems Gemini RTC
Gemini SoC real-time clock.
Required properties:
- compatible : Should be "cortina,gemini-rtc"
Examples:
rtc@45000000 {
compatible = "cortina,gemini-rtc";
reg = <0x45000000 0x100>;
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
};
* Faraday Technology FTRTC010 Real Time Clock
This RTC appears in for example the Storlink Gemini family of
SoCs.
Required properties:
- compatible : Should be one of:
"faraday,ftrtc010"
"cortina,gemini-rtc", "faraday,ftrtc010"
Optional properties:
- clocks: when present should contain clock references to the
PCLK and EXTCLK clocks. Faraday calls the later CLK1HZ and
says the clock should be 1 Hz, but implementers actually seem
to choose different clocks here, like Cortina who chose
32768 Hz (a typical low-power clock).
- clock-names: should name the clocks "PCLK" and "EXTCLK"
respectively.
Examples:
rtc@45000000 {
compatible = "cortina,gemini-rtc";
reg = <0x45000000 0x100>;
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&foo 0>, <&foo 1>;
clock-names = "PCLK", "EXTCLK";
};
STM32 Real Time Clock
Required properties:
- compatible: "st,stm32-rtc".
- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
the device is compatible with stm32(f4/f7) or stm32h7.
- reg: address range of rtc register set.
- clocks: reference to the clock entry ck_rtc.
- clocks: can use up to two clocks, depending on part used:
- "rtc_ck": RTC clock source.
It is required on stm32(f4/f7) and stm32h7.
- "pclk": RTC APB interface clock.
It is not present on stm32(f4/f7).
It is required on stm32h7.
- clock-names: must be "rtc_ck" and "pclk".
It is required only on stm32h7.
- interrupt-parent: phandle for the interrupt controller.
- interrupts: rtc alarm interrupt.
- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain
(RTC registers) write protection.
Optional properties (to override default ck_rtc parent clock):
- assigned-clocks: reference to the ck_rtc clock entry.
- assigned-clock-parents: phandle of the new parent clock of ck_rtc.
Optional properties (to override default rtc_ck parent clock):
- assigned-clocks: reference to the rtc_ck clock entry.
- assigned-clock-parents: phandle of the new parent clock of rtc_ck.
Example:
......@@ -25,3 +33,17 @@ Example:
interrupts = <17 1>;
st,syscfg = <&pwrcfg>;
};
rtc: rtc@58004000 {
compatible = "st,stm32h7-rtc";
reg = <0x58004000 0x400>;
clocks = <&rcc RTCAPB_CK>, <&rcc RTC_CK>;
clock-names = "pclk", "rtc_ck";
assigned-clocks = <&rcc RTC_CK>;
assigned-clock-parents = <&rcc LSE_CK>;
interrupt-parent = <&exti>;
interrupts = <17 1>;
interrupt-names = "alarm";
st,syscfg = <&pwrcfg>;
status = "disabled";
};
Real Time Clock (RTC) Drivers for Linux
=======================================
=======================================
Real Time Clock (RTC) Drivers for Linux
=======================================
When Linux developers talk about a "Real Time Clock", they usually mean
something that tracks wall clock time and is battery backed so that it
......@@ -32,8 +32,8 @@ only issue an alarm up to 24 hours in the future, other hardware may
be able to schedule one any time in the upcoming century.
Old PC/AT-Compatible driver: /dev/rtc
--------------------------------------
Old PC/AT-Compatible driver: /dev/rtc
--------------------------------------
All PCs (even Alpha machines) have a Real Time Clock built into them.
Usually they are built into the chipset of the computer, but some may
......@@ -105,8 +105,8 @@ that will be using this driver. See the code at the end of this document.
(The original /dev/rtc driver was written by Paul Gortmaker.)
New portable "RTC Class" drivers: /dev/rtcN
--------------------------------------------
New portable "RTC Class" drivers: /dev/rtcN
--------------------------------------------
Because Linux supports many non-ACPI and non-PC platforms, some of which
have more than one RTC style clock, it needed a more portable solution
......@@ -136,35 +136,39 @@ a high functionality RTC is integrated into the SOC. That system might read
the system clock from the discrete RTC, but use the integrated one for all
other tasks, because of its greater functionality.
SYSFS INTERFACE
SYSFS interface
---------------
The sysfs interface under /sys/class/rtc/rtcN provides access to various
rtc attributes without requiring the use of ioctls. All dates and times
are in the RTC's timezone, rather than in system time.
date: RTC-provided date
hctosys: 1 if the RTC provided the system time at boot via the
================ ==============================================================
date RTC-provided date
hctosys 1 if the RTC provided the system time at boot via the
CONFIG_RTC_HCTOSYS kernel option, 0 otherwise
max_user_freq: The maximum interrupt rate an unprivileged user may request
max_user_freq The maximum interrupt rate an unprivileged user may request
from this RTC.
name: The name of the RTC corresponding to this sysfs directory
since_epoch: The number of seconds since the epoch according to the RTC
time: RTC-provided time
wakealarm: The time at which the clock will generate a system wakeup
name The name of the RTC corresponding to this sysfs directory
since_epoch The number of seconds since the epoch according to the RTC
time RTC-provided time
wakealarm The time at which the clock will generate a system wakeup
event. This is a one shot wakeup event, so must be reset
after wake if a daily wakeup is required. Format is seconds since
the epoch by default, or if there's a leading +, seconds in the
future, or if there is a leading +=, seconds ahead of the current
alarm.
offset: The amount which the rtc clock has been adjusted in firmware.
after wake if a daily wakeup is required. Format is seconds
since the epoch by default, or if there's a leading +, seconds
in the future, or if there is a leading +=, seconds ahead of
the current alarm.
offset The amount which the rtc clock has been adjusted in firmware.
Visible only if the driver supports clock offset adjustment.
The unit is parts per billion, i.e. The number of clock ticks
which are added to or removed from the rtc's base clock per
billion ticks. A positive value makes a day pass more slowly,
longer, and a negative value makes a day pass more quickly.
*/nvmem The non volatile storage exported as a raw file, as described
in Documentation/nvmem/nvmem.txt
================ ==============================================================
IOCTL INTERFACE
IOCTL interface
---------------
The ioctl() calls supported by /dev/rtc are also supported by the RTC class
......
......@@ -1255,7 +1255,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
T: git git://github.com/ulli-kroll/linux.git
S: Maintained
F: arch/arm/mach-gemini/
F: drivers/rtc/rtc-gemini.c
F: drivers/rtc/rtc-ftrtc010.c
ARM/CSR SIRFPRIMA2 MACHINE SUPPORT
M: Barry Song <baohua@kernel.org>
......
......@@ -77,6 +77,14 @@ config RTC_DEBUG
Say yes here to enable debugging support in the RTC framework
and individual RTC drivers.
config RTC_NVMEM
bool "RTC non volatile storage support"
select NVMEM
default RTC_CLASS
help
Say yes here to add support for the non volatile (often battery
backed) storage present on RTCs.
comment "RTC interfaces"
config RTC_INTF_SYSFS
......@@ -197,6 +205,17 @@ config RTC_DRV_AC100
This driver can also be built as a module. If so, the module
will be called rtc-ac100.
config RTC_DRV_BRCMSTB
tristate "Broadcom STB wake-timer"
depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
default ARCH_BRCMSTB || BMIPS_GENERIC
help
If you say yes here you get support for the wake-timer found on
Broadcom STB SoCs (BCM7xxx).
This driver can also be built as a module. If so, the module will
be called rtc-brcmstb-waketimer.
config RTC_DRV_AS3722
tristate "ams AS3722 RTC driver"
depends on MFD_AS3722
......@@ -791,6 +810,14 @@ config RTC_DRV_DS3232
This driver can also be built as a module. If so, the module
will be called rtc-ds3232.
config RTC_DRV_DS3232_HWMON
bool "HWMON support for Dallas/Maxim DS3232/DS3234"
depends on RTC_DRV_DS3232 && HWMON && !(RTC_DRV_DS3232=y && HWMON=m)
default y
help
Say Y here if you want to expose temperature sensor data on
rtc-ds3232
config RTC_DRV_PCF2127
tristate "NXP PCF2127"
depends on RTC_I2C_AND_SPI
......@@ -1484,16 +1511,16 @@ config RTC_DRV_ARMADA38X
This driver can also be built as a module. If so, the module
will be called armada38x-rtc.
config RTC_DRV_GEMINI
tristate "Gemini SoC RTC"
depends on ARCH_GEMINI || COMPILE_TEST
config RTC_DRV_FTRTC010
tristate "Faraday Technology FTRTC010 RTC"
depends on HAS_IOMEM
default ARCH_GEMINI
help
If you say Y here you will get support for the
RTC found on Gemini SoC's.
Faraday Technolog FTRTC010 found on e.g. Gemini SoC's.
This driver can also be built as a module. If so, the module
will be called rtc-gemini.
will be called rtc-ftrtc010.
config RTC_DRV_PS3
tristate "PS3 RTC"
......
......@@ -15,6 +15,7 @@ ifdef CONFIG_RTC_DRV_EFI
rtc-core-y += rtc-efi-platform.o
endif
rtc-core-$(CONFIG_RTC_NVMEM) += nvmem.o
rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
......@@ -36,6 +37,7 @@ obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o
obj-$(CONFIG_RTC_DRV_BQ32K) += rtc-bq32k.o
obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
......@@ -67,7 +69,7 @@ obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
obj-$(CONFIG_RTC_DRV_GEMINI) += rtc-gemini.o
obj-$(CONFIG_RTC_DRV_FTRTC010) += rtc-ftrtc010.o
obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o
......
......@@ -150,59 +150,19 @@ static SIMPLE_DEV_PM_OPS(rtc_class_dev_pm_ops, rtc_suspend, rtc_resume);
#define RTC_CLASS_DEV_PM_OPS NULL
#endif
/**
* rtc_device_register - register w/ RTC class
* @dev: the device to register
*
* rtc_device_unregister() must be called when the class device is no
* longer needed.
*
* Returns the pointer to the new struct class device.
*/
struct rtc_device *rtc_device_register(const char *name, struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner)
/* Ensure the caller will set the id before releasing the device */
static struct rtc_device *rtc_allocate_device(void)
{
struct rtc_device *rtc;
struct rtc_wkalrm alrm;
int of_id = -1, id = -1, err;
if (dev->of_node)
of_id = of_alias_get_id(dev->of_node, "rtc");
else if (dev->parent && dev->parent->of_node)
of_id = of_alias_get_id(dev->parent->of_node, "rtc");
if (of_id >= 0) {
id = ida_simple_get(&rtc_ida, of_id, of_id + 1,
GFP_KERNEL);
if (id < 0)
dev_warn(dev, "/aliases ID %d not available\n",
of_id);
}
if (id < 0) {
id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
err = id;
goto exit;
}
}
rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
if (rtc == NULL) {
err = -ENOMEM;
goto exit_ida;
}
rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return NULL;
device_initialize(&rtc->dev);
rtc->id = id;
rtc->ops = ops;
rtc->owner = owner;
rtc->irq_freq = 1;
rtc->max_user_freq = 64;
rtc->dev.parent = dev;
rtc->dev.class = rtc_class;
rtc->dev.groups = rtc_get_dev_attribute_groups();
rtc->dev.release = rtc_device_release;
......@@ -224,7 +184,64 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
rtc->pie_timer.function = rtc_pie_update_irq;
rtc->pie_enabled = 0;
strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
return rtc;
}
static int rtc_device_get_id(struct device *dev)
{
int of_id = -1, id = -1;
if (dev->of_node)
of_id = of_alias_get_id(dev->of_node, "rtc");
else if (dev->parent && dev->parent->of_node)
of_id = of_alias_get_id(dev->parent->of_node, "rtc");
if (of_id >= 0) {
id = ida_simple_get(&rtc_ida, of_id, of_id + 1, GFP_KERNEL);
if (id < 0)
dev_warn(dev, "/aliases ID %d not available\n", of_id);
}
if (id < 0)
id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
return id;
}
/**
* rtc_device_register - register w/ RTC class
* @dev: the device to register
*
* rtc_device_unregister() must be called when the class device is no
* longer needed.
*
* Returns the pointer to the new struct class device.
*/
struct rtc_device *rtc_device_register(const char *name, struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner)
{
struct rtc_device *rtc;
struct rtc_wkalrm alrm;
int id, err;
id = rtc_device_get_id(dev);
if (id < 0) {
err = id;
goto exit;
}
rtc = rtc_allocate_device();
if (!rtc) {
err = -ENOMEM;
goto exit_ida;
}
rtc->id = id;
rtc->ops = ops;
rtc->owner = owner;
rtc->dev.parent = dev;
dev_set_name(&rtc->dev, "rtc%d", id);
/* Check to see if there is an ALARM already set in hw */
......@@ -238,20 +255,20 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
err = cdev_device_add(&rtc->char_dev, &rtc->dev);
if (err) {
dev_warn(&rtc->dev, "%s: failed to add char device %d:%d\n",
rtc->name, MAJOR(rtc->dev.devt), rtc->id);
name, MAJOR(rtc->dev.devt), rtc->id);
/* This will free both memory and the ID */
put_device(&rtc->dev);
goto exit;
} else {
dev_dbg(&rtc->dev, "%s: dev (%d:%d)\n", rtc->name,
dev_dbg(&rtc->dev, "%s: dev (%d:%d)\n", name,
MAJOR(rtc->dev.devt), rtc->id);
}
rtc_proc_add_device(rtc);
dev_info(dev, "rtc core: registered %s as %s\n",
rtc->name, dev_name(&rtc->dev));
name, dev_name(&rtc->dev));
return rtc;
......@@ -273,6 +290,8 @@ EXPORT_SYMBOL_GPL(rtc_device_register);
*/
void rtc_device_unregister(struct rtc_device *rtc)
{
rtc_nvmem_unregister(rtc);
mutex_lock(&rtc->ops_lock);
/*
* Remove innards of this RTC, then disable it, before
......@@ -356,6 +375,91 @@ void devm_rtc_device_unregister(struct device *dev, struct rtc_device *rtc)
}
EXPORT_SYMBOL_GPL(devm_rtc_device_unregister);
static void devm_rtc_release_device(struct device *dev, void *res)
{
struct rtc_device *rtc = *(struct rtc_device **)res;
if (rtc->registered)
rtc_device_unregister(rtc);
else
put_device(&rtc->dev);
}
struct rtc_device *devm_rtc_allocate_device(struct device *dev)
{
struct rtc_device **ptr, *rtc;
int id, err;
id = rtc_device_get_id(dev);
if (id < 0)
return ERR_PTR(id);
ptr = devres_alloc(devm_rtc_release_device, sizeof(*ptr), GFP_KERNEL);
if (!ptr) {
err = -ENOMEM;
goto exit_ida;
}
rtc = rtc_allocate_device();
if (!rtc) {
err = -ENOMEM;
goto exit_devres;
}
*ptr = rtc;
devres_add(dev, ptr);
rtc->id = id;
rtc->dev.parent = dev;
dev_set_name(&rtc->dev, "rtc%d", id);
return rtc;
exit_devres:
devres_free(ptr);
exit_ida:
ida_simple_remove(&rtc_ida, id);
return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(devm_rtc_allocate_device);
int __rtc_register_device(struct module *owner, struct rtc_device *rtc)
{
struct rtc_wkalrm alrm;
int err;
if (!rtc->ops)
return -EINVAL;
rtc->owner = owner;
/* Check to see if there is an ALARM already set in hw */
err = __rtc_read_alarm(rtc, &alrm);
if (!err && !rtc_valid_tm(&alrm.time))
rtc_initialize_alarm(rtc, &alrm);
rtc_dev_prepare(rtc);
err = cdev_device_add(&rtc->char_dev, &rtc->dev);
if (err)
dev_warn(rtc->dev.parent, "failed to add char device %d:%d\n",
MAJOR(rtc->dev.devt), rtc->id);
else
dev_dbg(rtc->dev.parent, "char device (%d:%d)\n",
MAJOR(rtc->dev.devt), rtc->id);
rtc_proc_add_device(rtc);
rtc_nvmem_register(rtc);
rtc->registered = true;
dev_info(rtc->dev.parent, "registered as %s\n",
dev_name(&rtc->dev));
return 0;
}
EXPORT_SYMBOL_GPL(__rtc_register_device);
static int __init rtc_init(void)
{
rtc_class = class_create(THIS_MODULE, "rtc");
......
......@@ -227,6 +227,13 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
missing = year;
}
/* Can't proceed if alarm is still invalid after replacing
* missing fields.
*/
err = rtc_valid_tm(&alarm->time);
if (err)
goto done;
/* with luck, no rollover is needed */
t_now = rtc_tm_to_time64(&now);
t_alm = rtc_tm_to_time64(&alarm->time);
......@@ -278,9 +285,9 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
dev_warn(&rtc->dev, "alarm rollover not handled\n");
}
done:
err = rtc_valid_tm(&alarm->time);
done:
if (err) {
dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n",
alarm->time.tm_year + 1900, alarm->time.tm_mon + 1,
......
/*
* RTC subsystem, nvmem interface
*
* Copyright (C) 2017 Alexandre Belloni
*
* 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/err.h>
#include <linux/types.h>
#include <linux/nvmem-consumer.h>
#include <linux/rtc.h>
#include <linux/sysfs.h>
#include "rtc-core.h"
/*
* Deprecated ABI compatibility, this should be removed at some point
*/
static const char nvram_warning[] = "Deprecated ABI, please use nvmem";
static ssize_t
rtc_nvram_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
struct rtc_device *rtc = attr->private;
dev_warn_once(kobj_to_dev(kobj), nvram_warning);
return nvmem_device_read(rtc->nvmem, off, count, buf);
}
static ssize_t
rtc_nvram_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
struct rtc_device *rtc = attr->private;
dev_warn_once(kobj_to_dev(kobj), nvram_warning);
return nvmem_device_write(rtc->nvmem, off, count, buf);