Commit acd04af6 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 9322af3e e88f319a
# 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>;
};
};
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>;
...
};
# 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>;
};
};
...@@ -11,12 +11,16 @@ maintainers: ...@@ -11,12 +11,16 @@ maintainers:
properties: properties:
compatible: compatible:
enum: oneOf:
- enum:
- qcom,pm8058-rtc - qcom,pm8058-rtc
- qcom,pm8921-rtc - qcom,pm8921-rtc
- qcom,pm8941-rtc - qcom,pm8941-rtc
- qcom,pm8018-rtc
- qcom,pmk8350-rtc - qcom,pmk8350-rtc
- items:
- enum:
- qcom,pm8018-rtc
- const: qcom,pm8921-rtc
reg: reg:
minItems: 1 minItems: 1
......
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>;
};
};
* 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>;
};
# 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>;
};
};
};
...@@ -433,7 +433,7 @@ config RTC_DRV_ISL12022 ...@@ -433,7 +433,7 @@ config RTC_DRV_ISL12022
config RTC_DRV_ISL12026 config RTC_DRV_ISL12026
tristate "Intersil ISL12026" tristate "Intersil ISL12026"
depends on OF || COMPILE_TEST depends on OF
help help
If you say yes here you get support for the If you say yes here you get support for the
Intersil ISL12026 RTC chip. Intersil ISL12026 RTC chip.
...@@ -1351,16 +1351,6 @@ config RTC_DRV_ASM9260 ...@@ -1351,16 +1351,6 @@ config RTC_DRV_ASM9260
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-asm9260. 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 config RTC_DRV_DIGICOLOR
tristate "Conexant Digicolor RTC" tristate "Conexant Digicolor RTC"
depends on ARCH_DIGICOLOR || COMPILE_TEST depends on ARCH_DIGICOLOR || COMPILE_TEST
......
...@@ -44,7 +44,6 @@ obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o ...@@ -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_DA9052) += rtc-da9052.o
obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o
obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o
obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o
obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o
obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
......
...@@ -374,11 +374,11 @@ struct rtc_device *devm_rtc_allocate_device(struct device *dev) ...@@ -374,11 +374,11 @@ struct rtc_device *devm_rtc_allocate_device(struct device *dev)
rtc->id = id; rtc->id = id;
rtc->dev.parent = dev; 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) if (err)
return ERR_PTR(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) if (err)
return ERR_PTR(err); return ERR_PTR(err);
......
...@@ -256,7 +256,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) ...@@ -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, * This could all instead be done in the lower level driver,
* but since more than one lower level RTC implementation needs it, * 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 */ /* Get the "before" timestamp */
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/kstrtox.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/rtc.h> #include <linux/rtc.h>
...@@ -673,13 +674,28 @@ static int abx80x_setup_watchdog(struct abx80x_priv *priv) ...@@ -673,13 +674,28 @@ static int abx80x_setup_watchdog(struct abx80x_priv *priv)
} }
#endif #endif
static int abx80x_probe(struct i2c_client *client, static const struct i2c_device_id abx80x_id[] = {
const struct i2c_device_id *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 device_node *np = client->dev.of_node;
struct abx80x_priv *priv; struct abx80x_priv *priv;
int i, data, err, trickle_cfg = -EINVAL; int i, data, err, trickle_cfg = -EINVAL;
char buf[7]; char buf[7];
const struct i2c_device_id *id = i2c_match_id(abx80x_id, client);
unsigned int part = id->driver_data; unsigned int part = id->driver_data;
unsigned int partnumber; unsigned int partnumber;
unsigned int majrev, minrev; unsigned int majrev, minrev;
...@@ -847,21 +863,6 @@ static int abx80x_probe(struct i2c_client *client, ...@@ -847,21 +863,6 @@ static int abx80x_probe(struct i2c_client *client,
return devm_rtc_register_device(priv->rtc); 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 #ifdef CONFIG_OF
static const struct of_device_id abx80x_of_match[] = { static const struct of_device_id abx80x_of_match[] = {
{ {
...@@ -914,7 +915,7 @@ static struct i2c_driver abx80x_driver = { ...@@ -914,7 +915,7 @@ static struct i2c_driver abx80x_driver = {
.name = "rtc-abx80x", .name = "rtc-abx80x",
.of_match_table = of_match_ptr(abx80x_of_match), .of_match_table = of_match_ptr(abx80x_of_match),
}, },
.probe = abx80x_probe, .probe_new = abx80x_probe,
.id_table = abx80x_id, .id_table = abx80x_id,
}; };
......
...@@ -130,7 +130,7 @@ static void at91_rtc_write_idr(u32 mask) ...@@ -130,7 +130,7 @@ static void at91_rtc_write_idr(u32 mask)
* *
* Note that there is still a possibility that the mask is updated * Note that there is still a possibility that the mask is updated
* before interrupts have actually been disabled in hardware. The only * 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 * the very register we are trying to emulate. The register read back
* is a reasonable heuristic. * is a reasonable heuristic.
*/ */
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kstrtox.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/bcd.h> #include <linux/bcd.h>
......
...@@ -744,6 +744,168 @@ static irqreturn_t cmos_interrupt(int irq, void *p) ...@@ -744,6 +744,168 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
return IRQ_NONE; 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 #ifdef CONFIG_PNP
#define INITSECTION #define INITSECTION
...@@ -827,19 +989,27 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) ...@@ -827,19 +989,27 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
if (info->address_space) if (info->address_space)
address_space = 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; 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; cmos_rtc.mon_alrm = info->rtc_mon_alarm;
if (info->rtc_century && info->rtc_century < 128)
cmos_rtc.century = info->rtc_century; cmos_rtc.century = info->rtc_century;
if (info->wake_on && info->wake_off) { if (info->wake_on && info->wake_off) {
cmos_rtc.wake_on = info->wake_on; cmos_rtc.wake_on = info->wake_on;
cmos_rtc.wake_off = info->wake_off; 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; cmos_rtc.dev = dev;
dev_set_drvdata(dev, &cmos_rtc); dev_set_drvdata(dev, &cmos_rtc);
...@@ -928,6 +1098,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) ...@@ -928,6 +1098,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
nvmem_cfg.size = address_space - NVRAM_OFFSET; nvmem_cfg.size = address_space - NVRAM_OFFSET;
devm_rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg); 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", dev_info(dev, "%s%s, %d bytes nvram%s\n",
!is_valid_irq(rtc_irq) ? "no alarms" : !is_valid_irq(rtc_irq) ? "no alarms" :
cmos_rtc.mon_alrm ? "alarms up to one year" : cmos_rtc.mon_alrm ? "alarms up to one year" :
...@@ -973,6 +1150,9 @@ static void cmos_do_remove(struct device *dev) ...@@ -973,6 +1150,9 @@ static void cmos_do_remove(struct device *dev)
hpet_unregister_irq_handler(cmos_interrupt); hpet_unregister_irq_handler(cmos_interrupt);
} }
if (!dev_get_platdata(dev))
acpi_rtc_event_cleanup();
cmos->rtc = NULL; cmos->rtc = NULL;
ports = cmos->iomem; ports = cmos->iomem;
...@@ -1122,9 +1302,6 @@ static void cmos_check_wkalrm(struct device *dev) ...@@ -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) static int __maybe_unused cmos_resume(struct device *dev)
{ {
struct cmos_rtc *cmos = dev_get_drvdata(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); ...@@ -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. * 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 #ifdef CONFIG_PNP
#include <linux/pnp.h> #include <linux/pnp.h>
static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
{ {
int irq, ret; int irq;
cmos_wake_setup(&pnp->dev);
if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) { if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
irq = 0; irq = 0;
...@@ -1375,13 +1390,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) ...@@ -1375,13 +1390,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
irq = pnp_irq(pnp, 0); irq = pnp_irq(pnp, 0);
} }
ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq); return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
if (ret)
return ret;
rtc_wake_setup(&pnp->dev);
return 0;
} }
static void cmos_pnp_remove(struct pnp_dev *pnp) static void cmos_pnp_remove(struct pnp_dev *pnp)
...@@ -1465,10 +1474,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {} ...@@ -1465,10 +1474,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
static int __init cmos_platform_probe(struct platform_device *pdev) static int __init cmos_platform_probe(struct platform_device *pdev)
{ {
struct resource *resource; struct resource *resource;
int irq, ret; int irq;
cmos_of_init(pdev); cmos_of_init(pdev);
cmos_wake_setup(&pdev->dev);
if (RTC_IOMAPPED) if (RTC_IOMAPPED)
resource = platform_get_resource(pdev, IORESOURCE_IO, 0); resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
...@@ -1478,13 +1486,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev) ...@@ -1478,13 +1486,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
if (irq < 0) if (irq < 0)
irq = -1; irq = -1;
ret = cmos_do_probe(&pdev->dev, resource, irq); return cmos_do_probe(&pdev->dev, resource, irq);
if (ret)
return ret;
rtc_wake_setup(&pdev->dev);
return 0;
} }
static int cmos_platform_remove(struct platform_device *pdev) static int cmos_platform_remove(struct platform_device *pdev)
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#define DRV_NAME "cros-ec-rtc" #define DRV_NAME "cros-ec-rtc"
#define SECS_PER_DAY (24 * 60 * 60)
/** /**
* struct cros_ec_rtc - Driver data for EC RTC * 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, ...@@ -43,13 +45,8 @@ static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command,
msg.msg.insize = sizeof(msg.data); msg.msg.insize = sizeof(msg.data);
ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
if (ret < 0) { if (ret < 0)
dev_err(cros_ec->dev,
"error getting %s from EC: %d\n",
command == EC_CMD_RTC_GET_VALUE ? "time" : "alarm",
ret);
return ret; return ret;
}
*response = msg.data.time; *response = msg.data.time;
...@@ -59,7 +56,7 @@ static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command, ...@@ -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, static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command,
u32 param) u32 param)
{ {
int ret = 0; int ret;
struct { struct {
struct cros_ec_command msg; struct cros_ec_command msg;
struct ec_response_rtc data; struct ec_response_rtc data;
...@@ -71,13 +68,8 @@ static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command, ...@@ -71,13 +68,8 @@ static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command,
msg.data.time = param; msg.data.time = param;
ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg);
if (ret < 0) { if (ret < 0)
dev_err(cros_ec->dev, "error setting %s on EC: %d\n",
command == EC_CMD_RTC_SET_VALUE ? "time" : "alarm",
ret);
return ret; return ret;
}
return 0; return 0;
} }
...@@ -190,9 +182,22 @@ static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -190,9 +182,22 @@ 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); ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "error setting alarm: %d\n", 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 ret;
} }
}
return 0; return 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");
...@@ -185,11 +185,6 @@ static int ds1302_probe(struct spi_device *spi) ...@@ -185,11 +185,6 @@ static int ds1302_probe(struct spi_device *spi)
return 0; return 0;
} }
static void ds1302_remove(struct spi_device *spi)
{
spi_set_drvdata(spi, NULL);
}
#ifdef CONFIG_OF #ifdef CONFIG_OF
static const struct of_device_id ds1302_dt_ids[] = { static const struct of_device_id ds1302_dt_ids[] = {
{ .compatible = "maxim,ds1302", }, { .compatible = "maxim,ds1302", },
...@@ -208,7 +203,6 @@ static struct spi_driver ds1302_driver = { ...@@ -208,7 +203,6 @@ static struct spi_driver ds1302_driver = {
.driver.name = "rtc-ds1302", .driver.name = "rtc-ds1302",
.driver.of_match_table = of_match_ptr(ds1302_dt_ids), .driver.of_match_table = of_match_ptr(ds1302_dt_ids),
.probe = ds1302_probe, .probe = ds1302_probe,
.remove = ds1302_remove,
.id_table = ds1302_spi_ids, .id_table = ds1302_spi_ids,
}; };
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kstrtox.h>
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/property.h> #include <linux/property.h>
...@@ -1218,8 +1219,7 @@ static ssize_t frequency_test_show(struct device *dev, ...@@ -1218,8 +1219,7 @@ static ssize_t frequency_test_show(struct device *dev,
regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg); regmap_read(ds1307->regmap, M41TXX_REG_CONTROL, &ctrl_reg);
return scnprintf(buf, PAGE_SIZE, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" : return sysfs_emit(buf, (ctrl_reg & M41TXX_BIT_FT) ? "on\n" : "off\n");
"off\n");
} }
static DEVICE_ATTR_RW(frequency_test); static DEVICE_ATTR_RW(frequency_test);
......
...@@ -112,7 +112,7 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt) ...@@ -112,7 +112,7 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
return err; return err;
century = (dt->tm_year / 100) + 19; 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) if (err)
return err; return err;
......
...@@ -158,8 +158,7 @@ static int ds1742_rtc_probe(struct platform_device *pdev) ...@@ -158,8 +158,7 @@ static int ds1742_rtc_probe(struct platform_device *pdev)
if (!pdata) if (!pdata)
return -ENOMEM; return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ioaddr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
ioaddr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ioaddr)) if (IS_ERR(ioaddr))
return PTR_ERR(ioaddr); return PTR_ERR(ioaddr);
......
...@@ -271,6 +271,8 @@ static int __init efi_rtc_probe(struct platform_device *dev) ...@@ -271,6 +271,8 @@ static int __init efi_rtc_probe(struct platform_device *dev)
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features); set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features);
device_init_wakeup(&dev->dev, true);
return devm_rtc_register_device(rtc); return devm_rtc_register_device(rtc);
} }
......
...@@ -327,12 +327,7 @@ static struct platform_driver ftm_rtc_driver = { ...@@ -327,12 +327,7 @@ static struct platform_driver ftm_rtc_driver = {
}, },
}; };
static int __init ftm_alarm_init(void) module_platform_driver(ftm_rtc_driver);
{
return platform_driver_register(&ftm_rtc_driver);
}
device_initcall(ftm_alarm_init);
MODULE_DESCRIPTION("NXP/Freescale FlexTimer alarm driver"); MODULE_DESCRIPTION("NXP/Freescale FlexTimer alarm driver");
MODULE_AUTHOR("Biwen Li <biwen.li@nxp.com>"); MODULE_AUTHOR("Biwen Li <biwen.li@nxp.com>");
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/hwmon.h>
/* ISL register offsets */ /* ISL register offsets */
#define ISL12022_REG_SC 0x00 #define ISL12022_REG_SC 0x00
...@@ -30,6 +31,9 @@ ...@@ -30,6 +31,9 @@
#define ISL12022_REG_SR 0x07 #define ISL12022_REG_SR 0x07
#define ISL12022_REG_INT 0x08 #define ISL12022_REG_INT 0x08
#define ISL12022_REG_BETA 0x0d
#define ISL12022_REG_TEMP_L 0x28
/* ISL register bits */ /* ISL register bits */
#define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */ #define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
...@@ -38,6 +42,7 @@ ...@@ -38,6 +42,7 @@
#define ISL12022_INT_WRTC (1 << 6) #define ISL12022_INT_WRTC (1 << 6)
#define ISL12022_BETA_TSE (1 << 7)
static struct i2c_driver isl12022_driver; static struct i2c_driver isl12022_driver;
...@@ -46,6 +51,93 @@ struct isl12022 { ...@@ -46,6 +51,93 @@ struct isl12022 {
struct regmap *regmap; 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 * In the routines that deal directly with the isl12022 hardware, we use
* rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
...@@ -160,6 +252,8 @@ static int isl12022_probe(struct i2c_client *client) ...@@ -160,6 +252,8 @@ static int isl12022_probe(struct i2c_client *client)
return PTR_ERR(isl12022->regmap); return PTR_ERR(isl12022->regmap);
} }
isl12022_hwmon_register(&client->dev);
isl12022->rtc = devm_rtc_allocate_device(&client->dev); isl12022->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl12022->rtc)) if (IS_ERR(isl12022->rtc))
return PTR_ERR(isl12022->rtc); return PTR_ERR(isl12022->rtc);
......
...@@ -797,7 +797,7 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq) ...@@ -797,7 +797,7 @@ static int isl1208_setup_irq(struct i2c_client *client, int irq)
} }
static int static int
isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) isl1208_probe(struct i2c_client *client)
{ {
int rc = 0; int rc = 0;
struct isl1208_state *isl1208; struct isl1208_state *isl1208;
...@@ -821,6 +821,8 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -821,6 +821,8 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (!isl1208->config) if (!isl1208->config)
return -ENODEV; return -ENODEV;
} else { } else {
const struct i2c_device_id *id = i2c_match_id(isl1208_id, client);
if (id->driver_data >= ISL_LAST_ID) if (id->driver_data >= ISL_LAST_ID)
return -ENODEV; return -ENODEV;
isl1208->config = &isl1208_configs[id->driver_data]; isl1208->config = &isl1208_configs[id->driver_data];
...@@ -906,7 +908,7 @@ static struct i2c_driver isl1208_driver = { ...@@ -906,7 +908,7 @@ static struct i2c_driver isl1208_driver = {
.name = "rtc-isl1208", .name = "rtc-isl1208",
.of_match_table = of_match_ptr(isl1208_of_match), .of_match_table = of_match_ptr(isl1208_of_match),
}, },
.probe = isl1208_probe, .probe_new = isl1208_probe,
.id_table = isl1208_id, .id_table = isl1208_id,
}; };
......
...@@ -692,7 +692,7 @@ static void wdt_disable(void) ...@@ -692,7 +692,7 @@ static void wdt_disable(void)
* @ppos: pointer to the position to write. No seeks allowed * @ppos: pointer to the position to write. No seeks allowed
* *
* A write to a watchdog device is defined as a keepalive signal. Any * 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, static ssize_t wdt_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -876,8 +876,7 @@ static struct notifier_block wdt_notifier = { ...@@ -876,8 +876,7 @@ static struct notifier_block wdt_notifier = {
***************************************************************************** *****************************************************************************
*/ */
static int m41t80_probe(struct i2c_client *client, static int m41t80_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
struct i2c_adapter *adapter = client->adapter; struct i2c_adapter *adapter = client->adapter;
int rc = 0; int rc = 0;
...@@ -897,11 +896,13 @@ static int m41t80_probe(struct i2c_client *client, ...@@ -897,11 +896,13 @@ static int m41t80_probe(struct i2c_client *client,
return -ENOMEM; return -ENOMEM;
m41t80_data->client = client; m41t80_data->client = client;
if (client->dev.of_node) if (client->dev.of_node) {
m41t80_data->features = (unsigned long) m41t80_data->features = (unsigned long)
of_device_get_match_data(&client->dev); 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; m41t80_data->features = id->driver_data;
}
i2c_set_clientdata(client, m41t80_data); i2c_set_clientdata(client, m41t80_data);
m41t80_data->rtc = devm_rtc_allocate_device(&client->dev); m41t80_data->rtc = devm_rtc_allocate_device(&client->dev);
...@@ -1007,7 +1008,7 @@ static struct i2c_driver m41t80_driver = { ...@@ -1007,7 +1008,7 @@ static struct i2c_driver m41t80_driver = {
.of_match_table = of_match_ptr(m41t80_of_match), .of_match_table = of_match_ptr(m41t80_of_match),
.pm = &m41t80_pm, .pm = &m41t80_pm,
}, },
.probe = m41t80_probe, .probe_new = m41t80_probe,
.remove = m41t80_remove, .remove = m41t80_remove,
.id_table = m41t80_id, .id_table = m41t80_id,
}; };
......
...@@ -212,22 +212,12 @@ static int msc313_rtc_probe(struct platform_device *pdev) ...@@ -212,22 +212,12 @@ static int msc313_rtc_probe(struct platform_device *pdev)
return ret; return ret;
} }
clk = devm_clk_get(dev, NULL); clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
dev_err(dev, "No input reference clock\n"); dev_err(dev, "No input reference clock\n");
return PTR_ERR(clk); 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); rate = clk_get_rate(clk);
writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L); writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H); writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
......
...@@ -336,8 +336,10 @@ static int mxc_rtc_probe(struct platform_device *pdev) ...@@ -336,8 +336,10 @@ static int mxc_rtc_probe(struct platform_device *pdev)
} }
pdata->rtc = devm_rtc_allocate_device(&pdev->dev); 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); return PTR_ERR(pdata->rtc);
}
pdata->rtc->ops = &mxc_rtc_ops; pdata->rtc->ops = &mxc_rtc_ops;
pdata->rtc->range_max = U32_MAX; pdata->rtc->range_max = U32_MAX;
......
...@@ -452,8 +452,7 @@ static const struct rtc_class_ops nct3018y_rtc_ops = { ...@@ -452,8 +452,7 @@ static const struct rtc_class_ops nct3018y_rtc_ops = {
.ioctl = nct3018y_ioctl, .ioctl = nct3018y_ioctl,
}; };
static int nct3018y_probe(struct i2c_client *client, static int nct3018y_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
struct nct3018y *nct3018y; struct nct3018y *nct3018y;
int err, flags; int err, flags;
...@@ -541,7 +540,7 @@ static struct i2c_driver nct3018y_driver = { ...@@ -541,7 +540,7 @@ static struct i2c_driver nct3018y_driver = {
.name = "rtc-nct3018y", .name = "rtc-nct3018y",
.of_match_table = of_match_ptr(nct3018y_of_match), .of_match_table = of_match_ptr(nct3018y_of_match),
}, },
.probe = nct3018y_probe, .probe_new = nct3018y_probe,
.id_table = nct3018y_id, .id_table = nct3018y_id,
}; };
......
...@@ -885,9 +885,17 @@ static const struct regmap_bus pcf2127_i2c_regmap = { ...@@ -885,9 +885,17 @@ static const struct regmap_bus pcf2127_i2c_regmap = {
static struct i2c_driver pcf2127_i2c_driver; static struct i2c_driver pcf2127_i2c_driver;
static int pcf2127_i2c_probe(struct i2c_client *client, static const struct i2c_device_id pcf2127_i2c_id[] = {
const struct i2c_device_id *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; struct regmap *regmap;
static const struct regmap_config config = { static const struct regmap_config config = {
.reg_bits = 8, .reg_bits = 8,
...@@ -910,20 +918,12 @@ static int pcf2127_i2c_probe(struct i2c_client *client, ...@@ -910,20 +918,12 @@ static int pcf2127_i2c_probe(struct i2c_client *client,
pcf2127_i2c_driver.driver.name, id->driver_data); 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 = { static struct i2c_driver pcf2127_i2c_driver = {
.driver = { .driver = {
.name = "rtc-pcf2127-i2c", .name = "rtc-pcf2127-i2c",
.of_match_table = of_match_ptr(pcf2127_of_match), .of_match_table = of_match_ptr(pcf2127_of_match),
}, },
.probe = pcf2127_i2c_probe, .probe_new = pcf2127_i2c_probe,
.id_table = pcf2127_i2c_id, .id_table = pcf2127_i2c_id,
}; };
......
...@@ -169,10 +169,10 @@ static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -169,10 +169,10 @@ static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (ret) if (ret)
return ret; return ret;
alrm->time.tm_sec = bcd2bin(buf[0]); alrm->time.tm_sec = bcd2bin(buf[0] & 0x7f);
alrm->time.tm_min = bcd2bin(buf[1]); alrm->time.tm_min = bcd2bin(buf[1] & 0x7f);
alrm->time.tm_hour = bcd2bin(buf[2]); alrm->time.tm_hour = bcd2bin(buf[2] & 0x3f);
alrm->time.tm_mday = bcd2bin(buf[3]); alrm->time.tm_mday = bcd2bin(buf[3] & 0x3f);
ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val); ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val);
if (ret) if (ret)
...@@ -424,7 +424,7 @@ static int pcf85063_clkout_control(struct clk_hw *hw, bool enable) ...@@ -424,7 +424,7 @@ static int pcf85063_clkout_control(struct clk_hw *hw, bool enable)
unsigned int buf; unsigned int buf;
int ret; int ret;
ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, &buf); ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf);
if (ret < 0) if (ret < 0)
return ret; return ret;
buf &= PCF85063_REG_CLKO_F_MASK; buf &= PCF85063_REG_CLKO_F_MASK;
......
...@@ -99,24 +99,24 @@ static irqreturn_t pcf8523_irq(int irq, void *dev_id) ...@@ -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) static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
struct pcf8523 *pcf8523 = dev_get_drvdata(dev); struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
u8 regs[7]; u8 regs[10];
int err; int err;
err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_SECONDS, regs, err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_CONTROL1, regs,
sizeof(regs)); sizeof(regs));
if (err < 0) if (err < 0)
return err; return err;
if (regs[0] & PCF8523_SECONDS_OS) if ((regs[0] & PCF8523_CONTROL1_STOP) || (regs[3] & PCF8523_SECONDS_OS))
return -EINVAL; return -EINVAL;
tm->tm_sec = bcd2bin(regs[0] & 0x7f); tm->tm_sec = bcd2bin(regs[3] & 0x7f);
tm->tm_min = bcd2bin(regs[1] & 0x7f); tm->tm_min = bcd2bin(regs[4] & 0x7f);
tm->tm_hour = bcd2bin(regs[2] & 0x3f); tm->tm_hour = bcd2bin(regs[5] & 0x3f);
tm->tm_mday = bcd2bin(regs[3] & 0x3f); tm->tm_mday = bcd2bin(regs[6] & 0x3f);
tm->tm_wday = regs[4] & 0x7; tm->tm_wday = regs[7] & 0x7;
tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1; tm->tm_mon = bcd2bin(regs[8] & 0x1f) - 1;
tm->tm_year = bcd2bin(regs[6]) + 100; tm->tm_year = bcd2bin(regs[9]) + 100;
return 0; return 0;
} }
......
...@@ -567,6 +567,8 @@ static int pcf8563_probe(struct i2c_client *client) ...@@ -567,6 +567,8 @@ static int pcf8563_probe(struct i2c_client *client)
client->irq); client->irq);
return err; return err;
} }
} else {
clear_bit(RTC_FEATURE_ALARM, pcf8563->rtc->features);
} }
err = devm_rtc_register_device(pcf8563->rtc); err = devm_rtc_register_device(pcf8563->rtc);
......
...@@ -324,16 +324,16 @@ static int pic32_rtc_probe(struct platform_device *pdev) ...@@ -324,16 +324,16 @@ static int pic32_rtc_probe(struct platform_device *pdev)
spin_lock_init(&pdata->alarm_lock); 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); clk_prepare_enable(pdata->clk);
pic32_rtc_enable(pdata, 1); pic32_rtc_enable(pdata, 1);
device_init_wakeup(&pdev->dev, 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->ops = &pic32_rtcops;
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;
......
...@@ -461,7 +461,6 @@ static const struct pm8xxx_rtc_regs pmk8350_regs = { ...@@ -461,7 +461,6 @@ static const struct pm8xxx_rtc_regs pmk8350_regs = {
*/ */
static const struct of_device_id pm8xxx_id_table[] = { static const struct of_device_id pm8xxx_id_table[] = {
{ .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs }, { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs },
{ .compatible = "qcom,pm8018-rtc", .data = &pm8921_regs },
{ .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs }, { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
{ .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs }, { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
{ .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs }, { .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs },
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/mfd/rk808.h> #include <linux/mfd/rk808.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c.h>
/* RTC_CTRL_REG bitfields */ /* RTC_CTRL_REG bitfields */
#define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0) #define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0)
...@@ -51,7 +50,7 @@ struct rk_rtc_compat_reg { ...@@ -51,7 +50,7 @@ struct rk_rtc_compat_reg {
}; };
struct rk808_rtc { struct rk808_rtc {
struct rk808 *rk808; struct regmap *regmap;
struct rtc_device *rtc; struct rtc_device *rtc;
struct rk_rtc_compat_reg *creg; struct rk_rtc_compat_reg *creg;
int irq; int irq;
...@@ -97,12 +96,11 @@ static void gregorian_to_rockchip(struct rtc_time *tm) ...@@ -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) static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
{ {
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 rtc_data[NUM_TIME_REGS]; u8 rtc_data[NUM_TIME_REGS];
int ret; int ret;
/* Force an update of the shadowed registers right now */ /* 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,
BIT_RTC_CTRL_REG_RTC_GET_TIME); BIT_RTC_CTRL_REG_RTC_GET_TIME);
if (ret) { if (ret) {
...@@ -116,7 +114,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) ...@@ -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 * 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. * 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, BIT_RTC_CTRL_REG_RTC_GET_TIME,
0); 0);
if (ret) { if (ret) {
...@@ -124,7 +122,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) ...@@ -124,7 +122,7 @@ static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm)
return ret; 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); rtc_data, NUM_TIME_REGS);
if (ret) { if (ret) {
dev_err(dev, "Failed to bulk read rtc_data: %d\n", 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) ...@@ -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) static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ {
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 rtc_data[NUM_TIME_REGS]; u8 rtc_data[NUM_TIME_REGS];
int ret; int ret;
...@@ -163,7 +160,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -163,7 +160,7 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
rtc_data[6] = bin2bcd(tm->tm_wday); rtc_data[6] = bin2bcd(tm->tm_wday);
/* Stop RTC while updating the RTC registers */ /* 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,
BIT_RTC_CTRL_REG_STOP_RTC_M); BIT_RTC_CTRL_REG_STOP_RTC_M);
if (ret) { if (ret) {
...@@ -171,14 +168,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -171,14 +168,14 @@ static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm)
return ret; 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); rtc_data, NUM_TIME_REGS);
if (ret) { if (ret) {
dev_err(dev, "Failed to bull write rtc_data: %d\n", ret); dev_err(dev, "Failed to bull write rtc_data: %d\n", ret);
return ret; return ret;
} }
/* Start RTC again */ /* 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); BIT_RTC_CTRL_REG_STOP_RTC_M, 0);
if (ret) { if (ret) {
dev_err(dev, "Failed to update RTC control: %d\n", 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) ...@@ -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) static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 alrm_data[NUM_ALARM_REGS]; u8 alrm_data[NUM_ALARM_REGS];
uint32_t int_reg; uint32_t int_reg;
int ret; int ret;
ret = regmap_bulk_read(rk808->regmap, ret = regmap_bulk_read(rk808_rtc->regmap,
rk808_rtc->creg->alarm_seconds_reg, rk808_rtc->creg->alarm_seconds_reg,
alrm_data, NUM_ALARM_REGS); alrm_data, NUM_ALARM_REGS);
if (ret) { if (ret) {
...@@ -212,7 +208,7 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -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; alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100;
rockchip_to_gregorian(&alrm->time); 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) { if (ret) {
dev_err(dev, "Failed to read RTC INT REG: %d\n", ret); dev_err(dev, "Failed to read RTC INT REG: %d\n", ret);
return ret; return ret;
...@@ -228,10 +224,9 @@ static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -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) static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc)
{ {
struct rk808 *rk808 = rk808_rtc->rk808;
int ret; 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); BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0);
return ret; return ret;
...@@ -239,10 +234,9 @@ static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc) ...@@ -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) static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc)
{ {
struct rk808 *rk808 = rk808_rtc->rk808;
int ret; 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,
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) ...@@ -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) static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{ {
struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev);
struct rk808 *rk808 = rk808_rtc->rk808;
u8 alrm_data[NUM_ALARM_REGS]; u8 alrm_data[NUM_ALARM_REGS];
int ret; int ret;
...@@ -272,7 +265,7 @@ static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -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[4] = bin2bcd(alrm->time.tm_mon + 1);
alrm_data[5] = bin2bcd(alrm->time.tm_year - 100); 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, rk808_rtc->creg->alarm_seconds_reg,
alrm_data, NUM_ALARM_REGS); alrm_data, NUM_ALARM_REGS);
if (ret) { if (ret) {
...@@ -313,20 +306,18 @@ static int rk808_rtc_alarm_irq_enable(struct device *dev, ...@@ -313,20 +306,18 @@ static int rk808_rtc_alarm_irq_enable(struct device *dev,
static irqreturn_t rk808_alarm_irq(int irq, void *data) static irqreturn_t rk808_alarm_irq(int irq, void *data)
{ {
struct rk808_rtc *rk808_rtc = data; struct rk808_rtc *rk808_rtc = data;
struct rk808 *rk808 = rk808_rtc->rk808;
struct i2c_client *client = rk808->i2c;
int ret; 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); RTC_STATUS_MASK);
if (ret) { if (ret) {
dev_err(&client->dev, dev_err(&rk808_rtc->rtc->dev,
"%s:Failed to update RTC status: %d\n", __func__, ret); "%s:Failed to update RTC status: %d\n", __func__, ret);
return ret; return ret;
} }
rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF); 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); "%s:irq=%d\n", __func__, irq);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -404,10 +395,12 @@ static int rk808_rtc_probe(struct platform_device *pdev) ...@@ -404,10 +395,12 @@ static int rk808_rtc_probe(struct platform_device *pdev)
break; break;
} }
platform_set_drvdata(pdev, rk808_rtc); 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. */ /* 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_STOP_RTC_M |
BIT_RTC_CTRL_REG_RTC_READSEL_M, BIT_RTC_CTRL_REG_RTC_READSEL_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) ...@@ -417,7 +410,7 @@ static int rk808_rtc_probe(struct platform_device *pdev)
return ret; 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); RTC_STATUS_MASK);
if (ret) { if (ret) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Ricoh RS5C313 RTC device/driver * Ricoh RS5C313 RTC device/driver
* Copyright (C) 2007 Nobuhiro Iwamatsu * 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: * Based on the old drivers/char/rs5c313_rtc.c by:
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init
* 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
* CONFIG_HPET_EMULATE_RTC * CONFIG_HPET_EMULATE_RTC
* 1.13 Nobuhiro Iwamatsu: Updata driver. * 1.13 Nobuhiro Iwamatsu: Update driver.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
...@@ -280,7 +280,7 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -280,7 +280,7 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
while (1) { while (1) {
RS5C313_CEENABLE; /* CE:H */ RS5C313_CEENABLE; /* CE:H */
/* Initiatlize control reg. 24 hour */ /* Initialize control reg. 24 hour */
rs5c313_write_cntreg(0x04); rs5c313_write_cntreg(0x04);
if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)) if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
......
...@@ -150,7 +150,7 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) ...@@ -150,7 +150,7 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
* least 80219 chips; this works around that bug. * least 80219 chips; this works around that bug.
* *
* The third method on the other hand doesn't work for the SMBus-only * 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. * the extra register in the process.
*/ */
if (rs5c->smbus) { if (rs5c->smbus) {
...@@ -791,8 +791,7 @@ static int rs5c_oscillator_setup(struct rs5c372 *rs5c372) ...@@ -791,8 +791,7 @@ static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
return 0; return 0;
} }
static int rs5c372_probe(struct i2c_client *client, static int rs5c372_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
int err = 0; int err = 0;
int smbus_mode = 0; int smbus_mode = 0;
...@@ -826,11 +825,13 @@ static int rs5c372_probe(struct i2c_client *client, ...@@ -826,11 +825,13 @@ static int rs5c372_probe(struct i2c_client *client,
rs5c372->client = client; rs5c372->client = client;
i2c_set_clientdata(client, rs5c372); i2c_set_clientdata(client, rs5c372);
if (client->dev.of_node) if (client->dev.of_node) {
rs5c372->type = (enum rtc_type) rs5c372->type = (enum rtc_type)
of_device_get_match_data(&client->dev); 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; rs5c372->type = id->driver_data;
}
/* we read registers 0x0f then 0x00-0x0f; skip the first one */ /* we read registers 0x0f then 0x00-0x0f; skip the first one */
rs5c372->regs = &rs5c372->buf[1]; rs5c372->regs = &rs5c372->buf[1];
...@@ -920,7 +921,7 @@ static struct i2c_driver rs5c372_driver = { ...@@ -920,7 +921,7 @@ static struct i2c_driver rs5c372_driver = {
.name = "rtc-rs5c372", .name = "rtc-rs5c372",
.of_match_table = of_match_ptr(rs5c372_of_match), .of_match_table = of_match_ptr(rs5c372_of_match),
}, },
.probe = rs5c372_probe, .probe_new = rs5c372_probe,
.remove = rs5c372_remove, .remove = rs5c372_remove,
.id_table = rs5c372_id, .id_table = rs5c372_id,
}; };
......
...@@ -902,9 +902,20 @@ static int rv3028_probe(struct i2c_client *client) ...@@ -902,9 +902,20 @@ static int rv3028_probe(struct i2c_client *client)
return PTR_ERR(rv3028->rtc); return PTR_ERR(rv3028->rtc);
if (client->irq > 0) { 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, ret = devm_request_threaded_irq(&client->dev, client->irq,
NULL, rv3028_handle_irq, NULL, rv3028_handle_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT, flags | IRQF_ONESHOT,
"rv3028", rv3028); "rv3028", rv3028);
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");
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/hwmon.h> #include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/kstrtox.h>
#include <linux/regmap.h> #include <linux/regmap.h>
/* Register map */ /* Register map */
......
...@@ -576,8 +576,16 @@ static int rv8803_regs_configure(struct rv8803_data *rv8803) ...@@ -576,8 +576,16 @@ static int rv8803_regs_configure(struct rv8803_data *rv8803)
return 0; return 0;
} }
static int rv8803_probe(struct i2c_client *client, static const struct i2c_device_id rv8803_id[] = {
const struct i2c_device_id *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 i2c_adapter *adapter = client->adapter;
struct rv8803_data *rv8803; struct rv8803_data *rv8803;
...@@ -605,11 +613,14 @@ static int rv8803_probe(struct i2c_client *client, ...@@ -605,11 +613,14 @@ static int rv8803_probe(struct i2c_client *client,
mutex_init(&rv8803->flags_lock); mutex_init(&rv8803->flags_lock);
rv8803->client = client; rv8803->client = client;
if (client->dev.of_node) if (client->dev.of_node) {
rv8803->type = (enum rv8803_type) rv8803->type = (enum rv8803_type)
of_device_get_match_data(&client->dev); 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; rv8803->type = id->driver_data;
}
i2c_set_clientdata(client, rv8803); i2c_set_clientdata(client, rv8803);
flags = rv8803_read_reg(client, RV8803_FLAG); flags = rv8803_read_reg(client, RV8803_FLAG);
...@@ -666,15 +677,6 @@ static int rv8803_probe(struct i2c_client *client, ...@@ -666,15 +677,6 @@ static int rv8803_probe(struct i2c_client *client,
return 0; 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[] = { static const __maybe_unused struct of_device_id rv8803_of_match[] = {
{ {
.compatible = "microcrystal,rv8803", .compatible = "microcrystal,rv8803",
...@@ -701,7 +703,7 @@ static struct i2c_driver rv8803_driver = { ...@@ -701,7 +703,7 @@ static struct i2c_driver rv8803_driver = {
.name = "rtc-rv8803", .name = "rtc-rv8803",
.of_match_table = of_match_ptr(rv8803_of_match), .of_match_table = of_match_ptr(rv8803_of_match),
}, },
.probe = rv8803_probe, .probe_new = rv8803_probe,
.id_table = rv8803_id, .id_table = rv8803_id,
}; };
module_i2c_driver(rv8803_driver); module_i2c_driver(rv8803_driver);
......
...@@ -376,7 +376,7 @@ static const struct spi_device_id rx6110_spi_id[] = { ...@@ -376,7 +376,7 @@ static const struct spi_device_id rx6110_spi_id[] = {
}; };
MODULE_DEVICE_TABLE(spi, 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" }, { .compatible = "epson,rx6110" },
{ }, { },
}; };
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kstrtox.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/rtc.h> #include <linux/rtc.h>
...@@ -519,9 +520,9 @@ static const struct attribute_group rx8025_attr_group = { ...@@ -519,9 +520,9 @@ static const struct attribute_group rx8025_attr_group = {
.attrs = rx8025_attrs, .attrs = rx8025_attrs,
}; };
static int rx8025_probe(struct i2c_client *client, static int rx8025_probe(struct i2c_client *client)
const struct i2c_device_id *id)
{ {
const struct i2c_device_id *id = i2c_match_id(rx8025_id, client);
struct i2c_adapter *adapter = client->adapter; struct i2c_adapter *adapter = client->adapter;
struct rx8025_data *rx8025; struct rx8025_data *rx8025;
int err = 0; int err = 0;
...@@ -580,7 +581,7 @@ static struct i2c_driver rx8025_driver = { ...@@ -580,7 +581,7 @@ static struct i2c_driver rx8025_driver = {
.driver = { .driver = {
.name = "rtc-rx8025", .name = "rtc-rx8025",
}, },
.probe = rx8025_probe, .probe_new = rx8025_probe,
.id_table = rx8025_id, .id_table = rx8025_id,
}; };
......
...@@ -355,7 +355,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev) ...@@ -355,7 +355,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features); set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, 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); ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -211,7 +211,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -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 i2c_client *client = to_i2c_client(dev);
struct s35390a *s35390a = i2c_get_clientdata(client); struct s35390a *s35390a = i2c_get_clientdata(client);
int i, err; int i;
char buf[7], status; char buf[7], status;
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, " 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) ...@@ -234,9 +234,7 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm)
for (i = 0; i < 7; ++i) for (i = 0; i < 7; ++i)
buf[i] = bitrev8(buf[i]); buf[i] = bitrev8(buf[i]);
err = s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); return s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf));
return err;
} }
static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm)
......
...@@ -429,14 +429,9 @@ static int s3c_rtc_probe(struct platform_device *pdev) ...@@ -429,14 +429,9 @@ static int s3c_rtc_probe(struct platform_device *pdev)
return PTR_ERR(info->base); return PTR_ERR(info->base);
info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); info->rtc_clk = devm_clk_get(&pdev->dev, "rtc");
if (IS_ERR(info->rtc_clk)) { if (IS_ERR(info->rtc_clk))
ret = PTR_ERR(info->rtc_clk); return dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_clk),
if (ret != -EPROBE_DEFER) "failed to find rtc clock\n");
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;
}
ret = clk_prepare_enable(info->rtc_clk); ret = clk_prepare_enable(info->rtc_clk);
if (ret) if (ret)
return ret; return ret;
......
...@@ -32,6 +32,14 @@ ...@@ -32,6 +32,14 @@
#define SNVS_LPPGDR_INIT 0x41736166 #define SNVS_LPPGDR_INIT 0x41736166
#define CNTR_TO_SECS_SH 15 #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 snvs_rtc_data {
struct rtc_device *rtc; struct rtc_device *rtc;
struct regmap *regmap; struct regmap *regmap;
...@@ -56,6 +64,7 @@ static u64 rtc_read_lpsrt(struct snvs_rtc_data *data) ...@@ -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) static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
{ {
u64 read1, read2; u64 read1, read2;
s64 diff;
unsigned int timeout = 100; unsigned int timeout = 100;
/* As expected, the registers might update between the read of the LSB /* 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) ...@@ -66,7 +75,8 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
do { do {
read2 = read1; read2 = read1;
read1 = rtc_read_lpsrt(data); read1 = rtc_read_lpsrt(data);
} while (read1 != read2 && --timeout); diff = read1 - read2;
} while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
if (!timeout) if (!timeout)
dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); 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) ...@@ -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) static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
{ {
u32 count1, count2; u32 count1, count2;
s32 diff;
unsigned int timeout = 100; unsigned int timeout = 100;
regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
do { do {
count2 = count1; count2 = count1;
regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &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) { if (!timeout) {
dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
return -ETIMEDOUT; return -ETIMEDOUT;
......
...@@ -238,6 +238,7 @@ static int st_rtc_probe(struct platform_device *pdev) ...@@ -238,6 +238,7 @@ static int st_rtc_probe(struct platform_device *pdev)
rtc->clkrate = clk_get_rate(rtc->clk); rtc->clkrate = clk_get_rate(rtc->clk);
if (!rtc->clkrate) { if (!rtc->clkrate) {
clk_disable_unprepare(rtc->clk);
dev_err(&pdev->dev, "Unable to fetch clock rate\n"); dev_err(&pdev->dev, "Unable to fetch clock rate\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* Author: Alessandro Zummo <a.zummo@towertech.it> * Author: Alessandro Zummo <a.zummo@towertech.it>
*/ */
#include <linux/kstrtox.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/rtc.h> #include <linux/rtc.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment