Commit b7769c45 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull RTC updates from Alexandre Belloni:
 "A new driver this cycle is making the bulk of the changes and the
  rx8010 driver has been rework to use the modern APIs.

  Summary:

  Subsystem:
   - new generic DT properties: aux-voltage-chargeable,
     trickle-voltage-millivolt

  New driver:
   - Microcrystal RV-3032

  Drivers:
   - ds1307: use aux-voltage-chargeable
   - r9701, rx8010: modernization of the driver
   - rv3028: fix clock output, trickle resistor values, RAM
     configuration registers"

* tag 'rtc-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (50 commits)
  rtc: r9701: set range
  rtc: r9701: convert to devm_rtc_allocate_device
  rtc: r9701: stop setting RWKCNT
  rtc: r9701: remove useless memset
  rtc: r9701: stop setting a default time
  rtc: r9701: remove leftover comment
  rtc: rv3032: Add a driver for Microcrystal RV-3032
  dt-bindings: rtc: rv3032: add RV-3032 bindings
  dt-bindings: rtc: add trickle-voltage-millivolt
  rtc: rv3028: ensure ram configuration registers are saved
  rtc: rv3028: factorize EERD bit handling
  rtc: rv3028: fix trickle resistor values
  rtc: rv3028: fix clock output support
  rtc: mt6397: Remove unused member dev
  rtc: rv8803: simplify the return expression of rv8803_nvram_write
  rtc: meson: simplify the return expression of meson_vrtc_probe
  rtc: rx8010: rename rx8010_init_client() to rx8010_init()
  rtc: ds1307: enable rx8130's backup battery, make it chargeable optionally
  rtc: ds1307: consider aux-voltage-chargeable
  rtc: ds1307: store previous charge default per chip
  ...
