RTC for 5.12

Subsystem:
  - Introduce features bitfield and the first feature: RTC_FEATURE_ALARM
 
 Removed drivers:
  - ab3100
  - coh901331
  - tx4939
  - sirfsoc
 
 Drivers:
  - use rtc_lock and rtc_unlock instead of opencoding
  - constify all struct rtc_class_ops
  - quiet maybe-unused variable warning
  - replace spin_lock_irqsave with spin_lock in hard IRQ
  - pcf2127: disable Power-On Reset Override and run OTP refresh
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEycoQi/giopmpPgB12wIijOdRNOUFAmAzAIAACgkQ2wIijOdR
 NOXVDhAArDkq1P46RK6GDQV6w++RTwqMRTVTCZLG0r+gOv6BiAo8TjEb+VMlJFi5
 4D4qVEo5BDxMxNRsB/vyWIrvXDpGW/vxTH3W4G/4lGHZObYluAGeoZ+qswRPaPHU
 upJd4OXK7AThjf9lhOuhiuea6oAGfhIl4keTu3pVUAfYMYBlS9zmU45pF4KESXzm
 6Wmed2QKx3+iUcBdwToMaDpd4uJcZ9HSPP/SPlO0P1KwhfUolCfFrHjY2oGuRVCN
 dYDZ995c5jx1PU5AlEBWXcWG7mWVEpESearUCjEKYiRgpJu85EJpDmoROa4XjL49
 XJYbfnM/ZFMVJpAKPGBuOX/PYMMyOOkiYQ0GE5iHYWBctzQr3cm6D9SMynymsJHY
 mo0abVSmWU6FmUH2+n4je7ixXfuf/H0T4/xYw+1xejwGk3XpWEVYwzU6YznCXKMn
 djPO6hL+87vJC8BaQNwdAGACrO4ludJdsX2XTNg89U8eUseuFb+xJjQ06ZJCHeFL
 zrdmHdkJkLqp7Zu/HnVTT74ZQ+bp/hn9voR19HFrMqwKtbPQUfOZhWjwJOcft/rk
 jFOdPadE+OwHDB8rvBshdqNbeyJ5AUeP+6+C6xgVAuLHWtpgG4UibXp+9MWbFcgk
 219o0s2ZI/rkX9n1K/3gmgp2Y4HlSOrYIkGiybvFl0cOpLJqoZk=
 =bK2K
 -----END PGP SIGNATURE-----

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

Pull RTC updates from Alexandre Belloni:
 "Many cleanups and a few drivers removal this cycle.

  Subsystem:
   - Introduce features bitfield and the first feature: RTC_FEATURE_ALARM

  Removed drivers:
   - ab3100
   - coh901331
   - tx4939
   - sirfsoc

  Drivers:
   - use rtc_lock and rtc_unlock instead of opencoding
   - constify all struct rtc_class_ops
   - quiet maybe-unused variable warning
   - replace spin_lock_irqsave with spin_lock in hard IRQ
   - pcf2127: disable Power-On Reset Override and run OTP refresh"

* tag 'rtc-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (81 commits)
  rtc: abx80x: Add utility function for writing configuration key
  rtc: pcf2127: properly set flag WD_CD for rtc chips(pcf2129, pca2129)
  rtc: pcf8563: Add NXP PCA8565 compatible
  rtc: s3c: quiet maybe-unused variable warning
  rtc: s3c: stop setting bogus time
  rtc: sd3078: quiet maybe-unused variable warning
  rtc: s35390a: quiet maybe-unused variable warning
  rtc: rx8581: quiet maybe-unused variable warning
  rtc: rx8010: quiet maybe-unused variable warning
  rtc: rv8803: quiet maybe-unused variable warning
  rtc: rv3032: quiet maybe-unused variable warning
  rtc: rv3029: quiet maybe-unused variable warning
  rtc: rv3028: quiet maybe-unused variable warning
  rtc: rs5c372: quiet maybe-unused variable warning
  rtc: pcf85363: quiet maybe-unused variable warning
  rtc: pcf85063: quiet maybe-unused variable warnings
  rtc: meson: quiet maybe-unused variable warning
  rtc: m41t80: quiet maybe-unused variable warning
  rtc: isl1208: quiet maybe-unused variable warning
  rtc: ds3232: quiet maybe-unused variable warning
  ...
This commit is contained in:
Linus Torvalds 2021-02-22 09:54:19 -08:00
commit 0328b5f2ef
64 changed files with 322 additions and 1718 deletions

View File

@ -20,6 +20,7 @@ properties:
- atmel,sama5d4-rtc - atmel,sama5d4-rtc
- atmel,sama5d2-rtc - atmel,sama5d2-rtc
- microchip,sam9x60-rtc - microchip,sam9x60-rtc
- microchip,sama7g5-rtc
reg: reg:
maxItems: 1 maxItems: 1

View File

@ -0,0 +1,51 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/nxp,pcf2127.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP PCF2127 Real Time Clock
allOf:
- $ref: "rtc.yaml#"
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
properties:
compatible:
const: nxp,pcf2127
reg:
maxItems: 1
interrupts:
maxItems: 1
start-year: true
reset-source: true
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
rtc@51 {
compatible = "nxp,pcf2127";
reg = <0x51>;
pinctrl-0 = <&rtc_nint_pins>;
interrupts-extended = <&gpio1 16 IRQ_TYPE_LEVEL_HIGH>;
reset-source;
};
};
...

View File

@ -5,7 +5,8 @@ Philips PCF8563/Epson RTC8564 Real Time Clock
Required properties: Required properties:
- compatible: Should contain "nxp,pcf8563", - compatible: Should contain "nxp,pcf8563",
"epson,rtc8564" or "epson,rtc8564" or
"microcrystal,rv8564" "microcrystal,rv8564" or
"nxp,pca8565"
- reg: I2C address for chip. - reg: I2C address for chip.
Optional property: Optional property:

View File

@ -1,13 +0,0 @@
SiRFSoC Real Time Clock
Required properties:
- compatible: must be "sirf,prima2-sysrtc"
- reg: address range of rtc register set.
- interrupts: rtc alarm interrupts.
Example:
rtc@2000 {
compatible = "sirf,prima2-sysrtc";
reg = <0x2000 0x1000>;
interrupts = <52 53 54>;
};

View File

@ -1,16 +0,0 @@
ST-Ericsson COH 901 331 Real Time Clock
Required properties:
- compatible: must be "stericsson,coh901331"
- reg: address range of rtc register set.
- interrupts: rtc alarm interrupt.
- clocks: phandle to the rtc clock source
Example:
rtc: rtc@c0017000 {
compatible = "stericsson,coh901331";
reg = <0xc0017000 0x1000>;
interrupt-parent = <&vicb>;
interrupts = <10>;
clocks = <&rtc_clk>;
};

View File

@ -48,12 +48,8 @@ properties:
- microcrystal,rv3029 - microcrystal,rv3029
# Real Time Clock # Real Time Clock
- microcrystal,rv8523 - microcrystal,rv8523
# Real-time clock
- nxp,pcf2127
# Real-time clock
- nxp,pcf2129
# Real-time clock
- nxp,pca2129 - nxp,pca2129
- nxp,pcf2129
# Real-time Clock Module # Real-time Clock Module
- pericom,pt7c4338 - pericom,pt7c4338
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC # I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC

View File

@ -692,6 +692,7 @@ config RTC_DRV_S5M
tristate "Samsung S2M/S5M series" tristate "Samsung S2M/S5M series"
depends on MFD_SEC_CORE || COMPILE_TEST depends on MFD_SEC_CORE || COMPILE_TEST
select REGMAP_IRQ select REGMAP_IRQ
select REGMAP_I2C
help help
If you say yes here you will get support for the If you say yes here you will get support for the
RTC of Samsung S2MPS14 and S5M PMIC series. RTC of Samsung S2MPS14 and S5M PMIC series.
@ -1258,14 +1259,6 @@ config RTC_DRV_PCF50633
If you say yes here you get support for the RTC subsystem of the If you say yes here you get support for the RTC subsystem of the
NXP PCF50633 used in embedded systems. NXP PCF50633 used in embedded systems.
config RTC_DRV_AB3100
tristate "ST-Ericsson AB3100 RTC"
depends on AB3100_CORE
default y if AB3100_CORE
help
Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC
support. This chip contains a battery- and capacitor-backed RTC.
config RTC_DRV_AB8500 config RTC_DRV_AB8500
tristate "ST-Ericsson AB8500 RTC" tristate "ST-Ericsson AB8500 RTC"
depends on AB8500_CORE depends on AB8500_CORE
@ -1288,7 +1281,7 @@ config RTC_DRV_OPAL
config RTC_DRV_ZYNQMP config RTC_DRV_ZYNQMP
tristate "Xilinx Zynq Ultrascale+ MPSoC RTC" tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
depends on OF depends on OF && HAS_IOMEM
help help
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.
@ -1575,13 +1568,6 @@ config RTC_DRV_STARFIRE
If you say Y here you will get support for the RTC found on If you say Y here you will get support for the RTC found on
Starfire systems. Starfire systems.
config RTC_DRV_TX4939
tristate "TX4939 SoC"
depends on SOC_TX4939 || COMPILE_TEST
help
Driver for the internal RTC (Realtime Clock) module found on
Toshiba TX4939 SoC.
config RTC_DRV_MV config RTC_DRV_MV
tristate "Marvell SoC RTC" tristate "Marvell SoC RTC"
depends on ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST depends on ARCH_DOVE || ARCH_MVEBU || COMPILE_TEST
@ -1596,6 +1582,7 @@ config RTC_DRV_MV
config RTC_DRV_ARMADA38X config RTC_DRV_ARMADA38X
tristate "Armada 38x Marvell SoC RTC" tristate "Armada 38x Marvell SoC RTC"
depends on ARCH_MVEBU || COMPILE_TEST depends on ARCH_MVEBU || COMPILE_TEST
depends on OF
help help
If you say yes here you will get support for the in-chip RTC If you say yes here you will get support for the in-chip RTC
that can be found in the Armada 38x Marvell's SoC device that can be found in the Armada 38x Marvell's SoC device
@ -1633,18 +1620,6 @@ config RTC_DRV_PS3
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-ps3. will be called rtc-ps3.
config RTC_DRV_COH901331
tristate "ST-Ericsson COH 901 331 RTC"
depends on ARCH_U300 || COMPILE_TEST
help
If you say Y here you will get access to ST-Ericsson
COH 901 331 RTC clock found in some ST-Ericsson Mobile
Platforms.
This driver can also be built as a module. If so, the module
will be called "rtc-coh901331".
config RTC_DRV_STMP config RTC_DRV_STMP
tristate "Freescale STMP3xxx/i.MX23/i.MX28 RTC" tristate "Freescale STMP3xxx/i.MX23/i.MX28 RTC"
depends on ARCH_MXS || COMPILE_TEST depends on ARCH_MXS || COMPILE_TEST
@ -1787,13 +1762,6 @@ config RTC_DRV_IMX_SC
If you say yes here you get support for the NXP i.MX System If you say yes here you get support for the NXP i.MX System
Controller RTC module. Controller RTC module.
config RTC_DRV_SIRFSOC
tristate "SiRFSOC RTC"
depends on ARCH_SIRF
help
Say "yes" here to support the real time clock on SiRF SOC chips.
This driver can also be built as a module called rtc-sirfsoc.
config RTC_DRV_ST_LPC config RTC_DRV_ST_LPC
tristate "STMicroelectronics LPC RTC" tristate "STMicroelectronics LPC RTC"
depends on ARCH_STI depends on ARCH_STI

View File

@ -19,7 +19,6 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o
obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o
obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o
obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o
obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o
obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o
obj-$(CONFIG_RTC_DRV_ABEOZ9) += rtc-ab-eoz9.o obj-$(CONFIG_RTC_DRV_ABEOZ9) += rtc-ab-eoz9.o
@ -38,7 +37,6 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o obj-$(CONFIG_RTC_DRV_BRCMSTB) += rtc-brcmstb-waketimer.o
obj-$(CONFIG_RTC_DRV_CADENCE) += rtc-cadence.o obj-$(CONFIG_RTC_DRV_CADENCE) += rtc-cadence.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_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_CROS_EC) += rtc-cros-ec.o
obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
@ -154,7 +152,6 @@ obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o obj-$(CONFIG_RTC_DRV_SC27XX) += rtc-sc27xx.o
obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o obj-$(CONFIG_RTC_DRV_SD3078) += rtc-sd3078.o
obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o
obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o
obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o
obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
@ -171,7 +168,6 @@ obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o
obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o
obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o
obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o

View File

@ -231,6 +231,8 @@ static struct rtc_device *rtc_allocate_device(void)
rtc->pie_timer.function = rtc_pie_update_irq; rtc->pie_timer.function = rtc_pie_update_irq;
rtc->pie_enabled = 0; rtc->pie_enabled = 0;
set_bit(RTC_FEATURE_ALARM, rtc->features);
return rtc; return rtc;
} }
@ -322,11 +324,6 @@ static void rtc_device_get_offset(struct rtc_device *rtc)
rtc->offset_secs = 0; rtc->offset_secs = 0;
} }
/**
* rtc_device_unregister - removes the previously registered RTC class device
*
* @rtc: the RTC class device to destroy
*/
static void devm_rtc_unregister_device(void *data) static void devm_rtc_unregister_device(void *data)
{ {
struct rtc_device *rtc = data; struct rtc_device *rtc = data;
@ -386,6 +383,9 @@ int __devm_rtc_register_device(struct module *owner, struct rtc_device *rtc)
return -EINVAL; return -EINVAL;
} }
if (!rtc->ops->set_alarm)
clear_bit(RTC_FEATURE_ALARM, rtc->features);
rtc->owner = owner; rtc->owner = owner;
rtc_device_get_offset(rtc); rtc_device_get_offset(rtc);

View File

@ -186,7 +186,7 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc,
if (!rtc->ops) { if (!rtc->ops) {
err = -ENODEV; err = -ENODEV;
} else if (!rtc->ops->read_alarm) { } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->read_alarm) {
err = -EINVAL; err = -EINVAL;
} else { } else {
alarm->enabled = 0; alarm->enabled = 0;
@ -392,7 +392,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
return err; return err;
if (!rtc->ops) { if (!rtc->ops) {
err = -ENODEV; err = -ENODEV;
} else if (!rtc->ops->read_alarm) { } else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->read_alarm) {
err = -EINVAL; err = -EINVAL;
} else { } else {
memset(alarm, 0, sizeof(struct rtc_wkalrm)); memset(alarm, 0, sizeof(struct rtc_wkalrm));
@ -436,7 +436,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
if (!rtc->ops) if (!rtc->ops)
err = -ENODEV; err = -ENODEV;
else if (!rtc->ops->set_alarm) else if (!test_bit(RTC_FEATURE_ALARM, rtc->features))
err = -EINVAL; err = -EINVAL;
else else
err = rtc->ops->set_alarm(rtc->dev.parent, alarm); err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
@ -451,7 +451,7 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
if (!rtc->ops) if (!rtc->ops)
return -ENODEV; return -ENODEV;
else if (!rtc->ops->set_alarm) else if (!test_bit(RTC_FEATURE_ALARM, rtc->features))
return -EINVAL; return -EINVAL;
err = rtc_valid_tm(&alarm->time); err = rtc_valid_tm(&alarm->time);
@ -531,7 +531,7 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
/* nothing */; /* nothing */;
else if (!rtc->ops) else if (!rtc->ops)
err = -ENODEV; err = -ENODEV;
else if (!rtc->ops->alarm_irq_enable) else if (!test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->alarm_irq_enable)
err = -EINVAL; err = -EINVAL;
else else
err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled); err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled);
@ -843,7 +843,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
static void rtc_alarm_disable(struct rtc_device *rtc) static void rtc_alarm_disable(struct rtc_device *rtc)
{ {
if (!rtc->ops || !rtc->ops->alarm_irq_enable) if (!rtc->ops || !test_bit(RTC_FEATURE_ALARM, rtc->features) || !rtc->ops->alarm_irq_enable)
return; return;
rtc->ops->alarm_irq_enable(rtc->dev.parent, false); rtc->ops->alarm_irq_enable(rtc->dev.parent, false);

View File

@ -1,254 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2007-2009 ST-Ericsson AB
* RTC clock driver for the AB3100 Analog Baseband Chip
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/mfd/abx500.h>
/* Clock rate in Hz */
#define AB3100_RTC_CLOCK_RATE 32768
/*
* The AB3100 RTC registers. These are the same for
* AB3000 and AB3100.
* Control register:
* Bit 0: RTC Monitor cleared=0, active=1, if you set it
* to 1 it remains active until RTC power is lost.
* Bit 1: 32 kHz Oscillator, 0 = on, 1 = bypass
* Bit 2: Alarm on, 0 = off, 1 = on
* Bit 3: 32 kHz buffer disabling, 0 = enabled, 1 = disabled
*/
#define AB3100_RTC 0x53
/* default setting, buffer disabled, alarm on */
#define RTC_SETTING 0x30
/* Alarm when AL0-AL3 == TI0-TI3 */
#define AB3100_AL0 0x56
#define AB3100_AL1 0x57
#define AB3100_AL2 0x58
#define AB3100_AL3 0x59
/* This 48-bit register that counts up at 32768 Hz */
#define AB3100_TI0 0x5a
#define AB3100_TI1 0x5b
#define AB3100_TI2 0x5c
#define AB3100_TI3 0x5d
#define AB3100_TI4 0x5e
#define AB3100_TI5 0x5f
/*
* RTC clock functions and device struct declaration
*/
static int ab3100_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2,
AB3100_TI3, AB3100_TI4, AB3100_TI5};
unsigned char buf[6];
u64 hw_counter = rtc_tm_to_time64(tm) * AB3100_RTC_CLOCK_RATE * 2;
int err = 0;
int i;
buf[0] = (hw_counter) & 0xFF;
buf[1] = (hw_counter >> 8) & 0xFF;
buf[2] = (hw_counter >> 16) & 0xFF;
buf[3] = (hw_counter >> 24) & 0xFF;
buf[4] = (hw_counter >> 32) & 0xFF;
buf[5] = (hw_counter >> 40) & 0xFF;
for (i = 0; i < 6; i++) {
err = abx500_set_register_interruptible(dev, 0,
regs[i], buf[i]);
if (err)
return err;
}
/* Set the flag to mark that the clock is now set */
return abx500_mask_and_set_register_interruptible(dev, 0,
AB3100_RTC,
0x01, 0x01);
}
static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
time64_t time;
u8 rtcval;
int err;
err = abx500_get_register_interruptible(dev, 0,
AB3100_RTC, &rtcval);
if (err)
return err;
if (!(rtcval & 0x01)) {
dev_info(dev, "clock not set (lost power)");
return -EINVAL;
} else {
u64 hw_counter;
u8 buf[6];
/* Read out time registers */
err = abx500_get_register_page_interruptible(dev, 0,
AB3100_TI0,
buf, 6);
if (err != 0)
return err;
hw_counter = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
((u64) buf[3] << 24) | ((u64) buf[2] << 16) |
((u64) buf[1] << 8) | (u64) buf[0];
time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
}
rtc_time64_to_tm(time, tm);
return 0;
}
static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
time64_t time;
u64 hw_counter;
u8 buf[6];
u8 rtcval;
int err;
/* Figure out if alarm is enabled or not */
err = abx500_get_register_interruptible(dev, 0,
AB3100_RTC, &rtcval);
if (err)
return err;
if (rtcval & 0x04)
alarm->enabled = 1;
else
alarm->enabled = 0;
/* No idea how this could be represented */
alarm->pending = 0;
/* Read out alarm registers, only 4 bytes */
err = abx500_get_register_page_interruptible(dev, 0,
AB3100_AL0, buf, 4);
if (err)
return err;
hw_counter = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
((u64) buf[1] << 24) | ((u64) buf[0] << 16);
time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
rtc_time64_to_tm(time, &alarm->time);
return rtc_valid_tm(&alarm->time);
}
static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3};
unsigned char buf[4];
time64_t secs;
u64 hw_counter;
int err;
int i;
secs = rtc_tm_to_time64(&alarm->time);
hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2;
buf[0] = (hw_counter >> 16) & 0xFF;
buf[1] = (hw_counter >> 24) & 0xFF;
buf[2] = (hw_counter >> 32) & 0xFF;
buf[3] = (hw_counter >> 40) & 0xFF;
/* Set the alarm */
for (i = 0; i < 4; i++) {
err = abx500_set_register_interruptible(dev, 0,
regs[i], buf[i]);
if (err)
return err;
}
/* Then enable the alarm */
return abx500_mask_and_set_register_interruptible(dev, 0,
AB3100_RTC, (1 << 2),
alarm->enabled << 2);
}
static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled)
{
/*
* It's not possible to enable/disable the alarm IRQ for this RTC.
* It does not actually trigger any IRQ: instead its only function is
* to power up the system, if it wasn't on. This will manifest as
* a "power up cause" in the AB3100 power driver (battery charging etc)
* and need to be handled there instead.
*/
if (enabled)
return abx500_mask_and_set_register_interruptible(dev, 0,
AB3100_RTC, (1 << 2),
1 << 2);
else
return abx500_mask_and_set_register_interruptible(dev, 0,
AB3100_RTC, (1 << 2),
0);
}
static const struct rtc_class_ops ab3100_rtc_ops = {
.read_time = ab3100_rtc_read_time,
.set_time = ab3100_rtc_set_time,
.read_alarm = ab3100_rtc_read_alarm,
.set_alarm = ab3100_rtc_set_alarm,
.alarm_irq_enable = ab3100_rtc_irq_enable,
};
static int __init ab3100_rtc_probe(struct platform_device *pdev)
{
int err;
u8 regval;
struct rtc_device *rtc;
/* The first RTC register needs special treatment */
err = abx500_get_register_interruptible(&pdev->dev, 0,
AB3100_RTC, &regval);
if (err) {
dev_err(&pdev->dev, "unable to read RTC register\n");
return -ENODEV;
}
if ((regval & 0xFE) != RTC_SETTING) {
dev_warn(&pdev->dev, "not default value in RTC reg 0x%x\n",
regval);
}
if ((regval & 1) == 0) {
/*
* Set bit to detect power loss.
* This bit remains until RTC power is lost.
*/
regval = 1 | RTC_SETTING;
err = abx500_set_register_interruptible(&pdev->dev, 0,
AB3100_RTC, regval);
/* Ignore any error on this write */
}
rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
rtc->ops = &ab3100_rtc_ops;
/* 48bit counter at (AB3100_RTC_CLOCK_RATE * 2) */
rtc->range_max = U32_MAX;
platform_set_drvdata(pdev, rtc);
return devm_rtc_register_device(rtc);
}
static struct platform_driver ab3100_rtc_driver = {
.driver = {
.name = "ab3100-rtc",
},
};
module_platform_driver_probe(ab3100_rtc_driver, ab3100_rtc_probe);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("AB3100 RTC Driver");
MODULE_LICENSE("GPL");

View File

@ -117,6 +117,16 @@ struct abx80x_priv {
struct watchdog_device wdog; struct watchdog_device wdog;
}; };
static int abx80x_write_config_key(struct i2c_client *client, u8 key)
{
if (i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, key) < 0) {
dev_err(&client->dev, "Unable to write configuration key\n");
return -EIO;
}
return 0;
}
static int abx80x_is_rc_mode(struct i2c_client *client) static int abx80x_is_rc_mode(struct i2c_client *client)
{ {
int flags = 0; int flags = 0;
@ -140,12 +150,8 @@ static int abx80x_enable_trickle_charger(struct i2c_client *client,
* Write the configuration key register to enable access to the Trickle * Write the configuration key register to enable access to the Trickle
* register * register
*/ */
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_MISC) < 0)
ABX8XX_CFG_KEY_MISC);
if (err < 0) {
dev_err(&client->dev, "Unable to write configuration key\n");
return -EIO; return -EIO;
}
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_TRICKLE, err = i2c_smbus_write_byte_data(client, ABX8XX_REG_TRICKLE,
ABX8XX_TRICKLE_CHARGE_ENABLE | ABX8XX_TRICKLE_CHARGE_ENABLE |
@ -358,12 +364,8 @@ static int abx80x_rtc_set_autocalibration(struct device *dev,
} }
/* Unlock write access to Oscillator Control Register */ /* Unlock write access to Oscillator Control Register */
retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
ABX8XX_CFG_KEY_OSC); return -EIO;
if (retval < 0) {
dev_err(dev, "Failed to write CONFIG_KEY register\n");
return retval;
}
retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags); retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
@ -450,12 +452,8 @@ static ssize_t oscillator_store(struct device *dev,
flags |= (ABX8XX_OSC_OSEL); flags |= (ABX8XX_OSC_OSEL);
/* Unlock write access on Oscillator Control register */ /* Unlock write access on Oscillator Control register */
retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_OSC) < 0)
ABX8XX_CFG_KEY_OSC); return -EIO;
if (retval < 0) {
dev_err(dev, "Failed to write CONFIG_KEY register\n");
return retval;
}
retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags); retval = i2c_smbus_write_byte_data(client, ABX8XX_REG_OSC, flags);
if (retval < 0) { if (retval < 0) {
@ -762,13 +760,8 @@ static int abx80x_probe(struct i2c_client *client,
* Write the configuration key register to enable access to * Write the configuration key register to enable access to
* the config2 register * the config2 register
*/ */
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY, if (abx80x_write_config_key(client, ABX8XX_CFG_KEY_MISC) < 0)
ABX8XX_CFG_KEY_MISC);
if (err < 0) {
dev_err(&client->dev,
"Unable to write configuration key\n");
return -EIO; return -EIO;
}
err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OUT_CTRL, err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OUT_CTRL,
data | ABX8XX_OUT_CTRL_EXDS); data | ABX8XX_OUT_CTRL_EXDS);

View File

@ -528,7 +528,7 @@ static irqreturn_t ac100_rtc_irq(int irq, void *data)
unsigned int val = 0; unsigned int val = 0;
int ret; int ret;
mutex_lock(&chip->rtc->ops_lock); rtc_lock(chip->rtc);
/* read status */ /* read status */
ret = regmap_read(regmap, AC100_ALM_INT_STA, &val); ret = regmap_read(regmap, AC100_ALM_INT_STA, &val);
@ -551,7 +551,7 @@ static irqreturn_t ac100_rtc_irq(int irq, void *data)
} }
out: out:
mutex_unlock(&chip->rtc->ops_lock); rtc_unlock(chip->rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -458,14 +458,6 @@ static const struct rtc_class_ops armada38x_rtc_ops = {
.set_offset = armada38x_rtc_set_offset, .set_offset = armada38x_rtc_set_offset,
}; };
static const struct rtc_class_ops armada38x_rtc_ops_noirq = {
.read_time = armada38x_rtc_read_time,
.set_time = armada38x_rtc_set_time,
.read_alarm = armada38x_rtc_read_alarm,
.read_offset = armada38x_rtc_read_offset,
.set_offset = armada38x_rtc_set_offset,
};
static const struct armada38x_rtc_data armada38x_data = { static const struct armada38x_rtc_data armada38x_data = {
.update_mbus_timing = rtc_update_38x_mbus_timing_params, .update_mbus_timing = rtc_update_38x_mbus_timing_params,
.read_rtc_reg = read_rtc_register_38x_wa, .read_rtc_reg = read_rtc_register_38x_wa,
@ -540,20 +532,15 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
} }
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
if (rtc->irq != -1) { if (rtc->irq != -1)
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
rtc->rtc_dev->ops = &armada38x_rtc_ops; else
} else { clear_bit(RTC_FEATURE_ALARM, rtc->rtc_dev->features);
/*
* If there is no interrupt available then we can't
* use the alarm
*/
rtc->rtc_dev->ops = &armada38x_rtc_ops_noirq;
}
/* Update RTC-MBUS bridge timing parameters */ /* Update RTC-MBUS bridge timing parameters */
rtc->data->update_mbus_timing(rtc); rtc->data->update_mbus_timing(rtc);
rtc->rtc_dev->ops = &armada38x_rtc_ops;
rtc->rtc_dev->range_max = U32_MAX; rtc->rtc_dev->range_max = U32_MAX;
return devm_rtc_register_device(rtc->rtc_dev); return devm_rtc_register_device(rtc->rtc_dev);

View File

@ -116,15 +116,15 @@ static irqreturn_t asm9260_rtc_irq(int irq, void *dev_id)
u32 isr; u32 isr;
unsigned long events = 0; unsigned long events = 0;
mutex_lock(&priv->rtc->ops_lock); rtc_lock(priv->rtc);
isr = ioread32(priv->iobase + HW_CIIR); isr = ioread32(priv->iobase + HW_CIIR);
if (!isr) { if (!isr) {
mutex_unlock(&priv->rtc->ops_lock); rtc_unlock(priv->rtc);
return IRQ_NONE; return IRQ_NONE;
} }
iowrite32(0, priv->iobase + HW_CIIR); iowrite32(0, priv->iobase + HW_CIIR);
mutex_unlock(&priv->rtc->ops_lock); rtc_unlock(priv->rtc);
events |= RTC_AF | RTC_IRQF; events |= RTC_AF | RTC_IRQF;

View File

@ -311,7 +311,7 @@ static const struct i2c_device_id bq32k_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, bq32k_id); MODULE_DEVICE_TABLE(i2c, bq32k_id);
static const struct of_device_id bq32k_of_match[] = { static const __maybe_unused struct of_device_id bq32k_of_match[] = {
{ .compatible = "ti,bq32000" }, { .compatible = "ti,bq32000" },
{ } { }
}; };

View File

@ -306,7 +306,7 @@ static int brcmstb_waketmr_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(brcmstb_waketmr_pm_ops, static SIMPLE_DEV_PM_OPS(brcmstb_waketmr_pm_ops,
brcmstb_waketmr_suspend, brcmstb_waketmr_resume); brcmstb_waketmr_suspend, brcmstb_waketmr_resume);
static const struct of_device_id brcmstb_waketmr_of_match[] = { static const __maybe_unused struct of_device_id brcmstb_waketmr_of_match[] = {
{ .compatible = "brcm,brcmstb-waketimer" }, { .compatible = "brcm,brcmstb-waketimer" },
{ /* sentinel */ }, { /* sentinel */ },
}; };

View File

