Commit bf644990 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull RTC updates from Alexandre Belloni:
 "Not much this cycle. I've pushed the at32ap700x removal late but it is
  unlikely to cause any issues.

  Summary:

  Subsystem:
   - Move ABI documentation to Documentation/ABI

  New driver:
   - NXP i.MX53 SRTC
   - Chrome OS EC RTC

  Drivers:
   - Remove at32ap700x
   - Many fixes in various error paths"

* tag 'rtc-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux:
  rtc: remove rtc-at32ap700x
  Documentation: rtc: move iotcl interface documentation to ABI
  Documentation: rtc: add sysfs file permissions
  Documentation: rtc: move sysfs documentation to ABI
  rtc: mxc_v2: remove __exit annotation
  rtc: mxc_v2: Remove unnecessary platform_get_resource() error check
  rtc: add mxc driver for i.MX53 SRTC
  dt-bindings: rtc: add bindings for i.MX53 SRTC
  rtc: r7301: Fix a possible sleep-in-atomic bug in rtc7301_set_time
  rtc: r7301: Fix a possible sleep-in-atomic bug in rtc7301_read_time
  rtc: omap: fix unbalanced clk_prepare_enable/clk_disable_unprepare
  rtc: ac100: Fix multiple race conditions
  rtc: sun6i: ensure rtc is kfree'd on error
  rtc: cros-ec: add cros-ec-rtc driver.
  mfd: cros_ec: Introduce RTC commands and events definitions.
  rtc: stm32: Fix copyright
  rtc: Remove unused RTC_DEVICE_NAME_SIZE
  rtc: r9701: Remove r9701_remove function
  rtc: brcmstb-waketimer: fix error handling in brcmstb_waketmr_probe()
