Commit a7efd197 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull RTC updates from Alexandre Belloni:
 "Mostly small fixes and two drivers gaining alarm support. Summary:

  Subsystem:

    - UIE emulation has been reworked to avoid calling driver callbacks
      when it is known it will not work

  Drivers:

   - ab-eoz9: add alarm support

   - pcf8523: add alarm support"

* tag 'rtc-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (27 commits)
  rtc: sysfs: check features instead of ops
  rtc: omap: use rtc_write to access OMAP_RTC_OSC_REG
  rtc: s5m: Remove reference to parent's device pdata
  rtc: ds1307: Fix wday settings for rx8130
  rtc: pcf8523: report oscillator failures
  rtc: pcf8523: add alarm support
  rtc: pcf8523: remove useless define
  rtc: rtc_update_irq_enable: rework UIE emulation
  rtc: ds1307: remove flags
  rtc: ds1307: replace HAS_ALARM by RTC_FEATURE_ALARM
  rtc: imx-sc: remove .read_alarm
  rtc: ds1511: remove unused function
  rtc: fsl-ftm-alarm: add MODULE_TABLE()
  rtc: rtc-spear: replace spin_lock_irqsave by spin_lock in hard IRQ
  dt-bindings: rtc: qcom-pm8xxx-rtc: Add qcom pm8xxx rtc bindings
  rtc: pm8xxx: Add RTC support for PMIC PMK8350
  rtc: ab-eoz9: make use of RTC_FEATURE_ALARM
  rtc: ab-eoz9: add alarm support
  rtc: ab-eoz9: set regmap max_register
  rtc: pcf85063: fallback to parent of_node
  ...