@ -574,12 +574,6 @@ static const struct rtc_class_ops cmos_rtc_ops = {
.alarm_irq_enable = cmos_alarm_irq_enable, .alarm_irq_enable = cmos_alarm_irq_enable,
}; };
static const struct rtc_class_ops cmos_rtc_ops_no_alarm = {
.read_time = cmos_read_time,
.set_time = cmos_set_time,
.proc = cmos_procfs,
};
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
/* /*
@ -649,11 +643,10 @@ static struct cmos_rtc cmos_rtc;
static irqreturn_t cmos_interrupt(int irq, void *p) static irqreturn_t cmos_interrupt(int irq, void *p)
{ {
unsigned long flags;
u8 irqstat; u8 irqstat;
u8 rtc_control; u8 rtc_control;
spin_lock_irqsave(&rtc_lock, flags); spin_lock(&rtc_lock);
/* When the HPET interrupt handler calls us, the interrupt /* When the HPET interrupt handler calls us, the interrupt
* status is passed as arg1 instead of the irq number. But * status is passed as arg1 instead of the irq number. But
@ -687,7 +680,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
hpet_mask_rtc_irq_bit(RTC_AIE); hpet_mask_rtc_irq_bit(RTC_AIE);
CMOS_READ(RTC_INTR_FLAGS); CMOS_READ(RTC_INTR_FLAGS);
} }
spin_unlock_irqrestore(&rtc_lock, flags); spin_unlock(&rtc_lock);
if (is_intr(irqstat)) { if (is_intr(irqstat)) {
rtc_update_irq(p, 1, irqstat); rtc_update_irq(p, 1, irqstat);
@ -865,11 +858,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
goto cleanup1; goto cleanup1;
} }
} else {
clear_bit(RTC_FEATURE_ALARM, cmos_rtc.rtc->features);
}
cmos_rtc.rtc->ops = &cmos_rtc_ops; cmos_rtc.rtc->ops = &cmos_rtc_ops;
} else {
cmos_rtc.rtc->ops = &cmos_rtc_ops_no_alarm;
}
retval = devm_rtc_register_device(cmos_rtc.rtc); retval = devm_rtc_register_device(cmos_rtc.rtc);
if (retval) if (retval)

View File

@ -1,290 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2007-2009 ST-Ericsson AB
* Real Time Clock interface for ST-Ericsson AB COH 901 331 RTC.
* Author: Linus Walleij <linus.walleij@stericsson.com>
* Based on rtc-pl031.c by Deepak Saxena <dsaxena@plexity.net>
* Copyright 2006 (c) MontaVista Software, Inc.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/rtc.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
/*
* Registers in the COH 901 331
*/
/* Alarm value 32bit (R/W) */
#define COH901331_ALARM 0x00U
/* Used to set current time 32bit (R/W) */
#define COH901331_SET_TIME 0x04U
/* Indication if current time is valid 32bit (R/-) */
#define COH901331_VALID 0x08U
/* Read the current time 32bit (R/-) */
#define COH901331_CUR_TIME 0x0cU
/* Event register for the "alarm" interrupt */
#define COH901331_IRQ_EVENT 0x10U
/* Mask register for the "alarm" interrupt */
#define COH901331_IRQ_MASK 0x14U
/* Force register for the "alarm" interrupt */
#define COH901331_IRQ_FORCE 0x18U
/*
* Reference to RTC block clock
* Notice that the frequent clk_enable()/clk_disable() on this
* clock is mainly to be able to turn on/off other clocks in the
* hierarchy as needed, the RTC clock is always on anyway.
*/
struct coh901331_port {
struct rtc_device *rtc;
struct clk *clk;
void __iomem *virtbase;
int irq;
#ifdef CONFIG_PM_SLEEP
u32 irqmaskstore;
#endif
};
static irqreturn_t coh901331_interrupt(int irq, void *data)
{
struct coh901331_port *rtap = data;
clk_enable(rtap->clk);
/* Ack IRQ */
writel(1, rtap->virtbase + COH901331_IRQ_EVENT);
/*
* Disable the interrupt. This is necessary because
* the RTC lives on a lower-clocked line and will
* not release the IRQ line until after a few (slower)
* clock cycles. The interrupt will be re-enabled when
* a new alarm is set anyway.
*/
writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
/* Set alarm flag */
rtc_update_irq(rtap->rtc, 1, RTC_AF);
return IRQ_HANDLED;
}
static int coh901331_read_time(struct device *dev, struct rtc_time *tm)
{
struct coh901331_port *rtap = dev_get_drvdata(dev);
clk_enable(rtap->clk);
/* Check if the time is valid */
if (!readl(rtap->virtbase + COH901331_VALID)) {
clk_disable(rtap->clk);
return -EINVAL;
}
rtc_time64_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm);
clk_disable(rtap->clk);
return 0;
}
static int coh901331_set_time(struct device *dev, struct rtc_time *tm)
{
struct coh901331_port *rtap = dev_get_drvdata(dev);
clk_enable(rtap->clk);
writel(rtc_tm_to_time64(tm), rtap->virtbase + COH901331_SET_TIME);
clk_disable(rtap->clk);
return 0;
}
static int coh901331_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct coh901331_port *rtap = dev_get_drvdata(dev);
clk_enable(rtap->clk);
rtc_time64_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time);
alarm->pending = readl(rtap->virtbase + COH901331_IRQ_EVENT) & 1U;
alarm->enabled = readl(rtap->virtbase + COH901331_IRQ_MASK) & 1U;
clk_disable(rtap->clk);
return 0;
}
static int coh901331_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct coh901331_port *rtap = dev_get_drvdata(dev);
unsigned long time = rtc_tm_to_time64(&alarm->time);
clk_enable(rtap->clk);
writel(time, rtap->virtbase + COH901331_ALARM);
writel(alarm->enabled, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
return 0;
}
static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct coh901331_port *rtap = dev_get_drvdata(dev);
clk_enable(rtap->clk);
if (enabled)
writel(1, rtap->virtbase + COH901331_IRQ_MASK);
else
writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
return 0;
}
static const struct rtc_class_ops coh901331_ops = {
.read_time = coh901331_read_time,
.set_time = coh901331_set_time,
.read_alarm = coh901331_read_alarm,
.set_alarm = coh901331_set_alarm,
.alarm_irq_enable = coh901331_alarm_irq_enable,
};
static int __exit coh901331_remove(struct platform_device *pdev)
{
struct coh901331_port *rtap = platform_get_drvdata(pdev);
if (rtap)
clk_unprepare(rtap->clk);
return 0;
}
static int __init coh901331_probe(struct platform_device *pdev)
{
int ret;
struct coh901331_port *rtap;
rtap = devm_kzalloc(&pdev->dev,
sizeof(struct coh901331_port), GFP_KERNEL);
if (!rtap)
return -ENOMEM;
rtap->virtbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtap->virtbase))
return PTR_ERR(rtap->virtbase);
rtap->irq = platform_get_irq(pdev, 0);
if (devm_request_irq(&pdev->dev, rtap->irq, coh901331_interrupt, 0,
"RTC COH 901 331 Alarm", rtap))
return -EIO;
rtap->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(rtap->clk)) {
ret = PTR_ERR(rtap->clk);
dev_err(&pdev->dev, "could not get clock\n");
return ret;
}
rtap->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtap->rtc))
return PTR_ERR(rtap->rtc);
rtap->rtc->ops = &coh901331_ops;
rtap->rtc->range_max = U32_MAX;
/* We enable/disable the clock only to assure it works */
ret = clk_prepare_enable(rtap->clk);
if (ret) {
dev_err(&pdev->dev, "could not enable clock\n");
return ret;
}
clk_disable(rtap->clk);
platform_set_drvdata(pdev, rtap);
ret = devm_rtc_register_device(rtap->rtc);
if (ret)
goto out_no_rtc;
return 0;
out_no_rtc:
clk_unprepare(rtap->clk);
return ret;
}
#ifdef CONFIG_PM_SLEEP
static int coh901331_suspend(struct device *dev)
{
struct coh901331_port *rtap = dev_get_drvdata(dev);
/*
* If this RTC alarm will be used for waking the system up,
* don't disable it of course. Else we just disable the alarm
* and await suspension.
*/
if (device_may_wakeup(dev)) {
enable_irq_wake(rtap->irq);
} else {
clk_enable(rtap->clk);
rtap->irqmaskstore = readl(rtap->virtbase + COH901331_IRQ_MASK);
writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
}
clk_unprepare(rtap->clk);
return 0;
}
static int coh901331_resume(struct device *dev)
{
int ret;
struct coh901331_port *rtap = dev_get_drvdata(dev);
ret = clk_prepare(rtap->clk);
if (ret)
return ret;
if (device_may_wakeup(dev)) {
disable_irq_wake(rtap->irq);
} else {
clk_enable(rtap->clk);
writel(rtap->irqmaskstore, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable(rtap->clk);
}
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(coh901331_pm_ops, coh901331_suspend, coh901331_resume);
static void coh901331_shutdown(struct platform_device *pdev)
{
struct coh901331_port *rtap = platform_get_drvdata(pdev);
clk_enable(rtap->clk);
writel(0, rtap->virtbase + COH901331_IRQ_MASK);
clk_disable_unprepare(rtap->clk);
}
static const struct of_device_id coh901331_dt_match[] = {
{ .compatible = "stericsson,coh901331" },
{},
};
MODULE_DEVICE_TABLE(of, coh901331_dt_match);
static struct platform_driver coh901331_driver = {
.driver = {
.name = "rtc-coh901331",
.pm = &coh901331_pm_ops,
.of_match_table = coh901331_dt_match,
},
.remove = __exit_p(coh901331_remove),
.shutdown = coh901331_shutdown,
};
module_platform_driver_probe(coh901331_driver, coh901331_probe);
MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
MODULE_DESCRIPTION("ST-Ericsson AB COH 901 331 RTC Driver");
MODULE_LICENSE("GPL");

View File

@ -205,7 +205,7 @@ static int __init dc_rtc_probe(struct platform_device *pdev)
return devm_rtc_register_device(rtc->rtc_dev); return devm_rtc_register_device(rtc->rtc_dev);
} }
static const struct of_device_id dc_dt_ids[] = { static const __maybe_unused struct of_device_id dc_dt_ids[] = {
{ .compatible = "cnxt,cx92755-rtc" }, { .compatible = "cnxt,cx92755-rtc" },
{ /* sentinel */ } { /* sentinel */ }
}; };

View File

@ -435,13 +435,12 @@ static const struct rtc_class_ops ds1305_ops = {
static void ds1305_work(struct work_struct *work) static void ds1305_work(struct work_struct *work)
{ {
struct ds1305 *ds1305 = container_of(work, struct ds1305, work); struct ds1305 *ds1305 = container_of(work, struct ds1305, work);
struct mutex *lock = &ds1305->rtc->ops_lock;
struct spi_device *spi = ds1305->spi; struct spi_device *spi = ds1305->spi;
u8 buf[3]; u8 buf[3];
int status; int status;
/* lock to protect ds1305->ctrl */ /* lock to protect ds1305->ctrl */
mutex_lock(lock); rtc_lock(ds1305->rtc);
/* Disable the IRQ, and clear its status ... for now, we "know" /* Disable the IRQ, and clear its status ... for now, we "know"
* that if more than one alarm is active, they're in sync. * that if more than one alarm is active, they're in sync.
@ -459,7 +458,7 @@ static void ds1305_work(struct work_struct *work)
if (status < 0) if (status < 0)
dev_dbg(&spi->dev, "clear irq --> %d\n", status); dev_dbg(&spi->dev, "clear irq --> %d\n", status);
mutex_unlock(lock); rtc_unlock(ds1305->rtc);
if (!test_bit(FLAG_EXITING, &ds1305->flags)) if (!test_bit(FLAG_EXITING, &ds1305->flags))
enable_irq(spi->irq); enable_irq(spi->irq);

View File

@ -558,11 +558,10 @@ static u8 do_trickle_setup_rx8130(struct ds1307 *ds1307, u32 ohms, bool diode)
static irqreturn_t rx8130_irq(int irq, void *dev_id) static irqreturn_t rx8130_irq(int irq, void *dev_id)
{ {
struct ds1307 *ds1307 = dev_id; struct ds1307 *ds1307 = dev_id;
struct mutex *lock = &ds1307->rtc->ops_lock;
u8 ctl[3]; u8 ctl[3];
int ret; int ret;
mutex_lock(lock); rtc_lock(ds1307->rtc);
/* Read control registers. */ /* Read control registers. */
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl,
@ -582,7 +581,7 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id)
rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF); rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);
out: out:
mutex_unlock(lock); rtc_unlock(ds1307->rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -139,7 +139,7 @@ static const struct i2c_device_id ds1672_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, ds1672_id); MODULE_DEVICE_TABLE(i2c, ds1672_id);
static const struct of_device_id ds1672_of_match[] = { static const __maybe_unused struct of_device_id ds1672_of_match[] = {
{ .compatible = "dallas,ds1672" }, { .compatible = "dallas,ds1672" },
{ } { }
}; };

View File

@ -658,7 +658,6 @@ ds1685_rtc_irq_handler(int irq, void *dev_id)
{ {
struct platform_device *pdev = dev_id; struct platform_device *pdev = dev_id;
struct ds1685_priv *rtc = platform_get_drvdata(pdev); struct ds1685_priv *rtc = platform_get_drvdata(pdev);
struct mutex *rtc_mutex;
u8 ctrlb, ctrlc; u8 ctrlb, ctrlc;
unsigned long events = 0; unsigned long events = 0;
u8 num_irqs = 0; u8 num_irqs = 0;
@ -667,8 +666,7 @@ ds1685_rtc_irq_handler(int irq, void *dev_id)
if (unlikely(!rtc)) if (unlikely(!rtc))
return IRQ_HANDLED; return IRQ_HANDLED;
rtc_mutex = &rtc->dev->ops_lock; rtc_lock(rtc->dev);
mutex_lock(rtc_mutex);
/* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */ /* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */
ctrlb = rtc->read(rtc, RTC_CTRL_B); ctrlb = rtc->read(rtc, RTC_CTRL_B);
@ -713,7 +711,7 @@ ds1685_rtc_irq_handler(int irq, void *dev_id)
} }
} }
rtc_update_irq(rtc->dev, num_irqs, events); rtc_update_irq(rtc->dev, num_irqs, events);
mutex_unlock(rtc_mutex); rtc_unlock(rtc->dev);
return events ? IRQ_HANDLED : IRQ_NONE; return events ? IRQ_HANDLED : IRQ_NONE;
} }

View File

@ -406,11 +406,10 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
{ {
struct device *dev = dev_id; struct device *dev = dev_id;
struct ds3232 *ds3232 = dev_get_drvdata(dev); struct ds3232 *ds3232 = dev_get_drvdata(dev);
struct mutex *lock = &ds3232->rtc->ops_lock;
int ret; int ret;
int stat, control; int stat, control;
mutex_lock(lock); rtc_lock(ds3232->rtc);
ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat); ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
if (ret) if (ret)
@ -448,7 +447,7 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
} }
unlock: unlock:
mutex_unlock(lock); rtc_unlock(ds3232->rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -593,7 +592,7 @@ static const struct i2c_device_id ds3232_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, ds3232_id); MODULE_DEVICE_TABLE(i2c, ds3232_id);
static const struct of_device_id ds3232_of_match[] = { static const __maybe_unused struct of_device_id ds3232_of_match[] = {
{ .compatible = "dallas,ds3232" }, { .compatible = "dallas,ds3232" },
{ } { }
}; };

View File

