Commit edafb6fe authored by Linus Torvalds's avatar Linus Torvalds

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

Pull RTC updates from Alexandre Belloni:
 "A quiet cycle this time.

   - ds1307: properly handle oscillator failure flags

   - imx-sc: alarm support

   - pcf2123: alarm support, correct offset handling

   - sun6i: add R40 support

   - simplify getting the adapter of an i2c client"

* tag 'rtc-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (37 commits)
  rtc: wm831x: Add IRQF_ONESHOT flag
  rtc: stm32: remove one condition check in stm32_rtc_set_alarm()
  rtc: pcf2123: Fix build error
  rtc: interface: Change type of 'count' from int to u64
  rtc: pcf8563: Clear event flags and disable interrupts before requesting irq
  rtc: pcf8563: Fix interrupt trigger method
  rtc: pcf2123: fix negative offset rounding
  rtc: pcf2123: add alarm support
  rtc: pcf2123: use %ptR
  rtc: pcf2123: port to regmap
  rtc: pcf2123: remove sysfs register view
  rtc: rx8025: simplify getting the adapter of a client
  rtc: rx8010: simplify getting the adapter of a client
  rtc: rv8803: simplify getting the adapter of a client
  rtc: m41t80: simplify getting the adapter of a client
  rtc: fm3130: simplify getting the adapter of a client
  rtc: tegra: Drop MODULE_ALIAS
  rtc: sun6i: Add R40 compatible
  dt-bindings: rtc: sun6i: Add the R40 RTC compatible
  dt-bindings: rtc: Convert Allwinner A31 RTC to a schema
  ...