parents 68a36336 35331b50
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/microcrystal,rv3032.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip RV-3032 RTC Device Tree Bindings
allOf:
- $ref: "rtc.yaml#"
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
properties:
compatible:
const: microcrystal,rv3032
reg:
maxItems: 1
interrupts:
maxItems: 1
start-year: true
trickle-resistor-ohms:
enum:
- 1000
- 2000
- 7000
- 11000
trickle-voltage-millivolt:
enum:
- 1750
- 3000
- 4400
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
rtc@51 {
compatible = "microcrystal,rv3032";
reg = <0x51>;
status = "okay";
pinctrl-0 = <&rtc_nint_pins>;
interrupts-extended = <&gpio1 16 IRQ_TYPE_LEVEL_HIGH>;
trickle-resistor-ohms = <7000>;
trickle-voltage-millivolt = <1750>;
};
};
...
...@@ -31,9 +31,16 @@ Optional properties: ...@@ -31,9 +31,16 @@ Optional properties:
Selected resistor for trickle charger Selected resistor for trickle charger
Possible values are 250, 2000, 4000 Possible values are 250, 2000, 4000
Should be given if trickle charger should be enabled Should be given if trickle charger should be enabled
- trickle-diode-disable : ds1339, ds1340 and ds 1388 only - aux-voltage-chargeable: ds1339, ds1340, ds1388 and rx8130 only
Tells whether the battery/supercap of the RTC (if any) is
chargeable or not.
Possible values are 0 (not chargeable), 1 (chargeable)
Deprecated properties:
- trickle-diode-disable : ds1339, ds1340 and ds1388 only
Do not use internal trickle charger diode Do not use internal trickle charger diode
Should be given if internal trickle charger diode should be disabled Should be given if internal trickle charger diode should be disabled
(superseded by aux-voltage-chargeable)
Example: Example:
ds1339: rtc@68 { ds1339: rtc@68 {
......
...@@ -17,6 +17,15 @@ properties: ...@@ -17,6 +17,15 @@ properties:
$nodename: $nodename:
pattern: "^rtc(@.*|-[0-9a-f])*$" pattern: "^rtc(@.*|-[0-9a-f])*$"
aux-voltage-chargeable:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1]
description: |
Tells whether the battery/supercap of the RTC (if any) is
chargeable or not:
0: not chargeable
1: chargeable
quartz-load-femtofarads: quartz-load-femtofarads:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
description: description:
...@@ -35,6 +44,7 @@ properties: ...@@ -35,6 +44,7 @@ properties:
description: description:
Do not use internal trickle charger diode. Should be given if Do not use internal trickle charger diode. Should be given if
internal trickle charger diode should be disabled. internal trickle charger diode should be disabled.
deprecated: true
trickle-resistor-ohms: trickle-resistor-ohms:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
...@@ -42,6 +52,12 @@ properties: ...@@ -42,6 +52,12 @@ properties:
Selected resistor for trickle charger. Should be given Selected resistor for trickle charger. Should be given
if trickle charger should be enabled. if trickle charger should be enabled.
trickle-voltage-millivolt:
description:
Selected voltage for trickle charger. Should be given
if trickle charger should be enabled and the trickle voltage is different
from the RTC main power supply.
wakeup-source: wakeup-source:
$ref: /schemas/types.yaml#/definitions/flag $ref: /schemas/types.yaml#/definitions/flag
description: description:
......
...@@ -669,6 +669,16 @@ config RTC_DRV_RV3028 ...@@ -669,6 +669,16 @@ config RTC_DRV_RV3028
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-rv3028. will be called rtc-rv3028.
config RTC_DRV_RV3032
tristate "Micro Crystal RV3032"
select REGMAP_I2C
help
If you say yes here you get support for the Micro Crystal
RV3032.
This driver can also be built as a module. If so, the module
will be called rtc-rv3032.
config RTC_DRV_RV8803 config RTC_DRV_RV8803
tristate "Micro Crystal RV8803, Epson RX8900" tristate "Micro Crystal RV8803, Epson RX8900"
help help
......
...@@ -141,6 +141,7 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o ...@@ -141,6 +141,7 @@ obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o
obj-$(CONFIG_RTC_DRV_RTD119X) += rtc-rtd119x.o obj-$(CONFIG_RTC_DRV_RTD119X) += rtc-rtd119x.o
obj-$(CONFIG_RTC_DRV_RV3028) += rtc-rv3028.o obj-$(CONFIG_RTC_DRV_RV3028) += rtc-rv3028.o
obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o
obj-$(CONFIG_RTC_DRV_RV3032) += rtc-rv3032.o
obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o
obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o
obj-$(CONFIG_RTC_DRV_RX6110) += rtc-rx6110.o obj-$(CONFIG_RTC_DRV_RX6110) += rtc-rx6110.o
......
...@@ -1006,6 +1006,7 @@ static int cmos_suspend(struct device *dev) ...@@ -1006,6 +1006,7 @@ static int cmos_suspend(struct device *dev)
enable_irq_wake(cmos->irq); enable_irq_wake(cmos->irq);
} }
memset(&cmos->saved_wkalrm, 0, sizeof(struct rtc_wkalrm));
cmos_read_alarm(dev, &cmos->saved_wkalrm); cmos_read_alarm(dev, &cmos->saved_wkalrm);
dev_dbg(dev, "suspend%s, ctrl %02x\n", dev_dbg(dev, "suspend%s, ctrl %02x\n",
...@@ -1054,6 +1055,7 @@ static void cmos_check_wkalrm(struct device *dev) ...@@ -1054,6 +1055,7 @@ static void cmos_check_wkalrm(struct device *dev)
return; return;
} }
memset(&current_alarm, 0, sizeof(struct rtc_wkalrm));
cmos_read_alarm(dev, &current_alarm); cmos_read_alarm(dev, &current_alarm);
t_current_expires = rtc_tm_to_time64(&current_alarm.time); t_current_expires = rtc_tm_to_time64(&current_alarm.time);
t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time); t_saved_expires = rtc_tm_to_time64(&cmos->saved_wkalrm.time);
......
...@@ -122,6 +122,9 @@ enum ds_type { ...@@ -122,6 +122,9 @@ enum ds_type {
#define RX8130_REG_FLAG_AF BIT(3) #define RX8130_REG_FLAG_AF BIT(3)
#define RX8130_REG_CONTROL0 0x1e #define RX8130_REG_CONTROL0 0x1e
#define RX8130_REG_CONTROL0_AIE BIT(3) #define RX8130_REG_CONTROL0_AIE BIT(3)
#define RX8130_REG_CONTROL1 0x1f
#define RX8130_REG_CONTROL1_INIEN BIT(4)
#define RX8130_REG_CONTROL1_CHGEN BIT(5)
#define MCP794XX_REG_CONTROL 0x07 #define MCP794XX_REG_CONTROL 0x07
# define MCP794XX_BIT_ALM0_EN 0x10 # define MCP794XX_BIT_ALM0_EN 0x10
...@@ -153,6 +156,7 @@ enum ds_type { ...@@ -153,6 +156,7 @@ enum ds_type {
#define DS1388_REG_CONTROL 0x0c #define DS1388_REG_CONTROL 0x0c
# define DS1388_BIT_RST BIT(0) # define DS1388_BIT_RST BIT(0)
# define DS1388_BIT_WDE BIT(1) # define DS1388_BIT_WDE BIT(1)
# define DS1388_BIT_nEOSC BIT(7)
/* negative offset step is -2.034ppm */ /* negative offset step is -2.034ppm */
#define M41TXX_NEG_OFFSET_STEP_PPB 2034 #define M41TXX_NEG_OFFSET_STEP_PPB 2034
...@@ -190,6 +194,15 @@ struct chip_desc { ...@@ -190,6 +194,15 @@ struct chip_desc {
u16 trickle_charger_reg; u16 trickle_charger_reg;
u8 (*do_trickle_setup)(struct ds1307 *, u32, u8 (*do_trickle_setup)(struct ds1307 *, u32,
bool); bool);
/* Does the RTC require trickle-resistor-ohms to select the value of
* the resistor between Vcc and Vbackup?
*/
bool requires_trickle_resistor;
/* Some RTC's batteries and supercaps were charged by default, others
* allow charging but were not configured previously to do so.
* Remember this behavior to stay backwards compatible.
*/
bool charge_default;
}; };
static const struct chip_desc chips[last_ds_type]; static const struct chip_desc chips[last_ds_type];
...@@ -352,6 +365,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) ...@@ -352,6 +365,10 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG, regmap_update_bits(ds1307->regmap, DS1340_REG_FLAG,
DS1340_BIT_OSF, 0); DS1340_BIT_OSF, 0);
break; break;
case ds_1388:
regmap_update_bits(ds1307->regmap, DS1388_REG_FLAG,
DS1388_BIT_OSF, 0);
break;
case mcp794xx: case mcp794xx:
/* /*
* these bits were cleared when preparing the date/time * these bits were cleared when preparing the date/time
...@@ -507,6 +524,8 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode) ...@@ -507,6 +524,8 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode)
u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE : u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
DS1307_TRICKLE_CHARGER_NO_DIODE; DS1307_TRICKLE_CHARGER_NO_DIODE;
setup |= DS13XX_TRICKLE_CHARGER_MAGIC;
switch (ohms) { switch (ohms) {
case 250: case 250:
setup |= DS1307_TRICKLE_CHARGER_250_OHM; setup |= DS1307_TRICKLE_CHARGER_250_OHM;
...@@ -525,6 +544,16 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode) ...@@ -525,6 +544,16 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, u32 ohms, bool diode)
return setup; return setup;
} }
static u8 do_trickle_setup_rx8130(struct ds1307 *ds1307, u32 ohms, bool diode)
{
/* make sure that the backup battery is enabled */
u8 setup = RX8130_REG_CONTROL1_INIEN;
if (diode)
setup |= RX8130_REG_CONTROL1_CHGEN;
return setup;
}
static irqreturn_t rx8130_irq(int irq, void *dev_id) static irqreturn_t rx8130_irq(int irq, void *dev_id)
{ {
struct ds1307 *ds1307 = dev_id; struct ds1307 *ds1307 = dev_id;
...@@ -979,6 +1008,8 @@ static const struct chip_desc chips[last_ds_type] = { ...@@ -979,6 +1008,8 @@ static const struct chip_desc chips[last_ds_type] = {
.bbsqi_bit = DS1339_BIT_BBSQI, .bbsqi_bit = DS1339_BIT_BBSQI,
.trickle_charger_reg = 0x10, .trickle_charger_reg = 0x10,
.do_trickle_setup = &do_trickle_setup_ds1339, .do_trickle_setup = &do_trickle_setup_ds1339,
.requires_trickle_resistor = true,
.charge_default = true,
}, },
[ds_1340] = { [ds_1340] = {
.century_reg = DS1307_REG_HOUR, .century_reg = DS1307_REG_HOUR,
...@@ -986,6 +1017,8 @@ static const struct chip_desc chips[last_ds_type] = { ...@@ -986,6 +1017,8 @@ static const struct chip_desc chips[last_ds_type] = {
.century_bit = DS1340_BIT_CENTURY, .century_bit = DS1340_BIT_CENTURY,
.do_trickle_setup = &do_trickle_setup_ds1339, .do_trickle_setup = &do_trickle_setup_ds1339,
.trickle_charger_reg = 0x08, .trickle_charger_reg = 0x08,
.requires_trickle_resistor = true,
.charge_default = true,
}, },
[ds_1341] = { [ds_1341] = {
.century_reg = DS1307_REG_MONTH, .century_reg = DS1307_REG_MONTH,
...@@ -1009,6 +1042,8 @@ static const struct chip_desc chips[last_ds_type] = { ...@@ -1009,6 +1042,8 @@ static const struct chip_desc chips[last_ds_type] = {
.offset = 0x10, .offset = 0x10,
.irq_handler = rx8130_irq, .irq_handler = rx8130_irq,
.rtc_ops = &rx8130_rtc_ops, .rtc_ops = &rx8130_rtc_ops,
.trickle_charger_reg = RX8130_REG_CONTROL1,
.do_trickle_setup = &do_trickle_setup_rx8130,
}, },
[m41t0] = { [m41t0] = {
.rtc_ops = &m41txx_rtc_ops, .rtc_ops = &m41txx_rtc_ops,
...@@ -1293,18 +1328,37 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val, ...@@ -1293,18 +1328,37 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val,
static u8 ds1307_trickle_init(struct ds1307 *ds1307, static u8 ds1307_trickle_init(struct ds1307 *ds1307,
const struct chip_desc *chip) const struct chip_desc *chip)
{ {
u32 ohms; u32 ohms, chargeable;
bool diode = true; bool diode = chip->charge_default;
if (!chip->do_trickle_setup) if (!chip->do_trickle_setup)
return 0; return 0;
if (device_property_read_u32(ds1307->dev, "trickle-resistor-ohms", if (device_property_read_u32(ds1307->dev, "trickle-resistor-ohms",
&ohms)) &ohms) && chip->requires_trickle_resistor)
return 0; return 0;
if (device_property_read_bool(ds1307->dev, "trickle-diode-disable")) /* aux-voltage-chargeable takes precedence over the deprecated
* trickle-diode-disable
*/
if (!device_property_read_u32(ds1307->dev, "aux-voltage-chargeable",
&chargeable)) {
switch (chargeable) {
case 0:
diode = false;
break;
case 1:
diode = true;
break;
default:
dev_warn(ds1307->dev,
"unsupported aux-voltage-chargeable value\n");
break;
}
} else if (device_property_read_bool(ds1307->dev,
"trickle-diode-disable")) {
diode = false; diode = false;
}
return chip->do_trickle_setup(ds1307, ohms, diode); return chip->do_trickle_setup(ds1307, ohms, diode);
} }
...@@ -1758,7 +1812,6 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1758,7 +1812,6 @@ static int ds1307_probe(struct i2c_client *client,
trickle_charger_setup = pdata->trickle_charger_setup; trickle_charger_setup = pdata->trickle_charger_setup;
if (trickle_charger_setup && chip->trickle_charger_reg) { if (trickle_charger_setup && chip->trickle_charger_reg) {
trickle_charger_setup |= DS13XX_TRICKLE_CHARGER_MAGIC;
dev_dbg(ds1307->dev, dev_dbg(ds1307->dev,
"writing trickle charger info 0x%x to 0x%x\n", "writing trickle charger info 0x%x to 0x%x\n",
trickle_charger_setup, chip->trickle_charger_reg); trickle_charger_setup, chip->trickle_charger_reg);
...@@ -1881,6 +1934,19 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1881,6 +1934,19 @@ static int ds1307_probe(struct i2c_client *client,
DS1307_REG_HOUR << 4 | 0x08, hour); DS1307_REG_HOUR << 4 | 0x08, hour);
} }
break; break;
case ds_1388:
err = regmap_read(ds1307->regmap, DS1388_REG_CONTROL, &tmp);
if (err) {
dev_dbg(ds1307->dev, "read error %d\n", err);
goto exit;
}
/* oscillator off? turn it on, so clock can tick. */
if (tmp & DS1388_BIT_nEOSC) {
tmp &= ~DS1388_BIT_nEOSC;
regmap_write(ds1307->regmap, DS1388_REG_CONTROL, tmp);
}
break;
default: default:
break; break;
} }
......
...@@ -193,12 +193,12 @@ ds1685_rtc_begin_data_access(struct ds1685_priv *rtc) ...@@ -193,12 +193,12 @@ ds1685_rtc_begin_data_access(struct ds1685_priv *rtc)
rtc->write(rtc, RTC_CTRL_B, rtc->write(rtc, RTC_CTRL_B,
(rtc->read(rtc, RTC_CTRL_B) | RTC_CTRL_B_SET)); (rtc->read(rtc, RTC_CTRL_B) | RTC_CTRL_B_SET));
/* Switch to Bank 1 */
ds1685_rtc_switch_to_bank1(rtc);
/* Read Ext Ctrl 4A and check the INCR bit to avoid a lockout. */ /* Read Ext Ctrl 4A and check the INCR bit to avoid a lockout. */
while (rtc->read(rtc, RTC_EXT_CTRL_4A) & RTC_CTRL_4A_INCR) while (rtc->read(rtc, RTC_EXT_CTRL_4A) & RTC_CTRL_4A_INCR)
cpu_relax(); cpu_relax();
/* Switch to Bank 1 */
ds1685_rtc_switch_to_bank1(rtc);
} }
/** /**
...@@ -213,7 +213,7 @@ static inline void ...@@ -213,7 +213,7 @@ static inline void
ds1685_rtc_end_data_access(struct ds1685_priv *rtc) ds1685_rtc_end_data_access(struct ds1685_priv *rtc)
{ {
/* Switch back to Bank 0 */ /* Switch back to Bank 0 */
ds1685_rtc_switch_to_bank1(rtc); ds1685_rtc_switch_to_bank0(rtc);
/* Clear the SET bit in Ctrl B */ /* Clear the SET bit in Ctrl B */
rtc->write(rtc, RTC_CTRL_B, rtc->write(rtc, RTC_CTRL_B,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Freescale FlexTimer Module (FTM) alarm device driver. * Freescale FlexTimer Module (FTM) alarm device driver.
* *
* Copyright 2014 Freescale Semiconductor, Inc. * Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2019 NXP * Copyright 2019-2020 NXP
* *
*/ */
...@@ -312,7 +312,7 @@ static const struct of_device_id ftm_rtc_match[] = { ...@@ -312,7 +312,7 @@ static const struct of_device_id ftm_rtc_match[] = {
}; };
static const struct acpi_device_id ftm_imx_acpi_ids[] = { static const struct acpi_device_id ftm_imx_acpi_ids[] = {
{"NXP0011",}, {"NXP0014",},
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, ftm_imx_acpi_ids); MODULE_DEVICE_TABLE(acpi, ftm_imx_acpi_ids);
......
...@@ -65,7 +65,6 @@ static const struct rtc_class_ops meson_vrtc_ops = { ...@@ -65,7 +65,6 @@ static const struct rtc_class_ops meson_vrtc_ops = {
static int meson_vrtc_probe(struct platform_device *pdev) static int meson_vrtc_probe(struct platform_device *pdev)
{ {
struct meson_vrtc_data *vrtc; struct meson_vrtc_data *vrtc;
int ret;
vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL); vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL);
if (!vrtc) if (!vrtc)
...@@ -84,11 +83,7 @@ static int meson_vrtc_probe(struct platform_device *pdev) ...@@ -84,11 +83,7 @@ static int meson_vrtc_probe(struct platform_device *pdev)
return PTR_ERR(vrtc->rtc); return PTR_ERR(vrtc->rtc);
vrtc->rtc->ops = &meson_vrtc_ops; vrtc->rtc->ops = &meson_vrtc_ops;
ret = rtc_register_device(vrtc->rtc); return rtc_register_device(vrtc->rtc);
if (ret)
return ret;
return 0;
} }
static int __maybe_unused meson_vrtc_suspend(struct device *dev) static int __maybe_unused meson_vrtc_suspend(struct device *dev)
......
...@@ -31,7 +31,8 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) ...@@ -31,7 +31,8 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
MTK_RTC_POLL_DELAY_US, MTK_RTC_POLL_DELAY_US,
MTK_RTC_POLL_TIMEOUT); MTK_RTC_POLL_TIMEOUT);
if (ret < 0) if (ret < 0)
dev_err(rtc->dev, "failed to write WRTGE: %d\n", ret); dev_err(rtc->rtc_dev->dev.parent,
"failed to write WRTGR: %d\n", ret);
return ret; return ret;
} }
......
...@@ -559,7 +559,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, ...@@ -559,7 +559,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */ pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */
pcf2127->rtc->uie_unsupported = 1; pcf2127->rtc->uie_unsupported = 1;
if (alarm_irq >= 0) { if (alarm_irq > 0) {
ret = devm_request_threaded_irq(dev, alarm_irq, NULL, ret = devm_request_threaded_irq(dev, alarm_irq, NULL,
pcf2127_rtc_irq, pcf2127_rtc_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
...@@ -570,7 +570,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, ...@@ -570,7 +570,7 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap,
} }
} }
if (alarm_irq >= 0 || device_property_read_bool(dev, "wakeup-source")) { if (alarm_irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
device_init_wakeup(dev, true); device_init_wakeup(dev, true);
pcf2127->rtc->ops = &pcf2127_rtc_alrm_ops; pcf2127->rtc->ops = &pcf2127_rtc_alrm_ops;
} }
......
...@@ -75,8 +75,6 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt) ...@@ -75,8 +75,6 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt)
if (ret) if (ret)
return ret; return ret;
memset(dt, 0, sizeof(*dt));
dt->tm_sec = bcd2bin(buf[0]); /* RSECCNT */ dt->tm_sec = bcd2bin(buf[0]); /* RSECCNT */
dt->tm_min = bcd2bin(buf[1]); /* RMINCNT */ dt->tm_min = bcd2bin(buf[1]); /* RMINCNT */
dt->tm_hour = bcd2bin(buf[2]); /* RHRCNT */ dt->tm_hour = bcd2bin(buf[2]); /* RHRCNT */
...@@ -85,20 +83,12 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt) ...@@ -85,20 +83,12 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt)
dt->tm_mon = bcd2bin(buf[4]) - 1; /* RMONCNT */ dt->tm_mon = bcd2bin(buf[4]) - 1; /* RMONCNT */
dt->tm_year = bcd2bin(buf[5]) + 100; /* RYRCNT */ dt->tm_year = bcd2bin(buf[5]) + 100; /* RYRCNT */
/* the rtc device may contain illegal values on power up
* according to the data sheet. make sure they are valid.
*/
return 0; return 0;
} }
static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) static int r9701_set_datetime(struct device *dev, struct rtc_time *dt)
{ {
int ret, year; int ret;
year = dt->tm_year + 1900;
if (year >= 2100 || year < 2000)
return -EINVAL;
ret = write_reg(dev, RHRCNT, bin2bcd(dt->tm_hour)); ret = write_reg(dev, RHRCNT, bin2bcd(dt->tm_hour));
ret = ret ? ret : write_reg(dev, RMINCNT, bin2bcd(dt->tm_min)); ret = ret ? ret : write_reg(dev, RMINCNT, bin2bcd(dt->tm_min));
...@@ -106,7 +96,6 @@ static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) ...@@ -106,7 +96,6 @@ static int r9701_set_datetime(struct device *dev, struct rtc_time *dt)
ret = ret ? ret : write_reg(dev, RDAYCNT, bin2bcd(dt->tm_mday)); ret = ret ? ret : write_reg(dev, RDAYCNT, bin2bcd(dt->tm_mday));
ret = ret ? ret : write_reg(dev, RMONCNT, bin2bcd(dt->tm_mon + 1)); ret = ret ? ret : write_reg(dev, RMONCNT, bin2bcd(dt->tm_mon + 1));
ret = ret ? ret : write_reg(dev, RYRCNT, bin2bcd(dt->tm_year - 100)); ret = ret ? ret : write_reg(dev, RYRCNT, bin2bcd(dt->tm_year - 100));
ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday);
return ret; return ret;
} }
...@@ -119,7 +108,6 @@ static const struct rtc_class_ops r9701_rtc_ops = { ...@@ -119,7 +108,6 @@ static const struct rtc_class_ops r9701_rtc_ops = {
static int r9701_probe(struct spi_device *spi) static int r9701_probe(struct spi_device *spi)
{ {
struct rtc_device *rtc; struct rtc_device *rtc;
struct rtc_time dt;
unsigned char tmp; unsigned char tmp;
int res; int res;
...@@ -130,35 +118,16 @@ static int r9701_probe(struct spi_device *spi) ...@@ -130,35 +118,16 @@ static int r9701_probe(struct spi_device *spi)
return -ENODEV; return -ENODEV;
} }
/* rtc = devm_rtc_allocate_device(&spi->dev);
* The device seems to be present. Now check if the registers
* contain invalid values. If so, try to write a default date:
* 2000/1/1 00:00:00
*/
if (r9701_get_datetime(&spi->dev, &dt)) {
dev_info(&spi->dev, "trying to repair invalid date/time\n");
dt.tm_sec = 0;
dt.tm_min = 0;
dt.tm_hour = 0;
dt.tm_mday = 1;
dt.tm_mon = 0;
dt.tm_year = 100;
if (r9701_set_datetime(&spi->dev, &dt) ||
r9701_get_datetime(&spi->dev, &dt)) {
dev_err(&spi->dev, "cannot repair RTC register\n");
return -ENODEV;
}
}
rtc = devm_rtc_device_register(&spi->dev, "r9701",
&r9701_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) if (IS_ERR(rtc))
return PTR_ERR(rtc); return PTR_ERR(rtc);
spi_set_drvdata(spi, rtc); spi_set_drvdata(spi, rtc);
rtc->ops = &r9701_rtc_ops;
rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc->range_max = RTC_TIMESTAMP_END_2099;
return 0; return rtc_register_device(rtc);
} }
static struct spi_driver r9701_driver = { static struct spi_driver r9701_driver = {
......
...@@ -366,15 +366,15 @@ static const struct rtc_class_ops rs5c313_rtc_ops = { ...@@ -366,15 +366,15 @@ static const struct rtc_class_ops rs5c313_rtc_ops = {
static int rs5c313_rtc_probe(struct platform_device *pdev) static int rs5c313_rtc_probe(struct platform_device *pdev)
{ {
struct rtc_device *rtc = devm_rtc_device_register(&pdev->dev, "rs5c313", struct rtc_device *rtc;
&rs5c313_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) rs5c313_init_port();
return PTR_ERR(rtc); rs5c313_check_xstp_bit();
platform_set_drvdata(pdev, rtc); rtc = devm_rtc_device_register(&pdev->dev, "rs5c313", &rs5c313_rtc_ops,
THIS_MODULE);
return 0; return PTR_ERR_OR_ZERO(rtc);
} }
static struct platform_driver rs5c313_rtc_platform_driver = { static struct platform_driver rs5c313_rtc_platform_driver = {
...@@ -384,27 +384,7 @@ static struct platform_driver rs5c313_rtc_platform_driver = { ...@@ -384,27 +384,7 @@ static struct platform_driver rs5c313_rtc_platform_driver = {
.probe = rs5c313_rtc_probe, .probe = rs5c313_rtc_probe,
}; };
static int __init rs5c313_rtc_init(void) module_platform_driver(rs5c313_rtc_platform_driver);
{
int err;
err = platform_driver_register(&rs5c313_rtc_platform_driver);
if (err)
return err;
rs5c313_init_port();
rs5c313_check_xstp_bit();
return 0;
}
static void __exit rs5c313_rtc_exit(void)
{
platform_driver_unregister(&rs5c313_rtc_platform_driver);
}
module_init(rs5c313_rtc_init);
module_exit(rs5c313_rtc_exit);
MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>"); MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver"); MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#define RV3028_EVT_CTRL_TSR BIT(2) #define RV3028_EVT_CTRL_TSR BIT(2)
#define RV3028_EEPROM_CMD_UPDATE 0x11
#define RV3028_EEPROM_CMD_WRITE 0x21 #define RV3028_EEPROM_CMD_WRITE 0x21
#define RV3028_EEPROM_CMD_READ 0x22 #define RV3028_EEPROM_CMD_READ 0x22
...@@ -95,7 +96,7 @@ struct rv3028_data { ...@@ -95,7 +96,7 @@ struct rv3028_data {
#endif #endif
}; };
static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000}; static u16 rv3028_trickle_resistors[] = {3000, 5000, 9000, 15000};
static ssize_t timestamp0_store(struct device *dev, static ssize_t timestamp0_store(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
...@@ -171,6 +172,88 @@ static const struct attribute_group rv3028_attr_group = { ...@@ -171,6 +172,88 @@ static const struct attribute_group rv3028_attr_group = {
.attrs = rv3028_attrs, .attrs = rv3028_attrs,
}; };
static int rv3028_exit_eerd(struct rv3028_data *rv3028, u32 eerd)
{
if (eerd)
return 0;
return regmap_update_bits(rv3028->regmap, RV3028_CTRL1, RV3028_CTRL1_EERD, 0);
}
static int rv3028_enter_eerd(struct rv3028_data *rv3028, u32 *eerd)
{
u32 ctrl1, status;
int ret;
ret = regmap_read(rv3028->regmap, RV3028_CTRL1, &ctrl1);
if (ret)
return ret;
*eerd = ctrl1 & RV3028_CTRL1_EERD;
if (*eerd)
return 0;
ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1,
RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
if (ret)
return ret;
ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
if (ret) {
rv3028_exit_eerd(rv3028, *eerd);
return ret;
}
return 0;
}
static int rv3028_update_eeprom(struct rv3028_data *rv3028, u32 eerd)
{
u32 status;
int ret;
ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
if (ret)
goto exit_eerd;
ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, RV3028_EEPROM_CMD_UPDATE);
if (ret)
goto exit_eerd;
usleep_range(63000, RV3028_EEBUSY_TIMEOUT);
ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
exit_eerd:
rv3028_exit_eerd(rv3028, eerd);
return ret;
}
static int rv3028_update_cfg(struct rv3028_data *rv3028, unsigned int reg,
unsigned int mask, unsigned int val)
{
u32 eerd;
int ret;
ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret)
return ret;
ret = regmap_update_bits(rv3028->regmap, reg, mask, val);
if (ret) {
rv3028_exit_eerd(rv3028, eerd);
return ret;
}
return rv3028_update_eeprom(rv3028, eerd);
}
static irqreturn_t rv3028_handle_irq(int irq, void *dev_id) static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
{ {
struct rv3028_data *rv3028 = dev_id; struct rv3028_data *rv3028 = dev_id;
...@@ -404,17 +487,32 @@ static int rv3028_read_offset(struct device *dev, long *offset) ...@@ -404,17 +487,32 @@ static int rv3028_read_offset(struct device *dev, long *offset)
static int rv3028_set_offset(struct device *dev, long offset) static int rv3028_set_offset(struct device *dev, long offset)
{ {
struct rv3028_data *rv3028 = dev_get_drvdata(dev); struct rv3028_data *rv3028 = dev_get_drvdata(dev);
u32 eerd;
int ret; int ret;
offset = clamp(offset, -244141L, 243187L) * 1000; offset = clamp(offset, -244141L, 243187L) * 1000;
offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT);
ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret)
return ret;
ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1); ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1);
if (ret < 0) if (ret < 0)
return ret; goto exit_eerd;
ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7),
offset << 7);
if (ret < 0)
goto exit_eerd;
return rv3028_update_eeprom(rv3028, eerd);
exit_eerd:
rv3028_exit_eerd(rv3028, eerd);
return ret;
return regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7),
offset << 7);
} }
static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
...@@ -451,49 +549,36 @@ static int rv3028_nvram_read(void *priv, unsigned int offset, void *val, ...@@ -451,49 +549,36 @@ static int rv3028_nvram_read(void *priv, unsigned int offset, void *val,
static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
size_t bytes) size_t bytes)
{ {
u32 status, ctrl1; struct rv3028_data *rv3028 = priv;
int i, ret, err; u32 status, eerd;
int i, ret;
u8 *buf = val; u8 *buf = val;
ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret) if (ret)
return ret; return ret;
if (!(ctrl1 & RV3028_CTRL1_EERD)) {
ret = regmap_update_bits(priv, RV3028_CTRL1,
RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
if (ret)
return ret;
ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT);
if (ret)
goto restore_eerd;
}
for (i = 0; i < bytes; i++) { for (i = 0; i < bytes; i++) {
ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]); ret = regmap_write(rv3028->regmap, RV3028_EEPROM_DATA, buf[i]);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
ret = regmap_write(priv, RV3028_EEPROM_CMD, ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
RV3028_EEPROM_CMD_WRITE); RV3028_EEPROM_CMD_WRITE);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT);
ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY), !(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL, RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT); RV3028_EEBUSY_TIMEOUT);
...@@ -502,13 +587,7 @@ static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, ...@@ -502,13 +587,7 @@ static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
} }
restore_eerd: restore_eerd:
if (!(ctrl1 & RV3028_CTRL1_EERD)) rv3028_exit_eerd(rv3028, eerd);
{
err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
0);
if (err && !ret)
ret = err;
}
return ret; return ret;
} }
...@@ -516,63 +595,44 @@ static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, ...@@ -516,63 +595,44 @@ static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val, static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val,
size_t bytes) size_t bytes)
{ {
u32 status, ctrl1, data; struct rv3028_data *rv3028 = priv;
int i, ret, err; u32 status, eerd, data;
int i, ret;
u8 *buf = val; u8 *buf = val;
ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); ret = rv3028_enter_eerd(rv3028, &eerd);
if (ret) if (ret)
return ret; return ret;
if (!(ctrl1 & RV3028_CTRL1_EERD)) {
ret = regmap_update_bits(priv, RV3028_CTRL1,
RV3028_CTRL1_EERD, RV3028_CTRL1_EERD);
if (ret)
return ret;
ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT);
if (ret)
goto restore_eerd;
}
for (i = 0; i < bytes; i++) { for (i = 0; i < bytes; i++) {
ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
ret = regmap_write(priv, RV3028_EEPROM_CMD, ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD,
RV3028_EEPROM_CMD_READ); RV3028_EEPROM_CMD_READ);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status,
!(status & RV3028_STATUS_EEBUSY), !(status & RV3028_STATUS_EEBUSY),
RV3028_EEBUSY_POLL, RV3028_EEBUSY_POLL,
RV3028_EEBUSY_TIMEOUT); RV3028_EEBUSY_TIMEOUT);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
ret = regmap_read(priv, RV3028_EEPROM_DATA, &data); ret = regmap_read(rv3028->regmap, RV3028_EEPROM_DATA, &data);
if (ret) if (ret)
goto restore_eerd; goto restore_eerd;
buf[i] = data; buf[i] = data;
} }
restore_eerd: restore_eerd:
if (!(ctrl1 & RV3028_CTRL1_EERD)) rv3028_exit_eerd(rv3028, eerd);
{
err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD,
0);
if (err && !ret)
ret = err;
}
return ret; return ret;
} }
...@@ -619,24 +679,23 @@ static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -619,24 +679,23 @@ static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate) unsigned long parent_rate)
{ {
int i, ret; int i, ret;
u32 enabled;
struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw); struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw);
ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &enabled);
if (ret < 0)
return ret;
ret = regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0); ret = regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0);
if (ret < 0) if (ret < 0)
return ret; return ret;
for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) { enabled &= RV3028_CLKOUT_CLKOE;
if (clkout_rates[i] == rate) {
ret = regmap_update_bits(rv3028->regmap,
RV3028_CLKOUT,
RV3028_CLKOUT_FD_MASK, i);
if (ret < 0)
return ret;
return regmap_write(rv3028->regmap, RV3028_CLKOUT, for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
RV3028_CLKOUT_CLKSY | RV3028_CLKOUT_CLKOE); if (clkout_rates[i] == rate)
} return rv3028_update_cfg(rv3028, RV3028_CLKOUT, 0xff,
} RV3028_CLKOUT_CLKSY | enabled | i);
return -EINVAL; return -EINVAL;
} }
...@@ -811,10 +870,8 @@ static int rv3028_probe(struct i2c_client *client) ...@@ -811,10 +870,8 @@ static int rv3028_probe(struct i2c_client *client)
break; break;
if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { if (i < ARRAY_SIZE(rv3028_trickle_resistors)) {
ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE |
RV3028_BACKUP_TCE | RV3028_BACKUP_TCR_MASK, RV3028_BACKUP_TCE | i);
RV3028_BACKUP_TCR_MASK,
RV3028_BACKUP_TCE | i);
if (ret) if (ret)
return ret; return ret;
} else { } else {
...@@ -835,7 +892,7 @@ static int rv3028_probe(struct i2c_client *client) ...@@ -835,7 +892,7 @@ static int rv3028_probe(struct i2c_client *client)
nvmem_cfg.priv = rv3028->regmap; nvmem_cfg.priv = rv3028->regmap;
rtc_nvmem_register(rv3028->rtc, &nvmem_cfg); rtc_nvmem_register(rv3028->rtc, &nvmem_cfg);
eeprom_cfg.priv = rv3028->regmap; eeprom_cfg.priv = rv3028;
rtc_nvmem_register(rv3028->rtc, &eeprom_cfg); rtc_nvmem_register(rv3028->rtc, &eeprom_cfg);
rv3028->rtc->max_user_freq = 1; rv3028->rtc->max_user_freq = 1;
......
This diff is collapsed.
...@@ -454,13 +454,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) ...@@ -454,13 +454,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
static int rv8803_nvram_write(void *priv, unsigned int offset, void *val, static int rv8803_nvram_write(void *priv, unsigned int offset, void *val,
size_t bytes) size_t bytes)
{ {
int ret; return rv8803_write_reg(priv, RV8803_RAM, *(u8 *)val);
ret = rv8803_write_reg(priv, RV8803_RAM, *(u8 *)val);
if (ret)
return ret;
return 0;
} }
static int rv8803_nvram_read(void *priv, unsigned int offset, static int rv8803_nvram_read(void *priv, unsigned int offset,
......
This diff is collapsed.
...@@ -494,13 +494,8 @@ static int s3c_rtc_probe(struct platform_device *pdev) ...@@ -494,13 +494,8 @@ static int s3c_rtc_probe(struct platform_device *pdev)
if (info->data->needs_src_clk) { if (info->data->needs_src_clk) {
info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src");
if (IS_ERR(info->rtc_src_clk)) { if (IS_ERR(info->rtc_src_clk)) {
ret = PTR_ERR(info->rtc_src_clk); ret = dev_err_probe(&pdev->dev, PTR_ERR(info->rtc_src_clk),
if (ret != -EPROBE_DEFER) "failed to find rtc source clock\n");
dev_err(&pdev->dev,
"failed to find rtc source clock\n");
else
dev_dbg(&pdev->dev,
"probe deferred due to missing rtc src clk\n");
goto err_src_clk; goto err_src_clk;
} }
ret = clk_prepare_enable(info->rtc_src_clk); ret = clk_prepare_enable(info->rtc_src_clk);
......
...@@ -173,7 +173,7 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -173,7 +173,7 @@ static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
return 0; return 0;
} }
static struct rtc_class_ops st_rtc_ops = { static const struct rtc_class_ops st_rtc_ops = {
.read_time = st_rtc_read_time, .read_time = st_rtc_read_time,
.set_time = st_rtc_set_time, .set_time = st_rtc_set_time,
.read_alarm = st_rtc_read_alarm, .read_alarm = st_rtc_read_alarm,
......
...@@ -72,7 +72,6 @@ struct mtk_rtc_data { ...@@ -72,7 +72,6 @@ struct mtk_rtc_data {
}; };
struct mt6397_rtc { struct mt6397_rtc {
struct device *dev;
struct rtc_device *rtc_dev; struct rtc_device *rtc_dev;
/* Protect register access from multiple tasks */ /* Protect register access from multiple tasks */
......
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