@ -428,10 +428,9 @@ static irqreturn_t hym8563_irq(int irq, void *dev_id)
{ {
struct hym8563 *hym8563 = (struct hym8563 *)dev_id; struct hym8563 *hym8563 = (struct hym8563 *)dev_id;
struct i2c_client *client = hym8563->client; struct i2c_client *client = hym8563->client;
struct mutex *lock = &hym8563->rtc->ops_lock;
int data, ret; int data, ret;
mutex_lock(lock); rtc_lock(hym8563->rtc);
/* Clear the alarm flag */ /* Clear the alarm flag */
@ -451,7 +450,7 @@ static irqreturn_t hym8563_irq(int irq, void *dev_id)
} }
out: out:
mutex_unlock(lock); rtc_unlock(hym8563->rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -99,7 +99,7 @@ static const struct i2c_device_id isl1208_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, isl1208_id); MODULE_DEVICE_TABLE(i2c, isl1208_id);
static const struct of_device_id isl1208_of_match[] = { static const __maybe_unused struct of_device_id isl1208_of_match[] = {
{ .compatible = "isil,isl1208", .data = &isl1208_configs[TYPE_ISL1208] }, { .compatible = "isil,isl1208", .data = &isl1208_configs[TYPE_ISL1208] },
{ .compatible = "isil,isl1209", .data = &isl1208_configs[TYPE_ISL1209] }, { .compatible = "isil,isl1209", .data = &isl1208_configs[TYPE_ISL1209] },
{ .compatible = "isil,isl1218", .data = &isl1208_configs[TYPE_ISL1218] }, { .compatible = "isil,isl1218", .data = &isl1208_configs[TYPE_ISL1218] },

View File

@ -85,7 +85,7 @@ static const struct i2c_device_id m41t80_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, m41t80_id); MODULE_DEVICE_TABLE(i2c, m41t80_id);
static const struct of_device_id m41t80_of_match[] = { static const __maybe_unused struct of_device_id m41t80_of_match[] = {
{ {
.compatible = "st,m41t62", .compatible = "st,m41t62",
.data = (void *)(M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT) .data = (void *)(M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT)
@ -158,21 +158,20 @@ static irqreturn_t m41t80_handle_irq(int irq, void *dev_id)
{ {
struct i2c_client *client = dev_id; struct i2c_client *client = dev_id;
struct m41t80_data *m41t80 = i2c_get_clientdata(client); struct m41t80_data *m41t80 = i2c_get_clientdata(client);
struct mutex *lock = &m41t80->rtc->ops_lock;
unsigned long events = 0; unsigned long events = 0;
int flags, flags_afe; int flags, flags_afe;
mutex_lock(lock); rtc_lock(m41t80->rtc);
flags_afe = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); flags_afe = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
if (flags_afe < 0) { if (flags_afe < 0) {
mutex_unlock(lock); rtc_unlock(m41t80->rtc);
return IRQ_NONE; return IRQ_NONE;
} }
flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (flags <= 0) { if (flags <= 0) {
mutex_unlock(lock); rtc_unlock(m41t80->rtc);
return IRQ_NONE; return IRQ_NONE;
} }
@ -189,7 +188,7 @@ static irqreturn_t m41t80_handle_irq(int irq, void *dev_id)
flags_afe); flags_afe);
} }
mutex_unlock(lock); rtc_unlock(m41t80->rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -397,10 +396,13 @@ static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return 0; return 0;
} }
static struct rtc_class_ops m41t80_rtc_ops = { static const struct rtc_class_ops m41t80_rtc_ops = {
.read_time = m41t80_rtc_read_time, .read_time = m41t80_rtc_read_time,
.set_time = m41t80_rtc_set_time, .set_time = m41t80_rtc_set_time,
.proc = m41t80_rtc_proc, .proc = m41t80_rtc_proc,
.read_alarm = m41t80_read_alarm,
.set_alarm = m41t80_set_alarm,
.alarm_irq_enable = m41t80_alarm_irq_enable,
}; };
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
@ -913,13 +915,10 @@ static int m41t80_probe(struct i2c_client *client,
wakeup_source = false; wakeup_source = false;
} }
} }
if (client->irq > 0 || wakeup_source) { if (client->irq > 0 || wakeup_source)
m41t80_rtc_ops.read_alarm = m41t80_read_alarm;
m41t80_rtc_ops.set_alarm = m41t80_set_alarm;
m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable;
/* Enable the wakealarm */
device_init_wakeup(&client->dev, true); device_init_wakeup(&client->dev, true);
} else
clear_bit(RTC_FEATURE_ALARM, m41t80_data->rtc->features);
m41t80_data->rtc->ops = &m41t80_rtc_ops; m41t80_data->rtc->ops = &m41t80_rtc_ops;
m41t80_data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; m41t80_data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;

View File

