RTC for 5.13
Subsystem: - UIE emulation has been reworked to avoid calling drivers callbacks when it is known it will not work Drivers: - ab-eoz9: add alarm support - pcf8523: add alarm support -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEycoQi/giopmpPgB12wIijOdRNOUFAmCPH5wACgkQ2wIijOdR NOWAww//VddoUhaGKYO7AdJ94XHgAU+LDncp30QB7KRJaBY8Cj6J/SqFi30bC93b 6Zp7Tbs2YFOCOTr3UPNvh9MxiwIWPLDXN6o8QzwoNpM8LfuODGaUe3QIu014ij96 hBQK9vDb6RE7db5Slr1w1kpdvC22esTwPrsT4+vbMkCyvoC3IZZork5xlrG+bP/A 0FCyCL6JW3pPfVptwOZ0lj5KbWU4SNdTztKtkm0T6tzCTSQWMrBSidENdWerPj68 TP1vtCewC7rl5JZWvdL9ZBATcIsPcysav00dUY21LJKcXVYUNmhSjA1xvKj2mBxC liQCLR1ejWP72ED9MISzgu17LNcBTM6RMDlprRF02KUL3kOvi4h9iTEQt3ROWd9V yh7qjIfNrxPCXNmZkNjeQcOSF2T+uEv/thPi0DkVXgwfIxCgD6Uwx+NqiucUvnfl 5bzdiDvaMTvGu23glGnEI80H1Y0Q8CoU0uKXPFzLCaH7cLZZNxk0SfXvD7/hFdR8 zVh64Zyheszo91EcVVtHEQ4guiGYnvr+/LAU3/VFmdFT+ZSVbmwLn65bBQUdfLzT 8l/18xMplYZtlBvhwu1KyHTWLeJGS39s7oYnbtyIGqKjknjIj+6hasuvcJWLd5Vi 8Xubu8EU2Qf0lcDl22LEI0Ijpm4IZO7CJ36YakkilLjad12jAps= =twkQ -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
a7efd197bc
|
@ -0,0 +1,62 @@
|
|||
# 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
|
|||
config RTC_DRV_IMXDI
|
||||
tristate "Freescale IMX DryIce Real Time Clock"
|
||||
depends on ARCH_MXC
|
||||
depends on OF
|
||||
help
|
||||
Support for Freescale IMX DryIce RTC
|
||||
|
||||
|
@ -1906,7 +1907,7 @@ config RTC_DRV_HID_SENSOR_TIME
|
|||
|
||||
config RTC_DRV_GOLDFISH
|
||||
tristate "Goldfish Real Time Clock"
|
||||
depends on OF && HAS_IOMEM
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
Say yes to enable RTC driver for the Goldfish based virtual platform.
|
||||
|
||||
|
|
|
@ -545,7 +545,7 @@ EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable);
|
|||
|
||||
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);
|
||||
if (err)
|
||||
|
@ -561,17 +561,21 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
|
|||
if (rtc->uie_rtctimer.enabled == enabled)
|
||||
goto out;
|
||||
|
||||
if (rtc->uie_unsupported) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
if (rtc->uie_unsupported || !test_bit(RTC_FEATURE_ALARM, rtc->features)) {
|
||||
mutex_unlock(&rtc->ops_lock);
|
||||
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
|
||||
return rtc_dev_update_irq_enable_emul(rtc, enabled);
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
struct rtc_time tm;
|
||||
ktime_t now, onesec;
|
||||
|
||||
rc = __rtc_read_time(rtc, &tm);
|
||||
if (rc)
|
||||
err = __rtc_read_time(rtc, &tm);
|
||||
if (err)
|
||||
goto out;
|
||||
onesec = ktime_set(1, 0);
|
||||
now = rtc_tm_to_ktime(tm);
|
||||
|
@ -585,24 +589,6 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
|
|||
out:
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtc_update_irq_enable);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/bcd.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
|
||||
|
@ -57,6 +58,24 @@
|
|||
|
||||
#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 ABEOZ953_TEMP_MAX 120
|
||||
#define ABEOZ953_TEMP_MIN -60
|
||||
|
@ -186,6 +205,98 @@ static int abeoz9_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
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)
|
||||
{
|
||||
u32 ohms = 0;
|
||||
|
@ -258,12 +369,16 @@ static int abeoz9_rtc_setup(struct device *dev, struct device_node *node)
|
|||
|
||||
static const struct rtc_class_ops rtc_ops = {
|
||||
.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 = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0x3f,
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_HWMON)
|
||||
|
@ -419,6 +534,24 @@ static int abeoz9_probe(struct i2c_client *client,
|
|||
data->rtc->ops = &rtc_ops;
|
||||
data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
|
||||
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);
|
||||
if (ret)
|
||||
|
|
|
@ -169,9 +169,6 @@ enum ds_type {
|
|||
|
||||
struct ds1307 {
|
||||
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 regmap *regmap;
|
||||
const char *name;
|
||||
|
@ -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);
|
||||
tmp = regs[DS1307_REG_HOUR] & 0x3f;
|
||||
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);
|
||||
tmp = regs[DS1307_REG_MONTH] & 0x1f;
|
||||
t->tm_mon = bcd2bin(tmp) - 1;
|
||||
|
@ -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_MIN] = bin2bcd(t->tm_min);
|
||||
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_MONTH] = bin2bcd(t->tm_mon + 1);
|
||||
|
||||
|
@ -411,9 +416,6 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
int ret;
|
||||
u8 regs[9];
|
||||
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -EINVAL;
|
||||
|
||||
/* read all ALARM1, ALARM2, and status registers at once */
|
||||
ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS,
|
||||
regs, sizeof(regs));
|
||||
|
@ -454,9 +456,6 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
u8 control, status;
|
||||
int ret;
|
||||
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -EINVAL;
|
||||
|
||||
dev_dbg(dev, "%s secs=%d, mins=%d, "
|
||||
"hours=%d, mday=%d, enabled=%d, pending=%d\n",
|
||||
"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)
|
|||
{
|
||||
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,
|
||||
DS1337_BIT_A1IE,
|
||||
enabled ? DS1337_BIT_A1IE : 0);
|
||||
|
@ -592,9 +588,6 @@ static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
u8 ald[3], ctl[3];
|
||||
int ret;
|
||||
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -EINVAL;
|
||||
|
||||
/* Read alarm registers. */
|
||||
ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald,
|
||||
sizeof(ald));
|
||||
|
@ -634,9 +627,6 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
u8 ald[3], ctl[3];
|
||||
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 "
|
||||
"enabled=%d pending=%d\n", __func__,
|
||||
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)
|
|||
struct ds1307 *ds1307 = dev_get_drvdata(dev);
|
||||
int ret, reg;
|
||||
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -EINVAL;
|
||||
|
||||
ret = regmap_read(ds1307->regmap, RX8130_REG_CONTROL0, ®);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -735,9 +722,6 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
u8 regs[10];
|
||||
int ret;
|
||||
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -EINVAL;
|
||||
|
||||
/* Read control and alarm 0 registers. */
|
||||
ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs,
|
||||
sizeof(regs));
|
||||
|
@ -793,9 +777,6 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
|
|||
unsigned char regs[10];
|
||||
int wday, ret;
|
||||
|
||||
if (!test_bit(HAS_ALARM, &ds1307->flags))
|
||||
return -EINVAL;
|
||||
|
||||
wday = mcp794xx_alm_weekday(dev, &t->time);
|
||||
if (wday < 0)
|
||||
return wday;
|
||||
|
@ -842,9 +823,6 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled)
|
|||
{
|
||||
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,
|
||||
MCP794XX_BIT_ALM0_EN,
|
||||
enabled ? MCP794XX_BIT_ALM0_EN : 0);
|
||||
|
@ -1641,7 +1619,7 @@ static int ds3231_clks_register(struct ds1307 *ds1307)
|
|||
* Interrupt signal due to alarm conditions and square-wave
|
||||
* 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;
|
||||
|
||||
init.name = ds3231_clks_names[i];
|
||||
|
@ -1964,15 +1942,15 @@ static int ds1307_probe(struct i2c_client *client,
|
|||
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);
|
||||
if (IS_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) {
|
||||
dev_info(ds1307->dev,
|
||||
"'wakeup-source' is set, request for an IRQ is disabled!\n");
|
||||
|
@ -1988,7 +1966,7 @@ static int ds1307_probe(struct i2c_client *client,
|
|||
if (err) {
|
||||
client->irq = 0;
|
||||
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");
|
||||
} else {
|
||||
dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq);
|
||||
|
|
|
@ -104,12 +104,6 @@ rtc_write(uint8_t val, uint32_t reg)
|
|||
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
|
||||
rtc_read(enum ds1511reg reg)
|
||||
{
|
||||
|
|
|
@ -310,6 +310,7 @@ static const struct of_device_id ftm_rtc_match[] = {
|
|||
{ .compatible = "fsl,lx2160a-ftm-alarm", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ftm_rtc_match);
|
||||
|
||||
static const struct acpi_device_id ftm_imx_acpi_ids[] = {
|
||||
{"NXP0014",},
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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 = {
|
||||
.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,
|
||||
};
|
||||
|
|
|
@ -840,19 +840,17 @@ static int __exit dryice_rtc_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id dryice_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx25-rtc" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, dryice_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver dryice_rtc_driver = {
|
||||
.driver = {
|
||||
.name = "imxdi_rtc",
|
||||
.of_match_table = of_match_ptr(dryice_dt_ids),
|
||||
.of_match_table = dryice_dt_ids,
|
||||
},
|
||||
.remove = __exit_p(dryice_rtc_remove),
|
||||
};
|
||||
|
|
|
@ -421,7 +421,7 @@ static int m48t59_rtc_probe(struct platform_device *pdev)
|
|||
/* Try to get irq number. We also can work in
|
||||
* the mode without IRQ.
|
||||
*/
|
||||
m48t59->irq = platform_get_irq(pdev, 0);
|
||||
m48t59->irq = platform_get_irq_optional(pdev, 0);
|
||||
if (m48t59->irq <= 0)
|
||||
m48t59->irq = NO_IRQ;
|
||||
|
||||
|
|
|
@ -415,7 +415,7 @@ static int mxc_rtc_probe(struct platform_device *pdev)
|
|||
static struct platform_driver mxc_rtc_driver = {
|
||||
.driver = {
|
||||
.name = "mxc_rtc",
|
||||
.of_match_table = of_match_ptr(imx_rtc_dt_ids),
|
||||
.of_match_table = imx_rtc_dt_ids,
|
||||
},
|
||||
.probe = mxc_rtc_probe,
|
||||
};
|
||||
|
|
|
@ -786,8 +786,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
|
|||
/* enable RTC functional clock */
|
||||
if (rtc->type->has_32kclk_en) {
|
||||
reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
|
||||
rtc_writel(rtc, OMAP_RTC_OSC_REG,
|
||||
reg | OMAP_RTC_OSC_32KCLK_EN);
|
||||
rtc_write(rtc, OMAP_RTC_OSC_REG, reg | OMAP_RTC_OSC_32KCLK_EN);
|
||||
}
|
||||
|
||||
/* clear old status */
|
||||
|
@ -845,7 +844,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
|
|||
reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
|
||||
reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
|
||||
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);
|
||||
|
|
|
@ -478,6 +478,7 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
|
|||
{
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
struct device_node *node = pcf85063->rtc->dev.parent->of_node;
|
||||
|
||||
init.name = "pcf85063-clkout";
|
||||
init.ops = &pcf85063_clkout_ops;
|
||||
|
@ -487,15 +488,13 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
|
|||
pcf85063->clkout_hw.init = &init;
|
||||
|
||||
/* optional override of the clockname */
|
||||
of_property_read_string(pcf85063->rtc->dev.of_node,
|
||||
"clock-output-names", &init.name);
|
||||
of_property_read_string(node, "clock-output-names", &init.name);
|
||||
|
||||
/* register the clock */
|
||||
clk = devm_clk_register(&pcf85063->rtc->dev, &pcf85063->clkout_hw);
|
||||
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(pcf85063->rtc->dev.of_node,
|
||||
of_clk_src_simple_get, clk);
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#define DRIVER_NAME "rtc-pcf8523"
|
||||
#include <linux/pm_wakeirq.h>
|
||||
|
||||
#define REG_CONTROL1 0x00
|
||||
#define REG_CONTROL1_CAP_SEL BIT(7)
|
||||
#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_PM_BLD BIT(7) /* battery low detection disabled */
|
||||
|
@ -32,9 +35,22 @@
|
|||
#define REG_MONTHS 0x08
|
||||
#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_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)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
|
@ -140,6 +156,27 @@ static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
|
|||
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)
|
||||
{
|
||||
u8 value;
|
||||
|
@ -259,11 +296,118 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
|||
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
|
||||
static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
unsigned int flags = 0;
|
||||
u8 value;
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
|
@ -272,9 +416,16 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|||
if (ret < 0)
|
||||
return 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:
|
||||
return -ENOIOCTLCMD;
|
||||
|
@ -322,6 +473,9 @@ static int pcf8523_rtc_set_offset(struct device *dev, long offset)
|
|||
static const struct rtc_class_ops pcf8523_rtc_ops = {
|
||||
.read_time = pcf8523_rtc_read_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,
|
||||
.read_offset = pcf8523_rtc_read_offset,
|
||||
.set_offset = pcf8523_rtc_set_offset,
|
||||
|
@ -330,12 +484,21 @@ static const struct rtc_class_ops pcf8523_rtc_ops = {
|
|||
static int pcf8523_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct pcf8523 *pcf8523;
|
||||
struct rtc_device *rtc;
|
||||
bool wakeup_source = false;
|
||||
int err;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
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);
|
||||
if (err < 0)
|
||||
dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
|
||||
|
@ -349,9 +512,32 @@ static int pcf8523_probe(struct i2c_client *client,
|
|||
if (IS_ERR(rtc))
|
||||
return PTR_ERR(rtc);
|
||||
|
||||
pcf8523->rtc = rtc;
|
||||
rtc->ops = &pcf8523_rtc_ops;
|
||||
rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
|
||||
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);
|
||||
}
|
||||
|
@ -373,7 +559,7 @@ MODULE_DEVICE_TABLE(of, pcf8523_of_match);
|
|||
|
||||
static struct i2c_driver pcf8523_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.name = "rtc-pcf8523",
|
||||
.of_match_table = of_match_ptr(pcf8523_of_match),
|
||||
},
|
||||
.probe = pcf8523_probe,
|
||||
|
|
|
@ -445,6 +445,16 @@ static const struct pm8xxx_rtc_regs pm8941_regs = {
|
|||
.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
|
||||
*/
|
||||
|
@ -453,6 +463,7 @@ static const struct of_device_id pm8xxx_id_table[] = {
|
|||
{ .compatible = "qcom,pm8018-rtc", .data = &pm8921_regs },
|
||||
{ .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs },
|
||||
{ .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs },
|
||||
{ .compatible = "qcom,pmk8350-rtc", .data = &pmk8350_regs },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
|
||||
|
|
|
@ -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_min = bcd2bin(date[RV3028_MIN] & 0x7f);
|
||||
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_mon = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1;
|
||||
tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100;
|
||||
|
@ -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_MIN] = bin2bcd(tm->tm_min);
|
||||
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_MONTH] = bin2bcd(tm->tm_mon + 1);
|
||||
date[RV3028_YEAR] = bin2bcd(tm->tm_year - 100);
|
||||
|
|
|
@ -447,6 +447,12 @@ static int rx6110_i2c_probe(struct i2c_client *client,
|
|||
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[] = {
|
||||
{ "rx6110", 0 },
|
||||
{ }
|
||||
|
@ -456,6 +462,7 @@ MODULE_DEVICE_TABLE(i2c, rx6110_i2c_id);
|
|||
static struct i2c_driver rx6110_i2c_driver = {
|
||||
.driver = {
|
||||
.name = RX6110_DRIVER_NAME,
|
||||
.acpi_match_table = rx6110_i2c_acpi_match,
|
||||
},
|
||||
.probe = rx6110_i2c_probe,
|
||||
.id_table = rx6110_i2c_id,
|
||||
|
|
|
@ -713,16 +713,10 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
|
|||
static int s5m_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
|
||||
struct sec_platform_data *pdata = s5m87xx->pdata;
|
||||
struct s5m_rtc_info *info;
|
||||
const struct regmap_config *regmap_cfg;
|
||||
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);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
struct spear_rtc_config *config = dev_id;
|
||||
unsigned long flags, events = 0;
|
||||
unsigned long events = 0;
|
||||
unsigned int irq_data;
|
||||
|
||||
spin_lock_irqsave(&config->lock, flags);
|
||||
spin_lock(&config->lock);
|
||||
irq_data = readl(config->ioaddr + STATUS_REG);
|
||||
spin_unlock_irqrestore(&config->lock, flags);
|
||||
spin_unlock(&config->lock);
|
||||
|
||||
if ((irq_data & RTC_INT_MASK)) {
|
||||
spear_rtc_clear_interrupt(config);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/rtc.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/tps65910.h>
|
||||
|
|
|
@ -273,7 +273,7 @@ static bool rtc_does_wakealarm(struct rtc_device *rtc)
|
|||
if (!device_can_wakeup(rtc->dev.parent))
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue