RTC for 6.2

Removed driver:
  - davinci
 
 Drivers:
  - convert i2c drivers to .probe_new
  - fix spelling mistakes and duplicated words in comments
  - cmos: rework wake setup and ACPI event handling
  - cros-ec: Limit RTC alarm range to fix alarmtimer
  - ds1347: fix century register handling
  - efi: wakeup support
  - isl12022: temperature sensor support
  - pcf85063: fix read_alarm and clkout
  - pcf8523: use stop bit to detect invalid time
  - pcf8563: use RTC_FEATURE_ALARM
  - snvs: be more flexible on LPSRT reads
  - many static checker fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEBqsFVZXh8s/0O5JiY6TcMGxwOjIFAmOeZV4ACgkQY6TcMGxw
 OjLUeRAAhOXdMW/J00D25lwFbPazXypF8v92j/TfjQiL23GMWgsiuH+etEl/eoHe
 XoAD2pGLdrd4Py2f5vRAYwW/dLVWRZ8nQHNSsur9BwgyyrZHEMti4zx3pm+ceT/k
 d1E/pagC5013SBXDgsJY6N3PyNxIrptY2ONip3dxQifKhYJ4SsiG0SVha/LkLJUt
 HvF0tvQd3+Iu+VM59fwOs5vFp11mJCALoFrlF0G4WyRWrl5ekIuVgVhMbmEPUmTL
 vuLZm2Z2a210jDckuOdpiD5z2KzGAHrS7HMdWSAMow0QeAZEv4gQT+HgPghaxhWk
 MIWlaJK32+D93wwGfQpyiC6yR+sT+YlSnSnLeA6g23RKE4uN7niiFKPgoa03zSQo
 /UBrgmzKwS2g8vxzKETUB7KMvkMaX4+jmxtdDzdct+hxSAJvOZPlNlm7AvH2M7ai
 /OtjdBSKlIYHLjQMbFTHI/iml2ESch7Q5HoPV+ZUhkvhE+9TWEaGU6BVfFMl9ODv
 92T+wxZMQNBbXNArgfpybW1q0L+jQgsh985hHegNGVh4qDLuHdo27oDymbLt27vj
 ABT3w38MsM9YYl7gRj8/lz0am0EVoK2fVk9B1Ixt9w9yKKSNpWpIdGQg0dmjsB9Z
 gYCtwOomJxhvZp5zeyGACfpxj/JvtJTsDTPSSXptnrZdDFnt2Jo=
 =DGOn
 -----END PGP SIGNATURE-----

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

Pull RTC updates from Alexandre Belloni:
 "Most of the changes are a rework of the cmos driver by Rafael and
  fixes for issues found using static checkers. The removal of a driver
  leads to a reduction of the number of LOC of the subsystem.

  Removed driver:
   - davinci

  Updates:
   - convert i2c drivers to .probe_new
   - fix spelling mistakes and duplicated words in comments
   - cmos: rework wake setup and ACPI event handling
   - cros-ec: Limit RTC alarm range to fix alarmtimer
   - ds1347: fix century register handling
   - efi: wakeup support
   - isl12022: temperature sensor support
   - pcf85063: fix read_alarm and clkout
   - pcf8523: use stop bit to detect invalid time
   - pcf8563: use RTC_FEATURE_ALARM
   - snvs: be more flexible on LPSRT reads
   - many static checker fixes"

* tag 'rtc-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (48 commits)
  rtc: ds1742: use devm_platform_get_and_ioremap_resource()
  rtc: mxc_v2: Add missing clk_disable_unprepare()
  rtc: rs5c313: correct some spelling mistakes
  rtc: at91rm9200: Fix syntax errors in comments
  rtc: remove duplicated words in comments
  rtc: rv3028: Use IRQ flags obtained from device tree if available
  rtc: ds1307: use sysfs_emit() to instead of scnprintf()
  rtc: isl12026: drop obsolete dependency on COMPILE_TEST
  dt-bindings: rtc: m41t80: Convert text schema to YAML one
  rtc: pcf85063: fix pcf85063_clkout_control
  rtc: rx6110: fix warning with !OF
  rtc: rk808: reduce 'struct rk808' usage
  rtc: msc313: Fix function prototype mismatch in msc313_rtc_probe()
  dt-bindings: rtc: convert rtc-meson.txt to dt-schema
  rtc: pic32: Move devm_rtc_allocate_device earlier in pic32_rtc_probe()
  rtc: st-lpc: Add missing clk_disable_unprepare in st_rtc_probe()
  rtc: pcf85063: Fix reading alarm
  rtc: pcf8523: fix for stop bit
  rtc: efi: Add wakeup support
  rtc: pcf8563: clear RTC_FEATURE_ALARM if no irq
  ...
This commit is contained in:
Linus Torvalds 2022-12-19 09:00:00 -06:00
commit acd04af6e4
49 changed files with 674 additions and 1000 deletions

View File

@ -0,0 +1,62 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/amlogic,meson6-rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic Meson6, Meson8, Meson8b and Meson8m2 RTC
maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>
- Martin Blumenstingl <martin.blumenstingl@googlemail.com>
allOf:
- $ref: rtc.yaml#
- $ref: /schemas/nvmem/nvmem.yaml#
properties:
compatible:
enum:
- amlogic,meson6-rtc
- amlogic,meson8-rtc
- amlogic,meson8b-rtc
- amlogic,meson8m2-rtc
reg:
maxItems: 1
clocks:
maxItems: 1
interrupts:
maxItems: 1
resets:
maxItems: 1
vdd-supply: true
required:
- compatible
- reg
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
rtc: rtc@740 {
compatible = "amlogic,meson6-rtc";
reg = <0x740 0x14>;
interrupts = <GIC_SPI 72 IRQ_TYPE_EDGE_RISING>;
clocks = <&rtc32k_xtal>;
vdd-supply = <&rtc_vdd>;
resets = <&reset_rtc>;
#address-cells = <1>;
#size-cells = <1>;
mac@0 {
reg = <0 6>;
};
};

View File

@ -1,30 +0,0 @@
Haoyu Microelectronics HYM8563 Real Time Clock
The HYM8563 provides basic rtc and alarm functionality
as well as a clock output of up to 32kHz.
Required properties:
- compatible: should be: "haoyu,hym8563"
- reg: i2c address
- #clock-cells: the value should be 0
Optional properties:
- clock-output-names: From common clock binding
- interrupts: rtc alarm/event interrupt
Example:
hym8563: hym8563@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
#clock-cells = <0>;
};
device {
...
clocks = <&hym8563>;
...
};

View File

@ -0,0 +1,56 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/haoyu,hym8563.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Haoyu Microelectronics HYM8563 RTC
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
properties:
compatible:
const: haoyu,hym8563
reg:
maxItems: 1
interrupts:
maxItems: 1
"#clock-cells":
const: 0
clock-output-names:
description: From common clock binding to override the default output clock name.
maxItems: 1
wakeup-source:
description: Enables wake up of host system on alarm.
allOf:
- $ref: rtc.yaml
unevaluatedProperties: false
required:
- compatible
- reg
- "#clock-cells"
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
rtc@51 {
compatible = "haoyu,hym8563";
reg = <0x51>;
interrupts = <13 IRQ_TYPE_EDGE_FALLING>;
#clock-cells = <0>;
};
};

View File

@ -11,12 +11,16 @@ maintainers:
properties:
compatible:
enum:
- qcom,pm8058-rtc
- qcom,pm8921-rtc
- qcom,pm8941-rtc
- qcom,pm8018-rtc
- qcom,pmk8350-rtc
oneOf:
- enum:
- qcom,pm8058-rtc
- qcom,pm8921-rtc
- qcom,pm8941-rtc
- qcom,pmk8350-rtc
- items:
- enum:
- qcom,pm8018-rtc
- const: qcom,pm8921-rtc
reg:
minItems: 1

View File

@ -1,39 +0,0 @@
ST M41T80 family of RTC and compatible
Required properties:
- compatible: should be one of:
"st,m41t62",
"st,m41t65",
"st,m41t80",
"st,m41t81",
"st,m41t81s",
"st,m41t82",
"st,m41t83",
"st,m41t84",
"st,m41t85",
"st,m41t87",
"microcrystal,rv4162",
- reg: I2C bus address of the device
Optional properties:
- interrupts: rtc alarm interrupt.
- clock-output-names: From common clock binding to override the default output
clock name
- wakeup-source: Enables wake up of host system on alarm
Optional child node:
- clock: Provide this if the square wave pin is used as boot-enabled fixed clock.
Example:
rtc@68 {
compatible = "st,m41t80";
reg = <0x68>;
interrupt-parent = <&UIC0>;
interrupts = <0x9 0x8>;
clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
};
};

View File

@ -1,35 +0,0 @@
* Amlogic Meson6, Meson8, Meson8b and Meson8m2 RTC
Required properties:
- compatible: should be one of the following describing the hardware:
* "amlogic,meson6-rtc"
* "amlogic,meson8-rtc"
* "amlogic,meson8b-rtc"
* "amlogic,meson8m2-rtc"
- reg: physical register space for the controller's memory mapped registers.
- interrupts: the interrupt line of the RTC block.
- clocks: reference to the external 32.768kHz crystal oscillator.
- vdd-supply: reference to the power supply of the RTC block.
- resets: reset controller reference to allow reset of the controller
Optional properties for the battery-backed non-volatile memory:
- #address-cells: should be 1 to address the battery-backed non-volatile memory
- #size-cells: should be 1 to reference the battery-backed non-volatile memory
Optional child nodes:
- see ../nvmem/nvmem.txt
Example:
rtc: rtc@740 {
compatible = "amlogic,meson6-rtc";
reg = <0x740 0x14>;
interrupts = <GIC_SPI 72 IRQ_TYPE_EDGE_RISING>;
clocks = <&rtc32k_xtal>;
vdd-supply = <&rtc_vdd>;
resets = <&reset RESET_RTC>;
#address-cells = <1>;
#size-cells = <1>;
};

View File

@ -0,0 +1,73 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/st,m41t80.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ST M41T80 family of RTC and compatible
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
properties:
compatible:
enum:
- st,m41t62
- st,m41t65
- st,m41t80
- st,m41t81
- st,m41t81s
- st,m41t82
- st,m41t83
- st,m41t84
- st,m41t85
- st,m41t87
- microcrystal,rv4162
reg:
maxItems: 1
interrupts:
maxItems: 1
"#clock-cells":
const: 1
clock-output-names:
maxItems: 1
description: From common clock binding to override the default output clock name.
clock:
type: object
$ref: /schemas/clock/fixed-clock.yaml#
properties:
clock-frequency:
const: 32768
allOf:
- $ref: rtc.yaml
unevaluatedProperties: false
required:
- compatible
- reg
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
rtc@68 {
compatible = "st,m41t80";
reg = <0x68>;
interrupt-parent = <&UIC0>;
interrupts = <0x9 0x8>;
clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
};
};
};

View File

@ -433,7 +433,7 @@ config RTC_DRV_ISL12022
config RTC_DRV_ISL12026
tristate "Intersil ISL12026"
depends on OF || COMPILE_TEST
depends on OF
help
If you say yes here you get support for the
Intersil ISL12026 RTC chip.
@ -1351,16 +1351,6 @@ config RTC_DRV_ASM9260
This driver can also be built as a module. If so, the module
will be called rtc-asm9260.
config RTC_DRV_DAVINCI
tristate "TI DaVinci RTC"
depends on ARCH_DAVINCI_DM365 || COMPILE_TEST
help
If you say yes here you get support for the RTC on the
DaVinci platforms (DM365).
This driver can also be built as a module. If so, the module
will be called rtc-davinci.
config RTC_DRV_DIGICOLOR
tristate "Conexant Digicolor RTC"
depends on ARCH_DIGICOLOR || COMPILE_TEST

View File

@ -44,7 +44,6 @@ obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o
obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o
obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o
obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o
obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o
obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o

View File

@ -374,11 +374,11 @@ struct rtc_device *devm_rtc_allocate_device(struct device *dev)
rtc->id = id;
rtc->dev.parent = dev;
err = dev_set_name(&rtc->dev, "rtc%d", id);
err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
if (err)
return ERR_PTR(err);
err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
err = dev_set_name(&rtc->dev, "rtc%d", id);
if (err)
return ERR_PTR(err);

View File

@ -256,7 +256,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
*
* This could all instead be done in the lower level driver,
* but since more than one lower level RTC implementation needs it,
* then it's probably best best to do it here instead of there..
* then it's probably best to do it here instead of there..
*/
/* Get the "before" timestamp */

View File