@ -313,11 +313,6 @@ static const struct rtc_class_ops m48t59_rtc_ops = {
.alarm_irq_enable = m48t59_rtc_alarm_irq_enable, .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 int m48t59_nvram_read(void *priv, unsigned int offset, void *val, static int m48t59_nvram_read(void *priv, unsigned int offset, void *val,
size_t size) size_t size)
{ {
@ -366,7 +361,6 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
struct m48t59_private *m48t59 = NULL; struct m48t59_private *m48t59 = NULL;
struct resource *res; struct resource *res;
int ret = -ENOMEM; int ret = -ENOMEM;
const struct rtc_class_ops *ops;
struct nvmem_config nvmem_cfg = { struct nvmem_config nvmem_cfg = {
.name = "m48t59-", .name = "m48t59-",
.word_size = 1, .word_size = 1,
@ -438,17 +432,21 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
} }
m48t59->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(m48t59->rtc))
return PTR_ERR(m48t59->rtc);
switch (pdata->type) { switch (pdata->type) {
case M48T59RTC_TYPE_M48T59: case M48T59RTC_TYPE_M48T59:
ops = &m48t59_rtc_ops;
pdata->offset = 0x1ff0; pdata->offset = 0x1ff0;
break; break;
case M48T59RTC_TYPE_M48T02: case M48T59RTC_TYPE_M48T02:
ops = &m48t02_rtc_ops; clear_bit(RTC_FEATURE_ALARM, m48t59->rtc->features);
pdata->offset = 0x7f0; pdata->offset = 0x7f0;
break; break;
case M48T59RTC_TYPE_M48T08: case M48T59RTC_TYPE_M48T08:
ops = &m48t02_rtc_ops; clear_bit(RTC_FEATURE_ALARM, m48t59->rtc->features);
pdata->offset = 0x1ff0; pdata->offset = 0x1ff0;
break; break;
default: default:
@ -459,11 +457,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
spin_lock_init(&m48t59->lock); spin_lock_init(&m48t59->lock);
platform_set_drvdata(pdev, m48t59); platform_set_drvdata(pdev, m48t59);
m48t59->rtc = devm_rtc_allocate_device(&pdev->dev); m48t59->rtc->ops = &m48t59_rtc_ops;
if (IS_ERR(m48t59->rtc))
return PTR_ERR(m48t59->rtc);
m48t59->rtc->ops = ops;
nvmem_cfg.size = pdata->offset; nvmem_cfg.size = pdata->offset;
ret = devm_rtc_nvmem_register(m48t59->rtc, &nvmem_cfg); ret = devm_rtc_nvmem_register(m48t59->rtc, &nvmem_cfg);

View File

@ -350,10 +350,9 @@ static irqreturn_t mcp795_irq(int irq, void *data)
{ {
struct spi_device *spi = data; struct spi_device *spi = data;
struct rtc_device *rtc = spi_get_drvdata(spi); struct rtc_device *rtc = spi_get_drvdata(spi);
struct mutex *lock = &rtc->ops_lock;
int ret; int ret;
mutex_lock(lock); rtc_lock(rtc);
/* Disable alarm. /* Disable alarm.
* There is no need to clear ALM0IF (Alarm 0 Interrupt Flag) bit, * There is no need to clear ALM0IF (Alarm 0 Interrupt Flag) bit,
@ -365,7 +364,7 @@ static irqreturn_t mcp795_irq(int irq, void *data)
"Failed to disable alarm in IRQ (ret=%d)\n", ret); "Failed to disable alarm in IRQ (ret=%d)\n", ret);
rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
mutex_unlock(lock); rtc_unlock(rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -380,7 +380,7 @@ out_disable_vdd:
return ret; return ret;
} }
static const struct of_device_id meson_rtc_dt_match[] = { static const __maybe_unused struct of_device_id meson_rtc_dt_match[] = {
{ .compatible = "amlogic,meson6-rtc", }, { .compatible = "amlogic,meson6-rtc", },
{ .compatible = "amlogic,meson8-rtc", }, { .compatible = "amlogic,meson8-rtc", },
{ .compatible = "amlogic,meson8b-rtc", }, { .compatible = "amlogic,meson8b-rtc", },

View File

@ -200,11 +200,6 @@ static irqreturn_t mv_rtc_interrupt(int irq, void *data)
static const struct rtc_class_ops mv_rtc_ops = { static const struct rtc_class_ops mv_rtc_ops = {
.read_time = mv_rtc_read_time, .read_time = mv_rtc_read_time,
.set_time = mv_rtc_set_time, .set_time = mv_rtc_set_time,
};
static const struct rtc_class_ops mv_rtc_alarm_ops = {
.read_time = mv_rtc_read_time,
.set_time = mv_rtc_set_time,
.read_alarm = mv_rtc_read_alarm, .read_alarm = mv_rtc_read_alarm,
.set_alarm = mv_rtc_set_alarm, .set_alarm = mv_rtc_set_alarm,
.alarm_irq_enable = mv_rtc_alarm_irq_enable, .alarm_irq_enable = mv_rtc_alarm_irq_enable,
@ -268,13 +263,12 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
} }
} }
if (pdata->irq >= 0) { if (pdata->irq >= 0)
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
pdata->rtc->ops = &mv_rtc_alarm_ops; else
} else { clear_bit(RTC_FEATURE_ALARM, pdata->rtc->features);
pdata->rtc->ops = &mv_rtc_ops;
}
pdata->rtc->ops = &mv_rtc_ops;
pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pdata->rtc->range_max = RTC_TIMESTAMP_END_2099; pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;

View File

@ -189,11 +189,10 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
struct platform_device *pdev = dev_id; struct platform_device *pdev = dev_id;
struct rtc_plat_data *pdata = platform_get_drvdata(pdev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
unsigned long flags;
u32 status; u32 status;
u32 events = 0; u32 events = 0;
spin_lock_irqsave(&pdata->rtc->irq_lock, flags); spin_lock(&pdata->rtc->irq_lock);
status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR);
/* clear interrupt sources */ /* clear interrupt sources */
writew(status, ioaddr + RTC_RTCISR); writew(status, ioaddr + RTC_RTCISR);
@ -209,7 +208,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
events |= (RTC_PF | RTC_IRQF); events |= (RTC_PF | RTC_IRQF);
rtc_update_irq(pdata->rtc, 1, events); rtc_update_irq(pdata->rtc, 1, events);
spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); spin_unlock(&pdata->rtc->irq_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -74,13 +74,12 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
struct device *dev = dev_id; struct device *dev = dev_id;
struct mxc_rtc_data *pdata = dev_get_drvdata(dev); struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
void __iomem *ioaddr = pdata->ioaddr; void __iomem *ioaddr = pdata->ioaddr;
unsigned long flags;
u32 lp_status; u32 lp_status;
u32 lp_cr; u32 lp_cr;
spin_lock_irqsave(&pdata->lock, flags); spin_lock(&pdata->lock);
if (clk_enable(pdata->clk)) { if (clk_enable(pdata->clk)) {
spin_unlock_irqrestore(&pdata->lock, flags); spin_unlock(&pdata->lock);
return IRQ_NONE; return IRQ_NONE;
} }
@ -104,7 +103,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
mxc_rtc_sync_lp_locked(dev, ioaddr); mxc_rtc_sync_lp_locked(dev, ioaddr);
clk_disable(pdata->clk); clk_disable(pdata->clk);
spin_unlock_irqrestore(&pdata->lock, flags); spin_unlock(&pdata->lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -224,32 +224,35 @@ static int opal_tpo_alarm_irq_enable(struct device *dev, unsigned int enabled)
return enabled ? 0 : opal_set_tpo_time(dev, &alarm); return enabled ? 0 : opal_set_tpo_time(dev, &alarm);
} }
static struct rtc_class_ops opal_rtc_ops = { static const struct rtc_class_ops opal_rtc_ops = {
.read_time = opal_get_rtc_time, .read_time = opal_get_rtc_time,
.set_time = opal_set_rtc_time, .set_time = opal_set_rtc_time,
.read_alarm = opal_get_tpo_time,
.set_alarm = opal_set_tpo_time,
.alarm_irq_enable = opal_tpo_alarm_irq_enable,
}; };
static int opal_rtc_probe(struct platform_device *pdev) static int opal_rtc_probe(struct platform_device *pdev)
{ {
struct rtc_device *rtc; struct rtc_device *rtc;
if (pdev->dev.of_node && rtc = devm_rtc_allocate_device(&pdev->dev);
(of_property_read_bool(pdev->dev.of_node, "wakeup-source") ||
of_property_read_bool(pdev->dev.of_node, "has-tpo")/* legacy */)) {
device_set_wakeup_capable(&pdev->dev, true);
opal_rtc_ops.read_alarm = opal_get_tpo_time;
opal_rtc_ops.set_alarm = opal_set_tpo_time;
opal_rtc_ops.alarm_irq_enable = opal_tpo_alarm_irq_enable;
}
rtc = devm_rtc_device_register(&pdev->dev, DRVNAME, &opal_rtc_ops,
THIS_MODULE);
if (IS_ERR(rtc)) if (IS_ERR(rtc))
return PTR_ERR(rtc); return PTR_ERR(rtc);
if (pdev->dev.of_node &&
(of_property_read_bool(pdev->dev.of_node, "wakeup-source") ||
of_property_read_bool(pdev->dev.of_node, "has-tpo")/* legacy */))
device_set_wakeup_capable(&pdev->dev, true);
else
clear_bit(RTC_FEATURE_ALARM, rtc->features);
rtc->ops = &opal_rtc_ops;
rtc->range_min = RTC_TIMESTAMP_BEGIN_0000;
rtc->range_max = RTC_TIMESTAMP_END_9999;
rtc->uie_unsupported = 1; rtc->uie_unsupported = 1;
return 0; return devm_rtc_register_device(rtc);
} }
static const struct of_device_id opal_rtc_match[] = { static const struct of_device_id opal_rtc_match[] = {

View File

@ -307,11 +307,10 @@ static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
static irqreturn_t pcf2123_rtc_irq(int irq, void *dev) static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
{ {
struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
struct mutex *lock = &pcf2123->rtc->ops_lock;
unsigned int val = 0; unsigned int val = 0;
int ret = IRQ_NONE; int ret = IRQ_NONE;
mutex_lock(lock); rtc_lock(pcf2123->rtc);
regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val); regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val);
/* Alarm? */ /* Alarm? */
@ -324,7 +323,7 @@ static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
rtc_update_irq(pcf2123->rtc, 1, RTC_IRQF | RTC_AF); rtc_update_irq(pcf2123->rtc, 1, RTC_IRQF | RTC_AF);
} }
mutex_unlock(lock); rtc_unlock(pcf2123->rtc);
return ret; return ret;
} }

View File

@ -26,6 +26,7 @@
/* Control register 1 */ /* Control register 1 */
#define PCF2127_REG_CTRL1 0x00 #define PCF2127_REG_CTRL1 0x00
#define PCF2127_BIT_CTRL1_POR_OVRD BIT(3)
#define PCF2127_BIT_CTRL1_TSF1 BIT(4) #define PCF2127_BIT_CTRL1_TSF1 BIT(4)
/* Control register 2 */ /* Control register 2 */
#define PCF2127_REG_CTRL2 0x01 #define PCF2127_REG_CTRL2 0x01
@ -57,6 +58,9 @@
#define PCF2127_REG_ALARM_DM 0x0D #define PCF2127_REG_ALARM_DM 0x0D
#define PCF2127_REG_ALARM_DW 0x0E #define PCF2127_REG_ALARM_DW 0x0E
#define PCF2127_BIT_ALARM_AE BIT(7) #define PCF2127_BIT_ALARM_AE BIT(7)
/* CLKOUT control register */
#define PCF2127_REG_CLKOUT 0x0f
#define PCF2127_BIT_CLKOUT_OTPR BIT(5)
/* Watchdog registers */ /* Watchdog registers */
#define PCF2127_REG_WD_CTL 0x10 #define PCF2127_REG_WD_CTL 0x10
#define PCF2127_BIT_WD_CTL_TF0 BIT(0) #define PCF2127_BIT_WD_CTL_TF0 BIT(0)
@ -225,12 +229,6 @@ static int pcf2127_rtc_ioctl(struct device *dev,
} }
} }
static const struct rtc_class_ops pcf2127_rtc_ops = {
.ioctl = pcf2127_rtc_ioctl,
.read_time = pcf2127_rtc_read_time,
.set_time = pcf2127_rtc_set_time,
};
static int pcf2127_nvmem_read(void *priv, unsigned int offset, static int pcf2127_nvmem_read(void *priv, unsigned int offset,
void *val, size_t bytes) void *val, size_t bytes)
{ {
@ -459,7 +457,7 @@ static irqreturn_t pcf2127_rtc_irq(int irq, void *dev)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static const struct rtc_class_ops pcf2127_rtc_alrm_ops = { static const struct rtc_class_ops pcf2127_rtc_ops = {
.ioctl = pcf2127_rtc_ioctl, .ioctl = pcf2127_rtc_ioctl,
.read_time = pcf2127_rtc_read_time, .read_time = pcf2127_rtc_read_time,
.set_time = pcf2127_rtc_set_time, .set_time = pcf2127_rtc_set_time,
@ -560,10 +558,11 @@ static const struct attribute_group pcf2127_attr_group = {
}; };
static int pcf2127_probe(struct device *dev, struct regmap *regmap, static int pcf2127_probe(struct device *dev, struct regmap *regmap,
int alarm_irq, const char *name, bool has_nvmem) int alarm_irq, const char *name, bool is_pcf2127)
{ {
struct pcf2127 *pcf2127; struct pcf2127 *pcf2127;
int ret = 0; int ret = 0;
unsigned int val;
dev_dbg(dev, "%s\n", __func__); dev_dbg(dev, "%s\n", __func__);
@ -584,6 +583,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099; pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099;
pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */ pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */
pcf2127->rtc->uie_unsupported = 1; pcf2127->rtc->uie_unsupported = 1;
clear_bit(RTC_FEATURE_ALARM, pcf2127->rtc->features);
if (alarm_irq > 0) { if (alarm_irq > 0) {
ret = devm_request_threaded_irq(dev, alarm_irq, NULL, ret = devm_request_threaded_irq(dev, alarm_irq, NULL,
@ -598,10 +598,10 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
if (alarm_irq > 0 || device_property_read_bool(dev, "wakeup-source")) { if (alarm_irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
device_init_wakeup(dev, true); device_init_wakeup(dev, true);
pcf2127->rtc->ops = &pcf2127_rtc_alrm_ops; set_bit(RTC_FEATURE_ALARM, pcf2127->rtc->features);
} }
if (has_nvmem) { if (is_pcf2127) {
struct nvmem_config nvmem_cfg = { struct nvmem_config nvmem_cfg = {
.priv = pcf2127, .priv = pcf2127,
.reg_read = pcf2127_nvmem_read, .reg_read = pcf2127_nvmem_read,
@ -612,10 +612,34 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
ret = devm_rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg); ret = devm_rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg);
} }
/*
* The "Power-On Reset Override" facility prevents the RTC to do a reset
* after power on. For normal operation the PORO must be disabled.
*/
regmap_clear_bits(pcf2127->regmap, PCF2127_REG_CTRL1,
PCF2127_BIT_CTRL1_POR_OVRD);
ret = regmap_read(pcf2127->regmap, PCF2127_REG_CLKOUT, &val);
if (ret < 0)
return ret;
if (!(val & PCF2127_BIT_CLKOUT_OTPR)) {
ret = regmap_set_bits(pcf2127->regmap, PCF2127_REG_CLKOUT,
PCF2127_BIT_CLKOUT_OTPR);
if (ret < 0)
return ret;
msleep(100);
}
/* /*
* Watchdog timer enabled and reset pin /RST activated when timed out. * Watchdog timer enabled and reset pin /RST activated when timed out.
* Select 1Hz clock source for watchdog timer. * Select 1Hz clock source for watchdog timer.
* Note: Countdown timer disabled and not available. * Note: Countdown timer disabled and not available.
* For pca2129, pcf2129, only bit[7] is for Symbol WD_CD
* of register watchdg_tim_ctl. The bit[6] is labeled
* as T. Bits labeled as T must always be written with
* logic 0.
*/ */
ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_WD_CTL, ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_WD_CTL,
PCF2127_BIT_WD_CTL_CD1 | PCF2127_BIT_WD_CTL_CD1 |
@ -623,7 +647,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
PCF2127_BIT_WD_CTL_TF1 | PCF2127_BIT_WD_CTL_TF1 |
PCF2127_BIT_WD_CTL_TF0, PCF2127_BIT_WD_CTL_TF0,
PCF2127_BIT_WD_CTL_CD1 | PCF2127_BIT_WD_CTL_CD1 |
PCF2127_BIT_WD_CTL_CD0 | (is_pcf2127 ? PCF2127_BIT_WD_CTL_CD0 : 0) |
PCF2127_BIT_WD_CTL_TF1); PCF2127_BIT_WD_CTL_TF1);
if (ret) { if (ret) {
dev_err(dev, "%s: watchdog config (wd_ctl) failed\n", __func__); dev_err(dev, "%s: watchdog config (wd_ctl) failed\n", __func__);

View File

@ -307,14 +307,6 @@ static int pcf85063_ioctl(struct device *dev, unsigned int cmd,
} }
static const struct rtc_class_ops pcf85063_rtc_ops = { static const struct rtc_class_ops pcf85063_rtc_ops = {
.read_time = pcf85063_rtc_read_time,
.set_time = pcf85063_rtc_set_time,
.read_offset = pcf85063_read_offset,
.set_offset = pcf85063_set_offset,
.ioctl = pcf85063_ioctl,
};
static const struct rtc_class_ops pcf85063_rtc_ops_alarm = {
.read_time = pcf85063_rtc_read_time, .read_time = pcf85063_rtc_read_time,
.set_time = pcf85063_rtc_set_time, .set_time = pcf85063_rtc_set_time,
.read_offset = pcf85063_read_offset, .read_offset = pcf85063_read_offset,
@ -509,15 +501,6 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
} }
#endif #endif
static const struct pcf85063_config pcf85063a_config = {
.regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x11,
},
.has_alarms = 1,
};
static const struct pcf85063_config pcf85063tp_config = { static const struct pcf85063_config pcf85063tp_config = {
.regmap = { .regmap = {
.reg_bits = 8, .reg_bits = 8,
@ -526,16 +509,6 @@ static const struct pcf85063_config pcf85063tp_config = {
}, },
}; };
static const struct pcf85063_config rv8263_config = {
.regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x11,
},
.has_alarms = 1,
.force_cap_7000 = 1,
};
static int pcf85063_probe(struct i2c_client *client) static int pcf85063_probe(struct i2c_client *client)
{ {
struct pcf85063 *pcf85063; struct pcf85063 *pcf85063;
@ -587,6 +560,7 @@ static int pcf85063_probe(struct i2c_client *client)
pcf85063->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; pcf85063->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pcf85063->rtc->range_max = RTC_TIMESTAMP_END_2099; pcf85063->rtc->range_max = RTC_TIMESTAMP_END_2099;
pcf85063->rtc->uie_unsupported = 1; pcf85063->rtc->uie_unsupported = 1;
clear_bit(RTC_FEATURE_ALARM, pcf85063->rtc->features);
if (config->has_alarms && client->irq > 0) { if (config->has_alarms && client->irq > 0) {
err = devm_request_threaded_irq(&client->dev, client->irq, err = devm_request_threaded_irq(&client->dev, client->irq,
@ -597,7 +571,7 @@ static int pcf85063_probe(struct i2c_client *client)
dev_warn(&pcf85063->rtc->dev, dev_warn(&pcf85063->rtc->dev,
"unable to request IRQ, alarms disabled\n"); "unable to request IRQ, alarms disabled\n");
} else { } else {
pcf85063->rtc->ops = &pcf85063_rtc_ops_alarm; set_bit(RTC_FEATURE_ALARM, pcf85063->rtc->features);
device_init_wakeup(&client->dev, true); device_init_wakeup(&client->dev, true);
err = dev_pm_set_wake_irq(&client->dev, client->irq); err = dev_pm_set_wake_irq(&client->dev, client->irq);
if (err) if (err)
@ -618,6 +592,25 @@ static int pcf85063_probe(struct i2c_client *client)
} }
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct pcf85063_config pcf85063a_config = {
.regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x11,
},
.has_alarms = 1,
};
static const struct pcf85063_config rv8263_config = {
.regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x11,
},
.has_alarms = 1,
.force_cap_7000 = 1,
};
static const struct of_device_id pcf85063_of_match[] = { static const struct of_device_id pcf85063_of_match[] = {
{ .compatible = "nxp,pcf85063", .data = &pcf85063tp_config }, { .compatible = "nxp,pcf85063", .data = &pcf85063tp_config },
{ .compatible = "nxp,pcf85063tp", .data = &pcf85063tp_config }, { .compatible = "nxp,pcf85063tp", .data = &pcf85063tp_config },

View File

@ -285,11 +285,6 @@ static irqreturn_t pcf85363_rtc_handle_irq(int irq, void *dev_id)
static const struct rtc_class_ops rtc_ops = { static const struct rtc_class_ops rtc_ops = {
.read_time = pcf85363_rtc_read_time, .read_time = pcf85363_rtc_read_time,
.set_time = pcf85363_rtc_set_time, .set_time = pcf85363_rtc_set_time,
};
static const struct rtc_class_ops rtc_ops_alarm = {
.read_time = pcf85363_rtc_read_time,
.set_time = pcf85363_rtc_set_time,
.read_alarm = pcf85363_rtc_read_alarm, .read_alarm = pcf85363_rtc_read_alarm,
.set_alarm = pcf85363_rtc_set_alarm, .set_alarm = pcf85363_rtc_set_alarm,
.alarm_irq_enable = pcf85363_rtc_alarm_irq_enable, .alarm_irq_enable = pcf85363_rtc_alarm_irq_enable,
@ -403,6 +398,7 @@ static int pcf85363_probe(struct i2c_client *client,
pcf85363->rtc->ops = &rtc_ops; pcf85363->rtc->ops = &rtc_ops;
pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pcf85363->rtc->range_max = RTC_TIMESTAMP_END_2099; pcf85363->rtc->range_max = RTC_TIMESTAMP_END_2099;
clear_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features);
if (client->irq > 0) { if (client->irq > 0) {
regmap_write(pcf85363->regmap, CTRL_FLAGS, 0); regmap_write(pcf85363->regmap, CTRL_FLAGS, 0);
@ -415,7 +411,7 @@ static int pcf85363_probe(struct i2c_client *client,
if (ret) if (ret)
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
else else
pcf85363->rtc->ops = &rtc_ops_alarm; set_bit(RTC_FEATURE_ALARM, pcf85363->rtc->features);
} }
ret = devm_rtc_register_device(pcf85363->rtc); ret = devm_rtc_register_device(pcf85363->rtc);
@ -428,7 +424,7 @@ static int pcf85363_probe(struct i2c_client *client,
return ret; return ret;
} }
static const struct of_device_id dev_ids[] = { static const __maybe_unused struct of_device_id dev_ids[] = {
{ .compatible = "nxp,pcf85263", .data = &pcf_85263_config }, { .compatible = "nxp,pcf85263", .data = &pcf_85263_config },
{ .compatible = "nxp,pcf85363", .data = &pcf_85363_config }, { .compatible = "nxp,pcf85363", .data = &pcf_85363_config },
{ /* sentinel */ } { /* sentinel */ }

View File

@ -597,6 +597,7 @@ static int pcf8563_probe(struct i2c_client *client,
static const struct i2c_device_id pcf8563_id[] = { static const struct i2c_device_id pcf8563_id[] = {
{ "pcf8563", 0 }, { "pcf8563", 0 },
{ "rtc8564", 0 }, { "rtc8564", 0 },
{ "pca8565", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, pcf8563_id); MODULE_DEVICE_TABLE(i2c, pcf8563_id);
@ -606,6 +607,7 @@ static const struct of_device_id pcf8563_of_match[] = {
{ .compatible = "nxp,pcf8563" }, { .compatible = "nxp,pcf8563" },
{ .compatible = "epson,rtc8564" }, { .compatible = "epson,rtc8564" },
{ .compatible = "microcrystal,rv8564" }, { .compatible = "microcrystal,rv8564" },
{ .compatible = "nxp,pca8565" },
{} {}
}; };
MODULE_DEVICE_TABLE(of, pcf8563_of_match); MODULE_DEVICE_TABLE(of, pcf8563_of_match);

View File

@ -352,12 +352,8 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
} }
} }
if (!adev->irq[0]) { if (!adev->irq[0])
/* When there's no interrupt, no point in exposing the alarm */ clear_bit(RTC_FEATURE_ALARM, ldata->rtc->features);
ops->read_alarm = NULL;
ops->set_alarm = NULL;
ops->alarm_irq_enable = NULL;
}
device_init_wakeup(&adev->dev, true); device_init_wakeup(&adev->dev, true);
ldata->rtc = devm_rtc_allocate_device(&adev->dev); ldata->rtc = devm_rtc_allocate_device(&adev->dev);

View File

@ -20,6 +20,7 @@
/* RTC_CTRL register bit fields */ /* RTC_CTRL register bit fields */
#define PM8xxx_RTC_ENABLE BIT(7) #define PM8xxx_RTC_ENABLE BIT(7)
#define PM8xxx_RTC_ALARM_CLEAR BIT(0) #define PM8xxx_RTC_ALARM_CLEAR BIT(0)
#define PM8xxx_RTC_ALARM_ENABLE BIT(7)
#define NUM_8_BIT_RTC_REGS 0x4 #define NUM_8_BIT_RTC_REGS 0x4
@ -265,6 +266,7 @@ rtc_rw_fail:
static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ {
int rc; int rc;
unsigned int ctrl_reg;
u8 value[NUM_8_BIT_RTC_REGS]; u8 value[NUM_8_BIT_RTC_REGS];
unsigned long secs; unsigned long secs;
struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
@ -282,6 +284,13 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
rtc_time64_to_tm(secs, &alarm->time); rtc_time64_to_tm(secs, &alarm->time);
rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
if (rc) {
dev_err(dev, "Read from RTC alarm control register failed\n");
return rc;
}
alarm->enabled = !!(ctrl_reg & PM8xxx_RTC_ALARM_ENABLE);
dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n", dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n",
&alarm->time, &alarm->time); &alarm->time, &alarm->time);
@ -343,16 +352,15 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; const struct pm8xxx_rtc_regs *regs = rtc_dd->regs;
unsigned int ctrl_reg; unsigned int ctrl_reg;
int rc; int rc;
unsigned long irq_flags;
rtc_update_irq(rtc_dd->rtc, 1, RTC_IRQF | RTC_AF); rtc_update_irq(rtc_dd->rtc, 1, RTC_IRQF | RTC_AF);
spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); spin_lock(&rtc_dd->ctrl_reg_lock);
/* Clear the alarm enable bit */ /* Clear the alarm enable bit */
rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg);
if (rc) { if (rc) {
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); spin_unlock(&rtc_dd->ctrl_reg_lock);
goto rtc_alarm_handled; goto rtc_alarm_handled;
} }
@ -360,13 +368,13 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg);
if (rc) { if (rc) {
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); spin_unlock(&rtc_dd->ctrl_reg_lock);
dev_err(rtc_dd->rtc_dev, dev_err(rtc_dd->rtc_dev,
"Write to alarm control register failed\n"); "Write to alarm control register failed\n");
goto rtc_alarm_handled; goto rtc_alarm_handled;
} }
spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); spin_unlock(&rtc_dd->ctrl_reg_lock);
/* Clear RTC alarm register */ /* Clear RTC alarm register */
rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl2, &ctrl_reg); rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl2, &ctrl_reg);

View File

@ -320,11 +320,10 @@ static irqreturn_t rtc7301_irq_handler(int irq, void *dev_id)
{ {
struct rtc_device *rtc = dev_id; struct rtc_device *rtc = dev_id;
struct rtc7301_priv *priv = dev_get_drvdata(rtc->dev.parent); struct rtc7301_priv *priv = dev_get_drvdata(rtc->dev.parent);
unsigned long flags;
irqreturn_t ret = IRQ_NONE; irqreturn_t ret = IRQ_NONE;
u8 alrm_ctrl; u8 alrm_ctrl;
spin_lock_irqsave(&priv->lock, flags); spin_lock(&priv->lock);
rtc7301_select_bank(priv, 1); rtc7301_select_bank(priv, 1);
@ -335,7 +334,7 @@ static irqreturn_t rtc7301_irq_handler(int irq, void *dev_id)
rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock(&priv->lock);
return ret; return ret;
} }

View File

@ -83,7 +83,7 @@ static const struct i2c_device_id rs5c372_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, rs5c372_id); MODULE_DEVICE_TABLE(i2c, rs5c372_id);
static const struct of_device_id rs5c372_of_match[] = { static const __maybe_unused struct of_device_id rs5c372_of_match[] = {
{ {
.compatible = "ricoh,r2025sd", .compatible = "ricoh,r2025sd",
.data = (void *)rtc_r2025sd .data = (void *)rtc_r2025sd

View File

@ -265,8 +265,7 @@ static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
} }
if (status & RV3028_STATUS_PORF) status &= ~RV3028_STATUS_PORF;
dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");
if (status & RV3028_STATUS_TF) { if (status & RV3028_STATUS_TF) {
status |= RV3028_STATUS_TF; status |= RV3028_STATUS_TF;
@ -311,10 +310,8 @@ static int rv3028_get_time(struct device *dev, struct rtc_time *tm)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (status & RV3028_STATUS_PORF) { if (status & RV3028_STATUS_PORF)
dev_warn(dev, "Voltage low, data is invalid.\n");
return -EINVAL; return -EINVAL;
}
ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date)); ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date));
if (ret) if (ret)
@ -770,9 +767,12 @@ static int rv3028_clkout_register_clk(struct rv3028_data *rv3028,
} }
#endif #endif
static struct rtc_class_ops rv3028_rtc_ops = { static const struct rtc_class_ops rv3028_rtc_ops = {
.read_time = rv3028_get_time, .read_time = rv3028_get_time,
.set_time = rv3028_set_time, .set_time = rv3028_set_time,
.read_alarm = rv3028_get_alarm,
.set_alarm = rv3028_set_alarm,
.alarm_irq_enable = rv3028_alarm_irq_enable,
.read_offset = rv3028_read_offset, .read_offset = rv3028_read_offset,
.set_offset = rv3028_set_offset, .set_offset = rv3028_set_offset,
.ioctl = rv3028_ioctl, .ioctl = rv3028_ioctl,
@ -823,9 +823,6 @@ static int rv3028_probe(struct i2c_client *client)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (status & RV3028_STATUS_PORF)
dev_warn(&client->dev, "Voltage low, data loss detected.\n");
if (status & RV3028_STATUS_AF) if (status & RV3028_STATUS_AF)
dev_warn(&client->dev, "An alarm may have been missed.\n"); dev_warn(&client->dev, "An alarm may have been missed.\n");
@ -841,12 +838,10 @@ static int rv3028_probe(struct i2c_client *client)
if (ret) { if (ret) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0; client->irq = 0;
} else {
rv3028_rtc_ops.read_alarm = rv3028_get_alarm;
rv3028_rtc_ops.set_alarm = rv3028_set_alarm;
rv3028_rtc_ops.alarm_irq_enable = rv3028_alarm_irq_enable;
} }
} }
if (!client->irq)
clear_bit(RTC_FEATURE_ALARM, rv3028->rtc->features);
ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1, ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
RV3028_CTRL1_WADA, RV3028_CTRL1_WADA); RV3028_CTRL1_WADA, RV3028_CTRL1_WADA);
@ -903,7 +898,7 @@ static int rv3028_probe(struct i2c_client *client)
return 0; return 0;
} }
static const struct of_device_id rv3028_of_match[] = { static const __maybe_unused struct of_device_id rv3028_of_match[] = {
{ .compatible = "microcrystal,rv3028", }, { .compatible = "microcrystal,rv3028", },
{ } { }
}; };

View File

@ -265,24 +265,23 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
{ {
struct device *dev = dev_id; struct device *dev = dev_id;
struct rv3029_data *rv3029 = dev_get_drvdata(dev); struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct mutex *lock = &rv3029->rtc->ops_lock;
unsigned int flags, controls; unsigned int flags, controls;
unsigned long events = 0; unsigned long events = 0;
int ret; int ret;
mutex_lock(lock); rtc_lock(rv3029->rtc);
ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls); ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
if (ret) { if (ret) {
dev_warn(dev, "Read IRQ Control Register error %d\n", ret); dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
mutex_unlock(lock); rtc_unlock(rv3029->rtc);
return IRQ_NONE; return IRQ_NONE;
} }
ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags); ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
if (ret) { if (ret) {
dev_warn(dev, "Read IRQ Flags Register error %d\n", ret); dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
mutex_unlock(lock); rtc_unlock(rv3029->rtc);
return IRQ_NONE; return IRQ_NONE;
} }
@ -297,7 +296,7 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags); regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags);
regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls); regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls);
} }
mutex_unlock(lock); rtc_unlock(rv3029->rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -694,10 +693,13 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
#endif /* CONFIG_RTC_DRV_RV3029_HWMON */ #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
static struct rtc_class_ops rv3029_rtc_ops = { static const struct rtc_class_ops rv3029_rtc_ops = {
.read_time = rv3029_read_time, .read_time = rv3029_read_time,
.set_time = rv3029_set_time, .set_time = rv3029_set_time,
.ioctl = rv3029_ioctl, .ioctl = rv3029_ioctl,
.read_alarm = rv3029_read_alarm,
.set_alarm = rv3029_set_alarm,
.alarm_irq_enable = rv3029_alarm_irq_enable,
}; };
static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq, static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
@ -739,12 +741,10 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
if (rc) { if (rc) {
dev_warn(dev, "unable to request IRQ, alarms disabled\n"); dev_warn(dev, "unable to request IRQ, alarms disabled\n");
rv3029->irq = 0; rv3029->irq = 0;
} else {
rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
} }
} }
if (!rv3029->irq)
clear_bit(RTC_FEATURE_ALARM, rv3029->rtc->features);
rv3029->rtc->ops = &rv3029_rtc_ops; rv3029->rtc->ops = &rv3029_rtc_ops;
rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
@ -808,7 +808,7 @@ static const struct i2c_device_id rv3029_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, rv3029_id); MODULE_DEVICE_TABLE(i2c, rv3029_id);
static const struct of_device_id rv3029_of_match[] = { static const __maybe_unused struct of_device_id rv3029_of_match[] = {
{ .compatible = "microcrystal,rv3029" }, { .compatible = "microcrystal,rv3029" },
{ } { }
}; };

View File

@ -804,12 +804,15 @@ static void rv3032_hwmon_register(struct device *dev)
devm_hwmon_device_register_with_info(dev, "rv3032", rv3032, &rv3032_hwmon_chip_info, NULL); devm_hwmon_device_register_with_info(dev, "rv3032", rv3032, &rv3032_hwmon_chip_info, NULL);
} }
static struct rtc_class_ops rv3032_rtc_ops = { static const struct rtc_class_ops rv3032_rtc_ops = {
.read_time = rv3032_get_time, .read_time = rv3032_get_time,
.set_time = rv3032_set_time, .set_time = rv3032_set_time,
.read_offset = rv3032_read_offset, .read_offset = rv3032_read_offset,
.set_offset = rv3032_set_offset, .set_offset = rv3032_set_offset,
.ioctl = rv3032_ioctl, .ioctl = rv3032_ioctl,
.read_alarm = rv3032_get_alarm,
.set_alarm = rv3032_set_alarm,
.alarm_irq_enable = rv3032_alarm_irq_enable,
}; };
static const struct regmap_config regmap_config = { static const struct regmap_config regmap_config = {
@ -868,12 +871,10 @@ static int rv3032_probe(struct i2c_client *client)
if (ret) { if (ret) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0; client->irq = 0;
} else {
rv3032_rtc_ops.read_alarm = rv3032_get_alarm;
rv3032_rtc_ops.set_alarm = rv3032_set_alarm;
rv3032_rtc_ops.alarm_irq_enable = rv3032_alarm_irq_enable;
} }
} }
if (!client->irq)
clear_bit(RTC_FEATURE_ALARM, rv3032->rtc->features);
ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1, ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1,
RV3032_CTRL1_WADA, RV3032_CTRL1_WADA); RV3032_CTRL1_WADA, RV3032_CTRL1_WADA);
@ -905,7 +906,7 @@ static int rv3032_probe(struct i2c_client *client)
return 0; return 0;
} }
static const struct of_device_id rv3032_of_match[] = { static const __maybe_unused struct of_device_id rv3032_of_match[] = {
{ .compatible = "microcrystal,rv3032", }, { .compatible = "microcrystal,rv3032", },
{ } { }
}; };

View File

@ -471,10 +471,13 @@ static int rv8803_nvram_read(void *priv, unsigned int offset,
return 0; return 0;
} }
static struct rtc_class_ops rv8803_rtc_ops = { static const struct rtc_class_ops rv8803_rtc_ops = {
.read_time = rv8803_get_time, .read_time = rv8803_get_time,
.set_time = rv8803_set_time, .set_time = rv8803_set_time,
.ioctl = rv8803_ioctl, .ioctl = rv8803_ioctl,
.read_alarm = rv8803_get_alarm,
.set_alarm = rv8803_set_alarm,
.alarm_irq_enable = rv8803_alarm_irq_enable,
}; };
static int rx8900_trickle_charger_init(struct rv8803_data *rv8803) static int rx8900_trickle_charger_init(struct rv8803_data *rv8803)
@ -567,12 +570,10 @@ static int rv8803_probe(struct i2c_client *client,
if (err) { if (err) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0; client->irq = 0;
} else {
rv8803_rtc_ops.read_alarm = rv8803_get_alarm;
rv8803_rtc_ops.set_alarm = rv8803_set_alarm;
rv8803_rtc_ops.alarm_irq_enable = rv8803_alarm_irq_enable;
} }
} }
if (!client->irq)
clear_bit(RTC_FEATURE_ALARM, rv8803->rtc->features);
err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA);
if (err) if (err)
@ -606,7 +607,7 @@ static const struct i2c_device_id rv8803_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, rv8803_id); MODULE_DEVICE_TABLE(i2c, rv8803_id);
static const struct of_device_id rv8803_of_match[] = { static const __maybe_unused struct of_device_id rv8803_of_match[] = {
{ {
.compatible = "microcrystal,rv8803", .compatible = "microcrystal,rv8803",
.data = (void *)rv_8803 .data = (void *)rv_8803

View File

@ -331,7 +331,7 @@ static int rx6110_probe(struct rx6110_data *rx6110, struct device *dev)
return 0; return 0;
} }
#ifdef CONFIG_SPI_MASTER #if IS_ENABLED(CONFIG_SPI_MASTER)
static struct regmap_config regmap_spi_config = { static struct regmap_config regmap_spi_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
@ -411,7 +411,7 @@ static void rx6110_spi_unregister(void)
} }
#endif /* CONFIG_SPI_MASTER */ #endif /* CONFIG_SPI_MASTER */
#ifdef CONFIG_I2C #if IS_ENABLED(CONFIG_I2C)
static struct regmap_config regmap_i2c_config = { static struct regmap_config regmap_i2c_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,

View File

@ -55,7 +55,7 @@ static const struct i2c_device_id rx8010_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, rx8010_id); MODULE_DEVICE_TABLE(i2c, rx8010_id);
static const struct of_device_id rx8010_of_match[] = { static const __maybe_unused struct of_device_id rx8010_of_match[] = {
{ .compatible = "epson,rx8010" }, { .compatible = "epson,rx8010" },
{ } { }
}; };
@ -73,11 +73,11 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
struct rx8010_data *rx8010 = i2c_get_clientdata(client); struct rx8010_data *rx8010 = i2c_get_clientdata(client);
int flagreg, err; int flagreg, err;
mutex_lock(&rx8010->rtc->ops_lock); rtc_lock(rx8010->rtc);
err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg); err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
if (err) { if (err) {
mutex_unlock(&rx8010->rtc->ops_lock); rtc_unlock(rx8010->rtc);
return IRQ_NONE; return IRQ_NONE;
} }
@ -100,7 +100,7 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
} }
err = regmap_write(rx8010->regs, RX8010_FLAG, flagreg); err = regmap_write(rx8010->regs, RX8010_FLAG, flagreg);
mutex_unlock(&rx8010->rtc->ops_lock); rtc_unlock(rx8010->rtc);
return err ? IRQ_NONE : IRQ_HANDLED; return err ? IRQ_NONE : IRQ_HANDLED;
} }
@ -354,13 +354,7 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
} }
} }
static const struct rtc_class_ops rx8010_rtc_ops_default = { static const struct rtc_class_ops rx8010_rtc_ops = {
.read_time = rx8010_get_time,
.set_time = rx8010_set_time,
.ioctl = rx8010_ioctl,
};
static const struct rtc_class_ops rx8010_rtc_ops_alarm = {
.read_time = rx8010_get_time, .read_time = rx8010_get_time,
.set_time = rx8010_set_time, .set_time = rx8010_set_time,
.ioctl = rx8010_ioctl, .ioctl = rx8010_ioctl,
@ -409,12 +403,11 @@ static int rx8010_probe(struct i2c_client *client)
dev_err(dev, "unable to request IRQ\n"); dev_err(dev, "unable to request IRQ\n");
return err; return err;
} }
rx8010->rtc->ops = &rx8010_rtc_ops_alarm;
} else { } else {
rx8010->rtc->ops = &rx8010_rtc_ops_default; clear_bit(RTC_FEATURE_ALARM, rx8010->rtc->features);
} }
rx8010->rtc->ops = &rx8010_rtc_ops;
rx8010->rtc->max_user_freq = 1; rx8010->rtc->max_user_freq = 1;
rx8010->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; rx8010->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rx8010->rtc->range_max = RTC_TIMESTAMP_END_2099; rx8010->rtc->range_max = RTC_TIMESTAMP_END_2099;

View File