parents 9b1f61d5 4d0185e6
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/qcom-pm8xxx-rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm PM8xxx PMIC RTC device
maintainers:
- Satya Priya <skakit@codeaurora.org>
properties:
compatible:
enum:
- qcom,pm8058-rtc
- qcom,pm8921-rtc
- qcom,pm8941-rtc
- qcom,pm8018-rtc
- qcom,pmk8350-rtc
reg:
maxItems: 1
interrupts:
maxItems: 1
allow-set-time:
$ref: /schemas/types.yaml#/definitions/flag
description:
Indicates that the setting of RTC time is allowed by the host CPU.
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/spmi/spmi.h>
spmi_bus: spmi@c440000 {
reg = <0x0c440000 0x1100>;
#address-cells = <2>;
#size-cells = <0>;
pmicintc: pmic@0 {
reg = <0x0 SPMI_USID>;
compatible = "qcom,pm8921";
interrupts = <104 8>;
#interrupt-cells = <2>;
interrupt-controller;
#address-cells = <1>;
#size-cells = <0>;
pm8921_rtc: rtc@11d {
compatible = "qcom,pm8921-rtc";
reg = <0x11d>;
interrupts = <0x27 0>;
};
};
};
...
...@@ -1339,6 +1339,7 @@ config RTC_DRV_DIGICOLOR ...@@ -1339,6 +1339,7 @@ config RTC_DRV_DIGICOLOR
config RTC_DRV_IMXDI config RTC_DRV_IMXDI
tristate "Freescale IMX DryIce Real Time Clock" tristate "Freescale IMX DryIce Real Time Clock"
depends on ARCH_MXC depends on ARCH_MXC
depends on OF
help help
Support for Freescale IMX DryIce RTC Support for Freescale IMX DryIce RTC
...@@ -1906,7 +1907,7 @@ config RTC_DRV_HID_SENSOR_TIME ...@@ -1906,7 +1907,7 @@ config RTC_DRV_HID_SENSOR_TIME
config RTC_DRV_GOLDFISH config RTC_DRV_GOLDFISH
tristate "Goldfish Real Time Clock" tristate "Goldfish Real Time Clock"
depends on OF && HAS_IOMEM depends on HAS_IOMEM
help help
Say yes to enable RTC driver for the Goldfish based virtual platform. Say yes to enable RTC driver for the Goldfish based virtual platform.
......
...@@ -545,7 +545,7 @@ EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable); ...@@ -545,7 +545,7 @@ EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable);
int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
{ {
int rc = 0, err; int err;
err = mutex_lock_interruptible(&rtc->ops_lock); err = mutex_lock_interruptible(&rtc->ops_lock);
if (err) if (err)
...@@ -561,17 +561,21 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) ...@@ -561,17 +561,21 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
if (rtc->uie_rtctimer.enabled == enabled) if (rtc->uie_rtctimer.enabled == enabled)
goto out; goto out;
if (rtc->uie_unsupported) { if (rtc->uie_unsupported || !test_bit(RTC_FEATURE_ALARM, rtc->features)) {
err = -EINVAL; mutex_unlock(&rtc->ops_lock);
goto out; #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
return rtc_dev_update_irq_enable_emul(rtc, enabled);
#else
return -EINVAL;
#endif
} }
if (enabled) { if (enabled) {
struct rtc_time tm; struct rtc_time tm;
ktime_t now, onesec; ktime_t now, onesec;
rc = __rtc_read_time(rtc, &tm); err = __rtc_read_time(rtc, &tm);
if (rc) if (err)
goto out; goto out;
onesec = ktime_set(1, 0); onesec = ktime_set(1, 0);
now = rtc_tm_to_ktime(tm); now = rtc_tm_to_ktime(tm);
...@@ -585,24 +589,6 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) ...@@ -585,24 +589,6 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
out: out:
mutex_unlock(&rtc->ops_lock); mutex_unlock(&rtc->ops_lock);
/*
* __rtc_read_time() failed, this probably means that the RTC time has
* never been set or less probably there is a transient error on the
* bus. In any case, avoid enabling emulation has this will fail when
* reading the time too.
*/
if (rc)
return rc;
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
/*
* Enable emulation if the driver returned -EINVAL to signal that it has
* been configured without interrupts or they are not available at the
* moment.
*/
if (err == -EINVAL)
err = rtc_dev_update_irq_enable_emul(rtc, enabled);
#endif
return err; return err;
} }
EXPORT_SYMBOL_GPL(rtc_update_irq_enable); EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/bitfield.h>
#include <linux/hwmon.h> #include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
...@@ -57,6 +58,24 @@ ...@@ -57,6 +58,24 @@
#define ABEOZ9_SEC_LEN 7 #define ABEOZ9_SEC_LEN 7
#define ABEOZ9_REG_ALARM_SEC 0x10
#define ABEOZ9_BIT_ALARM_SEC GENMASK(6, 0)
#define ABEOZ9_REG_ALARM_MIN 0x11
#define ABEOZ9_BIT_ALARM_MIN GENMASK(6, 0)
#define ABEOZ9_REG_ALARM_HOURS 0x12
#define ABEOZ9_BIT_ALARM_HOURS_PM BIT(5)
#define ABEOZ9_BIT_ALARM_HOURS GENMASK(4, 0)
#define ABEOZ9_REG_ALARM_DAYS 0x13
#define ABEOZ9_BIT_ALARM_DAYS GENMASK(5, 0)
#define ABEOZ9_REG_ALARM_WEEKDAYS 0x14
#define ABEOZ9_BIT_ALARM_WEEKDAYS GENMASK(2, 0)
#define ABEOZ9_REG_ALARM_MONTHS 0x15
#define ABEOZ9_BIT_ALARM_MONTHS GENMASK(4, 0)
#define ABEOZ9_REG_ALARM_YEARS 0x16
#define ABEOZ9_ALARM_LEN 7
#define ABEOZ9_BIT_ALARM_AE BIT(7)
#define ABEOZ9_REG_REG_TEMP 0x20 #define ABEOZ9_REG_REG_TEMP 0x20
#define ABEOZ953_TEMP_MAX 120 #define ABEOZ953_TEMP_MAX 120
#define ABEOZ953_TEMP_MIN -60 #define ABEOZ953_TEMP_MIN -60
...@@ -186,6 +205,98 @@ static int abeoz9_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -186,6 +205,98 @@ static int abeoz9_rtc_set_time(struct device *dev, struct rtc_time *tm)
return abeoz9_reset_validity(regmap); return abeoz9_reset_validity(regmap);
} }
static int abeoz9_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
struct regmap *regmap = data->regmap;
u8 regs[ABEOZ9_ALARM_LEN];
u8 val[2];
int ret;
ret = abeoz9_check_validity(dev);
if (ret)
return ret;
ret = regmap_bulk_read(regmap, ABEOZ9_REG_CTRL_INT, val, sizeof(val));
if (ret)
return ret;
alarm->enabled = val[0] & ABEOZ9_REG_CTRL_INT_AIE;
alarm->pending = val[1] & ABEOZ9_REG_CTRL_INT_FLAG_AF;
ret = regmap_bulk_read(regmap, ABEOZ9_REG_ALARM_SEC, regs, sizeof(regs));
if (ret)
return ret;
alarm->time.tm_sec = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_SEC, regs[0]));
alarm->time.tm_min = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_MIN, regs[1]));
alarm->time.tm_hour = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_HOURS, regs[2]));
if (FIELD_GET(ABEOZ9_BIT_ALARM_HOURS_PM, regs[2]))
alarm->time.tm_hour += 12;
alarm->time.tm_mday = bcd2bin(FIELD_GET(ABEOZ9_BIT_ALARM_DAYS, regs[3]));
return 0;
}
static int abeoz9_rtc_alarm_irq_enable(struct device *dev, u32 enable)
{
struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
return regmap_update_bits(data->regmap, ABEOZ9_REG_CTRL_INT,
ABEOZ9_REG_CTRL_INT_AIE,
FIELD_PREP(ABEOZ9_REG_CTRL_INT_AIE, enable));
}
static int abeoz9_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
u8 regs[ABEOZ9_ALARM_LEN] = {0};
int ret;
ret = regmap_update_bits(data->regmap, ABEOZ9_REG_CTRL_INT_FLAG,
ABEOZ9_REG_CTRL_INT_FLAG_AF, 0);
if (ret)
return ret;
regs[0] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_SEC,
bin2bcd(alarm->time.tm_sec));
regs[1] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_MIN,
bin2bcd(alarm->time.tm_min));
regs[2] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_HOURS,
bin2bcd(alarm->time.tm_hour));
regs[3] = ABEOZ9_BIT_ALARM_AE | FIELD_PREP(ABEOZ9_BIT_ALARM_DAYS,
bin2bcd(alarm->time.tm_mday));
ret = regmap_bulk_write(data->regmap, ABEOZ9_REG_ALARM_SEC, regs,
sizeof(regs));
if (ret)
return ret;
return abeoz9_rtc_alarm_irq_enable(dev, alarm->enabled);
}
static irqreturn_t abeoz9_rtc_irq(int irq, void *dev)
{
struct abeoz9_rtc_data *data = dev_get_drvdata(dev);
unsigned int val;
int ret;
ret = regmap_read(data->regmap, ABEOZ9_REG_CTRL_INT_FLAG, &val);
if (ret)
return IRQ_NONE;
if (!FIELD_GET(ABEOZ9_REG_CTRL_INT_FLAG_AF, val))
return IRQ_NONE;
regmap_update_bits(data->regmap, ABEOZ9_REG_CTRL_INT_FLAG,
ABEOZ9_REG_CTRL_INT_FLAG_AF, 0);
rtc_update_irq(data->rtc, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
}
static int abeoz9_trickle_parse_dt(struct device_node *node) static int abeoz9_trickle_parse_dt(struct device_node *node)
{ {
u32 ohms = 0; u32 ohms = 0;
...@@ -258,12 +369,16 @@ static int abeoz9_rtc_setup(struct device *dev, struct device_node *node) ...@@ -258,12 +369,16 @@ static int abeoz9_rtc_setup(struct device *dev, struct device_node *node)
static const struct rtc_class_ops rtc_ops = { static const struct rtc_class_ops rtc_ops = {
.read_time = abeoz9_rtc_get_time, .read_time = abeoz9_rtc_get_time,
.set_time = abeoz9_rtc_set_time, .set_time = abeoz9_rtc_set_time,
.read_alarm = abeoz9_rtc_read_alarm,
.set_alarm = abeoz9_rtc_set_alarm,
.alarm_irq_enable = abeoz9_rtc_alarm_irq_enable,
}; };
static const struct regmap_config abeoz9_rtc_regmap_config = { static const struct regmap_config abeoz9_rtc_regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.max_register = 0x3f,
}; };
#if IS_REACHABLE(CONFIG_HWMON) #if IS_REACHABLE(CONFIG_HWMON)
...@@ -419,6 +534,24 @@ static int abeoz9_probe(struct i2c_client *client, ...@@ -419,6 +534,24 @@ static int abeoz9_probe(struct i2c_client *client,
data->rtc->ops = &rtc_ops; data->rtc->ops = &rtc_ops;
data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
data->rtc->range_max = RTC_TIMESTAMP_END_2099; data->rtc->range_max = RTC_TIMESTAMP_END_2099;
data->rtc->uie_unsupported = 1;
clear_bit(RTC_FEATURE_ALARM, data->rtc->features);
if (client->irq > 0) {
ret = devm_request_threaded_irq(dev, client->irq, NULL,
abeoz9_rtc_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
dev_name(dev), dev);
if (ret) {
dev_err(dev, "failed to request alarm irq\n");
return ret;
}
}
if (client->irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
ret = device_init_wakeup(dev, true);
set_bit(RTC_FEATURE_ALARM, data->rtc->features);
}
ret = devm_rtc_register_device(data->rtc); ret = devm_rtc_register_device(data->rtc);
if (ret) if (ret)
......
...@@ -169,9 +169,6 @@ enum ds_type { ...@@ -169,9 +169,6 @@ enum ds_type {
struct ds1307 { struct ds1307 {
enum ds_type type; enum ds_type type;
unsigned long flags;
#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
#define HAS_ALARM 1 /* bit 1 == irq claimed */
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
const char *name; const char *name;
...@@ -296,7 +293,11 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) ...@@ -296,7 +293,11 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f); t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f);
tmp = regs[DS1307_REG_HOUR] & 0x3f; tmp = regs[DS1307_REG_HOUR] & 0x3f;
t->tm_hour = bcd2bin(tmp); t->tm_hour = bcd2bin(tmp);
t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1; /* rx8130 is bit position, not BCD */
if (ds1307->type == rx_8130)
t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f);
else
t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1;
t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f); t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f);
tmp = regs[DS1307_REG_MONTH] & 0x1f; tmp = regs[DS1307_REG_MONTH] & 0x1f;
t->tm_mon = bcd2bin(tmp) - 1; t->tm_mon = bcd2bin(tmp) - 1;
...@@ -343,7 +344,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) ...@@ -343,7 +344,11 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec); regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
regs[DS1307_REG_MIN] = bin2bcd(t->tm_min); regs[DS1307_REG_MIN] = bin2bcd(t->tm_min);
regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); /* rx8130 is bit position, not BCD */
if (ds1307->type == rx_8130)
regs[DS1307_REG_WDAY] = 1 << t->tm_wday;
else
regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday); regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1); regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
...@@ -411,9 +416,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -411,9 +416,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
int ret; int ret;
u8 regs[9]; u8 regs[9];
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
/* read all ALARM1, ALARM2, and status registers at once */ /* read all ALARM1, ALARM2, and status registers at once */
ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS,
regs, sizeof(regs)); regs, sizeof(regs));
...@@ -454,9 +456,6 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -454,9 +456,6 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
u8 control, status; u8 control, status;
int ret; int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
dev_dbg(dev, "%s secs=%d, mins=%d, " dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, enabled=%d, pending=%d\n", "hours=%d, mday=%d, enabled=%d, pending=%d\n",
"alarm set", t->time.tm_sec, t->time.tm_min, "alarm set", t->time.tm_sec, t->time.tm_min,
...@@ -512,9 +511,6 @@ static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -512,9 +511,6 @@ static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct ds1307 *ds1307 = dev_get_drvdata(dev); struct ds1307 *ds1307 = dev_get_drvdata(dev);
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -ENOTTY;
return regmap_update_bits(ds1307->regmap, DS1337_REG_CONTROL, return regmap_update_bits(ds1307->regmap, DS1337_REG_CONTROL,
DS1337_BIT_A1IE, DS1337_BIT_A1IE,
enabled ? DS1337_BIT_A1IE : 0); enabled ? DS1337_BIT_A1IE : 0);
...@@ -592,9 +588,6 @@ static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -592,9 +588,6 @@ static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t)
u8 ald[3], ctl[3]; u8 ald[3], ctl[3];
int ret; int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
/* Read alarm registers. */ /* Read alarm registers. */
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald,
sizeof(ald)); sizeof(ald));
...@@ -634,9 +627,6 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -634,9 +627,6 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
u8 ald[3], ctl[3]; u8 ald[3], ctl[3];
int ret; int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d " dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d "
"enabled=%d pending=%d\n", __func__, "enabled=%d pending=%d\n", __func__,
t->time.tm_sec, t->time.tm_min, t->time.tm_hour, t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
...@@ -681,9 +671,6 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -681,9 +671,6 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled)
struct ds1307 *ds1307 = dev_get_drvdata(dev); struct ds1307 *ds1307 = dev_get_drvdata(dev);
int ret, reg; int ret, reg;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
ret = regmap_read(ds1307->regmap, RX8130_REG_CONTROL0, &reg); ret = regmap_read(ds1307->regmap, RX8130_REG_CONTROL0, &reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -735,9 +722,6 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -735,9 +722,6 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
u8 regs[10]; u8 regs[10];
int ret; int ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
/* Read control and alarm 0 registers. */ /* Read control and alarm 0 registers. */
ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
sizeof(regs)); sizeof(regs));
...@@ -793,9 +777,6 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) ...@@ -793,9 +777,6 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
unsigned char regs[10]; unsigned char regs[10];
int wday, ret; int wday, ret;
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
wday = mcp794xx_alm_weekday(dev, &t->time); wday = mcp794xx_alm_weekday(dev, &t->time);
if (wday < 0) if (wday < 0)
return wday; return wday;
...@@ -842,9 +823,6 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled) ...@@ -842,9 +823,6 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ {
struct ds1307 *ds1307 = dev_get_drvdata(dev); struct ds1307 *ds1307 = dev_get_drvdata(dev);
if (!test_bit(HAS_ALARM, &ds1307->flags))
return -EINVAL;
return regmap_update_bits(ds1307->regmap, MCP794XX_REG_CONTROL, return regmap_update_bits(ds1307->regmap, MCP794XX_REG_CONTROL,
MCP794XX_BIT_ALM0_EN, MCP794XX_BIT_ALM0_EN,
enabled ? MCP794XX_BIT_ALM0_EN : 0); enabled ? MCP794XX_BIT_ALM0_EN : 0);
...@@ -1641,7 +1619,7 @@ static int ds3231_clks_register(struct ds1307 *ds1307) ...@@ -1641,7 +1619,7 @@ static int ds3231_clks_register(struct ds1307 *ds1307)
* Interrupt signal due to alarm conditions and square-wave * Interrupt signal due to alarm conditions and square-wave
* output share same pin, so don't initialize both. * output share same pin, so don't initialize both.
*/ */
if (i == DS3231_CLK_SQW && test_bit(HAS_ALARM, &ds1307->flags)) if (i == DS3231_CLK_SQW && test_bit(RTC_FEATURE_ALARM, ds1307->rtc->features))
continue; continue;
init.name = ds3231_clks_names[i]; init.name = ds3231_clks_names[i];
...@@ -1964,15 +1942,15 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1964,15 +1942,15 @@ static int ds1307_probe(struct i2c_client *client,
bin2bcd(tmp)); bin2bcd(tmp));
} }
if (want_irq || ds1307_can_wakeup_device) {
device_set_wakeup_capable(ds1307->dev, true);
set_bit(HAS_ALARM, &ds1307->flags);
}
ds1307->rtc = devm_rtc_allocate_device(ds1307->dev); ds1307->rtc = devm_rtc_allocate_device(ds1307->dev);
if (IS_ERR(ds1307->rtc)) if (IS_ERR(ds1307->rtc))
return PTR_ERR(ds1307->rtc); return PTR_ERR(ds1307->rtc);
if (want_irq || ds1307_can_wakeup_device)
device_set_wakeup_capable(ds1307->dev, true);
else
clear_bit(RTC_FEATURE_ALARM, ds1307->rtc->features);
if (ds1307_can_wakeup_device && !want_irq) { if (ds1307_can_wakeup_device && !want_irq) {
dev_info(ds1307->dev, dev_info(ds1307->dev,
"'wakeup-source' is set, request for an IRQ is disabled!\n"); "'wakeup-source' is set, request for an IRQ is disabled!\n");
...@@ -1988,7 +1966,7 @@ static int ds1307_probe(struct i2c_client *client, ...@@ -1988,7 +1966,7 @@ static int ds1307_probe(struct i2c_client *client,
if (err) { if (err) {
client->irq = 0; client->irq = 0;
device_set_wakeup_capable(ds1307->dev, false); device_set_wakeup_capable(ds1307->dev, false);
clear_bit(HAS_ALARM, &ds1307->flags); clear_bit(RTC_FEATURE_ALARM, ds1307->rtc->features);
dev_err(ds1307->dev, "unable to request IRQ!\n"); dev_err(ds1307->dev, "unable to request IRQ!\n");
} else { } else {
dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq); dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq);
......
...@@ -104,12 +104,6 @@ rtc_write(uint8_t val, uint32_t reg) ...@@ -104,12 +104,6 @@ rtc_write(uint8_t val, uint32_t reg)
writeb(val, ds1511_base + (reg * reg_spacing)); writeb(val, ds1511_base + (reg * reg_spacing));
} }
static inline void
rtc_write_alarm(uint8_t val, enum ds1511reg reg)
{
rtc_write((val | 0x80), reg);
}
static noinline uint8_t static noinline uint8_t
rtc_read(enum ds1511reg reg) rtc_read(enum ds1511reg reg)
{ {
......
...@@ -310,6 +310,7 @@ static const struct of_device_id ftm_rtc_match[] = { ...@@ -310,6 +310,7 @@ static const struct of_device_id ftm_rtc_match[] = {
{ .compatible = "fsl,lx2160a-ftm-alarm", }, { .compatible = "fsl,lx2160a-ftm-alarm", },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, ftm_rtc_match);
static const struct acpi_device_id ftm_imx_acpi_ids[] = { static const struct acpi_device_id ftm_imx_acpi_ids[] = {
{"NXP0014",}, {"NXP0014",},
......
...@@ -80,16 +80,6 @@ static int imx_sc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) ...@@ -80,16 +80,6 @@ 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); 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) 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_msg_timer_rtc_set_alarm msg;
...@@ -127,7 +117,6 @@ static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ...@@ -127,7 +117,6 @@ static int imx_sc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static const struct rtc_class_ops imx_sc_rtc_ops = { static const struct rtc_class_ops imx_sc_rtc_ops = {
.read_time = imx_sc_rtc_read_time, .read_time = imx_sc_rtc_read_time,
.set_time = imx_sc_rtc_set_time, .set_time = imx_sc_rtc_set_time,
.read_alarm = imx_sc_rtc_read_alarm,
.set_alarm = imx_sc_rtc_set_alarm, .set_alarm = imx_sc_rtc_set_alarm,
.alarm_irq_enable = imx_sc_rtc_alarm_irq_enable, .alarm_irq_enable = imx_sc_rtc_alarm_irq_enable,
}; };
......
...@@ -840,19 +840,17 @@ static int __exit dryice_rtc_remove(struct platform_device *pdev) ...@@ -840,19 +840,17 @@ static int __exit dryice_rtc_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_OF
static const struct of_device_id dryice_dt_ids[] = { static const struct of_device_id dryice_dt_ids[] = {
{ .compatible = "fsl,imx25-rtc" }, { .compatible = "fsl,imx25-rtc" },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, dryice_dt_ids); MODULE_DEVICE_TABLE(of, dryice_dt_ids);
#endif
static struct platform_driver dryice_rtc_driver = { static struct platform_driver dryice_rtc_driver = {
.driver = { .driver = {
.name = "imxdi_rtc", .name = "imxdi_rtc",
.of_match_table = of_match_ptr(dryice_dt_ids), .of_match_table = dryice_dt_ids,
}, },
.remove = __exit_p(dryice_rtc_remove), .remove = __exit_p(dryice_rtc_remove),
}; };
......
...@@ -421,7 +421,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev) ...@@ -421,7 +421,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
/* Try to get irq number. We also can work in /* Try to get irq number. We also can work in
* the mode without IRQ. * the mode without IRQ.
*/ */
m48t59->irq = platform_get_irq(pdev, 0); m48t59->irq = platform_get_irq_optional(pdev, 0);
if (m48t59->irq <= 0) if (m48t59->irq <= 0)
m48t59->irq = NO_IRQ; m48t59->irq = NO_IRQ;
......
...@@ -415,7 +415,7 @@ static int mxc_rtc_probe(struct platform_device *pdev) ...@@ -415,7 +415,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
static struct platform_driver mxc_rtc_driver = { static struct platform_driver mxc_rtc_driver = {
.driver = { .driver = {
.name = "mxc_rtc", .name = "mxc_rtc",
.of_match_table = of_match_ptr(imx_rtc_dt_ids), .of_match_table = imx_rtc_dt_ids,
}, },
.probe = mxc_rtc_probe, .probe = mxc_rtc_probe,
}; };
......
...@@ -786,8 +786,7 @@ static int omap_rtc_probe(struct platform_device *pdev) ...@@ -786,8 +786,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
/* enable RTC functional clock */ /* enable RTC functional clock */
if (rtc->type->has_32kclk_en) { if (rtc->type->has_32kclk_en) {
reg = rtc_read(rtc, OMAP_RTC_OSC_REG); reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
rtc_writel(rtc, OMAP_RTC_OSC_REG, rtc_write(rtc, OMAP_RTC_OSC_REG, reg | OMAP_RTC_OSC_32KCLK_EN);
reg | OMAP_RTC_OSC_32KCLK_EN);
} }
/* clear old status */ /* clear old status */
...@@ -845,7 +844,7 @@ static int omap_rtc_probe(struct platform_device *pdev) ...@@ -845,7 +844,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
reg = rtc_read(rtc, OMAP_RTC_OSC_REG); reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE; reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC; reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
rtc_writel(rtc, OMAP_RTC_OSC_REG, reg); rtc_write(rtc, OMAP_RTC_OSC_REG, reg);
} }
rtc->type->lock(rtc); rtc->type->lock(rtc);
......
...@@ -478,6 +478,7 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063) ...@@ -478,6 +478,7 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
{ {
struct clk *clk; struct clk *clk;
struct clk_init_data init; struct clk_init_data init;
struct device_node *node = pcf85063->rtc->dev.parent->of_node;
init.name = "pcf85063-clkout"; init.name = "pcf85063-clkout";
init.ops = &pcf85063_clkout_ops; init.ops = &pcf85063_clkout_ops;
...@@ -487,15 +488,13 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063) ...@@ -487,15 +488,13 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
pcf85063->clkout_hw.init = &init; pcf85063->clkout_hw.init = &init;
/* optional override of the clockname */ /* optional override of the clockname */
of_property_read_string(pcf85063->rtc->dev.of_node, of_property_read_string(node, "clock-output-names", &init.name);
"clock-output-names", &init.name);
/* register the clock */ /* register the clock */
clk = devm_clk_register(&pcf85063->rtc->dev, &pcf85063->clkout_hw); clk = devm_clk_register(&pcf85063->rtc->dev, &pcf85063->clkout_hw);
if (!IS_ERR(clk)) if (!IS_ERR(clk))
of_clk_add_provider(pcf85063->rtc->dev.of_node, of_clk_add_provider(node, of_clk_src_simple_get, clk);
of_clk_src_simple_get, clk);
return clk; return clk;
} }
......
...@@ -8,12 +8,15 @@ ...@@ -8,12 +8,15 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/pm_wakeirq.h>
#define DRIVER_NAME "rtc-pcf8523"
#define REG_CONTROL1 0x00 #define REG_CONTROL1 0x00
#define REG_CONTROL1_CAP_SEL BIT(7) #define REG_CONTROL1_CAP_SEL BIT(7)
#define REG_CONTROL1_STOP BIT(5) #define REG_CONTROL1_STOP BIT(5)
#define REG_CONTROL1_AIE BIT(1)
#define REG_CONTROL2 0x01
#define REG_CONTROL2_AF BIT(3)
#define REG_CONTROL3 0x02 #define REG_CONTROL3 0x02
#define REG_CONTROL3_PM_BLD BIT(7) /* battery low detection disabled */ #define REG_CONTROL3_PM_BLD BIT(7) /* battery low detection disabled */
...@@ -32,9 +35,22 @@ ...@@ -32,9 +35,22 @@
#define REG_MONTHS 0x08 #define REG_MONTHS 0x08
#define REG_YEARS 0x09 #define REG_YEARS 0x09
#define REG_MINUTE_ALARM 0x0a
#define REG_HOUR_ALARM 0x0b
#define REG_DAY_ALARM 0x0c
#define REG_WEEKDAY_ALARM 0x0d
#define ALARM_DIS BIT(7)
#define REG_OFFSET 0x0e #define REG_OFFSET 0x0e
#define REG_OFFSET_MODE BIT(7) #define REG_OFFSET_MODE BIT(7)
#define REG_TMR_CLKOUT_CTRL 0x0f
struct pcf8523 {
struct rtc_device *rtc;
struct i2c_client *client;
};
static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep) static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
{ {
struct i2c_msg msgs[2]; struct i2c_msg msgs[2];
...@@ -140,6 +156,27 @@ static int pcf8523_set_pm(struct i2c_client *client, u8 pm) ...@@ -140,6 +156,27 @@ static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
return 0; return 0;
} }
static irqreturn_t pcf8523_irq(int irq, void *dev_id)
{
struct pcf8523 *pcf8523 = i2c_get_clientdata(dev_id);
u8 value;
int err;
err = pcf8523_read(pcf8523->client, REG_CONTROL2, &value);
if (err < 0)
return IRQ_HANDLED;
if (value & REG_CONTROL2_AF) {
value &= ~REG_CONTROL2_AF;
pcf8523_write(pcf8523->client, REG_CONTROL2, value);
rtc_update_irq(pcf8523->rtc, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
static int pcf8523_stop_rtc(struct i2c_client *client) static int pcf8523_stop_rtc(struct i2c_client *client)
{ {
u8 value; u8 value;
...@@ -259,11 +296,118 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -259,11 +296,118 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
return pcf8523_start_rtc(client); return pcf8523_start_rtc(client);
} }
static int pcf8523_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
struct i2c_client *client = to_i2c_client(dev);
u8 start = REG_MINUTE_ALARM, regs[4];
struct i2c_msg msgs[2];
u8 value;
int err;
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = &start;
msgs[1].addr = client->addr;
msgs[1].flags = I2C_M_RD;
msgs[1].len = sizeof(regs);
msgs[1].buf = regs;
err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (err < 0)
return err;
tm->time.tm_sec = 0;
tm->time.tm_min = bcd2bin(regs[0] & 0x7F);
tm->time.tm_hour = bcd2bin(regs[1] & 0x3F);
tm->time.tm_mday = bcd2bin(regs[2] & 0x3F);
tm->time.tm_wday = bcd2bin(regs[3] & 0x7);
err = pcf8523_read(client, REG_CONTROL1, &value);
if (err < 0)
return err;
tm->enabled = !!(value & REG_CONTROL1_AIE);
err = pcf8523_read(client, REG_CONTROL2, &value);
if (err < 0)
return err;
tm->pending = !!(value & REG_CONTROL2_AF);
return 0;
}
static int pcf8523_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
u8 value;
int err;
err = pcf8523_read(client, REG_CONTROL1, &value);
if (err < 0)
return err;
value &= REG_CONTROL1_AIE;
if (enabled)
value |= REG_CONTROL1_AIE;
err = pcf8523_write(client, REG_CONTROL1, value);
if (err < 0)
return err;
return 0;
}
static int pcf8523_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_msg msg;
u8 regs[5];
int err;
err = pcf8523_irq_enable(dev, 0);
if (err)
return err;
err = pcf8523_write(client, REG_CONTROL2, 0);
if (err < 0)
return err;
/* The alarm has no seconds, round up to nearest minute */
if (tm->time.tm_sec) {
time64_t alarm_time = rtc_tm_to_time64(&tm->time);
alarm_time += 60 - tm->time.tm_sec;
rtc_time64_to_tm(alarm_time, &tm->time);
}
regs[0] = REG_MINUTE_ALARM;
regs[1] = bin2bcd(tm->time.tm_min);
regs[2] = bin2bcd(tm->time.tm_hour);
regs[3] = bin2bcd(tm->time.tm_mday);
regs[4] = ALARM_DIS;
msg.addr = client->addr;
msg.flags = 0;
msg.len = sizeof(regs);
msg.buf = regs;
err = i2c_transfer(client->adapter, &msg, 1);
if (err < 0)
return err;
if (tm->enabled)
return pcf8523_irq_enable(dev, tm->enabled);
return 0;
}
#ifdef CONFIG_RTC_INTF_DEV #ifdef CONFIG_RTC_INTF_DEV
static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd, static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
unsigned int flags = 0;
u8 value;
int ret; int ret;
switch (cmd) { switch (cmd) {
...@@ -272,9 +416,16 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd, ...@@ -272,9 +416,16 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret) if (ret)
ret = RTC_VL_BACKUP_LOW; flags |= RTC_VL_BACKUP_LOW;
return put_user(ret, (unsigned int __user *)arg); ret = pcf8523_read(client, REG_SECONDS, &value);
if (ret < 0)
return ret;
if (value & REG_SECONDS_OS)
flags |= RTC_VL_DATA_INVALID;
return put_user(flags, (unsigned int __user *)arg);
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
...@@ -322,6 +473,9 @@ static int pcf8523_rtc_set_offset(struct device *dev, long offset) ...@@ -322,6 +473,9 @@ static int pcf8523_rtc_set_offset(struct device *dev, long offset)
static const struct rtc_class_ops pcf8523_rtc_ops = { static const struct rtc_class_ops pcf8523_rtc_ops = {
.read_time = pcf8523_rtc_read_time, .read_time = pcf8523_rtc_read_time,
.set_time = pcf8523_rtc_set_time, .set_time = pcf8523_rtc_set_time,
.read_alarm = pcf8523_rtc_read_alarm,
.set_alarm = pcf8523_rtc_set_alarm,
.alarm_irq_enable = pcf8523_irq_enable,
.ioctl = pcf8523_rtc_ioctl, .ioctl = pcf8523_rtc_ioctl,
.read_offset = pcf8523_rtc_read_offset, .read_offset = pcf8523_rtc_read_offset,
.set_offset = pcf8523_rtc_set_offset, .set_offset = pcf8523_rtc_set_offset,
...@@ -330,12 +484,21 @@ static const struct rtc_class_ops pcf8523_rtc_ops = { ...@@ -330,12 +484,21 @@ static const struct rtc_class_ops pcf8523_rtc_ops = {
static int pcf8523_probe(struct i2c_client *client, static int pcf8523_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct pcf8523 *pcf8523;
struct rtc_device *rtc; struct rtc_device *rtc;
bool wakeup_source = false;
int err; int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV; return -ENODEV;
pcf8523 = devm_kzalloc(&client->dev, sizeof(struct pcf8523), GFP_KERNEL);
if (!pcf8523)
return -ENOMEM;
i2c_set_clientdata(client, pcf8523);
pcf8523->client = client;
err = pcf8523_load_capacitance(client); err = pcf8523_load_capacitance(client);
if (err < 0) if (err < 0)
dev_warn(&client->dev, "failed to set xtal load capacitance: %d", dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
...@@ -349,9 +512,32 @@ static int pcf8523_probe(struct i2c_client *client, ...@@ -349,9 +512,32 @@ static int pcf8523_probe(struct i2c_client *client,
if (IS_ERR(rtc)) if (IS_ERR(rtc))
return PTR_ERR(rtc); return PTR_ERR(rtc);
pcf8523->rtc = rtc;
rtc->ops = &pcf8523_rtc_ops; rtc->ops = &pcf8523_rtc_ops;
rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc->range_max = RTC_TIMESTAMP_END_2099; rtc->range_max = RTC_TIMESTAMP_END_2099;
rtc->uie_unsupported = 1;
if (client->irq > 0) {
err = pcf8523_write(client, REG_TMR_CLKOUT_CTRL, 0x38);
if (err < 0)
return err;
err = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf8523_irq,
IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,
dev_name(&rtc->dev), client);
if (err)
return err;
dev_pm_set_wake_irq(&client->dev, client->irq);
}
#ifdef CONFIG_OF
wakeup_source = of_property_read_bool(client->dev.of_node, "wakeup-source");
#endif
if (client->irq > 0 || wakeup_source)
device_init_wakeup(&client->dev, true);
return devm_rtc_register_device(rtc); return devm_rtc_register_device(rtc);
} }
...@@ -373,7 +559,7 @@ MODULE_DEVICE_TABLE(of, pcf8523_of_match); ...@@ -373,7 +559,7 @@ MODULE_DEVICE_TABLE(of, pcf8523_of_match);
static struct i2c_driver pcf8523_driver = { static struct i2c_driver pcf8523_driver = {
.driver = { .driver = {
.name = DRIVER_NAME, .name = "rtc-pcf8523",
.of_match_table = of_match_ptr(pcf8523_of_match), .of_match_table = of_match_ptr(pcf8523_of_match),
}, },
.probe = pcf8523_probe, .probe = pcf8523_probe,
......
...@@ -445,6 +445,16 @@ static const struct pm8xxx_rtc_regs pm8941_regs = { ...@@ -445,6 +445,16 @@ static const struct pm8xxx_rtc_regs pm8941_regs = {
.alarm_en = BIT(7), .alarm_en = BIT(7),
}; };
static const struct pm8xxx_rtc_regs pmk8350_regs = {
.ctrl = 0x6146,
.write = 0x6140,
.read = 0x6148,
.alarm_rw = 0x6240,
.alarm_ctrl = 0x6246,
.alarm_ctrl2 = 0x6248,
.alarm_en = BIT(7),
};
/* /*
* Hardcoded RTC bases until IORESOURCE_REG mapping is figured out * Hardcoded RTC bases until IORESOURCE_REG mapping is figured out
*/ */
...@@ -453,6 +463,7 @@ static const struct of_device_id pm8xxx_id_table[] = { ...@@ -453,6 +463,7 @@ static const struct of_device_id pm8xxx_id_table[] = {
{ .compatible = "qcom,pm8018-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 },
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, pm8xxx_id_table); MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
......
...@@ -320,7 +320,7 @@ static int rv3028_get_time(struct device *dev, struct rtc_time *tm) ...@@ -320,7 +320,7 @@ static int rv3028_get_time(struct device *dev, struct rtc_time *tm)
tm->tm_sec = bcd2bin(date[RV3028_SEC] & 0x7f); tm->tm_sec = bcd2bin(date[RV3028_SEC] & 0x7f);
tm->tm_min = bcd2bin(date[RV3028_MIN] & 0x7f); tm->tm_min = bcd2bin(date[RV3028_MIN] & 0x7f);
tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f); tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f);
tm->tm_wday = ilog2(date[RV3028_WDAY] & 0x7f); tm->tm_wday = date[RV3028_WDAY] & 0x7f;
tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f); tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f);
tm->tm_mon = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1; tm->tm_mon = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1;
tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100; tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100;
...@@ -337,7 +337,7 @@ static int rv3028_set_time(struct device *dev, struct rtc_time *tm) ...@@ -337,7 +337,7 @@ static int rv3028_set_time(struct device *dev, struct rtc_time *tm)
date[RV3028_SEC] = bin2bcd(tm->tm_sec); date[RV3028_SEC] = bin2bcd(tm->tm_sec);
date[RV3028_MIN] = bin2bcd(tm->tm_min); date[RV3028_MIN] = bin2bcd(tm->tm_min);
date[RV3028_HOUR] = bin2bcd(tm->tm_hour); date[RV3028_HOUR] = bin2bcd(tm->tm_hour);
date[RV3028_WDAY] = 1 << (tm->tm_wday); date[RV3028_WDAY] = tm->tm_wday;
date[RV3028_DAY] = bin2bcd(tm->tm_mday); date[RV3028_DAY] = bin2bcd(tm->tm_mday);
date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1); date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1);
date[RV3028_YEAR] = bin2bcd(tm->tm_year - 100); date[RV3028_YEAR] = bin2bcd(tm->tm_year - 100);
......
...@@ -447,6 +447,12 @@ static int rx6110_i2c_probe(struct i2c_client *client, ...@@ -447,6 +447,12 @@ static int rx6110_i2c_probe(struct i2c_client *client,
return rx6110_probe(rx6110, &client->dev); return rx6110_probe(rx6110, &client->dev);
} }
static const struct acpi_device_id rx6110_i2c_acpi_match[] = {
{ "SECC6110" },
{ }
};
MODULE_DEVICE_TABLE(acpi, rx6110_i2c_acpi_match);
static const struct i2c_device_id rx6110_i2c_id[] = { static const struct i2c_device_id rx6110_i2c_id[] = {
{ "rx6110", 0 }, { "rx6110", 0 },
{ } { }
...@@ -456,6 +462,7 @@ MODULE_DEVICE_TABLE(i2c, rx6110_i2c_id); ...@@ -456,6 +462,7 @@ MODULE_DEVICE_TABLE(i2c, rx6110_i2c_id);
static struct i2c_driver rx6110_i2c_driver = { static struct i2c_driver rx6110_i2c_driver = {
.driver = { .driver = {
.name = RX6110_DRIVER_NAME, .name = RX6110_DRIVER_NAME,
.acpi_match_table = rx6110_i2c_acpi_match,
}, },
.probe = rx6110_i2c_probe, .probe = rx6110_i2c_probe,
.id_table = rx6110_i2c_id, .id_table = rx6110_i2c_id,
......
...@@ -713,16 +713,10 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) ...@@ -713,16 +713,10 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
static int s5m_rtc_probe(struct platform_device *pdev) static int s5m_rtc_probe(struct platform_device *pdev)
{ {
struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent); struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
struct sec_platform_data *pdata = s5m87xx->pdata;
struct s5m_rtc_info *info; struct s5m_rtc_info *info;
const struct regmap_config *regmap_cfg; const struct regmap_config *regmap_cfg;
int ret, alarm_irq; int ret, alarm_irq;
if (!pdata) {
dev_err(pdev->dev.parent, "Platform data not supplied\n");
return -ENODEV;
}
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
......
...@@ -153,12 +153,12 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config) ...@@ -153,12 +153,12 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config)
static irqreturn_t spear_rtc_irq(int irq, void *dev_id) static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
{ {
struct spear_rtc_config *config = dev_id; struct spear_rtc_config *config = dev_id;
unsigned long flags, events = 0; unsigned long events = 0;
unsigned int irq_data; unsigned int irq_data;
spin_lock_irqsave(&config->lock, flags); spin_lock(&config->lock);
irq_data = readl(config->ioaddr + STATUS_REG); irq_data = readl(config->ioaddr + STATUS_REG);
spin_unlock_irqrestore(&config->lock, flags); spin_unlock(&config->lock);
if ((irq_data & RTC_INT_MASK)) { if ((irq_data & RTC_INT_MASK)) {
spear_rtc_clear_interrupt(config); spear_rtc_clear_interrupt(config);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/property.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mfd/tps65910.h> #include <linux/mfd/tps65910.h>
......
...@@ -273,7 +273,7 @@ static bool rtc_does_wakealarm(struct rtc_device *rtc) ...@@ -273,7 +273,7 @@ static bool rtc_does_wakealarm(struct rtc_device *rtc)
if (!device_can_wakeup(rtc->dev.parent)) if (!device_can_wakeup(rtc->dev.parent))
return false; return false;
return rtc->ops->set_alarm != NULL; return !!test_bit(RTC_FEATURE_ALARM, rtc->features);
} }
static umode_t rtc_attr_is_visible(struct kobject *kobj, static umode_t rtc_attr_is_visible(struct kobject *kobj,
......
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