parents b89e32cc 4402be2b
What: /dev/rtcX
Date: April 2005
KernelVersion: 2.6.12
Contact: linux-rtc@vger.kernel.org
Description:
The ioctl interface to drivers for real-time clocks (RTCs).
Following actions are supported:
* RTC_RD_TIME, RTC_SET_TIME: Read or set the RTC time. Time
format is a Gregorian calendar date and 24 hour wall clock
time.
* RTC_AIE_ON, RTC_AIE_OFF: Enable or disable the alarm interrupt
for RTCs that support alarms
* RTC_ALM_READ, RTC_ALM_SET: Read or set the alarm time for
RTCs that support alarms. Can be set upto 24 hours in the
future. Requires a separate RTC_AIE_ON call to enable the
alarm interrupt. (Prefer to use RTC_WKALM_*)
* RTC_WKALM_RD, RTC_WKALM_SET: For RTCs that support a more
powerful interface, which can issue alarms beyond 24 hours and
enable IRQs in the same request.
* RTC_PIE_ON, RTC_PIE_OFF: Enable or disable the periodic
interrupt for RTCs that support periodic interrupts.
* RTC_UIE_ON, RTC_UIE_OFF: Enable or disable the update
interrupt for RTCs that support it.
* RTC_IRQP_READ, RTC_IRQP_SET: Read or set the frequency for
periodic interrupts for RTCs that support periodic interrupts.
Requires a separate RTC_PIE_ON call to enable the periodic
interrupts.
The ioctl() calls supported by the older /dev/rtc interface are
also supported by the newer RTC class framework. However,
because the chips and systems are not standardized, some PC/AT
functionality might not be provided. And in the same way, some
newer features -- including those enabled by ACPI -- are exposed
by the RTC class framework, but can't be supported by the older
driver.
What: /sys/class/rtc/
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
The rtc/ class subdirectory belongs to the RTC subsystem.
What: /sys/class/rtc/rtcX/
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
The /sys/class/rtc/rtc{0,1,2,3,...} directories correspond
to each RTC device.
What: /sys/class/rtc/rtcX/date
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) RTC-provided date in YYYY-MM-DD format
What: /sys/class/rtc/rtcX/hctosys
Date: September 2009
KernelVersion: 2.6.32
Contact: linux-rtc@vger.kernel.org
Description:
(RO) 1 if the RTC provided the system time at boot via the
CONFIG_RTC_HCTOSYS kernel option, 0 otherwise
What: /sys/class/rtc/rtcX/max_user_freq
Date: October 2007
KernelVersion: 2.6.24
Contact: linux-rtc@vger.kernel.org
Description:
(RW) The maximum interrupt rate an unprivileged user may request
from this RTC.
What: /sys/class/rtc/rtcX/name
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) The name of the RTC corresponding to this sysfs directory
What: /sys/class/rtc/rtcX/since_epoch
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) RTC-provided time as the number of seconds since the epoch
What: /sys/class/rtc/rtcX/time
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) RTC-provided time in 24-hour notation (hh:mm:ss)
What: /sys/class/rtc/rtcX/*/nvmem
Date: February 2016
KernelVersion: 4.6
Contact: linux-rtc@vger.kernel.org
Description:
(RW) The non volatile storage exported as a raw file, as
described in Documentation/nvmem/nvmem.txt
What: /sys/class/rtc/rtcX/offset
Date: February 2016
KernelVersion: 4.6
Contact: linux-rtc@vger.kernel.org
Description:
(RW) 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.
What: /sys/class/rtc/rtcX/wakealarm
Date: February 2007
KernelVersion: 2.6.20
Contact: linux-rtc@vger.kernel.org
Description:
(RW) 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.
* i.MX53 Secure Real Time Clock (SRTC)
Required properties:
- compatible: should be: "fsl,imx53-rtc"
- reg: physical base address of the controller and length of memory mapped
region.
- clocks: should contain the phandle for the rtc clock
- interrupts: rtc alarm interrupt
Example:
rtc@53fa4000 {
compatible = "fsl,imx53-rtc";
reg = <0x53fa4000 0x4000>;
interrupts = <24>;
clocks = <&clks IMX5_CLK_SRTC_GATE>;
};
...@@ -136,82 +136,5 @@ a high functionality RTC is integrated into the SOC. That system might read ...@@ -136,82 +136,5 @@ 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 the system clock from the discrete RTC, but use the integrated one for all
other tasks, because of its greater functionality. other tasks, because of its greater functionality.
SYSFS interface Check out tools/testing/selftests/timers/rtctest.c for an example usage of the
--------------- ioctl 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
CONFIG_RTC_HCTOSYS kernel option, 0 otherwise
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
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.
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
---------------
The ioctl() calls supported by /dev/rtc are also supported by the RTC class
framework. However, because the chips and systems are not standardized,
some PC/AT functionality might not be provided. And in the same way, some
newer features -- including those enabled by ACPI -- are exposed by the
RTC class framework, but can't be supported by the older driver.
* RTC_RD_TIME, RTC_SET_TIME ... every RTC supports at least reading
time, returning the result as a Gregorian calendar date and 24 hour
wall clock time. To be most useful, this time may also be updated.
* RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC
is connected to an IRQ line, it can often issue an alarm IRQ up to
24 hours in the future. (Use RTC_WKALM_* by preference.)
* RTC_WKALM_SET, RTC_WKALM_RD ... RTCs that can issue alarms beyond
the next 24 hours use a slightly more powerful API, which supports
setting the longer alarm time and enabling its IRQ using a single
request (using the same model as EFI firmware).
* RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, the RTC framework
will emulate this mechanism.
* RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... these icotls
are emulated via a kernel hrtimer.
In many cases, the RTC alarm can be a system wake event, used to force
Linux out of a low power sleep state (or hibernation) back to a fully
operational state. For example, a system could enter a deep power saving
state until it's time to execute some scheduled tasks.
Note that many of these ioctls are handled by the common rtc-dev interface.
Some common examples:
* RTC_RD_TIME, RTC_SET_TIME: the read_time/set_time functions will be
called with appropriate values.
* RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: gets or sets
the alarm rtc_timer. May call the set_alarm driver function.
* RTC_IRQP_SET, RTC_IRQP_READ: These are emulated by the generic code.
* RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code.
If all else fails, check out the tools/testing/selftests/timers/rtctest.c test!
...@@ -1255,6 +1255,16 @@ config RTC_DRV_ZYNQMP ...@@ -1255,6 +1255,16 @@ config RTC_DRV_ZYNQMP
If you say yes here you get support for the RTC controller found on If you say yes here you get support for the RTC controller found on
Xilinx Zynq Ultrascale+ MPSoC. Xilinx Zynq Ultrascale+ MPSoC.
config RTC_DRV_CROS_EC
tristate "Chrome OS EC RTC driver"
depends on MFD_CROS_EC
help
If you say yes here you will get support for the
Chrome OS Embedded Controller's RTC.
This driver can also be built as a module. If so, the module
will be called rtc-cros-ec.
comment "on-CPU RTC drivers" comment "on-CPU RTC drivers"
config RTC_DRV_ASM9260 config RTC_DRV_ASM9260
...@@ -1392,13 +1402,6 @@ config RTC_DRV_PL031 ...@@ -1392,13 +1402,6 @@ config RTC_DRV_PL031
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called rtc-pl031. module will be called rtc-pl031.
config RTC_DRV_AT32AP700X
tristate "AT32AP700X series RTC"
depends on PLATFORM_AT32AP || COMPILE_TEST
help
Driver for the internal RTC (Realtime Clock) on Atmel AVR32
AT32AP700x family processors.
config RTC_DRV_AT91RM9200 config RTC_DRV_AT91RM9200
tristate "AT91RM9200 or some AT91SAM9 RTC" tristate "AT91RM9200 or some AT91SAM9 RTC"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
...@@ -1689,6 +1692,16 @@ config RTC_DRV_MXC ...@@ -1689,6 +1692,16 @@ config RTC_DRV_MXC
This driver can also be built as a module, if so, the module This driver can also be built as a module, if so, the module
will be called "rtc-mxc". will be called "rtc-mxc".
config RTC_DRV_MXC_V2
tristate "Freescale MXC Real Time Clock for i.MX53"
depends on ARCH_MXC
help
If you say yes here you get support for the Freescale MXC
SRTC module in i.MX53 processor.
This driver can also be built as a module, if so, the module
will be called "rtc-mxc_v2".
config RTC_DRV_SNVS config RTC_DRV_SNVS
tristate "Freescale SNVS RTC support" tristate "Freescale SNVS RTC support"
select REGMAP_MMIO select REGMAP_MMIO
......
...@@ -33,7 +33,6 @@ obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o ...@@ -33,7 +33,6 @@ obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o
obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o
obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o
obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o
obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o
obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o
...@@ -44,6 +43,7 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o ...@@ -44,6 +43,7 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o
obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o
obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o
obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o
obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o
...@@ -106,6 +106,7 @@ obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o ...@@ -106,6 +106,7 @@ obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o
obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o
obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o
obj-$(CONFIG_RTC_DRV_MXC_V2) += rtc-mxc_v2.o
obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o
......
...@@ -569,6 +569,12 @@ static int ac100_rtc_probe(struct platform_device *pdev) ...@@ -569,6 +569,12 @@ static int ac100_rtc_probe(struct platform_device *pdev)
return chip->irq; return chip->irq;
} }
chip->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(chip->rtc))
return PTR_ERR(chip->rtc);
chip->rtc->ops = &ac100_rtc_ops;
ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL, ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL,
ac100_rtc_irq, ac100_rtc_irq,
IRQF_SHARED | IRQF_ONESHOT, IRQF_SHARED | IRQF_ONESHOT,
...@@ -588,17 +594,16 @@ static int ac100_rtc_probe(struct platform_device *pdev) ...@@ -588,17 +594,16 @@ static int ac100_rtc_probe(struct platform_device *pdev)
/* clear counter alarm pending interrupts */ /* clear counter alarm pending interrupts */
regmap_write(chip->regmap, AC100_ALM_INT_STA, AC100_ALM_INT_ENABLE); regmap_write(chip->regmap, AC100_ALM_INT_STA, AC100_ALM_INT_ENABLE);
chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-ac100",
&ac100_rtc_ops, THIS_MODULE);
if (IS_ERR(chip->rtc)) {
dev_err(&pdev->dev, "unable to register device\n");
return PTR_ERR(chip->rtc);
}
ret = ac100_rtc_register_clks(chip); ret = ac100_rtc_register_clks(chip);
if (ret) if (ret)
return ret; return ret;
ret = rtc_register_device(chip->rtc);
if (ret) {
dev_err(&pdev->dev, "unable to register device\n");
return ret;
}
dev_info(&pdev->dev, "RTC enabled\n"); dev_info(&pdev->dev, "RTC enabled\n");
return 0; return 0;
......
/*
* An RTC driver for the AVR32 AT32AP700x processor series.
*
* Copyright (C) 2007 Atmel Corporation
*
* 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/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/rtc.h>
#include <linux/io.h>
/*
* This is a bare-bones RTC. It runs during most system sleep states, but has
* no battery backup and gets reset during system restart. It must be
* initialized from an external clock (network, I2C, etc) before it can be of
* much use.
*
* The alarm functionality is limited by the hardware, not supporting
* periodic interrupts.
*/
#define RTC_CTRL 0x00
#define RTC_CTRL_EN 0
#define RTC_CTRL_PCLR 1
#define RTC_CTRL_TOPEN 2
#define RTC_CTRL_PSEL 8
#define RTC_VAL 0x04
#define RTC_TOP 0x08
#define RTC_IER 0x10
#define RTC_IER_TOPI 0
#define RTC_IDR 0x14
#define RTC_IDR_TOPI 0
#define RTC_IMR 0x18
#define RTC_IMR_TOPI 0
#define RTC_ISR 0x1c
#define RTC_ISR_TOPI 0
#define RTC_ICR 0x20
#define RTC_ICR_TOPI 0
#define RTC_BIT(name) (1 << RTC_##name)
#define RTC_BF(name, value) ((value) << RTC_##name)
#define rtc_readl(dev, reg) \
__raw_readl((dev)->regs + RTC_##reg)
#define rtc_writel(dev, reg, value) \
__raw_writel((value), (dev)->regs + RTC_##reg)
struct rtc_at32ap700x {
struct rtc_device *rtc;
void __iomem *regs;
unsigned long alarm_time;
unsigned long irq;
/* Protect against concurrent register access. */
spinlock_t lock;
};
static int at32_rtc_readtime(struct device *dev, struct rtc_time *tm)
{
struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
unsigned long now;
now = rtc_readl(rtc, VAL);
rtc_time_to_tm(now, tm);
return 0;
}
static int at32_rtc_settime(struct device *dev, struct rtc_time *tm)
{
struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
unsigned long now;
int ret;
ret = rtc_tm_to_time(tm, &now);
if (ret == 0)
rtc_writel(rtc, VAL, now);
return ret;
}
static int at32_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
spin_lock_irq(&rtc->lock);
rtc_time_to_tm(rtc->alarm_time, &alrm->time);
alrm->enabled = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0;
alrm->pending = rtc_readl(rtc, ISR) & RTC_BIT(ISR_TOPI) ? 1 : 0;
spin_unlock_irq(&rtc->lock);
return 0;
}
static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
unsigned long rtc_unix_time;
unsigned long alarm_unix_time;
int ret;
rtc_unix_time = rtc_readl(rtc, VAL);
ret = rtc_tm_to_time(&alrm->time, &alarm_unix_time);
if (ret)
return ret;
if (alarm_unix_time < rtc_unix_time)
return -EINVAL;
spin_lock_irq(&rtc->lock);
rtc->alarm_time = alarm_unix_time;
rtc_writel(rtc, TOP, rtc->alarm_time);
if (alrm->enabled)
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
| RTC_BIT(CTRL_TOPEN));
else
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
& ~RTC_BIT(CTRL_TOPEN));
spin_unlock_irq(&rtc->lock);
return ret;
}
static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct rtc_at32ap700x *rtc = dev_get_drvdata(dev);
int ret = 0;
spin_lock_irq(&rtc->lock);
if (enabled) {
if (rtc_readl(rtc, VAL) > rtc->alarm_time) {
ret = -EINVAL;
goto out;
}
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
| RTC_BIT(CTRL_TOPEN));
rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
rtc_writel(rtc, IER, RTC_BIT(IER_TOPI));
} else {
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
& ~RTC_BIT(CTRL_TOPEN));
rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI));
rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
}
out:
spin_unlock_irq(&rtc->lock);
return ret;
}
static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id)
{
struct rtc_at32ap700x *rtc = (struct rtc_at32ap700x *)dev_id;
unsigned long isr = rtc_readl(rtc, ISR);
unsigned long events = 0;
int ret = IRQ_NONE;
spin_lock(&rtc->lock);
if (isr & RTC_BIT(ISR_TOPI)) {
rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI));
rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI));
rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL)
& ~RTC_BIT(CTRL_TOPEN));
rtc_writel(rtc, VAL, rtc->alarm_time);
events = RTC_AF | RTC_IRQF;
rtc_update_irq(rtc->rtc, 1, events);
ret = IRQ_HANDLED;
}
spin_unlock(&rtc->lock);
return ret;
}
static const struct rtc_class_ops at32_rtc_ops = {
.read_time = at32_rtc_readtime,
.set_time = at32_rtc_settime,
.read_alarm = at32_rtc_readalarm,
.set_alarm = at32_rtc_setalarm,
.alarm_irq_enable = at32_rtc_alarm_irq_enable,
};
static int __init at32_rtc_probe(struct platform_device *pdev)
{
struct resource *regs;
struct rtc_at32ap700x *rtc;
int irq;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(struct rtc_at32ap700x),
GFP_KERNEL);
if (!rtc)
return -ENOMEM;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_dbg(&pdev->dev, "no mmio resource defined\n");
return -ENXIO;
}
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
dev_dbg(&pdev->dev, "could not get irq\n");
return -ENXIO;
}
rtc->irq = irq;
rtc->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
if (!rtc->regs) {
dev_dbg(&pdev->dev, "could not map I/O memory\n");
return -ENOMEM;
}
spin_lock_init(&rtc->lock);
/*
* Maybe init RTC: count from zero at 1 Hz, disable wrap irq.
*
* Do not reset VAL register, as it can hold an old time
* from last JTAG reset.
*/
if (!(rtc_readl(rtc, CTRL) & RTC_BIT(CTRL_EN))) {
rtc_writel(rtc, CTRL, RTC_BIT(CTRL_PCLR));
rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI));
rtc_writel(rtc, CTRL, RTC_BF(CTRL_PSEL, 0xe)
| RTC_BIT(CTRL_EN));
}
ret = devm_request_irq(&pdev->dev, irq, at32_rtc_interrupt, IRQF_SHARED,
"rtc", rtc);
if (ret) {
dev_dbg(&pdev->dev, "could not request irq %d\n", irq);
return ret;
}
platform_set_drvdata(pdev, rtc);
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&at32_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
dev_dbg(&pdev->dev, "could not register rtc device\n");
return PTR_ERR(rtc->rtc);
}
device_init_wakeup(&pdev->dev, 1);
dev_info(&pdev->dev, "Atmel RTC for AT32AP700x at %08lx irq %ld\n",
(unsigned long)rtc->regs, rtc->irq);
return 0;
}
static int __exit at32_rtc_remove(struct platform_device *pdev)
{
device_init_wakeup(&pdev->dev, 0);
return 0;
}
MODULE_ALIAS("platform:at32ap700x_rtc");
static struct platform_driver at32_rtc_driver = {
.remove = __exit_p(at32_rtc_remove),
.driver = {
.name = "at32ap700x_rtc",
},
};
module_platform_driver_probe(at32_rtc_driver, at32_rtc_probe);
MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
MODULE_DESCRIPTION("Real time clock for AVR32 AT32AP700x");
MODULE_LICENSE("GPL");
...@@ -253,7 +253,7 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) ...@@ -253,7 +253,7 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, timer->irq, brcmstb_waketmr_irq, 0, ret = devm_request_irq(dev, timer->irq, brcmstb_waketmr_irq, 0,
"brcmstb-waketimer", timer); "brcmstb-waketimer", timer);
if (ret < 0) if (ret < 0)
return ret; goto err_clk;
timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot; timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot;
register_reboot_notifier(&timer->reboot_notifier); register_reboot_notifier(&timer->reboot_notifier);
...@@ -262,12 +262,21 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) ...@@ -262,12 +262,21 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev)
&brcmstb_waketmr_ops, THIS_MODULE); &brcmstb_waketmr_ops, THIS_MODULE);
if (IS_ERR(timer->rtc)) { if (IS_ERR(timer->rtc)) {
dev_err(dev, "unable to register device\n"); dev_err(dev, "unable to register device\n");
unregister_reboot_notifier(&timer->reboot_notifier); ret = PTR_ERR(timer->rtc);
return PTR_ERR(timer->rtc); goto err_notifier;
} }
dev_info(dev, "registered, with irq %d\n", timer->irq); dev_info(dev, "registered, with irq %d\n", timer->irq);
return 0;
err_notifier:
unregister_reboot_notifier(&timer->reboot_notifier);
err_clk:
if (timer->clk)
clk_disable_unprepare(timer->clk);
return ret; return ret;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -753,8 +753,10 @@ static int omap_rtc_probe(struct platform_device *pdev) ...@@ -753,8 +753,10 @@ static int omap_rtc_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rtc->base = devm_ioremap_resource(&pdev->dev, res); rtc->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(rtc->base)) if (IS_ERR(rtc->base)) {
clk_disable_unprepare(rtc->clk);
return PTR_ERR(rtc->base); return PTR_ERR(rtc->base);
}
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
...@@ -887,6 +889,7 @@ static int omap_rtc_probe(struct platform_device *pdev) ...@@ -887,6 +889,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
return 0; return 0;
err: err:
clk_disable_unprepare(rtc->clk);
device_init_wakeup(&pdev->dev, false); device_init_wakeup(&pdev->dev, false);
rtc->type->lock(rtc); rtc->type->lock(rtc);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
......
...@@ -95,7 +95,7 @@ static int rtc7301_wait_while_busy(struct rtc7301_priv *priv) ...@@ -95,7 +95,7 @@ static int rtc7301_wait_while_busy(struct rtc7301_priv *priv)
if (!(val & RTC7301_CONTROL_BUSY)) if (!(val & RTC7301_CONTROL_BUSY))
return 0; return 0;
usleep_range(200, 300); udelay(300);
} }
return -ETIMEDOUT; return -ETIMEDOUT;
...@@ -235,7 +235,7 @@ static int rtc7301_set_time(struct device *dev, struct rtc_time *tm) ...@@ -235,7 +235,7 @@ static int rtc7301_set_time(struct device *dev, struct rtc_time *tm)
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
rtc7301_stop(priv); rtc7301_stop(priv);
usleep_range(200, 300); udelay(300);
rtc7301_select_bank(priv, 0); rtc7301_select_bank(priv, 0);
rtc7301_write_time(priv, tm, false); rtc7301_write_time(priv, tm, false);
rtc7301_start(priv); rtc7301_start(priv);
......
...@@ -164,17 +164,11 @@ static int r9701_probe(struct spi_device *spi) ...@@ -164,17 +164,11 @@ static int r9701_probe(struct spi_device *spi)
return 0; return 0;
} }
static int r9701_remove(struct spi_device *spi)
{
return 0;
}
static struct spi_driver r9701_driver = { static struct spi_driver r9701_driver = {
.driver = { .driver = {
.name = "rtc-r9701", .name = "rtc-r9701",
}, },
.probe = r9701_probe, .probe = r9701_probe,
.remove = r9701_remove,
}; };
module_spi_driver(r9701_driver); module_spi_driver(r9701_driver);
......
/* /*
* Copyright (C) Amelie Delaunay 2016 * Copyright (C) STMicroelectronics SA 2017
* Author: Amelie Delaunay <amelie.delaunay@st.com> * Author: Amelie Delaunay <amelie.delaunay@st.com> for STMicroelectronics.
* License terms: GNU General Public License (GPL), version 2 * License terms: GNU General Public License (GPL), version 2
*/ */
......
...@@ -201,8 +201,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) ...@@ -201,8 +201,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2), clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2),
GFP_KERNEL); GFP_KERNEL);
if (!clk_data) if (!clk_data) {
kfree(rtc);
return; return;
}
spin_lock_init(&rtc->lock); spin_lock_init(&rtc->lock);
......
...@@ -291,6 +291,9 @@ enum host_event_code { ...@@ -291,6 +291,9 @@ enum host_event_code {
/* EC desires to change state of host-controlled USB mux */ /* EC desires to change state of host-controlled USB mux */
EC_HOST_EVENT_USB_MUX = 28, EC_HOST_EVENT_USB_MUX = 28,
/* EC RTC event occurred */
EC_HOST_EVENT_RTC = 26,
/* /*
* The high bit of the event mask is not used as a host event code. If * The high bit of the event mask is not used as a host event code. If
* it reads back as set, then the entire event mask should be * it reads back as set, then the entire event mask should be
...@@ -799,6 +802,8 @@ enum ec_feature_code { ...@@ -799,6 +802,8 @@ enum ec_feature_code {
EC_FEATURE_USB_MUX = 23, EC_FEATURE_USB_MUX = 23,
/* Motion Sensor code has an internal software FIFO */ /* Motion Sensor code has an internal software FIFO */
EC_FEATURE_MOTION_SENSE_FIFO = 24, EC_FEATURE_MOTION_SENSE_FIFO = 24,
/* EC has RTC feature that can be controlled by host commands */
EC_FEATURE_RTC = 27,
}; };
#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
...@@ -1709,6 +1714,9 @@ struct ec_response_rtc { ...@@ -1709,6 +1714,9 @@ struct ec_response_rtc {
#define EC_CMD_RTC_SET_VALUE 0x46 #define EC_CMD_RTC_SET_VALUE 0x46
#define EC_CMD_RTC_SET_ALARM 0x47 #define EC_CMD_RTC_SET_ALARM 0x47
/* Pass as param to SET_ALARM to clear the current alarm */
#define EC_RTC_ALARM_CLEAR 0
/*****************************************************************************/ /*****************************************************************************/
/* Port80 log access */ /* Port80 log access */
......
...@@ -87,7 +87,6 @@ struct rtc_class_ops { ...@@ -87,7 +87,6 @@ struct rtc_class_ops {
int (*set_offset)(struct device *, long offset); int (*set_offset)(struct device *, long offset);
}; };
#define RTC_DEVICE_NAME_SIZE 20
typedef struct rtc_task { typedef struct rtc_task {
void (*func)(void *private_data); void (*func)(void *private_data);
void *private_data; void *private_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment