Commit a7efd197 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
# 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>;
        };
      };
    };
...
+2 −1
Original line number Diff line number Diff line
@@ -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.

+10 −24
Original line number Diff line number Diff line
@@ -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);
+134 −1
Original line number Diff line number Diff line
@@ -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;
@@ -259,11 +370,15 @@ 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,
	.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)
+17 −39
Original line number Diff line number Diff line
@@ -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,6 +293,10 @@ 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);
	/* 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;
@@ -343,6 +344,10 @@ 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);
	/* 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, &reg);
	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);
Loading