@ -12,6 +12,7 @@
#include <linux/bcd.h>
#include <linux/i2c.h>
#include <linux/kstrtox.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/rtc.h>
@ -673,13 +674,28 @@ static int abx80x_setup_watchdog(struct abx80x_priv *priv)
}
#endif
static int abx80x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static const struct i2c_device_id abx80x_id[] = {
{ "abx80x", ABX80X },
{ "ab0801", AB0801 },
{ "ab0803", AB0803 },
{ "ab0804", AB0804 },
{ "ab0805", AB0805 },
{ "ab1801", AB1801 },
{ "ab1803", AB1803 },
{ "ab1804", AB1804 },
{ "ab1805", AB1805 },
{ "rv1805", RV1805 },
{ }
};
MODULE_DEVICE_TABLE(i2c, abx80x_id);
static int abx80x_probe(struct i2c_client *client)
{
struct device_node *np = client->dev.of_node;
struct abx80x_priv *priv;
int i, data, err, trickle_cfg = -EINVAL;
char buf[7];
const struct i2c_device_id *id = i2c_match_id(abx80x_id, client);
unsigned int part = id->driver_data;
unsigned int partnumber;
unsigned int majrev, minrev;
@ -847,21 +863,6 @@ static int abx80x_probe(struct i2c_client *client,
return devm_rtc_register_device(priv->rtc);
}
static const struct i2c_device_id abx80x_id[] = {
{ "abx80x", ABX80X },
{ "ab0801", AB0801 },
{ "ab0803", AB0803 },
{ "ab0804", AB0804 },
{ "ab0805", AB0805 },
{ "ab1801", AB1801 },
{ "ab1803", AB1803 },
{ "ab1804", AB1804 },
{ "ab1805", AB1805 },
{ "rv1805", RV1805 },
{ }
};
MODULE_DEVICE_TABLE(i2c, abx80x_id);
#ifdef CONFIG_OF
static const struct of_device_id abx80x_of_match[] = {
{
@ -914,7 +915,7 @@ static struct i2c_driver abx80x_driver = {
.name = "rtc-abx80x",
.of_match_table = of_match_ptr(abx80x_of_match),
},
.probe = abx80x_probe,
.probe_new = abx80x_probe,
.id_table = abx80x_id,
};

View File

@ -130,7 +130,7 @@ static void at91_rtc_write_idr(u32 mask)
*
* Note that there is still a possibility that the mask is updated
* before interrupts have actually been disabled in hardware. The only
* way to be certain would be to poll the IMR-register, which is is
* way to be certain would be to poll the IMR-register, which is
* the very register we are trying to emulate. The register read back
* is a reasonable heuristic.
*/

View File

@ -13,6 +13,7 @@
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/init.h>
#include <linux/kstrtox.h>
#include <linux/errno.h>
#include <linux/bcd.h>

View File

@ -744,6 +744,168 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
return IRQ_NONE;
}
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
static u32 rtc_handler(void *context)
{
struct device *dev = context;
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char rtc_control = 0;
unsigned char rtc_intr;
unsigned long flags;
/*
* Always update rtc irq when ACPI is used as RTC Alarm.
* Or else, ACPI SCI is enabled during suspend/resume only,
* update rtc irq in that case.
*/
if (cmos_use_acpi_alarm())
cmos_interrupt(0, (void *)cmos->rtc);
else {
/* Fix me: can we use cmos_interrupt() here as well? */
spin_lock_irqsave(&rtc_lock, flags);
if (cmos_rtc.suspend_ctrl)
rtc_control = CMOS_READ(RTC_CONTROL);
if (rtc_control & RTC_AIE) {
cmos_rtc.suspend_ctrl &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_update_irq(cmos->rtc, 1, rtc_intr);
}
spin_unlock_irqrestore(&rtc_lock, flags);
}
pm_wakeup_hard_event(dev);
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
return ACPI_INTERRUPT_HANDLED;
}
static void acpi_rtc_event_setup(struct device *dev)
{
if (acpi_disabled)
return;
acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
/*
* After the RTC handler is installed, the Fixed_RTC event should
* be disabled. Only when the RTC alarm is set will it be enabled.
*/
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
}
static void acpi_rtc_event_cleanup(void)
{
if (acpi_disabled)
return;
acpi_remove_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler);
}
static void rtc_wake_on(struct device *dev)
{
acpi_clear_event(ACPI_EVENT_RTC);
acpi_enable_event(ACPI_EVENT_RTC, 0);
}
static void rtc_wake_off(struct device *dev)
{
acpi_disable_event(ACPI_EVENT_RTC, 0);
}
#ifdef CONFIG_X86
/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
static void use_acpi_alarm_quirks(void)
{
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return;
if (!is_hpet_enabled())
return;
if (dmi_get_bios_year() < 2015)
return;
use_acpi_alarm = true;
}
#else
static inline void use_acpi_alarm_quirks(void) { }
#endif
static void acpi_cmos_wake_setup(struct device *dev)
{
if (acpi_disabled)
return;
use_acpi_alarm_quirks();
cmos_rtc.wake_on = rtc_wake_on;
cmos_rtc.wake_off = rtc_wake_off;
/* ACPI tables bug workaround. */
if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
acpi_gbl_FADT.month_alarm);
acpi_gbl_FADT.month_alarm = 0;
}
cmos_rtc.day_alrm = acpi_gbl_FADT.day_alarm;
cmos_rtc.mon_alrm = acpi_gbl_FADT.month_alarm;
cmos_rtc.century = acpi_gbl_FADT.century;
if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
dev_info(dev, "RTC can wake from S4\n");
/* RTC always wakes from S1/S2/S3, and often S4/STD */
device_init_wakeup(dev, 1);
}
static void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
acpi_event_status rtc_status;
acpi_status status;
if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
return;
status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
if (ACPI_FAILURE(status)) {
dev_err(dev, "Could not get RTC status\n");
} else if (rtc_status & ACPI_EVENT_FLAG_SET) {
unsigned char mask;
*rtc_control &= ~RTC_AIE;
CMOS_WRITE(*rtc_control, RTC_CONTROL);
mask = CMOS_READ(RTC_INTR_FLAGS);
rtc_update_irq(cmos->rtc, 1, mask);
}
}
#else /* !CONFIG_ACPI */
static inline void acpi_rtc_event_setup(struct device *dev)
{
}
static inline void acpi_rtc_event_cleanup(void)
{
}
static inline void acpi_cmos_wake_setup(struct device *dev)
{
}
static inline void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control)
{
}
#endif /* CONFIG_ACPI */
#ifdef CONFIG_PNP
#define INITSECTION
@ -827,19 +989,27 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
if (info->address_space)
address_space = info->address_space;
if (info->rtc_day_alarm && info->rtc_day_alarm < 128)
cmos_rtc.day_alrm = info->rtc_day_alarm;
if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128)
cmos_rtc.mon_alrm = info->rtc_mon_alarm;
if (info->rtc_century && info->rtc_century < 128)
cmos_rtc.century = info->rtc_century;
cmos_rtc.day_alrm = info->rtc_day_alarm;
cmos_rtc.mon_alrm = info->rtc_mon_alarm;
cmos_rtc.century = info->rtc_century;
if (info->wake_on && info->wake_off) {
cmos_rtc.wake_on = info->wake_on;
cmos_rtc.wake_off = info->wake_off;
}
} else {
acpi_cmos_wake_setup(dev);
}
if (cmos_rtc.day_alrm >= 128)
cmos_rtc.day_alrm = 0;
if (cmos_rtc.mon_alrm >= 128)
cmos_rtc.mon_alrm = 0;
if (cmos_rtc.century >= 128)
cmos_rtc.century = 0;
cmos_rtc.dev = dev;
dev_set_drvdata(dev, &cmos_rtc);
@ -928,6 +1098,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
nvmem_cfg.size = address_space - NVRAM_OFFSET;
devm_rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg);
/*
* Everything has gone well so far, so by default register a handler for
* the ACPI RTC fixed event.
*/
if (!info)
acpi_rtc_event_setup(dev);
dev_info(dev, "%s%s, %d bytes nvram%s\n",
!is_valid_irq(rtc_irq) ? "no alarms" :
cmos_rtc.mon_alrm ? "alarms up to one year" :
@ -973,6 +1150,9 @@ static void cmos_do_remove(struct device *dev)
hpet_unregister_irq_handler(cmos_interrupt);
}
if (!dev_get_platdata(dev))
acpi_rtc_event_cleanup();
cmos->rtc = NULL;
ports = cmos->iomem;
@ -1122,9 +1302,6 @@ static void cmos_check_wkalrm(struct device *dev)
}
}
static void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control);
static int __maybe_unused cmos_resume(struct device *dev)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
@ -1191,175 +1368,13 @@ static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
* predate even PNPBIOS should set up platform_bus devices.
*/
#ifdef CONFIG_ACPI
#include <linux/acpi.h>
static u32 rtc_handler(void *context)
{
struct device *dev = context;
struct cmos_rtc *cmos = dev_get_drvdata(dev);
unsigned char rtc_control = 0;
unsigned char rtc_intr;
unsigned long flags;
/*
* Always update rtc irq when ACPI is used as RTC Alarm.
* Or else, ACPI SCI is enabled during suspend/resume only,
* update rtc irq in that case.
*/
if (cmos_use_acpi_alarm())
cmos_interrupt(0, (void *)cmos->rtc);
else {
/* Fix me: can we use cmos_interrupt() here as well? */
spin_lock_irqsave(&rtc_lock, flags);
if (cmos_rtc.suspend_ctrl)
rtc_control = CMOS_READ(RTC_CONTROL);
if (rtc_control & RTC_AIE) {
cmos_rtc.suspend_ctrl &= ~RTC_AIE;
CMOS_WRITE(rtc_control, RTC_CONTROL);
rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
rtc_update_irq(cmos->rtc, 1, rtc_intr);
}
spin_unlock_irqrestore(&rtc_lock, flags);
}
pm_wakeup_hard_event(dev);
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
return ACPI_INTERRUPT_HANDLED;
}
static inline void rtc_wake_setup(struct device *dev)
{
if (acpi_disabled)
return;
acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
/*
* After the RTC handler is installed, the Fixed_RTC event should
* be disabled. Only when the RTC alarm is set will it be enabled.
*/
acpi_clear_event(ACPI_EVENT_RTC);
acpi_disable_event(ACPI_EVENT_RTC, 0);
}
static void rtc_wake_on(struct device *dev)
{
acpi_clear_event(ACPI_EVENT_RTC);
acpi_enable_event(ACPI_EVENT_RTC, 0);
}
static void rtc_wake_off(struct device *dev)
{
acpi_disable_event(ACPI_EVENT_RTC, 0);
}
#ifdef CONFIG_X86
/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
static void use_acpi_alarm_quirks(void)
{
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
return;
if (!is_hpet_enabled())
return;
if (dmi_get_bios_year() < 2015)
return;
use_acpi_alarm = true;
}
#else
static inline void use_acpi_alarm_quirks(void) { }
#endif
/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
* its device node and pass extra config data. This helps its driver use
* capabilities that the now-obsolete mc146818 didn't have, and informs it
* that this board's RTC is wakeup-capable (per ACPI spec).
*/
static struct cmos_rtc_board_info acpi_rtc_info;
static void cmos_wake_setup(struct device *dev)
{
if (acpi_disabled)
return;
use_acpi_alarm_quirks();
acpi_rtc_info.wake_on = rtc_wake_on;
acpi_rtc_info.wake_off = rtc_wake_off;
/* workaround bug in some ACPI tables */
if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
acpi_gbl_FADT.month_alarm);
acpi_gbl_FADT.month_alarm = 0;
}
acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
acpi_rtc_info.rtc_century = acpi_gbl_FADT.century;
/* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
dev_info(dev, "RTC can wake from S4\n");
dev->platform_data = &acpi_rtc_info;
/* RTC always wakes from S1/S2/S3, and often S4/STD */
device_init_wakeup(dev, 1);
}
static void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control)
{
struct cmos_rtc *cmos = dev_get_drvdata(dev);
acpi_event_status rtc_status;
acpi_status status;
if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
return;
status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
if (ACPI_FAILURE(status)) {
dev_err(dev, "Could not get RTC status\n");
} else if (rtc_status & ACPI_EVENT_FLAG_SET) {
unsigned char mask;
*rtc_control &= ~RTC_AIE;
CMOS_WRITE(*rtc_control, RTC_CONTROL);
mask = CMOS_READ(RTC_INTR_FLAGS);
rtc_update_irq(cmos->rtc, 1, mask);
}
}
#else
static void cmos_wake_setup(struct device *dev)
{
}
static void cmos_check_acpi_rtc_status(struct device *dev,
unsigned char *rtc_control)
{
}
static void rtc_wake_setup(struct device *dev)
{
}
#endif
#ifdef CONFIG_PNP
#include <linux/pnp.h>
static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
{
int irq, ret;
cmos_wake_setup(&pnp->dev);
int irq;
if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
irq = 0;
@ -1375,13 +1390,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
irq = pnp_irq(pnp, 0);
}
ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
if (ret)
return ret;
rtc_wake_setup(&pnp->dev);
return 0;
return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
}
static void cmos_pnp_remove(struct pnp_dev *pnp)
@ -1465,10 +1474,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
static int __init cmos_platform_probe(struct platform_device *pdev)
{
struct resource *resource;
int irq, ret;
int irq;
cmos_of_init(pdev);
cmos_wake_setup(&pdev->dev);
if (RTC_IOMAPPED)
resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
@ -1478,13 +1486,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
if (irq < 0)
irq = -1;
ret = cmos_do_probe(&pdev->dev, resource, irq);
if (ret)
return ret;
rtc_wake_setup(&pdev->dev);
return 0;
return cmos_do_probe(&pdev->dev, resource, irq);
}
static int cmos_platform_remove(struct platform_device *pdev)

View File

@ -14,6 +14,8 @@
#define DRV_NAME "cros-ec-rtc"
#define SECS_PER_DAY (24 * 60 * 60)
/**
* struct cros_ec_rtc - Driver data for EC RTC
*
@ -43,13 +45,8 @@ static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command,
msg.msg.insize = sizeof(msg.data);
ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
if (ret < 0) {
dev_err(cros_ec->dev,
"error getting %s from EC: %d\n",
command == EC_CMD_RTC_GET_VALUE ? "time" : "alarm",
ret);
if (ret < 0)
return ret;
}
*response = msg.data.time;
@ -59,7 +56,7 @@ static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command,
static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command,
u32 param)
{
int ret = 0;
int ret;
struct {
struct cros_ec_command msg;
struct ec_response_rtc data;
@ -71,13 +68,8 @@ static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command,
msg.data.time = param;
ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
if (ret < 0) {
dev_err(cros_ec->dev, "error setting %s on EC: %d\n",
command == EC_CMD_RTC_SET_VALUE ? "time" : "alarm",
ret);
if (ret < 0)
return ret;
}
return 0;
}
@ -190,8 +182,21 @@ static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset);
if (ret < 0) {
dev_err(dev, "error setting alarm: %d\n", ret);
return ret;
if (ret == -EINVAL && alarm_offset >= SECS_PER_DAY) {
/*
* RTC chips on some older Chromebooks can only handle
* alarms up to 24h in the future. Try to set an alarm
* below that limit to avoid suspend failures.
*/
ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM,
SECS_PER_DAY - 1);
}
if (ret < 0) {
dev_err(dev, "error setting alarm in %u seconds: %d\n",
alarm_offset, ret);
return ret;
}
}
return 0;

View File

@ -1,512 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* DaVinci Power Management and Real Time Clock Driver for TI platforms
*
* Copyright (C) 2009 Texas Instruments, Inc
*
* Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
/*
* The DaVinci RTC is a simple RTC with the following
* Sec: 0 - 59 : BCD count
* Min: 0 - 59 : BCD count
* Hour: 0 - 23 : BCD count
* Day: 0 - 0x7FFF(32767) : Binary count ( Over 89 years )
*/
/* PRTC interface registers */
#define DAVINCI_PRTCIF_PID 0x00
#define PRTCIF_CTLR 0x04
#define PRTCIF_LDATA 0x08
#define PRTCIF_UDATA 0x0C
#define PRTCIF_INTEN 0x10
#define PRTCIF_INTFLG 0x14
/* PRTCIF_CTLR bit fields */
#define PRTCIF_CTLR_BUSY BIT(31)
#define PRTCIF_CTLR_SIZE BIT(25)
#define PRTCIF_CTLR_DIR BIT(24)
#define PRTCIF_CTLR_BENU_MSB BIT(23)
#define PRTCIF_CTLR_BENU_3RD_BYTE BIT(22)
#define PRTCIF_CTLR_BENU_2ND_BYTE BIT(21)
#define PRTCIF_CTLR_BENU_LSB BIT(20)
#define PRTCIF_CTLR_BENU_MASK (0x00F00000)
#define PRTCIF_CTLR_BENL_MSB BIT(19)
#define PRTCIF_CTLR_BENL_3RD_BYTE BIT(18)
#define PRTCIF_CTLR_BENL_2ND_BYTE BIT(17)
#define PRTCIF_CTLR_BENL_LSB BIT(16)
#define PRTCIF_CTLR_BENL_MASK (0x000F0000)
/* PRTCIF_INTEN bit fields */
#define PRTCIF_INTEN_RTCSS BIT(1)
#define PRTCIF_INTEN_RTCIF BIT(0)
#define PRTCIF_INTEN_MASK (PRTCIF_INTEN_RTCSS \
| PRTCIF_INTEN_RTCIF)
/* PRTCIF_INTFLG bit fields */
#define PRTCIF_INTFLG_RTCSS BIT(1)
#define PRTCIF_INTFLG_RTCIF BIT(0)
#define PRTCIF_INTFLG_MASK (PRTCIF_INTFLG_RTCSS \
| PRTCIF_INTFLG_RTCIF)
/* PRTC subsystem registers */
#define PRTCSS_RTC_INTC_EXTENA1 (0x0C)
#define PRTCSS_RTC_CTRL (0x10)
#define PRTCSS_RTC_WDT (0x11)
#define PRTCSS_RTC_TMR0 (0x12)
#define PRTCSS_RTC_TMR1 (0x13)
#define PRTCSS_RTC_CCTRL (0x14)
#define PRTCSS_RTC_SEC (0x15)
#define PRTCSS_RTC_MIN (0x16)
#define PRTCSS_RTC_HOUR (0x17)
#define PRTCSS_RTC_DAY0 (0x18)
#define PRTCSS_RTC_DAY1 (0x19)
#define PRTCSS_RTC_AMIN (0x1A)
#define PRTCSS_RTC_AHOUR (0x1B)
#define PRTCSS_RTC_ADAY0 (0x1C)
#define PRTCSS_RTC_ADAY1 (0x1D)
#define PRTCSS_RTC_CLKC_CNT (0x20)
/* PRTCSS_RTC_INTC_EXTENA1 */
#define PRTCSS_RTC_INTC_EXTENA1_MASK (0x07)
/* PRTCSS_RTC_CTRL bit fields */
#define PRTCSS_RTC_CTRL_WDTBUS BIT(7)
#define PRTCSS_RTC_CTRL_WEN BIT(6)
#define PRTCSS_RTC_CTRL_WDRT BIT(5)
#define PRTCSS_RTC_CTRL_WDTFLG BIT(4)
#define PRTCSS_RTC_CTRL_TE BIT(3)
#define PRTCSS_RTC_CTRL_TIEN BIT(2)
#define PRTCSS_RTC_CTRL_TMRFLG BIT(1)
#define PRTCSS_RTC_CTRL_TMMD BIT(0)
/* PRTCSS_RTC_CCTRL bit fields */
#define PRTCSS_RTC_CCTRL_CALBUSY BIT(7)
#define PRTCSS_RTC_CCTRL_DAEN BIT(5)
#define PRTCSS_RTC_CCTRL_HAEN BIT(4)
#define PRTCSS_RTC_CCTRL_MAEN BIT(3)
#define PRTCSS_RTC_CCTRL_ALMFLG BIT(2)
#define PRTCSS_RTC_CCTRL_AIEN BIT(1)
#define PRTCSS_RTC_CCTRL_CAEN BIT(0)
static DEFINE_SPINLOCK(davinci_rtc_lock);
struct davinci_rtc {
struct rtc_device *rtc;
void __iomem *base;
int irq;
};
static inline void rtcif_write(struct davinci_rtc *davinci_rtc,
u32 val, u32 addr)
{
writel(val, davinci_rtc->base + addr);
}
static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr)
{
return readl(davinci_rtc->base + addr);
}
static inline void rtcif_wait(struct davinci_rtc *davinci_rtc)
{
while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY)
cpu_relax();
}
static inline void rtcss_write(struct davinci_rtc *davinci_rtc,
unsigned long val, u8 addr)
{
rtcif_wait(davinci_rtc);
rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR);
rtcif_write(davinci_rtc, val, PRTCIF_LDATA);
rtcif_wait(davinci_rtc);
}
static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr)
{
rtcif_wait(davinci_rtc);
rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr,
PRTCIF_CTLR);
rtcif_wait(davinci_rtc);
return rtcif_read(davinci_rtc, PRTCIF_LDATA);
}
static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc)
{
while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
PRTCSS_RTC_CCTRL_CALBUSY)
cpu_relax();
}
static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev)
{
struct davinci_rtc *davinci_rtc = class_dev;
unsigned long events = 0;
u32 irq_flg;
u8 alm_irq, tmr_irq;
u8 rtc_ctrl, rtc_cctrl;
int ret = IRQ_NONE;
irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) &
PRTCIF_INTFLG_RTCSS;
alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
PRTCSS_RTC_CCTRL_ALMFLG;
tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) &
PRTCSS_RTC_CTRL_TMRFLG;
if (irq_flg) {
if (alm_irq) {
events |= RTC_IRQF | RTC_AF;
rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
rtc_cctrl |= PRTCSS_RTC_CCTRL_ALMFLG;
rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
} else if (tmr_irq) {
events |= RTC_IRQF | RTC_PF;
rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
rtc_ctrl |= PRTCSS_RTC_CTRL_TMRFLG;
rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
}
rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS,
PRTCIF_INTFLG);
rtc_update_irq(davinci_rtc->rtc, 1, events);
ret = IRQ_HANDLED;
}
return ret;
}
static int
davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
u8 rtc_ctrl;
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&davinci_rtc_lock, flags);
rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
switch (cmd) {
case RTC_WIE_ON:
rtc_ctrl |= PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG;
break;
case RTC_WIE_OFF:
rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN;
break;
default:
ret = -ENOIOCTLCMD;
}
rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
return ret;
}
static void convertfromdays(u16 days, struct rtc_time *tm)
{
int tmp_days, year, mon;
for (year = 2000;; year++) {
tmp_days = rtc_year_days(1, 12, year);
if (days >= tmp_days)
days -= tmp_days;
else {
for (mon = 0;; mon++) {
tmp_days = rtc_month_days(mon, year);
if (days >= tmp_days) {
days -= tmp_days;
} else {
tm->tm_year = year - 1900;
tm->tm_mon = mon;
tm->tm_mday = days + 1;
break;
}
}
break;
}
}
}
static void convert2days(u16 *days, struct rtc_time *tm)
{
int i;
*days = 0;
for (i = 2000; i < 1900 + tm->tm_year; i++)
*days += rtc_year_days(1, 12, i);
*days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year);
}
static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
u16 days = 0;
u8 day0, day1;
unsigned long flags;
spin_lock_irqsave(&davinci_rtc_lock, flags);
davinci_rtcss_calendar_wait(davinci_rtc);
tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC));
davinci_rtcss_calendar_wait(davinci_rtc);
tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN));
davinci_rtcss_calendar_wait(davinci_rtc);
tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR));
davinci_rtcss_calendar_wait(davinci_rtc);
day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0);
davinci_rtcss_calendar_wait(davinci_rtc);
day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1);
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
days |= day1;
days <<= 8;
days |= day0;
convertfromdays(days, tm);
return 0;
}
static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
u16 days;
u8 rtc_cctrl;
unsigned long flags;
convert2days(&days, tm);
spin_lock_irqsave(&davinci_rtc_lock, flags);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1);
rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN;
rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
return 0;
}
static int davinci_rtc_alarm_irq_enable(struct device *dev,
unsigned int enabled)
{
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
unsigned long flags;
u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
spin_lock_irqsave(&davinci_rtc_lock, flags);
if (enabled)
rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN |
PRTCSS_RTC_CCTRL_HAEN |
PRTCSS_RTC_CCTRL_MAEN |
PRTCSS_RTC_CCTRL_ALMFLG |
PRTCSS_RTC_CCTRL_AIEN;
else
rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN;
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
return 0;
}
static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
u16 days = 0;
u8 day0, day1;
unsigned long flags;
alm->time.tm_sec = 0;
spin_lock_irqsave(&davinci_rtc_lock, flags);
davinci_rtcss_calendar_wait(davinci_rtc);
alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN));
davinci_rtcss_calendar_wait(davinci_rtc);
alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR));
davinci_rtcss_calendar_wait(davinci_rtc);
day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0);
davinci_rtcss_calendar_wait(davinci_rtc);
day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1);
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
days |= day1;
days <<= 8;
days |= day0;
convertfromdays(days, &alm->time);
alm->pending = !!(rtcss_read(davinci_rtc,
PRTCSS_RTC_CCTRL) &
PRTCSS_RTC_CCTRL_AIEN);
alm->enabled = alm->pending && device_may_wakeup(dev);
return 0;
}
static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
unsigned long flags;
u16 days;
convert2days(&days, &alm->time);
spin_lock_irqsave(&davinci_rtc_lock, flags);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0);
davinci_rtcss_calendar_wait(davinci_rtc);
rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1);
spin_unlock_irqrestore(&davinci_rtc_lock, flags);
return 0;
}
static const struct rtc_class_ops davinci_rtc_ops = {
.ioctl = davinci_rtc_ioctl,
.read_time = davinci_rtc_read_time,
.set_time = davinci_rtc_set_time,
.alarm_irq_enable = davinci_rtc_alarm_irq_enable,
.read_alarm = davinci_rtc_read_alarm,
.set_alarm = davinci_rtc_set_alarm,
};
static int __init davinci_rtc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct davinci_rtc *davinci_rtc;
int ret = 0;
davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL);
if (!davinci_rtc)
return -ENOMEM;
davinci_rtc->irq = platform_get_irq(pdev, 0);
if (davinci_rtc->irq < 0)
return davinci_rtc->irq;
davinci_rtc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(davinci_rtc->base))
return PTR_ERR(davinci_rtc->base);
platform_set_drvdata(pdev, davinci_rtc);
davinci_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(davinci_rtc->rtc))
return PTR_ERR(davinci_rtc->rtc);
davinci_rtc->rtc->ops = &davinci_rtc_ops;
davinci_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
davinci_rtc->rtc->range_max = RTC_TIMESTAMP_BEGIN_2000 + (1 << 16) * 86400ULL - 1;
rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG);
rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1);
rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL);
rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
ret = devm_request_irq(dev, davinci_rtc->irq, davinci_rtc_interrupt,
0, "davinci_rtc", davinci_rtc);
if (ret < 0) {
dev_err(dev, "unable to register davinci RTC interrupt\n");
return ret;
}
/* Enable interrupts */
rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN);
rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK,
PRTCSS_RTC_INTC_EXTENA1);
rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL);
device_init_wakeup(&pdev->dev, 0);
return devm_rtc_register_device(davinci_rtc->rtc);
}
static int __exit davinci_rtc_remove(struct platform_device *pdev)
{
struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev);
device_init_wakeup(&pdev->dev, 0);
rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
return 0;
}
static struct platform_driver davinci_rtc_driver = {
.remove = __exit_p(davinci_rtc_remove),
.driver = {
.name = "rtc_davinci",
},
};
module_platform_driver_probe(davinci_rtc_driver, davinci_rtc_probe);
MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>");
MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver");
MODULE_LICENSE("GPL");

View File

@ -185,11 +185,6 @@ static int ds1302_probe(struct spi_device *spi)
return 0;
}
static void ds1302_remove(struct spi_device *spi)
{
spi_set_drvdata(spi, NULL);
}
#ifdef CONFIG_OF
static const struct of_device_id ds1302_dt_ids[] = {
{ .compatible = "maxim,ds1302", },
@ -208,7 +203,6 @@ static struct spi_driver ds1302_driver = {
.driver.name = "rtc-ds1302",
.driver.of_match_table = of_match_ptr(ds1302_dt_ids),
.probe = ds1302_probe,
.remove = ds1302_remove,
.id_table = ds1302_spi_ids,
};

View File

@ -11,6 +11,7 @@
#include <linux/bcd.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kstrtox.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/property.h>
@ -1218,8 +1219,7 @@ static ssize_t frequency_test_show(struct device *dev,
regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg);
return scnprintf(buf, PAGE_SIZE, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" :
"off\n");
return sysfs_emit(buf, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" : "off\n");
}
static DEVICE_ATTR_RW(frequency_test);

View File

@ -112,7 +112,7 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
return err;
century = (dt->tm_year / 100) + 19;
err = regmap_write(map, DS1347_CENTURY_REG, century);
err = regmap_write(map, DS1347_CENTURY_REG, bin2bcd(century));
if (err)
return err;

View File

@ -158,8 +158,7 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
ioaddr = devm_ioremap_resource(&pdev->dev, res);
ioaddr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(ioaddr))
return PTR_ERR(ioaddr);

View File

@ -271,6 +271,8 @@ static int __init efi_rtc_probe(struct platform_device *dev)
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features);
device_init_wakeup(&dev->dev, true);
return devm_rtc_register_device(rtc);
}

View File

@ -327,12 +327,7 @@ static struct platform_driver ftm_rtc_driver = {
},
};
static int __init ftm_alarm_init(void)
{
return platform_driver_register(&ftm_rtc_driver);
}
device_initcall(ftm_alarm_init);
module_platform_driver(ftm_rtc_driver);
MODULE_DESCRIPTION("NXP/Freescale FlexTimer alarm driver");
MODULE_AUTHOR("Biwen Li <biwen.li@nxp.com>");

View File

@ -17,6 +17,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/hwmon.h>
/* ISL register offsets */
#define ISL12022_REG_SC 0x00
@ -30,6 +31,9 @@
#define ISL12022_REG_SR 0x07
#define ISL12022_REG_INT 0x08
#define ISL12022_REG_BETA 0x0d
#define ISL12022_REG_TEMP_L 0x28
/* ISL register bits */
#define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
@ -38,6 +42,7 @@
#define ISL12022_INT_WRTC (1 << 6)
#define ISL12022_BETA_TSE (1 << 7)
static struct i2c_driver isl12022_driver;
@ -46,6 +51,93 @@ struct isl12022 {
struct regmap *regmap;
};
static umode_t isl12022_hwmon_is_visible(const void *data,
enum hwmon_sensor_types type,
u32 attr, int channel)
{
if (type == hwmon_temp && attr == hwmon_temp_input)
return 0444;
return 0;
}
/*
* A user-initiated temperature conversion is not started by this function,
* so the temperature is updated once every ~60 seconds.
*/
static int isl12022_hwmon_read_temp(struct device *dev, long *mC)
{
struct isl12022 *isl12022 = dev_get_drvdata(dev);
struct regmap *regmap = isl12022->regmap;
u8 temp_buf[2];
int temp, ret;
ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L,
temp_buf, sizeof(temp_buf));
if (ret)
return ret;
/*
* Temperature is represented as a 10-bit number, unit half-Kelvins.
*/
temp = (temp_buf[1] << 8) | temp_buf[0];
temp *= 500;
temp -= 273000;
*mC = temp;
return 0;
}
static int isl12022_hwmon_read(struct device *dev,
enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
{
if (type == hwmon_temp && attr == hwmon_temp_input)
return isl12022_hwmon_read_temp(dev, val);
return -EOPNOTSUPP;
}
static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
NULL
};
static const struct hwmon_ops isl12022_hwmon_ops = {
.is_visible = isl12022_hwmon_is_visible,
.read = isl12022_hwmon_read,
};
static const struct hwmon_chip_info isl12022_hwmon_chip_info = {
.ops = &isl12022_hwmon_ops,
.info = isl12022_hwmon_info,
};
static void isl12022_hwmon_register(struct device *dev)
{
struct isl12022 *isl12022;
struct device *hwmon;
int ret;
if (!IS_REACHABLE(CONFIG_HWMON))
return;
isl12022 = dev_get_drvdata(dev);
ret = regmap_update_bits(isl12022->regmap, ISL12022_REG_BETA,
ISL12022_BETA_TSE, ISL12022_BETA_TSE);
if (ret) {
dev_warn(dev, "unable to enable temperature sensor\n");
return;
}
hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", isl12022,
&isl12022_hwmon_chip_info,
NULL);
if (IS_ERR(hwmon))
dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon);
}
/*
* In the routines that deal directly with the isl12022 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
@ -160,6 +252,8 @@ static int isl12022_probe(struct i2c_client *client)
return PTR_ERR(isl12022->regmap);
}
isl12022_hwmon_register(&client->dev);
isl12022->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl12022->rtc))
return PTR_ERR(isl12022->rtc);

View File

@ -797,7 +797,7 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq)
}
static int
isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
isl1208_probe(struct i2c_client *client)
{
int rc = 0;
struct isl1208_state *isl1208;
@ -821,6 +821,8 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (!isl1208->config)
return -ENODEV;
} else {
const struct i2c_device_id *id = i2c_match_id(isl1208_id, client);
if (id->driver_data >= ISL_LAST_ID)
return -ENODEV;
isl1208->config = &isl1208_configs[id->driver_data];
@ -906,7 +908,7 @@ static struct i2c_driver isl1208_driver = {
.name = "rtc-isl1208",
.of_match_table = of_match_ptr(isl1208_of_match),
},
.probe = isl1208_probe,
.probe_new = isl1208_probe,
.id_table = isl1208_id,
};

View File

@ -692,7 +692,7 @@ static void wdt_disable(void)
* @ppos: pointer to the position to write. No seeks allowed
*
* A write to a watchdog device is defined as a keepalive signal. Any
* write of data will do, as we we don't define content meaning.
* write of data will do, as we don't define content meaning.
*/
static ssize_t wdt_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
@ -876,8 +876,7 @@ static struct notifier_block wdt_notifier = {
*****************************************************************************
*/
static int m41t80_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int m41t80_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
int rc = 0;
@ -897,11 +896,13 @@ static int m41t80_probe(struct i2c_client *client,
return -ENOMEM;
m41t80_data->client = client;
if (client->dev.of_node)
if (client->dev.of_node) {
m41t80_data->features = (unsigned long)
of_device_get_match_data(&client->dev);
else
} else {
const struct i2c_device_id *id = i2c_match_id(m41t80_id, client);
m41t80_data->features = id->driver_data;
}
i2c_set_clientdata(client, m41t80_data);
m41t80_data->rtc = devm_rtc_allocate_device(&client->dev);
@ -1007,7 +1008,7 @@ static struct i2c_driver m41t80_driver = {
.of_match_table = of_match_ptr(m41t80_of_match),
.pm = &m41t80_pm,
},
.probe = m41t80_probe,
.probe_new = m41t80_probe,
.remove = m41t80_remove,
.id_table = m41t80_id,
};

View File

@ -212,22 +212,12 @@ static int msc313_rtc_probe(struct platform_device *pdev)
return ret;
}
clk = devm_clk_get(dev, NULL);
clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(clk)) {
dev_err(dev, "No input reference clock\n");
return PTR_ERR(clk);
}
ret = clk_prepare_enable(clk);
if (ret) {
dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
return ret;
}
ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk);
if (ret)
return ret;
rate = clk_get_rate(clk);
writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);

View File

@ -336,8 +336,10 @@ static int mxc_rtc_probe(struct platform_device *pdev)
}
pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc))
if (IS_ERR(pdata->rtc)) {
clk_disable_unprepare(pdata->clk);
return PTR_ERR(pdata->rtc);
}
pdata->rtc->ops = &mxc_rtc_ops;
pdata->rtc->range_max = U32_MAX;

View File

@ -452,8 +452,7 @@ static const struct rtc_class_ops nct3018y_rtc_ops = {
.ioctl = nct3018y_ioctl,
};
static int nct3018y_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int nct3018y_probe(struct i2c_client *client)
{
struct nct3018y *nct3018y;
int err, flags;
@ -541,7 +540,7 @@ static struct i2c_driver nct3018y_driver = {
.name = "rtc-nct3018y",
.of_match_table = of_match_ptr(nct3018y_of_match),
},
.probe = nct3018y_probe,
.probe_new = nct3018y_probe,
.id_table = nct3018y_id,
};

View File

@ -885,9 +885,17 @@ static const struct regmap_bus pcf2127_i2c_regmap = {
static struct i2c_driver pcf2127_i2c_driver;
static int pcf2127_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static const struct i2c_device_id pcf2127_i2c_id[] = {
{ "pcf2127", 1 },
{ "pcf2129", 0 },
{ "pca2129", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id);
static int pcf2127_i2c_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_match_id(pcf2127_i2c_id, client);
struct regmap *regmap;
static const struct regmap_config config = {
.reg_bits = 8,
@ -910,20 +918,12 @@ static int pcf2127_i2c_probe(struct i2c_client *client,
pcf2127_i2c_driver.driver.name, id->driver_data);
}
static const struct i2c_device_id pcf2127_i2c_id[] = {
{ "pcf2127", 1 },
{ "pcf2129", 0 },
{ "pca2129", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id);
static struct i2c_driver pcf2127_i2c_driver = {
.driver = {
.name = "rtc-pcf2127-i2c",
.of_match_table = of_match_ptr(pcf2127_of_match),
},
.probe = pcf2127_i2c_probe,
.probe_new = pcf2127_i2c_probe,
.id_table = pcf2127_i2c_id,
};

View File

@ -169,10 +169,10 @@ static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (ret)
return ret;
alrm->time.tm_sec = bcd2bin(buf[0]);
alrm->time.tm_min = bcd2bin(buf[1]);
alrm->time.tm_hour = bcd2bin(buf[2]);
alrm->time.tm_mday = bcd2bin(buf[3]);
alrm->time.tm_sec = bcd2bin(buf[0] & 0x7f);
alrm->time.tm_min = bcd2bin(buf[1] & 0x7f);
alrm->time.tm_hour = bcd2bin(buf[2] & 0x3f);
alrm->time.tm_mday = bcd2bin(buf[3] & 0x3f);
ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val);
if (ret)
@ -424,7 +424,7 @@ static int pcf85063_clkout_control(struct clk_hw *hw, bool enable)
unsigned int buf;
int ret;
ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, &buf);
ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf);
if (ret < 0)
return ret;
buf &= PCF85063_REG_CLKO_F_MASK;

View File

@ -99,24 +99,24 @@ static irqreturn_t pcf8523_irq(int irq, void *dev_id)
static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
u8 regs[7];
u8 regs[10];
int err;
err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_SECONDS, regs,
err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_CONTROL1, regs,
sizeof(regs));
if (err < 0)
return err;
if (regs[0] & PCF8523_SECONDS_OS)
if ((regs[0] & PCF8523_CONTROL1_STOP) || (regs[3] & PCF8523_SECONDS_OS))
return -EINVAL;
tm->tm_sec = bcd2bin(regs[0] & 0x7f);
tm->tm_min = bcd2bin(regs[1] & 0x7f);
tm->tm_hour = bcd2bin(regs[2] & 0x3f);
tm->tm_mday = bcd2bin(regs[3] & 0x3f);
tm->tm_wday = regs[4] & 0x7;
tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1;
tm->tm_year = bcd2bin(regs[6]) + 100;
tm->tm_sec = bcd2bin(regs[3] & 0x7f);
tm->tm_min = bcd2bin(regs[4] & 0x7f);
tm->tm_hour = bcd2bin(regs[5] & 0x3f);
tm->tm_mday = bcd2bin(regs[6] & 0x3f);
tm->tm_wday = regs[7] & 0x7;
tm->tm_mon = bcd2bin(regs[8] & 0x1f) - 1;
tm->tm_year = bcd2bin(regs[9]) + 100;
return 0;
}

View File

@ -567,6 +567,8 @@ static int pcf8563_probe(struct i2c_client *client)
client->irq);
return err;
}
} else {
clear_bit(RTC_FEATURE_ALARM, pcf8563->rtc->features);
}
err = devm_rtc_register_device(pcf8563->rtc);

View File

@ -324,16 +324,16 @@ static int pic32_rtc_probe(struct platform_device *pdev)
spin_lock_init(&pdata->alarm_lock);
pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc))
return PTR_ERR(pdata->rtc);
clk_prepare_enable(pdata->clk);
pic32_rtc_enable(pdata, 1);
device_init_wakeup(&pdev->dev, 1);
pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(pdata->rtc))
return PTR_ERR(pdata->rtc);
pdata->rtc->ops = &pic32_rtcops;
pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;

View File

@ -461,7 +461,6 @@ static const struct pm8xxx_rtc_regs pmk8350_regs = {
*/
static const struct of_device_id pm8xxx_id_table[] = {
{ .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs },
{ .compatible = "qcom,pm8018-rtc", .data = &pm8921_regs },
{ .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
{ .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
{ .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs },

View File

@ -14,7 +14,6 @@
#include <linux/bcd.h>
#include <linux/mfd/rk808.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
/* RTC_CTRL_REG bitfields */
#define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0)
@ -51,7 +50,7 @@ struct rk_rtc_compat_reg {
};
struct rk808_rtc {
struct rk808 *rk808;
struct regmap *regmap;
struct rtc_device *rtc;
struct rk_rtc_compat_reg *creg;
int irq;
@ -97,12 +96,11 @@ static void gregorian_to_rockchip(struct rtc_time *tm)
static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 rtc_data[NUM_TIME_REGS];
int ret;
/* Force an update of the shadowed registers right now */
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
BIT_RTC_CTRL_REG_RTC_GET_TIME);
if (ret) {
@ -116,7 +114,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
* 32khz. If we clear the GET_TIME bit here, the time of i2c transfer
* certainly more than 31.25us: 16 * 2.5us at 400kHz bus frequency.
*/
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_RTC_GET_TIME,
0);
if (ret) {
@ -124,7 +122,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
return ret;
}
ret = regmap_bulk_read(rk808->regmap, rk808_rtc->creg->seconds_reg,
ret = regmap_bulk_read(rk808_rtc->regmap, rk808_rtc->creg->seconds_reg,
rtc_data, NUM_TIME_REGS);
if (ret) {
dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret);
@ -148,7 +146,6 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 rtc_data[NUM_TIME_REGS];
int ret;
@ -163,7 +160,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_data[6] = bin2bcd(tm->tm_wday);
/* Stop RTC while updating the RTC registers */
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_STOP_RTC_M,
BIT_RTC_CTRL_REG_STOP_RTC_M);
if (ret) {
@ -171,14 +168,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
return ret;
}
ret = regmap_bulk_write(rk808->regmap, rk808_rtc->creg->seconds_reg,
ret = regmap_bulk_write(rk808_rtc->regmap, rk808_rtc->creg->seconds_reg,
rtc_data, NUM_TIME_REGS);
if (ret) {
dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
return ret;
}
/* Start RTC again */
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
if (ret) {
dev_err(dev, "Failed to update RTC control: %d\n", ret);
@ -191,12 +188,11 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 alrm_data[NUM_ALARM_REGS];
uint32_t int_reg;
int ret;
ret = regmap_bulk_read(rk808->regmap,
ret = regmap_bulk_read(rk808_rtc->regmap,
rk808_rtc->creg->alarm_seconds_reg,
alrm_data, NUM_ALARM_REGS);
if (ret) {
@ -212,7 +208,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
rockchip_to_gregorian(&alrm->time);
ret = regmap_read(rk808->regmap, rk808_rtc->creg->int_reg, &int_reg);
ret = regmap_read(rk808_rtc->regmap, rk808_rtc->creg->int_reg, &int_reg);
if (ret) {
dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
return ret;
@ -228,10 +224,9 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
{
struct rk808 *rk808 = rk808_rtc->rk808;
int ret;
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->int_reg,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
return ret;
@ -239,10 +234,9 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
{
struct rk808 *rk808 = rk808_rtc->rk808;
int ret;
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->int_reg,
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->int_reg,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M,
BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
@ -252,7 +246,6 @@ static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 alrm_data[NUM_ALARM_REGS];
int ret;
@ -272,7 +265,7 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1);
alrm_data[5] = bin2bcd(alrm->time.tm_year - 100);
ret = regmap_bulk_write(rk808->regmap,
ret = regmap_bulk_write(rk808_rtc->regmap,
rk808_rtc->creg->alarm_seconds_reg,
alrm_data, NUM_ALARM_REGS);
if (ret) {
@ -313,20 +306,18 @@ static int rk808_rtc_alarm_irq_enable(struct device *dev,
static irqreturn_t rk808_alarm_irq(int irq, void *data)
{
struct rk808_rtc *rk808_rtc = data;
struct rk808 *rk808 = rk808_rtc->rk808;
struct i2c_client *client = rk808->i2c;
int ret;
ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
ret = regmap_write(rk808_rtc->regmap, rk808_rtc->creg->status_reg,
RTC_STATUS_MASK);
if (ret) {
dev_err(&client->dev,
dev_err(&rk808_rtc->rtc->dev,
"%s:Failed to update RTC status: %d\n", __func__, ret);
return ret;
}
rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF);
dev_dbg(&client->dev,
dev_dbg(&rk808_rtc->rtc->dev,
"%s:irq=%d\n", __func__, irq);
return IRQ_HANDLED;
}
@ -404,10 +395,12 @@ static int rk808_rtc_probe(struct platform_device *pdev)
break;
}
platform_set_drvdata(pdev, rk808_rtc);
rk808_rtc->rk808 = rk808;
rk808_rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!rk808_rtc->regmap)
return -ENODEV;
/* start rtc running by default, and use shadowed timer. */
ret = regmap_update_bits(rk808->regmap, rk808_rtc->creg->ctrl_reg,
ret = regmap_update_bits(rk808_rtc->regmap, rk808_rtc->creg->ctrl_reg,
BIT_RTC_CTRL_REG_STOP_RTC_M |
BIT_RTC_CTRL_REG_RTC_READSEL_M,
BIT_RTC_CTRL_REG_RTC_READSEL_M);
@ -417,7 +410,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
return ret;
}
ret = regmap_write(rk808->regmap, rk808_rtc->creg->status_reg,
ret = regmap_write(rk808_rtc->regmap, rk808_rtc->creg->status_reg,
RTC_STATUS_MASK);
if (ret) {
dev_err(&pdev->dev,

View File

@ -2,7 +2,7 @@
* Ricoh RS5C313 RTC device/driver
* Copyright (C) 2007 Nobuhiro Iwamatsu
*
* 2005-09-19 modifed by kogiidena
* 2005-09-19 modified by kogiidena
*
* Based on the old drivers/char/rs5c313_rtc.c by:
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
@ -36,7 +36,7 @@
* 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init
* 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
* CONFIG_HPET_EMULATE_RTC
* 1.13 Nobuhiro Iwamatsu: Updata driver.
* 1.13 Nobuhiro Iwamatsu: Update driver.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@ -280,7 +280,7 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
while (1) {
RS5C313_CEENABLE; /* CE:H */
/* Initiatlize control reg. 24 hour */
/* Initialize control reg. 24 hour */
rs5c313_write_cntreg(0x04);
if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))

View File

@ -150,7 +150,7 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
* least 80219 chips; this works around that bug.
*
* The third method on the other hand doesn't work for the SMBus-only
* configurations, so we use the the first method there, stripping off
* configurations, so we use the first method there, stripping off
* the extra register in the process.
*/
if (rs5c->smbus) {
@ -791,8 +791,7 @@ static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
return 0;
}
static int rs5c372_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int rs5c372_probe(struct i2c_client *client)
{
int err = 0;
int smbus_mode = 0;
@ -826,11 +825,13 @@ static int rs5c372_probe(struct i2c_client *client,
rs5c372->client = client;
i2c_set_clientdata(client, rs5c372);
if (client->dev.of_node)
if (client->dev.of_node) {
rs5c372->type = (enum rtc_type)
of_device_get_match_data(&client->dev);
else
} else {
const struct i2c_device_id *id = i2c_match_id(rs5c372_id, client);
rs5c372->type = id->driver_data;
}
/* we read registers 0x0f then 0x00-0x0f; skip the first one */
rs5c372->regs = &rs5c372->buf[1];
@ -920,7 +921,7 @@ static struct i2c_driver rs5c372_driver = {
.name = "rtc-rs5c372",
.of_match_table = of_match_ptr(rs5c372_of_match),
},
.probe = rs5c372_probe,
.probe_new = rs5c372_probe,
.remove = rs5c372_remove,
.id_table = rs5c372_id,
};

View File

@ -902,9 +902,20 @@ static int rv3028_probe(struct i2c_client *client)
return PTR_ERR(rv3028->rtc);
if (client->irq > 0) {
unsigned long flags;
/*
* If flags = 0, devm_request_threaded_irq() will use IRQ flags
* obtained from device tree.
*/
if (dev_fwnode(&client->dev))
flags = 0;
else
flags = IRQF_TRIGGER_LOW;
ret = devm_request_threaded_irq(&client->dev, client->irq,
NULL, rv3028_handle_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
flags | IRQF_ONESHOT,
"rv3028", rv3028);
if (ret) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");

View File

@ -17,6 +17,7 @@
#include <linux/of.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/kstrtox.h>
#include <linux/regmap.h>
/* Register map */

View File

@ -576,8 +576,16 @@ static int rv8803_regs_configure(struct rv8803_data *rv8803)
return 0;
}
static int rv8803_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static const struct i2c_device_id rv8803_id[] = {
{ "rv8803", rv_8803 },
{ "rv8804", rx_8804 },
{ "rx8803", rx_8803 },
{ "rx8900", rx_8900 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rv8803_id);
static int rv8803_probe(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
struct rv8803_data *rv8803;
@ -605,11 +613,14 @@ static int rv8803_probe(struct i2c_client *client,
mutex_init(&rv8803->flags_lock);
rv8803->client = client;
if (client->dev.of_node)
if (client->dev.of_node) {
rv8803->type = (enum rv8803_type)
of_device_get_match_data(&client->dev);
else
} else {
const struct i2c_device_id *id = i2c_match_id(rv8803_id, client);
rv8803->type = id->driver_data;
}
i2c_set_clientdata(client, rv8803);
flags = rv8803_read_reg(client, RV8803_FLAG);
@ -666,15 +677,6 @@ static int rv8803_probe(struct i2c_client *client,
return 0;
}
static const struct i2c_device_id rv8803_id[] = {
{ "rv8803", rv_8803 },
{ "rv8804", rx_8804 },
{ "rx8803", rx_8803 },
{ "rx8900", rx_8900 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rv8803_id);
static const __maybe_unused struct of_device_id rv8803_of_match[] = {
{
.compatible = "microcrystal,rv8803",
@ -701,7 +703,7 @@ static struct i2c_driver rv8803_driver = {
.name = "rtc-rv8803",
.of_match_table = of_match_ptr(rv8803_of_match),
},
.probe = rv8803_probe,
.probe_new = rv8803_probe,
.id_table = rv8803_id,
};
module_i2c_driver(rv8803_driver);

View File

@ -376,7 +376,7 @@ static const struct spi_device_id rx6110_spi_id[] = {
};
MODULE_DEVICE_TABLE(spi, rx6110_spi_id);
static const struct of_device_id rx6110_spi_of_match[] = {
static const __maybe_unused struct of_device_id rx6110_spi_of_match[] = {
{ .compatible = "epson,rx6110" },
{ },
};

View File

@ -19,6 +19,7 @@
#include <linux/bitops.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/kstrtox.h>
#include <linux/module.h>
#include <linux/rtc.h>
@ -519,9 +520,9 @@ static const struct attribute_group rx8025_attr_group = {
.attrs = rx8025_attrs,
};
static int rx8025_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int rx8025_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_match_id(rx8025_id, client);
struct i2c_adapter *adapter = client->adapter;
struct rx8025_data *rx8025;
int err = 0;
@ -580,7 +581,7 @@ static struct i2c_driver rx8025_driver = {
.driver = {
.name = "rtc-rx8025",
},
.probe = rx8025_probe,
.probe_new = rx8025_probe,
.id_table = rx8025_id,
};

View File

@ -355,7 +355,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
devm_pm_runtime_enable(&pdev->dev);
ret = devm_pm_runtime_enable(&pdev->dev);
if (ret < 0)
return ret;
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0)
return ret;

View File

@ -211,7 +211,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct s35390a *s35390a = i2c_get_clientdata(client);
int i, err;
int i;
char buf[7], status;
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, "
@ -234,9 +234,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
for (i = 0; i < 7; ++i)
buf[i] = bitrev8(buf[i]);
err = s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf));
return err;
return s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf));
}
static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)

View File

@ -429,14 +429,9 @@ static int s3c_rtc_probe(struct platform_device *pdev)
return PTR_ERR(info->base);
info->rtc_clk = devm_clk_get(&pdev->dev, "rtc");
if (IS_ERR(info->rtc_clk)) {
ret = PTR_ERR(info->rtc_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "failed to find rtc clock\n");
else
dev_dbg(&pdev->dev, "probe deferred due to missing rtc clk\n");
return ret;
}
if (IS_ERR(info->rtc_clk))
return dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_clk),
"failed to find rtc clock\n");
ret = clk_prepare_enable(info->rtc_clk);
if (ret)
return ret;

View File

@ -32,6 +32,14 @@
#define SNVS_LPPGDR_INIT 0x41736166
#define CNTR_TO_SECS_SH 15
/* The maximum RTC clock cycles that are allowed to pass between two
* consecutive clock counter register reads. If the values are corrupted a
* bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles
* we end at 10ms which should be enough for most cases. If it once takes
* longer than expected we do a retry.
*/
#define MAX_RTC_READ_DIFF_CYCLES 320
struct snvs_rtc_data {
struct rtc_device *rtc;
struct regmap *regmap;
@ -56,6 +64,7 @@ static u64 rtc_read_lpsrt(struct snvs_rtc_data *data)
static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
{
u64 read1, read2;
s64 diff;
unsigned int timeout = 100;
/* As expected, the registers might update between the read of the LSB
@ -66,7 +75,8 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
do {
read2 = read1;
read1 = rtc_read_lpsrt(data);
} while (read1 != read2 && --timeout);
diff = read1 - read2;
} while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
if (!timeout)
dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
@ -78,13 +88,15 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
{
u32 count1, count2;
s32 diff;
unsigned int timeout = 100;
regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
do {
count2 = count1;
regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
} while (count1 != count2 && --timeout);
diff = count1 - count2;
} while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
if (!timeout) {
dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
return -ETIMEDOUT;

View File

@ -238,6 +238,7 @@ static int st_rtc_probe(struct platform_device *pdev)
rtc->clkrate = clk_get_rate(rtc->clk);
if (!rtc->clkrate) {
clk_disable_unprepare(rtc->clk);
dev_err(&pdev->dev, "Unable to fetch clock rate\n");
return -EINVAL;
}

View File

@ -6,6 +6,7 @@
* Author: Alessandro Zummo <a.zummo@towertech.it>
*/
#include <linux/kstrtox.h>
#include <linux/module.h>
#include <linux/rtc.h>