@ -142,10 +142,9 @@ static irqreturn_t rx8025_handle_irq(int irq, void *dev_id)
{ {
struct i2c_client *client = dev_id; struct i2c_client *client = dev_id;
struct rx8025_data *rx8025 = i2c_get_clientdata(client); struct rx8025_data *rx8025 = i2c_get_clientdata(client);
struct mutex *lock = &rx8025->rtc->ops_lock;
int status; int status;
mutex_lock(lock); rtc_lock(rx8025->rtc);
status = rx8025_read_reg(client, RX8025_REG_CTRL2); status = rx8025_read_reg(client, RX8025_REG_CTRL2);
if (status < 0) if (status < 0)
goto out; goto out;
@ -170,7 +169,7 @@ static irqreturn_t rx8025_handle_irq(int irq, void *dev_id)
} }
out: out:
mutex_unlock(lock); rtc_unlock(rx8025->rtc);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -314,7 +314,7 @@ static const struct i2c_device_id rx8581_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, rx8581_id); MODULE_DEVICE_TABLE(i2c, rx8581_id);
static const struct of_device_id rx8581_of_match[] = { static const __maybe_unused struct of_device_id rx8581_of_match[] = {
{ .compatible = "epson,rx8571", .data = &rx8571_config }, { .compatible = "epson,rx8571", .data = &rx8571_config },
{ .compatible = "epson,rx8581", .data = &rx8581_config }, { .compatible = "epson,rx8581", .data = &rx8581_config },
{ /* sentinel */ } { /* sentinel */ }

View File

@ -55,7 +55,7 @@ static const struct i2c_device_id s35390a_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, s35390a_id); MODULE_DEVICE_TABLE(i2c, s35390a_id);
static const struct of_device_id s35390a_of_match[] = { static const __maybe_unused struct of_device_id s35390a_of_match[] = {
{ .compatible = "s35390a" }, { .compatible = "s35390a" },
{ .compatible = "sii,s35390a" }, { .compatible = "sii,s35390a" },
{ } { }

View File

@ -382,7 +382,6 @@ static int s3c_rtc_remove(struct platform_device *pdev)
static int s3c_rtc_probe(struct platform_device *pdev) static int s3c_rtc_probe(struct platform_device *pdev)
{ {
struct s3c_rtc *info = NULL; struct s3c_rtc *info = NULL;
struct rtc_time rtc_tm;
int ret; int ret;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
@ -448,20 +447,6 @@ static int s3c_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
/* Check RTC Time */
if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) {
rtc_tm.tm_year = 100;
rtc_tm.tm_mon = 0;
rtc_tm.tm_mday = 1;
rtc_tm.tm_hour = 0;
rtc_tm.tm_min = 0;
rtc_tm.tm_sec = 0;
s3c_rtc_settime(&pdev->dev, &rtc_tm);
dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
}
/* register RTC and exit */ /* register RTC and exit */
info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops,
THIS_MODULE); THIS_MODULE);
@ -573,7 +558,7 @@ static struct s3c_rtc_data const s3c6410_rtc_data = {
.disable = s3c6410_rtc_disable, .disable = s3c6410_rtc_disable,
}; };
static const struct of_device_id s3c_rtc_dt_match[] = { static const __maybe_unused struct of_device_id s3c_rtc_dt_match[] = {
{ {
.compatible = "samsung,s3c2410-rtc", .compatible = "samsung,s3c2410-rtc",
.data = &s3c2410_rtc_data, .data = &s3c2410_rtc_data,

View File

@ -760,7 +760,8 @@ static int s5m_rtc_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
info->i2c = i2c_new_dummy_device(s5m87xx->i2c->adapter, RTC_I2C_ADDR); info->i2c = devm_i2c_new_dummy_device(&pdev->dev, s5m87xx->i2c->adapter,
RTC_I2C_ADDR);
if (IS_ERR(info->i2c)) { if (IS_ERR(info->i2c)) {
dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n"); dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
return PTR_ERR(info->i2c); return PTR_ERR(info->i2c);
@ -771,7 +772,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
ret = PTR_ERR(info->regmap); ret = PTR_ERR(info->regmap);
dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n", dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n",
ret); ret);
goto err; return ret;
} }
info->dev = &pdev->dev; info->dev = &pdev->dev;
@ -781,26 +782,25 @@ static int s5m_rtc_probe(struct platform_device *pdev)
if (s5m87xx->irq_data) { if (s5m87xx->irq_data) {
info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq); info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
if (info->irq <= 0) { if (info->irq <= 0) {
ret = -EINVAL;
dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n",
alarm_irq); alarm_irq);
goto err; return -EINVAL;
} }
} }
platform_set_drvdata(pdev, info); platform_set_drvdata(pdev, info);
ret = s5m8767_rtc_init_reg(info); ret = s5m8767_rtc_init_reg(info);
if (ret)
return ret;
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc", info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
&s5m_rtc_ops, THIS_MODULE); &s5m_rtc_ops, THIS_MODULE);
if (IS_ERR(info->rtc_dev)) { if (IS_ERR(info->rtc_dev))
ret = PTR_ERR(info->rtc_dev); return PTR_ERR(info->rtc_dev);
goto err;
}
if (!info->irq) { if (!info->irq) {
dev_info(&pdev->dev, "Alarm IRQ not available\n"); dev_info(&pdev->dev, "Alarm IRQ not available\n");
@ -813,22 +813,8 @@ static int s5m_rtc_probe(struct platform_device *pdev)
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
info->irq, ret); info->irq, ret);
goto err;
}
return 0;
err:
i2c_unregister_device(info->i2c);
return ret; return ret;
} }
static int s5m_rtc_remove(struct platform_device *pdev)
{
struct s5m_rtc_info *info = platform_get_drvdata(pdev);
i2c_unregister_device(info->i2c);
return 0; return 0;
} }
@ -874,7 +860,6 @@ static struct platform_driver s5m_rtc_driver = {
.pm = &s5m_rtc_pm_ops, .pm = &s5m_rtc_pm_ops,
}, },
.probe = s5m_rtc_probe, .probe = s5m_rtc_probe,
.remove = s5m_rtc_remove,
.id_table = s5m_rtc_id, .id_table = s5m_rtc_id,
}; };

View File

@ -207,7 +207,7 @@ static const struct i2c_device_id sd3078_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, sd3078_id); MODULE_DEVICE_TABLE(i2c, sd3078_id);
static const struct of_device_id rtc_dt_match[] = { static const __maybe_unused struct of_device_id rtc_dt_match[] = {
{ .compatible = "whwave,sd3078" }, { .compatible = "whwave,sd3078" },
{}, {},
}; };

View File

@ -1,446 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* SiRFSoC Real Time Clock interface for Linux
*
* Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company.
*/
#include <linux/module.h>
#include <linux/err.h>
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/rtc/sirfsoc_rtciobrg.h>
#define RTC_CN 0x00
#define RTC_ALARM0 0x04
#define RTC_ALARM1 0x18
#define RTC_STATUS 0x08
#define RTC_SW_VALUE 0x40
#define SIRFSOC_RTC_AL1E (1<<6)
#define SIRFSOC_RTC_AL1 (1<<4)
#define SIRFSOC_RTC_HZE (1<<3)
#define SIRFSOC_RTC_AL0E (1<<2)
#define SIRFSOC_RTC_HZ (1<<1)
#define SIRFSOC_RTC_AL0 (1<<0)
#define RTC_DIV 0x0c
#define RTC_DEEP_CTRL 0x14
#define RTC_CLOCK_SWITCH 0x1c
#define SIRFSOC_RTC_CLK 0x03 /* others are reserved */
/* Refer to RTC DIV switch */
#define RTC_HZ 16
/* This macro is also defined in arch/arm/plat-sirfsoc/cpu.c */
#define RTC_SHIFT 4
#define INTR_SYSRTC_CN 0x48
struct sirfsoc_rtc_drv {
struct rtc_device *rtc;
u32 rtc_base;
u32 irq;
unsigned irq_wake;
/* Overflow for every 8 years extra time */
u32 overflow_rtc;
spinlock_t lock;
struct regmap *regmap;
#ifdef CONFIG_PM
u32 saved_counter;
u32 saved_overflow_rtc;
#endif
};
static u32 sirfsoc_rtc_readl(struct sirfsoc_rtc_drv *rtcdrv, u32 offset)
{
u32 val;
regmap_read(rtcdrv->regmap, rtcdrv->rtc_base + offset, &val);
return val;
}
static void sirfsoc_rtc_writel(struct sirfsoc_rtc_drv *rtcdrv,
u32 offset, u32 val)
{
regmap_write(rtcdrv->regmap, rtcdrv->rtc_base + offset, val);
}
static int sirfsoc_rtc_read_alarm(struct device *dev,
struct rtc_wkalrm *alrm)
{
unsigned long rtc_alarm, rtc_count;
struct sirfsoc_rtc_drv *rtcdrv;
rtcdrv = dev_get_drvdata(dev);
spin_lock_irq(&rtcdrv->lock);
rtc_count = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
rtc_alarm = sirfsoc_rtc_readl(rtcdrv, RTC_ALARM0);
memset(alrm, 0, sizeof(struct rtc_wkalrm));
/*
* assume alarm interval not beyond one round counter overflow_rtc:
* 0->0xffffffff
*/
/* if alarm is in next overflow cycle */
if (rtc_count > rtc_alarm)
rtc_time64_to_tm((rtcdrv->overflow_rtc + 1)
<< (BITS_PER_LONG - RTC_SHIFT)
| rtc_alarm >> RTC_SHIFT, &alrm->time);
else
rtc_time64_to_tm(rtcdrv->overflow_rtc
<< (BITS_PER_LONG - RTC_SHIFT)
| rtc_alarm >> RTC_SHIFT, &alrm->time);
if (sirfsoc_rtc_readl(rtcdrv, RTC_STATUS) & SIRFSOC_RTC_AL0E)
alrm->enabled = 1;
spin_unlock_irq(&rtcdrv->lock);
return 0;
}
static int sirfsoc_rtc_set_alarm(struct device *dev,
struct rtc_wkalrm *alrm)
{
unsigned long rtc_status_reg, rtc_alarm;
struct sirfsoc_rtc_drv *rtcdrv;
rtcdrv = dev_get_drvdata(dev);
if (alrm->enabled) {
rtc_alarm = rtc_tm_to_time64(&alrm->time);
spin_lock_irq(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
/*
* An ongoing alarm in progress - ingore it and not
* to return EBUSY
*/
dev_info(dev, "An old alarm was set, will be replaced by a new one\n");
}
sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, rtc_alarm << RTC_SHIFT);
rtc_status_reg &= ~0x07; /* mask out the lower status bits */
/*
* This bit RTC_AL sets it as a wake-up source for Sleep Mode
* Writing 1 into this bit will clear it
*/
rtc_status_reg |= SIRFSOC_RTC_AL0;
/* enable the RTC alarm interrupt */
rtc_status_reg |= SIRFSOC_RTC_AL0E;
sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
spin_unlock_irq(&rtcdrv->lock);
} else {
/*
* if this function was called with enabled=0
* then it could mean that the application is
* trying to cancel an ongoing alarm
*/
spin_lock_irq(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
/* clear the RTC status register's alarm bit */
rtc_status_reg &= ~0x07;
/* write 1 into SIRFSOC_RTC_AL0 to force a clear */
rtc_status_reg |= (SIRFSOC_RTC_AL0);
/* Clear the Alarm enable bit */
rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
sirfsoc_rtc_writel(rtcdrv, RTC_STATUS,
rtc_status_reg);
}
spin_unlock_irq(&rtcdrv->lock);
}
return 0;
}
static int sirfsoc_rtc_read_time(struct device *dev,
struct rtc_time *tm)
{
unsigned long tmp_rtc = 0;
struct sirfsoc_rtc_drv *rtcdrv;
rtcdrv = dev_get_drvdata(dev);
/*
* This patch is taken from WinCE - Need to validate this for
* correctness. To work around sirfsoc RTC counter double sync logic
* fail, read several times to make sure get stable value.
*/
do {
tmp_rtc = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
cpu_relax();
} while (tmp_rtc != sirfsoc_rtc_readl(rtcdrv, RTC_CN));
rtc_time64_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT)
| tmp_rtc >> RTC_SHIFT, tm);
return 0;
}
static int sirfsoc_rtc_set_time(struct device *dev,
struct rtc_time *tm)
{
unsigned long rtc_time;
struct sirfsoc_rtc_drv *rtcdrv;
rtcdrv = dev_get_drvdata(dev);
rtc_time = rtc_tm_to_time64(tm);
rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT);
sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc);
sirfsoc_rtc_writel(rtcdrv, RTC_CN, rtc_time << RTC_SHIFT);
return 0;
}
static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
unsigned long rtc_status_reg = 0x0;
struct sirfsoc_rtc_drv *rtcdrv;
rtcdrv = dev_get_drvdata(dev);
spin_lock_irq(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
if (enabled)
rtc_status_reg |= SIRFSOC_RTC_AL0E;
else
rtc_status_reg &= ~SIRFSOC_RTC_AL0E;
sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
spin_unlock_irq(&rtcdrv->lock);
return 0;
}
static const struct rtc_class_ops sirfsoc_rtc_ops = {
.read_time = sirfsoc_rtc_read_time,
.set_time = sirfsoc_rtc_set_time,
.read_alarm = sirfsoc_rtc_read_alarm,
.set_alarm = sirfsoc_rtc_set_alarm,
.alarm_irq_enable = sirfsoc_rtc_alarm_irq_enable
};
static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
{
struct sirfsoc_rtc_drv *rtcdrv = pdata;
unsigned long rtc_status_reg = 0x0;
unsigned long events = 0x0;
spin_lock(&rtcdrv->lock);
rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
/* this bit will be set ONLY if an alarm was active
* and it expired NOW
* So this is being used as an ASSERT
*/
if (rtc_status_reg & SIRFSOC_RTC_AL0) {
/*
* clear the RTC status register's alarm bit
* mask out the lower status bits
*/
rtc_status_reg &= ~0x07;
/* write 1 into SIRFSOC_RTC_AL0 to ACK the alarm interrupt */
rtc_status_reg |= (SIRFSOC_RTC_AL0);
/* Clear the Alarm enable bit */
rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
}
sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
spin_unlock(&rtcdrv->lock);
/* this should wake up any apps polling/waiting on the read
* after setting the alarm
*/
events |= RTC_IRQF | RTC_AF;
rtc_update_irq(rtcdrv->rtc, 1, events);
return IRQ_HANDLED;
}
static const struct of_device_id sirfsoc_rtc_of_match[] = {
{ .compatible = "sirf,prima2-sysrtc"},
{},
};
static const struct regmap_config sysrtc_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.fast_io = true,
};
MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match);
static int sirfsoc_rtc_probe(struct platform_device *pdev)
{
int err;
unsigned long rtc_div;
struct sirfsoc_rtc_drv *rtcdrv;
struct device_node *np = pdev->dev.of_node;
rtcdrv = devm_kzalloc(&pdev->dev,
sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL);
if (rtcdrv == NULL)
return -ENOMEM;
spin_lock_init(&rtcdrv->lock);
err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
if (err) {
dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");
return err;
}
platform_set_drvdata(pdev, rtcdrv);
/* Register rtc alarm as a wakeup source */
device_init_wakeup(&pdev->dev, 1);
rtcdrv->regmap = devm_regmap_init_iobg(&pdev->dev,
&sysrtc_regmap_config);
if (IS_ERR(rtcdrv->regmap)) {
err = PTR_ERR(rtcdrv->regmap);
dev_err(&pdev->dev, "Failed to allocate register map: %d\n",
err);
return err;
}
/*
* Set SYS_RTC counter in RTC_HZ HZ Units
* We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
* If 16HZ, therefore RTC_DIV = 1023;
*/
rtc_div = ((32768 / RTC_HZ) / 2) - 1;
sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);
/* 0x3 -> RTC_CLK */
sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);
/* reset SYS RTC ALARM0 */
sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);
/* reset SYS RTC ALARM1 */
sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);
/* Restore RTC Overflow From Register After Command Reboot */
rtcdrv->overflow_rtc =
sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);
rtcdrv->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtcdrv->rtc))
return PTR_ERR(rtcdrv->rtc);
rtcdrv->rtc->ops = &sirfsoc_rtc_ops;
rtcdrv->rtc->range_max = (1ULL << 60) - 1;
rtcdrv->irq = platform_get_irq(pdev, 0);
err = devm_request_irq(&pdev->dev, rtcdrv->irq, sirfsoc_rtc_irq_handler,
IRQF_SHARED, pdev->name, rtcdrv);
if (err) {
dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n");
return err;
}
return devm_rtc_register_device(rtcdrv->rtc);
}
#ifdef CONFIG_PM_SLEEP
static int sirfsoc_rtc_suspend(struct device *dev)
{
struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev);
rtcdrv->overflow_rtc =
sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);
rtcdrv->saved_counter =
sirfsoc_rtc_readl(rtcdrv, RTC_CN);
rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc;
if (device_may_wakeup(dev) && !enable_irq_wake(rtcdrv->irq))
rtcdrv->irq_wake = 1;
return 0;
}
static int sirfsoc_rtc_resume(struct device *dev)
{
u32 tmp;
struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev);
/*
* if resume from snapshot and the rtc power is lost,
* restroe the rtc settings
*/
if (SIRFSOC_RTC_CLK != sirfsoc_rtc_readl(rtcdrv, RTC_CLOCK_SWITCH)) {
u32 rtc_div;
/* 0x3 -> RTC_CLK */
sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);
/*
* Set SYS_RTC counter in RTC_HZ HZ Units
* We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
* If 16HZ, therefore RTC_DIV = 1023;
*/
rtc_div = ((32768 / RTC_HZ) / 2) - 1;
sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);
/* reset SYS RTC ALARM0 */
sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);
/* reset SYS RTC ALARM1 */
sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);
}
rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc;
/*
* if current counter is small than previous,
* it means overflow in sleep
*/
tmp = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
if (tmp <= rtcdrv->saved_counter)
rtcdrv->overflow_rtc++;
/*
*PWRC Value Be Changed When Suspend, Restore Overflow
* In Memory To Register
*/
sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc);
if (device_may_wakeup(dev) && rtcdrv->irq_wake) {
disable_irq_wake(rtcdrv->irq);
rtcdrv->irq_wake = 0;
}
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(sirfsoc_rtc_pm_ops,
sirfsoc_rtc_suspend, sirfsoc_rtc_resume);
static struct platform_driver sirfsoc_rtc_driver = {
.driver = {
.name = "sirfsoc-rtc",
.pm = &sirfsoc_rtc_pm_ops,
.of_match_table = sirfsoc_rtc_of_match,
},
.probe = sirfsoc_rtc_probe,
};
module_platform_driver(sirfsoc_rtc_driver);
MODULE_DESCRIPTION("SiRF SoC rtc driver");
MODULE_AUTHOR("Xianglong Du <Xianglong.Du@csr.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:sirfsoc-rtc");