parents 47ebe00b f0162d21
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/allwinner,sun4i-a10-rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allwinner A10 RTC Device Tree Bindings
allOf:
- $ref: "rtc.yaml#"
maintainers:
- Chen-Yu Tsai <wens@csie.org>
- Maxime Ripard <maxime.ripard@bootlin.com>
properties:
compatible:
enum:
- allwinner,sun4i-a10-rtc
- allwinner,sun7i-a20-rtc
reg:
maxItems: 1
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
rtc: rtc@1c20d00 {
compatible = "allwinner,sun4i-a10-rtc";
reg = <0x01c20d00 0x20>;
interrupts = <24>;
};
...
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/allwinner,sun6i-a31-rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allwinner A31 RTC Device Tree Bindings
maintainers:
- Chen-Yu Tsai <wens@csie.org>
- Maxime Ripard <maxime.ripard@bootlin.com>
properties:
"#clock-cells":
const: 1
compatible:
oneOf:
- const: allwinner,sun6i-a31-rtc
- const: allwinner,sun8i-a23-rtc
- const: allwinner,sun8i-h3-rtc
- const: allwinner,sun8i-r40-rtc
- const: allwinner,sun8i-v3-rtc
- const: allwinner,sun50i-h5-rtc
- items:
- const: allwinner,sun50i-a64-rtc
- const: allwinner,sun8i-h3-rtc
reg:
maxItems: 1
interrupts:
minItems: 1
maxItems: 2
items:
- description: RTC Alarm 0
- description: RTC Alarm 1
clocks:
maxItems: 1
clock-output-names:
minItems: 1
maxItems: 3
description:
The RTC provides up to three clocks
- the Low Frequency Oscillator or LOSC, at index 0,
- the Low Frequency Oscillator External output (X32KFOUT in
the datasheet), at index 1,
- the Internal Oscillator, at index 2.
allOf:
- $ref: "rtc.yaml#"
- if:
properties:
compatible:
contains:
const: allwinner,sun6i-a31-rtc
then:
properties:
clock-output-names:
minItems: 1
maxItems: 1
- if:
properties:
compatible:
contains:
enum:
- allwinner,sun8i-a23-rtc
- allwinner,sun8i-r40-rtc
- allwinner,sun8i-v3-rtc
then:
properties:
clock-output-names:
minItems: 2
maxItems: 2
- if:
properties:
compatible:
contains:
enum:
- allwinner,sun8i-h3-rtc
- allwinner,sun50i-h5-rtc
then:
properties:
clock-output-names:
minItems: 3
maxItems: 3
- if:
properties:
compatible:
contains:
const: allwinner,sun8i-r40-rtc
then:
properties:
interrupts:
minItems: 1
maxItems: 1
else:
properties:
interrupts:
minItems: 2
maxItems: 2
required:
- "#clock-cells"
- compatible
- reg
- interrupts
- clocks
- clock-output-names
additionalProperties: false
examples:
- |
rtc: rtc@1f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x400>;
interrupts = <0 40 4>, <0 41 4>;
clock-output-names = "osc32k";
clocks = <&ext_osc32k>;
#clock-cells = <1>;
};
...
Generic device tree bindings for Real Time Clock devices
========================================================
This document describes generic bindings which can be used to describe Real Time
Clock devices in a device tree.
Required properties
-------------------
- compatible : name of RTC device following generic names recommended practice.
For other required properties e.g. to describe register sets,
clocks, etc. check the binding documentation of the specific driver.
Optional properties
-------------------
- start-year : if provided, the default hardware range supported by the RTC is
shifted so the first usable year is the specified one.
The following properties may not be supported by all drivers. However, if a
driver wants to support one of the below features, it should adapt the bindings
below.
- trickle-resistor-ohms : Selected resistor for trickle charger. Should be given
if trickle charger should be enabled
- trickle-diode-disable : Do not use internal trickle charger diode Should be
given if internal trickle charger diode should be
disabled
- wakeup-source : Enables wake up of host system on alarm
- quartz-load-femtofarads : The capacitive load of the quartz(x-tal),
expressed in femto Farad (fF).
The default value shall be listed (if optional),
and likewise all valid values.
Trivial RTCs
------------
This is a list of trivial RTC devices that have simple device tree
bindings, consisting only of a compatible field, an address and
possibly an interrupt line.
Compatible Vendor / Chip
========== =============
abracon,abb5zes3 AB-RTCMC-32.768kHz-B5ZE-S3: Real Time Clock/Calendar Module with I2C Interface
abracon,abeoz9 AB-RTCMC-32.768kHz-EOZ9: Real Time Clock/Calendar Module with I2C Interface
dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output
dallas,ds1672 Dallas DS1672 Real-time Clock
dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM
epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
epson,rx8571 I2C-BUS INTERFACE REAL TIME CLOCK MODULE with Battery Backed RAM
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
emmicro,em3027 EM Microelectronic EM3027 Real-time Clock
isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM
isil,isl1218 Intersil ISL1218 Low Power RTC with Battery Backed SRAM
isil,isl12022 Intersil ISL12022 Real-time Clock
microcrystal,rv3028 Real Time Clock Module with I2C-Bus
microcrystal,rv3029 Real Time Clock Module with I2C-Bus
microcrystal,rv8523 Real Time Clock
nxp,pcf2127 Real-time clock
nxp,pcf2129 Real-time clock
nxp,pcf8563 Real-time clock/calendar
pericom,pt7c4338 Real-time Clock Module
ricoh,r2025sd I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,r2221tl I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rs5c372a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rs5c372b I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rv5c386 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rv5c387a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
sii,s35390a 2-wire CMOS real-time clock
whwave,sd3078 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
xircom,x1205 Xircom X1205 I2C RTC
This file has been moved to rtc.yaml.
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: RTC Generic Binding
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
description: |
This document describes generic bindings which can be used to
describe Real Time Clock devices in a device tree.
properties:
$nodename:
pattern: "^rtc(@.*|-[0-9a-f])*$"
quartz-load-femtofarads:
$ref: /schemas/types.yaml#/definitions/uint32
description:
The capacitive load of the quartz(x-tal), expressed in femto
Farad (fF). The default value shall be listed (if optional),
and likewise all valid values.
start-year:
$ref: /schemas/types.yaml#/definitions/uint32
description:
If provided, the default hardware range supported by the RTC is
shifted so the first usable year is the specified one.
trickle-diode-disable:
$ref: /schemas/types.yaml#/definitions/flag
description:
Do not use internal trickle charger diode. Should be given if
internal trickle charger diode should be disabled.
trickle-resistor-ohms:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Selected resistor for trickle charger. Should be given
if trickle charger should be enabled.
wakeup-source:
$ref: /schemas/types.yaml#/definitions/flag
description:
Enables wake up of host system on alarm.
...
* sun6i Real Time Clock
RTC controller for the Allwinner A31
Required properties:
- compatible : Should be one of the following combinations:
- "allwinner,sun6i-a31-rtc"
- "allwinner,sun8i-a23-rtc"
- "allwinner,sun8i-h3-rtc"
- "allwinner,sun8i-r40-rtc", "allwinner,sun8i-h3-rtc"
- "allwinner,sun8i-v3-rtc"
- "allwinner,sun50i-a64-rtc", "allwinner,sun8i-h3-rtc"
- "allwinner,sun50i-h5-rtc"
Where there are two or more compatible strings, this
denotes the hardware covered by the most specific one
is backward-compatible with the latter ones, and the
implementation for the latter ones can be used, albeit
with reduced functionality.
- reg : physical base address of the controller and length of
memory mapped region.
- interrupts : IRQ lines for the RTC alarm 0 and alarm 1, in that order.
Required properties for new device trees
- clocks : phandle to the 32kHz external oscillator
- clock-output-names : names of up to three clock outputs. See below.
- #clock-cells : must be equal to 1.
The RTC provides the following clocks at the given indices:
- 0: LOSC
- 1: LOSC external output, known as X32KFOUT in the datasheet.
This clock is not available on the A31 and is deprecated for old
device trees still using the "allwinner,sun6i-a31-rtc" compatible.
- 2: InternalOSC, or internal RC oscillator (A64/H3/H5 only)
Example:
rtc: rtc@1f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x400>;
interrupts = <0 40 4>, <0 41 4>;
clock-output-names = "osc32k";
clocks = <&ext_osc32k>;
#clock-cells = <1>;
};
* sun4i/sun7i Real Time Clock
RTC controller for the Allwinner A10/A20
Required properties:
- compatible : Should be "allwinner,sun4i-a10-rtc" or "allwinner,sun7i-a20-rtc"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: IRQ line for the RTC.
Example:
rtc: rtc@1c20d00 {
compatible = "allwinner,sun4i-a10-rtc";
reg = <0x01c20d00 0x20>;
interrupts = <24>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/trivial-rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Trivial RTCs
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
description: |
This is a list of trivial RTC devices that have simple device tree
bindings, consisting only of a compatible field, an address and
possibly an interrupt line.
allOf:
- $ref: "rtc.yaml#"
properties:
compatible:
enum:
# AB-RTCMC-32.768kHz-B5ZE-S3: Real Time Clock/Calendar Module with I2C Interface
- abracon,abb5zes3
# AB-RTCMC-32.768kHz-EOZ9: Real Time Clock/Calendar Module with I2C Interface
- abracon,abeoz9
# I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output
- dallas,ds1374
# Dallas DS1672 Real-time Clock
- dallas,ds1672
# Extremely Accurate I²C RTC with Integrated Crystal and SRAM
- dallas,ds3232
# I2C-BUS INTERFACE REAL TIME CLOCK MODULE
- epson,rx8010
# I2C-BUS INTERFACE REAL TIME CLOCK MODULE with Battery Backed RAM
- epson,rx8571
# I2C-BUS INTERFACE REAL TIME CLOCK MODULE
- epson,rx8581
# Intersil ISL1208 Low Power RTC with Battery Backed SRAM
- isil,isl1208
# Intersil ISL1218 Low Power RTC with Battery Backed SRAM
- isil,isl1218
# Intersil ISL12022 Real-time Clock
- isil,isl12022
# Real Time Clock Module with I2C-Bus
- microcrystal,rv3028
# Real Time Clock Module with I2C-Bus
- microcrystal,rv3029
# Real Time Clock
- microcrystal,rv8523
# Real-time clock
- nxp,pcf2127
# Real-time clock
- nxp,pcf2129
# Real-time clock/calendar
- nxp,pcf8563
# Real-time Clock Module
- pericom,pt7c4338
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
- ricoh,r2025sd
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
- ricoh,r2221tl
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
- ricoh,rs5c372a
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
- ricoh,rs5c372b
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
- ricoh,rv5c386
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
- ricoh,rv5c387a
# 2-wire CMOS real-time clock
- sii,s35390a
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
- whwave,sd3078
# Xircom X1205 I2C RTC
- xircom,x1205
reg:
maxItems: 1
interrupts:
maxItems: 1
start-year: true
required:
- compatible
- reg
additionalProperties: false
...
......@@ -562,7 +562,7 @@ config RTC_DRV_TPS6586X
config RTC_DRV_TPS65910
tristate "TI TPS65910 RTC driver"
depends on RTC_CLASS && MFD_TPS65910
depends on MFD_TPS65910
help
If you say yes here you get support for the RTC on the
TPS65910 chips.
......@@ -820,6 +820,7 @@ config RTC_DRV_MAX6902
config RTC_DRV_PCF2123
tristate "NXP PCF2123"
select REGMAP_SPI
help
If you say yes here you get support for the NXP PCF2123
RTC chip.
......
......@@ -633,7 +633,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
{
struct rtc_device *rtc;
ktime_t period;
int count;
u64 count;
rtc = container_of(timer, struct rtc_device, pie_timer);
......
......@@ -222,6 +222,45 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
return -EINVAL;
}
tmp = regs[DS1307_REG_SECS];
switch (ds1307->type) {
case ds_1307:
case m41t0:
case m41t00:
case m41t11:
if (tmp & DS1307_BIT_CH)
return -EINVAL;
break;
case ds_1308:
case ds_1338:
if (tmp & DS1307_BIT_CH)
return -EINVAL;
ret = regmap_read(ds1307->regmap, DS1307_REG_CONTROL, &tmp);
if (ret)
return ret;
if (tmp & DS1338_BIT_OSF)
return -EINVAL;
break;
case ds_1340:
if (tmp & DS1340_BIT_nEOSC)
return -EINVAL;
ret = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp);
if (ret)
return ret;
if (tmp & DS1340_BIT_OSF)
return -EINVAL;
break;
case mcp794xx:
if (!(tmp & MCP794XX_BIT_ST))
return -EINVAL;
break;
default:
break;
}
t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f);
t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
tmp = regs[DS1307_REG_HOUR] & 0x3f;
......@@ -286,7 +325,17 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
if (t->tm_year > 199 && chip->century_bit)
regs[chip->century_reg] |= chip->century_bit;
if (ds1307->type == mcp794xx) {
switch (ds1307->type) {
case ds_1308:
case ds_1338:
regmap_update_bits(ds1307->regmap, DS1307_REG_CONTROL,
DS1338_BIT_OSF, 0);
break;
case ds_1340:
regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG,
DS1340_BIT_OSF, 0);
break;
case mcp794xx:
/*
* these bits were cleared when preparing the date/time
* values and need to be set again before writing the
......@@ -294,6 +343,9 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
*/
regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
break;
default:
break;
}
dev_dbg(dev, "%s: %7ph\n", "write", regs);
......@@ -1702,7 +1754,6 @@ static int ds1307_probe(struct i2c_client *client,
break;
}
read_rtc:
/* read RTC registers */
err = regmap_bulk_read(ds1307->regmap, chip->offset, regs,
sizeof(regs));
......@@ -1711,75 +1762,11 @@ static int ds1307_probe(struct i2c_client *client,
goto exit;
}
/*
* minimal sanity checking; some chips (like DS1340) don't
* specify the extra bits as must-be-zero, but there are
* still a few values that are clearly out-of-range.
*/
tmp = regs[DS1307_REG_SECS];
switch (ds1307->type) {
case ds_1307:
case m41t0:
case m41t00:
case m41t11:
/* clock halted? turn it on, so clock can tick. */
if (tmp & DS1307_BIT_CH) {
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
dev_warn(ds1307->dev, "SET TIME!\n");
goto read_rtc;
}
break;
case ds_1308:
case ds_1338:
/* clock halted? turn it on, so clock can tick. */
if (tmp & DS1307_BIT_CH)
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
/* oscillator fault? clear flag, and warn */
if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
regmap_write(ds1307->regmap, DS1307_REG_CONTROL,
regs[DS1307_REG_CONTROL] &
~DS1338_BIT_OSF);
dev_warn(ds1307->dev, "SET TIME!\n");
goto read_rtc;
}
break;
case ds_1340:
/* clock halted? turn it on, so clock can tick. */
if (tmp & DS1340_BIT_nEOSC)
regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
err = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator fault? clear flag, and warn */
if (tmp & DS1340_BIT_OSF) {
regmap_write(ds1307->regmap, DS1340_REG_FLAG, 0);
dev_warn(ds1307->dev, "SET TIME!\n");
}
break;
case mcp794xx:
/* make sure that the backup battery is enabled */
if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
regmap_write(ds1307->regmap, DS1307_REG_WDAY,
regs[DS1307_REG_WDAY] |
MCP794XX_BIT_VBATEN);
}
/* clock halted? turn it on, so clock can tick. */
if (!(tmp & MCP794XX_BIT_ST)) {
regmap_write(ds1307->regmap, DS1307_REG_SECS,
MCP794XX_BIT_ST);
dev_warn(ds1307->dev, "SET TIME!\n");
goto read_rtc;
}
break;
default:
break;
if (ds1307->type == mcp794xx &&
!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
regmap_write(ds1307->regmap, DS1307_REG_WDAY,
regs[DS1307_REG_WDAY] |
MCP794XX_BIT_VBATEN);
}
tmp = regs[DS1307_REG_HOUR];
......
......@@ -182,9 +182,10 @@ static void ds2404_enable_osc(struct device *dev)
static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
{
unsigned long time = 0;
__le32 hw_time = 0;
ds2404_read_memory(dev, 0x203, 4, (u8 *)&time);
time = le32_to_cpu(time);
ds2404_read_memory(dev, 0x203, 4, (u8 *)&hw_time);
time = le32_to_cpu(hw_time);
rtc_time64_to_tm(time, dt);
return 0;
......
......@@ -104,8 +104,7 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t)
fm3130_rtc_mode(dev, FM3130_MODE_READ);
/* read the RTC date and time registers all at once */
tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent),
fm3130->msg, 2);
tmp = i2c_transfer(fm3130->client->adapter, fm3130->msg, 2);
if (tmp != 2) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
......@@ -197,8 +196,7 @@ static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
}
/* read the RTC alarm registers all at once */
tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent),
&fm3130->msg[2], 2);
tmp = i2c_transfer(fm3130->client->adapter, &fm3130->msg[2], 2);
if (tmp != 2) {
dev_err(dev, "%s error %d\n", "read", tmp);
return -EIO;
......@@ -348,7 +346,7 @@ static int fm3130_probe(struct i2c_client *client,
struct fm3130 *fm3130;
int err = -ENODEV;
int tmp;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter,
I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
......
......@@ -3,6 +3,7 @@
* Copyright 2018 NXP.
*/
#include <dt-bindings/firmware/imx/rsrc.h>
#include <linux/arm-smccc.h>
#include <linux/firmware/imx/sci.h>
#include <linux/module.h>
......@@ -11,11 +12,15 @@
#include <linux/rtc.h>
#define IMX_SC_TIMER_FUNC_GET_RTC_SEC1970 9
#define IMX_SC_TIMER_FUNC_SET_RTC_ALARM 8
#define IMX_SC_TIMER_FUNC_SET_RTC_TIME 6
#define IMX_SIP_SRTC 0xC2000002
#define IMX_SIP_SRTC_SET_TIME 0x0
#define SC_IRQ_GROUP_RTC 2
#define SC_IRQ_RTC 1
static struct imx_sc_ipc *rtc_ipc_handle;
static struct rtc_device *imx_sc_rtc;
......@@ -24,6 +29,16 @@ struct imx_sc_msg_timer_get_rtc_time {
u32 time;
} __packed;
struct imx_sc_msg_timer_rtc_set_alarm {
struct imx_sc_rpc_msg hdr;
u16 year;
u8 mon;
u8 day;
u8 hour;
u8 min;
u8 sec;
} __packed;
static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct imx_sc_msg_timer_get_rtc_time msg;
......@@ -60,9 +75,77 @@ static int imx_sc_rtc_set_time(struct device *dev, struct rtc_time *tm)
return res.a0;
}
static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
{
return imx_scu_irq_group_enable(SC_IRQ_GROUP_RTC, SC_IRQ_RTC, enable);
}
static int imx_sc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
/*
* SCU firmware does NOT provide read alarm API, but .read_alarm
* callback is required by RTC framework to support alarm function,
* so just return here.
*/
return 0;
}
static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct imx_sc_msg_timer_rtc_set_alarm msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
int ret;
struct rtc_time *alrm_tm = &alrm->time;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_TIMER;
hdr->func = IMX_SC_TIMER_FUNC_SET_RTC_ALARM;
hdr->size = 3;
msg.year = alrm_tm->tm_year + 1900;
msg.mon = alrm_tm->tm_mon + 1;
msg.day = alrm_tm->tm_mday;
msg.hour = alrm_tm->tm_hour;
msg.min = alrm_tm->tm_min;
msg.sec = alrm_tm->tm_sec;
ret = imx_scu_call_rpc(rtc_ipc_handle, &msg, true);
if (ret) {
dev_err(dev, "set rtc alarm failed, ret %d\n", ret);
return ret;
}
ret = imx_sc_rtc_alarm_irq_enable(dev, alrm->enabled);
if (ret) {
dev_err(dev, "enable rtc alarm failed, ret %d\n", ret);
return ret;
}
return 0;
}
static const struct rtc_class_ops imx_sc_rtc_ops = {
.read_time = imx_sc_rtc_read_time,
.set_time = imx_sc_rtc_set_time,
.read_alarm = imx_sc_rtc_read_alarm,
.set_alarm = imx_sc_rtc_set_alarm,
.alarm_irq_enable = imx_sc_rtc_alarm_irq_enable,
};
static int imx_sc_rtc_alarm_notify(struct notifier_block *nb,
unsigned long event, void *group)
{
/* ignore non-rtc irq */
if (!((event & SC_IRQ_RTC) && (*(u8 *)group == SC_IRQ_GROUP_RTC)))
return 0;
rtc_update_irq(imx_sc_rtc, 1, RTC_IRQF | RTC_AF);
return 0;
}
static struct notifier_block imx_sc_rtc_alarm_sc_notifier = {
.notifier_call = imx_sc_rtc_alarm_notify,
};
static int imx_sc_rtc_probe(struct platform_device *pdev)
......@@ -73,6 +156,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev)
if (ret)
return ret;
device_init_wakeup(&pdev->dev, true);
imx_sc_rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(imx_sc_rtc))
return PTR_ERR(imx_sc_rtc);
......@@ -87,6 +172,8 @@ static int imx_sc_rtc_probe(struct platform_device *pdev)
return ret;
}
imx_scu_irq_register_notifier(&imx_sc_rtc_alarm_sc_notifier);
return 0;
}
......
......@@ -872,7 +872,7 @@ static struct notifier_block wdt_notifier = {
static int m41t80_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
int rc = 0;
struct rtc_time tm;
struct m41t80_data *m41t80_data = NULL;
......
This diff is collapsed.
......@@ -560,7 +560,6 @@ static int pcf8563_probe(struct i2c_client *client,
struct pcf8563 *pcf8563;
int err;
unsigned char buf;
unsigned char alm_pending;
dev_dbg(&client->dev, "%s\n", __func__);
......@@ -584,13 +583,13 @@ static int pcf8563_probe(struct i2c_client *client,
return err;
}
err = pcf8563_get_alarm_mode(client, NULL, &alm_pending);
if (err) {
dev_err(&client->dev, "%s: read error\n", __func__);
/* Clear flags and disable interrupts */
buf = 0;
err = pcf8563_write_block_data(client, PCF8563_REG_ST2, 1, &buf);
if (err < 0) {
dev_err(&client->dev, "%s: write error\n", __func__);
return err;
}
if (alm_pending)
pcf8563_set_alarm_mode(client, 0);
pcf8563->rtc = devm_rtc_device_register(&client->dev,
pcf8563_driver.driver.name,
......@@ -602,7 +601,7 @@ static int pcf8563_probe(struct i2c_client *client,
if (client->irq > 0) {
err = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf8563_irq,
IRQF_SHARED|IRQF_ONESHOT|IRQF_TRIGGER_FALLING,
IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,
pcf8563_driver.driver.name, client);
if (err) {
dev_err(&client->dev, "unable to request IRQ %d\n",
......
......@@ -517,7 +517,7 @@ static int rx8900_trickle_charger_init(struct rv8803_data *rv8803)
static int rv8803_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
struct rv8803_data *rv8803;
int err, flags;
struct nvmem_config nvmem_cfg = {
......
......@@ -433,7 +433,7 @@ static struct rtc_class_ops rx8010_rtc_ops = {
static int rx8010_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
struct rx8010_data *rx8010;
int err = 0;
......
......@@ -501,7 +501,7 @@ static void rx8025_sysfs_unregister(struct device *dev)
static int rx8025_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
struct rx8025_data *rx8025;
int err = 0;
......
......@@ -32,21 +32,22 @@
#define S35390A_ALRM_BYTE_MINS 2
/* flags for STATUS1 */
#define S35390A_FLAG_POC 0x01
#define S35390A_FLAG_BLD 0x02
#define S35390A_FLAG_INT2 0x04
#define S35390A_FLAG_24H 0x40
#define S35390A_FLAG_RESET 0x80
#define S35390A_FLAG_POC BIT(0)
#define S35390A_FLAG_BLD BIT(1)
#define S35390A_FLAG_INT2 BIT(2)
#define S35390A_FLAG_24H BIT(6)
#define S35390A_FLAG_RESET BIT(7)
/* flag for STATUS2 */
#define S35390A_FLAG_TEST 0x01
#define S35390A_INT2_MODE_MASK 0xF0
#define S35390A_FLAG_TEST BIT(0)
/* INT2 pin output mode */
#define S35390A_INT2_MODE_MASK 0x0E
#define S35390A_INT2_MODE_NOINTR 0x00
#define S35390A_INT2_MODE_FREQ 0x10
#define S35390A_INT2_MODE_ALARM 0x40
#define S35390A_INT2_MODE_PMIN_EDG 0x20
#define S35390A_INT2_MODE_ALARM BIT(1) /* INT2AE */
#define S35390A_INT2_MODE_PMIN_EDG BIT(2) /* INT2ME */
#define S35390A_INT2_MODE_FREQ BIT(3) /* INT2FE */
#define S35390A_INT2_MODE_PMIN (BIT(3) | BIT(2)) /* INT2FE | INT2ME */
static const struct i2c_device_id s35390a_id[] = {
{ "s35390a", 0 },
......@@ -284,6 +285,9 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);
if (alm->time.tm_sec != 0)
dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n");
/* disable interrupt (which deasserts the irq line) */
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
if (err < 0)
......@@ -299,9 +303,6 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
else
sts = S35390A_INT2_MODE_NOINTR;
/* This chip expects the bits of each byte to be in reverse order */
sts = bitrev8(sts);
/* set interupt mode*/
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
if (err < 0)
......@@ -339,7 +340,7 @@ static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
if (err < 0)
return err;
if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) {
if ((sts & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) {
/*
* When the alarm isn't enabled, the register to configure
* the alarm time isn't accessible.
......@@ -431,14 +432,14 @@ static int s35390a_probe(struct i2c_client *client,
unsigned int i;
struct s35390a *s35390a;
char buf, status1;
struct device *dev = &client->dev;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
err = -ENODEV;
goto exit;
}
s35390a = devm_kzalloc(&client->dev, sizeof(struct s35390a),
GFP_KERNEL);
s35390a = devm_kzalloc(dev, sizeof(struct s35390a), GFP_KERNEL);
if (!s35390a) {
err = -ENOMEM;
goto exit;
......@@ -452,8 +453,8 @@ static int s35390a_probe(struct i2c_client *client,
s35390a->client[i] = i2c_new_dummy(client->adapter,
client->addr + i);
if (!s35390a->client[i]) {
dev_err(&client->dev, "Address %02x unavailable\n",
client->addr + i);
dev_err(dev, "Address %02x unavailable\n",
client->addr + i);
err = -EBUSY;
goto exit_dummy;
}
......@@ -462,7 +463,7 @@ static int s35390a_probe(struct i2c_client *client,
err_read = s35390a_read_status(s35390a, &status1);
if (err_read < 0) {
err = err_read;
dev_err(&client->dev, "error resetting chip\n");
dev_err(dev, "error resetting chip\n");
goto exit_dummy;
}
......@@ -476,28 +477,30 @@ static int s35390a_probe(struct i2c_client *client,
buf = 0;
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1);
if (err < 0) {
dev_err(&client->dev, "error disabling alarm");
dev_err(dev, "error disabling alarm");
goto exit_dummy;
}
} else {
err = s35390a_disable_test_mode(s35390a);
if (err < 0) {
dev_err(&client->dev, "error disabling test mode\n");
dev_err(dev, "error disabling test mode\n");
goto exit_dummy;
}
}
device_set_wakeup_capable(&client->dev, 1);
device_set_wakeup_capable(dev, 1);
s35390a->rtc = devm_rtc_device_register(&client->dev,
s35390a_driver.driver.name,
&s35390a_rtc_ops, THIS_MODULE);
s35390a->rtc = devm_rtc_device_register(dev, s35390a_driver.driver.name,
&s35390a_rtc_ops, THIS_MODULE);
if (IS_ERR(s35390a->rtc)) {
err = PTR_ERR(s35390a->rtc);
goto exit_dummy;
}
/* supports per-minute alarms only, therefore set uie_unsupported */
s35390a->rtc->uie_unsupported = 1;
if (status1 & S35390A_FLAG_INT2)
rtc_update_irq(s35390a->rtc, 1, RTC_AF);
......
......@@ -162,10 +162,6 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
now_secs = rtc_tm_to_time64(&now);
alarm_secs = rtc_tm_to_time64(&t->time);
/* Invalid alarm time */
if (now_secs > alarm_secs)
return -EINVAL;
memcpy(&rtc->alarm, t, sizeof(struct rtc_wkalrm));
/* Now many secs to fire */
......
......@@ -519,11 +519,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
/* Write to Alarm register */
writel_relaxed(alrmar, rtc->base + regs->alrmar);
if (alrm->enabled)
stm32_rtc_alarm_irq_enable(dev, 1);
else
stm32_rtc_alarm_irq_enable(dev, 0);
stm32_rtc_alarm_irq_enable(dev, alrm->enabled);
end:
stm32_rtc_wpr_lock(rtc);
......
......@@ -672,6 +672,7 @@ static const struct of_device_id sun6i_rtc_dt_ids[] = {
{ .compatible = "allwinner,sun6i-a31-rtc" },
{ .compatible = "allwinner,sun8i-a23-rtc" },
{ .compatible = "allwinner,sun8i-h3-rtc" },
{ .compatible = "allwinner,sun8i-r40-rtc" },
{ .compatible = "allwinner,sun8i-v3-rtc" },
{ .compatible = "allwinner,sun50i-h5-rtc" },
{ /* sentinel */ },
......
This diff is collapsed.
......@@ -133,6 +133,7 @@ static int test_probe(struct platform_device *plat_dev)
break;
default:
rtd->rtc->ops = &test_rtc_ops;
device_init_wakeup(&plat_dev->dev, 1);
}
timer_setup(&rtd->alarm, test_rtc_alarm_handler, 0);
......
......@@ -143,7 +143,7 @@ static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
struct tps65910 *tps = dev_get_drvdata(dev->parent);
int ret;
ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data,
ret = regmap_bulk_read(tps->regmap, TPS65910_ALARM_SECONDS, alarm_data,
NUM_TIME_REGS);
if (ret < 0) {
dev_err(dev, "rtc_read_alarm error %d\n", ret);
......
......@@ -435,7 +435,8 @@ static int wm831x_rtc_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL,
wm831x_alm_irq,
IRQF_TRIGGER_RISING, "RTC alarm",
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"RTC alarm",
wm831x_rtc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
......
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