View File

@ -209,7 +209,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
const struct stm32_rtc_events *evts = &rtc->data->events; const struct stm32_rtc_events *evts = &rtc->data->events;
unsigned int status, cr; unsigned int status, cr;
mutex_lock(&rtc->rtc_dev->ops_lock); rtc_lock(rtc->rtc_dev);
status = readl_relaxed(rtc->base + regs->sr); status = readl_relaxed(rtc->base + regs->sr);
cr = readl_relaxed(rtc->base + regs->cr); cr = readl_relaxed(rtc->base + regs->cr);
@ -226,7 +226,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
stm32_rtc_clear_event_flags(rtc, evts->alra); stm32_rtc_clear_event_flags(rtc, evts->alra);
} }
mutex_unlock(&rtc->rtc_dev->ops_lock); rtc_unlock(rtc->rtc_dev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }

View File

@ -232,7 +232,7 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data)
{ {
struct device *dev = data; struct device *dev = data;
struct tegra_rtc_info *info = dev_get_drvdata(dev); struct tegra_rtc_info *info = dev_get_drvdata(dev);
unsigned long events = 0, flags; unsigned long events = 0;
u32 status; u32 status;
status = readl(info->base + TEGRA_RTC_REG_INTR_STATUS); status = readl(info->base + TEGRA_RTC_REG_INTR_STATUS);
@ -240,10 +240,10 @@ static irqreturn_t tegra_rtc_irq_handler(int irq, void *data)
/* clear the interrupt masks and status on any IRQ */ /* clear the interrupt masks and status on any IRQ */
tegra_rtc_wait_while_busy(dev); tegra_rtc_wait_while_busy(dev);
spin_lock_irqsave(&info->lock, flags); spin_lock(&info->lock);
writel(0, info->base + TEGRA_RTC_REG_INTR_MASK); writel(0, info->base + TEGRA_RTC_REG_INTR_MASK);
writel(status, info->base + TEGRA_RTC_REG_INTR_STATUS); writel(status, info->base + TEGRA_RTC_REG_INTR_STATUS);
spin_unlock_irqrestore(&info->lock, flags); spin_unlock(&info->lock);
} }
/* check if alarm */ /* check if alarm */

View File

@ -361,13 +361,6 @@ static const struct rtc_class_ops tps65910_rtc_ops = {
.set_offset = tps65910_set_offset, .set_offset = tps65910_set_offset,
}; };
static const struct rtc_class_ops tps65910_rtc_ops_noirq = {
.read_time = tps65910_rtc_read_time,
.set_time = tps65910_rtc_set_time,
.read_offset = tps65910_read_offset,
.set_offset = tps65910_set_offset,
};
static int tps65910_rtc_probe(struct platform_device *pdev) static int tps65910_rtc_probe(struct platform_device *pdev)
{ {
struct tps65910 *tps65910 = NULL; struct tps65910 *tps65910 = NULL;
@ -426,11 +419,15 @@ static int tps65910_rtc_probe(struct platform_device *pdev)
tps_rtc->irq = irq; tps_rtc->irq = irq;
if (irq != -1) { if (irq != -1) {
if (device_property_present(tps65910->dev, "wakeup-source"))
device_init_wakeup(&pdev->dev, 1);
else
device_set_wakeup_capable(&pdev->dev, 1); device_set_wakeup_capable(&pdev->dev, 1);
tps_rtc->rtc->ops = &tps65910_rtc_ops; } else {
} else clear_bit(RTC_FEATURE_ALARM, tps_rtc->rtc->features);
tps_rtc->rtc->ops = &tps65910_rtc_ops_noirq; }
tps_rtc->rtc->ops = &tps65910_rtc_ops;
tps_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; tps_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
tps_rtc->rtc->range_max = RTC_TIMESTAMP_END_2099; tps_rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;

View File

@ -1,303 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* TX4939 internal RTC driver
* Based on RBTX49xx patch from CELF patch archive.
*
* (C) Copyright TOSHIBA CORPORATION 2005-2007
*/
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/gfp.h>
#define TX4939_RTCCTL_ALME 0x00000080
#define TX4939_RTCCTL_ALMD 0x00000040
#define TX4939_RTCCTL_BUSY 0x00000020
#define TX4939_RTCCTL_COMMAND 0x00000007
#define TX4939_RTCCTL_COMMAND_NOP 0x00000000
#define TX4939_RTCCTL_COMMAND_GETTIME 0x00000001
#define TX4939_RTCCTL_COMMAND_SETTIME 0x00000002
#define TX4939_RTCCTL_COMMAND_GETALARM 0x00000003
#define TX4939_RTCCTL_COMMAND_SETALARM 0x00000004
#define TX4939_RTCTBC_PM 0x00000080
#define TX4939_RTCTBC_COMP 0x0000007f
#define TX4939_RTC_REG_RAMSIZE 0x00000100
#define TX4939_RTC_REG_RWBSIZE 0x00000006
struct tx4939_rtc_reg {
__u32 ctl;
__u32 adr;
__u32 dat;
__u32 tbc;
};
struct tx4939rtc_plat_data {
struct rtc_device *rtc;
struct tx4939_rtc_reg __iomem *rtcreg;
spinlock_t lock;
};
static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd)
{
int i = 0;
__raw_writel(cmd, &rtcreg->ctl);
/* This might take 30us (next 32.768KHz clock) */
while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) {
/* timeout on approx. 100us (@ GBUS200MHz) */
if (i++ > 200 * 100)
return -EBUSY;
cpu_relax();
}
return 0;
}
static int tx4939_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
unsigned long secs = rtc_tm_to_time64(tm);
int i, ret;
unsigned char buf[6];
buf[0] = 0;
buf[1] = 0;
buf[2] = secs;
buf[3] = secs >> 8;
buf[4] = secs >> 16;
buf[5] = secs >> 24;
spin_lock_irq(&pdata->lock);
__raw_writel(0, &rtcreg->adr);
for (i = 0; i < 6; i++)
__raw_writel(buf[i], &rtcreg->dat);
ret = tx4939_rtc_cmd(rtcreg,
TX4939_RTCCTL_COMMAND_SETTIME |
(__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
spin_unlock_irq(&pdata->lock);
return ret;
}
static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
int i, ret;
unsigned long sec;
unsigned char buf[6];
spin_lock_irq(&pdata->lock);
ret = tx4939_rtc_cmd(rtcreg,
TX4939_RTCCTL_COMMAND_GETTIME |
(__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
if (ret) {
spin_unlock_irq(&pdata->lock);
return ret;
}
__raw_writel(2, &rtcreg->adr);
for (i = 2; i < 6; i++)
buf[i] = __raw_readl(&rtcreg->dat);
spin_unlock_irq(&pdata->lock);
sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
(buf[3] << 8) | buf[2];
rtc_time64_to_tm(sec, tm);
return 0;
}
static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
int i, ret;
unsigned long sec;
unsigned char buf[6];
sec = rtc_tm_to_time64(&alrm->time);
buf[0] = 0;
buf[1] = 0;
buf[2] = sec;
buf[3] = sec >> 8;
buf[4] = sec >> 16;
buf[5] = sec >> 24;
spin_lock_irq(&pdata->lock);
__raw_writel(0, &rtcreg->adr);
for (i = 0; i < 6; i++)
__raw_writel(buf[i], &rtcreg->dat);
ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM |
(alrm->enabled ? TX4939_RTCCTL_ALME : 0));
spin_unlock_irq(&pdata->lock);
return ret;
}
static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
int i, ret;
unsigned long sec;
unsigned char buf[6];
u32 ctl;
spin_lock_irq(&pdata->lock);
ret = tx4939_rtc_cmd(rtcreg,
TX4939_RTCCTL_COMMAND_GETALARM |
(__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
if (ret) {
spin_unlock_irq(&pdata->lock);
return ret;
}
__raw_writel(2, &rtcreg->adr);
for (i = 2; i < 6; i++)
buf[i] = __raw_readl(&rtcreg->dat);
ctl = __raw_readl(&rtcreg->ctl);
alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0;
alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0;
spin_unlock_irq(&pdata->lock);
sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
(buf[3] << 8) | buf[2];
rtc_time64_to_tm(sec, &alrm->time);
return rtc_valid_tm(&alrm->time);
}
static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev);
spin_lock_irq(&pdata->lock);
tx4939_rtc_cmd(pdata->rtcreg,
TX4939_RTCCTL_COMMAND_NOP |
(enabled ? TX4939_RTCCTL_ALME : 0));
spin_unlock_irq(&pdata->lock);
return 0;
}
static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id)
{
struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev_id);
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
unsigned long events = RTC_IRQF;
spin_lock(&pdata->lock);
if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) {
events |= RTC_AF;
tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP);
}
spin_unlock(&pdata->lock);
rtc_update_irq(pdata->rtc, 1, events);
return IRQ_HANDLED;
}
static const struct rtc_class_ops tx4939_rtc_ops = {
.read_time = tx4939_rtc_read_time,
.read_alarm = tx4939_rtc_read_alarm,
.set_alarm = tx4939_rtc_set_alarm,
.set_time = tx4939_rtc_set_time,
.alarm_irq_enable = tx4939_rtc_alarm_irq_enable,
};
static int tx4939_nvram_read(void *priv, unsigned int pos, void *val,
size_t bytes)
{
struct tx4939rtc_plat_data *pdata = priv;
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
u8 *buf = val;
spin_lock_irq(&pdata->lock);
for (; bytes; bytes--) {
__raw_writel(pos++, &rtcreg->adr);
*buf++ = __raw_readl(&rtcreg->dat);
}
spin_unlock_irq(&pdata->lock);
return 0;
}
static int tx4939_nvram_write(void *priv, unsigned int pos, void *val,
size_t bytes)
{
struct tx4939rtc_plat_data *pdata = priv;
struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
u8 *buf = val;
spin_lock_irq(&pdata->lock);
for (; bytes; bytes--) {
__raw_writel(pos++, &rtcreg->adr);
__raw_writel(*buf++, &rtcreg->dat);
}
spin_unlock_irq(&pdata->lock);
return 0;
}
static int __init tx4939_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct tx4939rtc_plat_data *pdata;
int irq, ret;
struct nvmem_config nvmem_cfg = {
.name = "tx4939_nvram",
.size = TX4939_RTC_REG_RAMSIZE,
.reg_read = tx4939_nvram_read,
.reg_write = tx4939_nvram_write,
};
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return -ENODEV;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
platform_set_drvdata(pdev, pdata);
pdata->rtcreg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(pdata->rtcreg))
return PTR_ERR(pdata->rtcreg);
spin_lock_init(&pdata->lock);
tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
0, pdev->name, &pdev->dev) < 0)
return -EBUSY;
rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
rtc->ops = &tx4939_rtc_ops;
rtc->range_max = U32_MAX;
pdata->rtc = rtc;
nvmem_cfg.priv = pdata;
ret = devm_rtc_nvmem_register(rtc, &nvmem_cfg);
if (ret)
return ret;
return devm_rtc_register_device(rtc);
}
static int __exit tx4939_rtc_remove(struct platform_device *pdev)
{
struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev);
spin_lock_irq(&pdata->lock);
tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
spin_unlock_irq(&pdata->lock);
return 0;
}
static struct platform_driver tx4939_rtc_driver = {
.remove = __exit_p(tx4939_rtc_remove),
.driver = {
.name = "tx4939rtc",
},
};
module_platform_driver_probe(tx4939_rtc_driver, tx4939_rtc_probe);
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
MODULE_DESCRIPTION("TX4939 internal RTC driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:tx4939rtc");

View File

@ -141,6 +141,8 @@ struct rtc_device {
*/ */
unsigned long set_offset_nsec; unsigned long set_offset_nsec;
unsigned long features[BITS_TO_LONGS(RTC_FEATURE_CNT)];
time64_t range_min; time64_t range_min;
timeu64_t range_max; timeu64_t range_max;
time64_t start_secs; time64_t start_secs;

View File

@ -1,21 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* RTC I/O Bridge interfaces for CSR SiRFprimaII
* ARM access the registers of SYSRTC, GPSRTC and PWRC through this module
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*/
#ifndef _SIRFSOC_RTC_IOBRG_H_
#define _SIRFSOC_RTC_IOBRG_H_
struct regmap_config;
extern void sirfsoc_rtc_iobrg_besyncing(void);
extern u32 sirfsoc_rtc_iobrg_readl(u32 addr);
extern void sirfsoc_rtc_iobrg_writel(u32 val, u32 addr);
struct regmap *devm_regmap_init_iobg(struct device *dev,
const struct regmap_config *config);
#endif

View File

@ -110,6 +110,11 @@ struct rtc_pll_info {
#define RTC_AF 0x20 /* Alarm interrupt */ #define RTC_AF 0x20 /* Alarm interrupt */
#define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */ #define RTC_UF 0x10 /* Update interrupt for 1Hz RTC */
/* feature list */
#define RTC_FEATURE_ALARM 0
#define RTC_FEATURE_ALARM_RES_MINUTE 1
#define RTC_FEATURE_NEED_WEEK_DAY 2
#define RTC_FEATURE_CNT 3
#define RTC_MAX_FREQ 8192 #define RTC_MAX_FREQ 8192