linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/16] rtc: rv3029: cleanup and features
@ 2019-12-14 22:10 Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 01/16] rtc: rv3029: use proper name for the driver Alexandre Belloni
                   ` (15 more replies)
  0 siblings, 16 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Hi,

This series cleans up the rv3029 driver and adds a few features:
RTC_VL_READ and RTC_VL_CLR support, correct rtc range enforcement, NVRAM
support.

This series depends on the previously sent RTC_VL_READ unification.

Alexandre Belloni (16):
  rtc: rv3029: use proper name for the driver
  rtc: rv3029: let regmap validate the register ranges
  rtc: rv3029: remove open coded regmap_update_bits
  rtc: rv3029: remove race condition when update STATUS
  rtc: rv3029: avoid reading the status register uselessly
  rtc: rv3029: get rid of rv3029_get_sr
  rtc: rv3029: simplify rv3029_alarm_irq_enable
  rtc: rv3029: simplify rv3029_set_alarm
  rtc: rv3029: drop rv3029_read_regs and rv3029_write_regs
  rtc: rv3029: add RTC_VL_READ and RTC_VL_CLEAR support
  rtc: rv3029: correctly handle PON and VLOW2
  rtc: rv3029: convert to devm_rtc_allocate_device
  rtc: rv3029: let the core handle rtc range
  rtc: rv3029: remove useless error messages
  rtc: rv3029: annotate init and exit functions
  rtc: rv3029: add nvram support

 drivers/rtc/rtc-rv3029c2.c | 444 +++++++++++++++----------------------
 include/linux/rtc.h        |   1 +
 2 files changed, 185 insertions(+), 260 deletions(-)

-- 
2.23.0


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/16] rtc: rv3029: use proper name for the driver
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 02/16] rtc: rv3029: let regmap validate the register ranges Alexandre Belloni
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

The correct name for the rtc is rv3029. c2 is actually the package form
factor rv3029c3 exists and simply has a smaller form factor.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 90a004c6398e..e68329eb5af2 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -879,7 +879,7 @@ MODULE_DEVICE_TABLE(of, rv3029_of_match);
 
 static struct i2c_driver rv3029_driver = {
 	.driver = {
-		.name = "rtc-rv3029c2",
+		.name = "rv3029",
 		.of_match_table = of_match_ptr(rv3029_of_match),
 	},
 	.probe		= rv3029_i2c_probe,
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/16] rtc: rv3029: let regmap validate the register ranges
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 01/16] rtc: rv3029: use proper name for the driver Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 03/16] rtc: rv3029: remove open coded regmap_update_bits Alexandre Belloni
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Instead of trying to validate the accessed registers in custom functions,
let regmap handle that. This allows to defines all the holes in the
register range and gives access to the regmap debugfs register dump.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 39 +++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index e68329eb5af2..aed28e29a5fd 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -126,10 +126,6 @@ static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
 {
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
-	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
-		return -EINVAL;
-
 	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
 
@@ -138,10 +134,6 @@ static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 {
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
-	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
-		return -EINVAL;
-
 	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
 
@@ -837,17 +829,34 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 	return 0;
 }
 
+static const struct regmap_range rv3029_holes_range[] = {
+	regmap_reg_range(0x05, 0x07),
+	regmap_reg_range(0x0f, 0x0f),
+	regmap_reg_range(0x17, 0x17),
+	regmap_reg_range(0x1a, 0x1f),
+	regmap_reg_range(0x21, 0x27),
+	regmap_reg_range(0x34, 0x37),
+};
+
+static const struct regmap_access_table rv3029_regs = {
+	.no_ranges =	rv3029_holes_range,
+	.n_no_ranges =	ARRAY_SIZE(rv3029_holes_range),
+};
+
+static const struct regmap_config config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.rd_table = &rv3029_regs,
+	.wr_table = &rv3029_regs,
+	.max_register = 0x3f,
+};
+
 #if IS_ENABLED(CONFIG_I2C)
 
 static int rv3029_i2c_probe(struct i2c_client *client,
 			    const struct i2c_device_id *id)
 {
 	struct regmap *regmap;
-	static const struct regmap_config config = {
-		.reg_bits = 8,
-		.val_bits = 8,
-	};
-
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
 				     I2C_FUNC_SMBUS_BYTE)) {
 		dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
@@ -913,10 +922,6 @@ static void rv3029_unregister_driver(void)
 
 static int rv3049_probe(struct spi_device *spi)
 {
-	static const struct regmap_config config = {
-		.reg_bits = 8,
-		.val_bits = 8,
-	};
 	struct regmap *regmap;
 
 	regmap = devm_regmap_init_spi(spi, &config);
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/16] rtc: rv3029: remove open coded regmap_update_bits
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 01/16] rtc: rv3029: use proper name for the driver Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 02/16] rtc: rv3029: let regmap validate the register ranges Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 04/16] rtc: rv3029: remove race condition when update STATUS Alexandre Belloni
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

rv3029_update_bits open codes regmap_update_bits and forgets to properly
lock the register range while doing so. Use regmap_update_bits instead.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 26 ++++++--------------------
 1 file changed, 6 insertions(+), 20 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index aed28e29a5fd..36b4da260caf 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -137,23 +137,6 @@ static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
 
-static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
-{
-	u8 buf;
-	int ret;
-
-	ret = rv3029_read_regs(dev, reg, &buf, 1);
-	if (ret < 0)
-		return ret;
-	buf &= ~mask;
-	buf |= set & mask;
-	ret = rv3029_write_regs(dev, reg, &buf, 1);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
 static int rv3029_get_sr(struct device *dev, u8 *buf)
 {
 	int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
@@ -200,14 +183,17 @@ static int rv3029_eeprom_busywait(struct device *dev)
 
 static int rv3029_eeprom_exit(struct device *dev)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+
 	/* Re-enable eeprom refresh */
-	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
+	return regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
 				  RV3029_ONOFF_CTRL_EERE,
 				  RV3029_ONOFF_CTRL_EERE);
 }
 
 static int rv3029_eeprom_enter(struct device *dev)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	int ret;
 	u8 sr;
 
@@ -236,8 +222,8 @@ static int rv3029_eeprom_enter(struct device *dev)
 	}
 
 	/* Disable eeprom refresh. */
-	ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE,
-				 0);
+	ret = regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
+				 RV3029_ONOFF_CTRL_EERE, 0);
 	if (ret < 0)
 		return ret;
 
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/16] rtc: rv3029: remove race condition when update STATUS
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (2 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 03/16] rtc: rv3029: remove open coded regmap_update_bits Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 05/16] rtc: rv3029: avoid reading the status register uselessly Alexandre Belloni
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

There is no lock preventing concurrent access to the status register from
bth the rtc subsystem and the hwmon subsystem. Use regmap_update_bits to
ensure updating RV3029_STATUS is properly locked.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 34 ++++++----------------------------
 1 file changed, 6 insertions(+), 28 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 36b4da260caf..4e7514433b79 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -147,19 +147,6 @@ static int rv3029_get_sr(struct device *dev, u8 *buf)
 	return 0;
 }
 
-static int rv3029_set_sr(struct device *dev, u8 val)
-{
-	u8 buf[1];
-	int sr;
-
-	buf[0] = val;
-	sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
-	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
-	if (sr < 0)
-		return -EIO;
-	return 0;
-}
-
 static int rv3029_eeprom_busywait(struct device *dev)
 {
 	int i, ret;
@@ -205,9 +192,9 @@ static int rv3029_eeprom_enter(struct device *dev)
 		/* We clear the bits and retry once just in case
 		 * we had a brown out in early startup.
 		 */
-		sr &= ~RV3029_STATUS_VLOW1;
-		sr &= ~RV3029_STATUS_VLOW2;
-		ret = rv3029_set_sr(dev, sr);
+		ret = regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+					 RV3029_STATUS_VLOW1 |
+					 RV3029_STATUS_VLOW2, 0);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
@@ -515,6 +502,7 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 
 static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	u8 regs[8];
 	int ret;
 
@@ -539,19 +527,9 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 	if (ret < 0)
 		return ret;
 
-	ret = rv3029_get_sr(dev, regs);
-	if (ret < 0) {
-		dev_err(dev, "%s: reading SR failed\n", __func__);
-		return ret;
-	}
 	/* clear PON bit */
-	ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
-	if (ret < 0) {
-		dev_err(dev, "%s: reading SR failed\n", __func__);
-		return ret;
-	}
-
-	return 0;
+	return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+				  RV3029_STATUS_PON, 0);
 }
 
 static const struct rv3029_trickle_tab_elem {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/16] rtc: rv3029: avoid reading the status register uselessly
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (3 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 04/16] rtc: rv3029: remove race condition when update STATUS Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 06/16] rtc: rv3029: get rid of rv3029_get_sr Alexandre Belloni
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

RV3029_STATUS is read in multiple location but its value is never used
afterwards. Avoid this register access when not necessary.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 26 --------------------------
 1 file changed, 26 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 4e7514433b79..0e0a10cbfd67 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -333,16 +333,9 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
 
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
-	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029_get_sr(dev, buf);
-	if (ret < 0) {
-		dev_err(dev, "%s: reading SR failed\n", __func__);
-		return -EIO;
-	}
-
 	ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
@@ -380,12 +373,6 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	int ret;
 	u8 regs[8], controls, flags;
 
-	ret = rv3029_get_sr(dev, regs);
-	if (ret < 0) {
-		dev_err(dev, "%s: reading SR failed\n", __func__);
-		return -EIO;
-	}
-
 	ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
 			       RV3029_ALARM_SECTION_LEN);
 
@@ -459,12 +446,6 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	ret = rv3029_get_sr(dev, regs);
-	if (ret < 0) {
-		dev_err(dev, "%s: reading SR failed\n", __func__);
-		return -EIO;
-	}
-
 	/* Activate all the alarms with AE_x bit */
 	regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
 	regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
@@ -748,7 +729,6 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 {
 	struct rv3029_data *rv3029;
 	int rc = 0;
-	u8 buf[1];
 
 	rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
 	if (!rv3029)
@@ -759,12 +739,6 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 	rv3029->dev = dev;
 	dev_set_drvdata(dev, rv3029);
 
-	rc = rv3029_get_sr(dev, buf);
-	if (rc < 0) {
-		dev_err(dev, "reading status failed\n");
-		return rc;
-	}
-
 	rv3029_trickle_config(dev);
 	rv3029_hwmon_register(dev, name);
 
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/16] rtc: rv3029: get rid of rv3029_get_sr
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (4 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 05/16] rtc: rv3029: avoid reading the status register uselessly Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 07/16] rtc: rv3029: simplify rv3029_alarm_irq_enable Alexandre Belloni
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

There is no point in having 2 indirections before calling regmap_read,
especially since rv3029_get_sr also changes the return value without any
good reason. Call regmap_read directly.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 0e0a10cbfd67..f92fbb4db173 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -137,23 +137,13 @@ static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
 
-static int rv3029_get_sr(struct device *dev, u8 *buf)
-{
-	int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
-
-	if (ret < 0)
-		return -EIO;
-	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
-	return 0;
-}
-
-static int rv3029_eeprom_busywait(struct device *dev)
+static int rv3029_eeprom_busywait(struct rv3029_data *rv3029)
 {
+	unsigned int sr;
 	int i, ret;
-	u8 sr;
 
 	for (i = 100; i > 0; i--) {
-		ret = rv3029_get_sr(dev, &sr);
+		ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -161,7 +151,7 @@ static int rv3029_eeprom_busywait(struct device *dev)
 		usleep_range(1000, 10000);
 	}
 	if (i <= 0) {
-		dev_err(dev, "EEPROM busy wait timeout.\n");
+		dev_err(rv3029->dev, "EEPROM busy wait timeout.\n");
 		return -ETIMEDOUT;
 	}
 
@@ -181,11 +171,11 @@ static int rv3029_eeprom_exit(struct device *dev)
 static int rv3029_eeprom_enter(struct device *dev)
 {
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	unsigned int sr;
 	int ret;
-	u8 sr;
 
 	/* Check whether we are in the allowed voltage range. */
-	ret = rv3029_get_sr(dev, &sr);
+	ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -198,7 +188,7 @@ static int rv3029_eeprom_enter(struct device *dev)
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret = rv3029_get_sr(dev, &sr);
+		ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -215,7 +205,7 @@ static int rv3029_eeprom_enter(struct device *dev)
 		return ret;
 
 	/* Wait for any previous eeprom accesses to finish. */
-	ret = rv3029_eeprom_busywait(dev);
+	ret = rv3029_eeprom_busywait(rv3029);
 	if (ret < 0)
 		rv3029_eeprom_exit(dev);
 
@@ -243,6 +233,7 @@ static int rv3029_eeprom_read(struct device *dev, u8 reg,
 static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			       u8 const buf[], size_t len)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	int ret, err;
 	size_t i;
 	u8 tmp;
@@ -260,7 +251,7 @@ static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			if (ret < 0)
 				break;
 		}
-		ret = rv3029_eeprom_busywait(dev);
+		ret = rv3029_eeprom_busywait(rv3029);
 		if (ret < 0)
 			break;
 	}
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/16] rtc: rv3029: simplify rv3029_alarm_irq_enable
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (5 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 06/16] rtc: rv3029: get rid of rv3029_get_sr Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 08/16] rtc: rv3029: simplify rv3029_set_alarm Alexandre Belloni
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Use regmap_update_bits instead of open coding it in
rv3029_alarm_irq_enable.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 25 ++++---------------------
 1 file changed, 4 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index f92fbb4db173..468542e98294 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -399,28 +399,11 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 
 static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
 {
-	int ret;
-	u8 controls;
-
-	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
-	if (ret < 0) {
-		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
-		return ret;
-	}
-
-	/* enable/disable AIE irq */
-	if (enable)
-		controls |= RV3029_IRQ_CTRL_AIE;
-	else
-		controls &= ~RV3029_IRQ_CTRL_AIE;
-
-	ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
-	if (ret < 0) {
-		dev_err(dev, "can't update INT reg\n");
-		return ret;
-	}
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
-	return 0;
+	return regmap_update_bits(rv3029->regmap, RV3029_IRQ_CTRL,
+				  RV3029_IRQ_CTRL_AIE,
+				  enable ? RV3029_IRQ_CTRL_AIE : 0);
 }
 
 static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/16] rtc: rv3029: simplify rv3029_set_alarm
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (6 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 07/16] rtc: rv3029: simplify rv3029_alarm_irq_enable Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 09/16] rtc: rv3029: drop rv3029_read_regs and rv3029_write_regs Alexandre Belloni
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

It is unecessay to test alarm->enabled before calling
rv3029_alarm_irq_enable.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 468542e98294..d41be87be4c5 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -440,19 +440,7 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (ret < 0)
 		return ret;
 
-	if (alarm->enabled) {
-		/* enable AIE irq */
-		ret = rv3029_alarm_irq_enable(dev, 1);
-		if (ret)
-			return ret;
-	} else {
-		/* disable AIE irq */
-		ret = rv3029_alarm_irq_enable(dev, 0);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
+	return rv3029_alarm_irq_enable(dev, alarm->enabled);
 }
 
 static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/16] rtc: rv3029: drop rv3029_read_regs and rv3029_write_regs
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (7 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 08/16] rtc: rv3029: simplify rv3029_set_alarm Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 10/16] rtc: rv3029: add RTC_VL_READ and RTC_VL_CLEAR support Alexandre Belloni
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

rv3029_read_regs and rv3029_write_regs are simply calling
regmap_bulk_{read,write}. Drop them and call regmap_{,bulk}_{read,write} as
appropriate.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 104 ++++++++++++++++---------------------
 1 file changed, 46 insertions(+), 58 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index d41be87be4c5..f327a7713e04 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -121,22 +121,6 @@ struct rv3029_data {
 	int irq;
 };
 
-static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
-			    unsigned int len)
-{
-	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
-
-	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
-}
-
-static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
-			     unsigned int len)
-{
-	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
-
-	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
-}
-
 static int rv3029_eeprom_busywait(struct rv3029_data *rv3029)
 {
 	unsigned int sr;
@@ -158,19 +142,16 @@ static int rv3029_eeprom_busywait(struct rv3029_data *rv3029)
 	return ret;
 }
 
-static int rv3029_eeprom_exit(struct device *dev)
+static int rv3029_eeprom_exit(struct rv3029_data *rv3029)
 {
-	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
-
 	/* Re-enable eeprom refresh */
 	return regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
 				  RV3029_ONOFF_CTRL_EERE,
 				  RV3029_ONOFF_CTRL_EERE);
 }
 
-static int rv3029_eeprom_enter(struct device *dev)
+static int rv3029_eeprom_enter(struct rv3029_data *rv3029)
 {
-	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	unsigned int sr;
 	int ret;
 
@@ -192,7 +173,7 @@ static int rv3029_eeprom_enter(struct device *dev)
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
-			dev_err(dev,
+			dev_err(rv3029->dev,
 				"Supply voltage is too low to safely access the EEPROM.\n");
 			return -ENODEV;
 		}
@@ -207,47 +188,47 @@ static int rv3029_eeprom_enter(struct device *dev)
 	/* Wait for any previous eeprom accesses to finish. */
 	ret = rv3029_eeprom_busywait(rv3029);
 	if (ret < 0)
-		rv3029_eeprom_exit(dev);
+		rv3029_eeprom_exit(rv3029);
 
 	return ret;
 }
 
-static int rv3029_eeprom_read(struct device *dev, u8 reg,
+static int rv3029_eeprom_read(struct rv3029_data *rv3029, u8 reg,
 			      u8 buf[], size_t len)
 {
 	int ret, err;
 
-	err = rv3029_eeprom_enter(dev);
+	err = rv3029_eeprom_enter(rv3029);
 	if (err < 0)
 		return err;
 
-	ret = rv3029_read_regs(dev, reg, buf, len);
+	ret = regmap_bulk_read(rv3029->regmap, reg, buf, len);
 
-	err = rv3029_eeprom_exit(dev);
+	err = rv3029_eeprom_exit(rv3029);
 	if (err < 0)
 		return err;
 
 	return ret;
 }
 
-static int rv3029_eeprom_write(struct device *dev, u8 reg,
+static int rv3029_eeprom_write(struct rv3029_data *rv3029, u8 reg,
 			       u8 const buf[], size_t len)
 {
-	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	unsigned int tmp;
 	int ret, err;
 	size_t i;
-	u8 tmp;
 
-	err = rv3029_eeprom_enter(dev);
+	err = rv3029_eeprom_enter(rv3029);
 	if (err < 0)
 		return err;
 
 	for (i = 0; i < len; i++, reg++) {
-		ret = rv3029_read_regs(dev, reg, &tmp, 1);
+		ret = regmap_read(rv3029->regmap, reg, &tmp);
 		if (ret < 0)
 			break;
 		if (tmp != buf[i]) {
-			ret = rv3029_write_regs(dev, reg, &buf[i], 1);
+			tmp = buf[i];
+			ret = regmap_write(rv3029->regmap, reg, tmp);
 			if (ret < 0)
 				break;
 		}
@@ -256,25 +237,25 @@ static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			break;
 	}
 
-	err = rv3029_eeprom_exit(dev);
+	err = rv3029_eeprom_exit(rv3029);
 	if (err < 0)
 		return err;
 
 	return ret;
 }
 
-static int rv3029_eeprom_update_bits(struct device *dev,
+static int rv3029_eeprom_update_bits(struct rv3029_data *rv3029,
 				     u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
 
-	ret = rv3029_eeprom_read(dev, reg, &buf, 1);
+	ret = rv3029_eeprom_read(rv3029, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &= ~mask;
 	buf |= set & mask;
-	ret = rv3029_eeprom_write(dev, reg, &buf, 1);
+	ret = rv3029_eeprom_write(rv3029, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 
@@ -286,20 +267,20 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
 	struct device *dev = dev_id;
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	struct mutex *lock = &rv3029->rtc->ops_lock;
+	unsigned int flags, controls;
 	unsigned long events = 0;
-	u8 flags, controls;
 	int ret;
 
 	mutex_lock(lock);
 
-	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
 	if (ret) {
 		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
 		mutex_unlock(lock);
 		return IRQ_NONE;
 	}
 
-	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
 	if (ret) {
 		dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
 		mutex_unlock(lock);
@@ -314,8 +295,8 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
 
 	if (events) {
 		rtc_update_irq(rv3029->rtc, 1, events);
-		rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
-		rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+		regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags);
+		regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls);
 	}
 	mutex_unlock(lock);
 
@@ -324,10 +305,11 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
 
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
+	ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
 		dev_err(dev, "%s: reading RTC section failed\n", __func__);
@@ -360,24 +342,25 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 
 static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	struct rtc_time *const tm = &alarm->time;
+	unsigned int controls, flags;
 	int ret;
-	u8 regs[8], controls, flags;
+	u8 regs[8];
 
-	ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
+	ret = regmap_bulk_read(rv3029->regmap, RV3029_A_SC, regs,
 			       RV3029_ALARM_SECTION_LEN);
-
 	if (ret < 0) {
 		dev_err(dev, "%s: reading alarm section failed\n", __func__);
 		return ret;
 	}
 
-	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
 	if (ret) {
 		dev_err(dev, "Read IRQ Control Register error %d\n", ret);
 		return ret;
 	}
-	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
 	if (ret < 0) {
 		dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
 		return ret;
@@ -408,6 +391,7 @@ static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
 
 static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -435,7 +419,7 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		| RV3029_A_AE_X;
 
 	/* Write the alarm */
-	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
+	ret = regmap_bulk_write(rv3029->regmap, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
@@ -465,7 +449,7 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 	regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
 	regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
 
-	ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
+	ret = regmap_bulk_write(rv3029->regmap, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
@@ -534,6 +518,7 @@ static const struct rv3029_trickle_tab_elem {
 
 static void rv3029_trickle_config(struct device *dev)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	struct device_node *of_node = dev->of_node;
 	const struct rv3029_trickle_tab_elem *elem;
 	int i, err;
@@ -560,7 +545,7 @@ static void rv3029_trickle_config(struct device *dev)
 			 "Trickle charger enabled at %d ohms resistance.\n",
 			 elem->r);
 	}
-	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
+	err = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
 	if (err < 0)
@@ -569,12 +554,12 @@ static void rv3029_trickle_config(struct device *dev)
 
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
 
-static int rv3029_read_temp(struct device *dev, int *temp_mC)
+static int rv3029_read_temp(struct rv3029_data *rv3029, int *temp_mC)
 {
+	unsigned int temp;
 	int ret;
-	u8 temp;
 
-	ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
+	ret = regmap_read(rv3029->regmap, RV3029_TEMP_PAGE, &temp);
 	if (ret < 0)
 		return ret;
 
@@ -587,9 +572,10 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
 				      struct device_attribute *attr,
 				      char *buf)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	int ret, temp_mC;
 
-	ret = rv3029_read_temp(dev, &temp_mC);
+	ret = rv3029_read_temp(rv3029, &temp_mC);
 	if (ret < 0)
 		return ret;
 
@@ -601,9 +587,10 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 						const char *buf,
 						size_t count)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	unsigned int th_set_bits = 0;
 	unsigned long interval_ms;
 	int ret;
-	u8 th_set_bits = 0;
 
 	ret = kstrtoul(buf, 10, &interval_ms);
 	if (ret < 0)
@@ -614,7 +601,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 		if (interval_ms >= 16000)
 			th_set_bits |= RV3029_EECTRL_THP;
 	}
-	ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_EECTRL_THE | RV3029_EECTRL_THP,
 					th_set_bits);
 	if (ret < 0)
@@ -627,10 +614,11 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
 						 struct device_attribute *attr,
 						 char *buf)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	int ret, interval_ms;
 	u8 eectrl;
 
-	ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_read(rv3029, RV3029_CONTROL_E2P_EECTRL,
 				 &eectrl, 1);
 	if (ret < 0)
 		return ret;
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/16] rtc: rv3029: add RTC_VL_READ and RTC_VL_CLEAR support
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (8 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 09/16] rtc: rv3029: drop rv3029_read_regs and rv3029_write_regs Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 11/16] rtc: rv3029: correctly handle PON and VLOW2 Alexandre Belloni
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

The RV3029 can report three different conditions: power on, voltage dropped
and data is lost and voltage is low and temperature compensation has
stopped. The first two conditions amount to the same status, the RTC data
is invalid.

VLOW1 has to be cleared manually to resume temperature compensation, this
is achieved using RTC_VL_CLEAR.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index f327a7713e04..6ae96baa111a 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -459,6 +459,35 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 				  RV3029_STATUS_PON, 0);
 }
 
+static int rv3029_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	unsigned long vl = 0;
+	int sr, ret = 0;
+
+	switch (cmd) {
+	case RTC_VL_READ:
+		ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
+		if (ret < 0)
+			return ret;
+
+		if (sr & RV3029_STATUS_VLOW1)
+			vl = RTC_VL_ACCURACY_LOW;
+
+		if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
+			vl |= RTC_VL_DATA_INVALID;
+
+		return put_user(vl, (unsigned int __user *)arg);
+
+	case RTC_VL_CLR:
+		return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+					  RV3029_STATUS_VLOW1, 0);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -672,6 +701,7 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
 static struct rtc_class_ops rv3029_rtc_ops = {
 	.read_time	= rv3029_read_time,
 	.set_time	= rv3029_set_time,
+	.ioctl		= rv3029_ioctl,
 };
 
 static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/16] rtc: rv3029: correctly handle PON and VLOW2
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (9 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 10/16] rtc: rv3029: add RTC_VL_READ and RTC_VL_CLEAR support Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 12/16] rtc: rv3029: convert to devm_rtc_allocate_device Alexandre Belloni
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

In case the data is invalid (PON or VLOW2 are set in STATUS, explicitly
tell userspace that the time is invalid. Only remove VLOW2 when setting a
new valid time.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 6ae96baa111a..433aad16897e 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -159,20 +159,21 @@ static int rv3029_eeprom_enter(struct rv3029_data *rv3029)
 	ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
 	if (ret < 0)
 		return ret;
-	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+	if (sr & RV3029_STATUS_VLOW2)
+		return -ENODEV;
+	if (sr & RV3029_STATUS_VLOW1) {
 		/* We clear the bits and retry once just in case
 		 * we had a brown out in early startup.
 		 */
 		ret = regmap_update_bits(rv3029->regmap, RV3029_STATUS,
-					 RV3029_STATUS_VLOW1 |
-					 RV3029_STATUS_VLOW2, 0);
+					 RV3029_STATUS_VLOW1, 0);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
 		ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
 		if (ret < 0)
 			return ret;
-		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+		if (sr & RV3029_STATUS_VLOW1) {
 			dev_err(rv3029->dev,
 				"Supply voltage is too low to safely access the EEPROM.\n");
 			return -ENODEV;
@@ -306,9 +307,17 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	unsigned int sr;
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
+	ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
+	if (ret < 0)
+		return ret;
+
+	if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
+		return -EINVAL;
+
 	ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
@@ -454,9 +463,9 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 	if (ret < 0)
 		return ret;
 
-	/* clear PON bit */
+	/* clear PON and VLOW2 bits */
 	return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
-				  RV3029_STATUS_PON, 0);
+				  RV3029_STATUS_PON | RV3029_STATUS_VLOW2, 0);
 }
 
 static int rv3029_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 12/16] rtc: rv3029: convert to devm_rtc_allocate_device
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (10 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 11/16] rtc: rv3029: correctly handle PON and VLOW2 Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 13/16] rtc: rv3029: let the core handle rtc range Alexandre Belloni
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

This allows further improvement of the driver.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 433aad16897e..555c88c2edbb 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -731,12 +731,9 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 	rv3029_trickle_config(dev);
 	rv3029_hwmon_register(dev, name);
 
-	rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
-					       THIS_MODULE);
-	if (IS_ERR(rv3029->rtc)) {
-		dev_err(dev, "unable to register the class device\n");
+	rv3029->rtc = devm_rtc_allocate_device(dev);
+	if (IS_ERR(rv3029->rtc))
 		return PTR_ERR(rv3029->rtc);
-	}
 
 	if (rv3029->irq > 0) {
 		rc = devm_request_threaded_irq(dev, rv3029->irq,
@@ -753,7 +750,9 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 		}
 	}
 
-	return 0;
+	rv3029->rtc->ops = &rv3029_rtc_ops;
+
+	return rtc_register_device(rv3029->rtc);
 }
 
 static const struct regmap_range rv3029_holes_range[] = {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 13/16] rtc: rv3029: let the core handle rtc range
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (11 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 12/16] rtc: rv3029: convert to devm_rtc_allocate_device Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 14/16] rtc: rv3029: remove useless error messages Alexandre Belloni
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Despite the comment, the RV3029 uses a 7bit BCD register for the year,
making 2079 the last supported year.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 18 ++----------------
 include/linux/rtc.h        |  1 +
 2 files changed, 3 insertions(+), 16 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 555c88c2edbb..001d98aa33cc 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -405,14 +405,6 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	int ret;
 	u8 regs[8];
 
-	/*
-	 * The clock has an 8 bit wide bcd-coded register (they never learn)
-	 * for the year. tm_year is an offset from 1900 and we are interested
-	 * in the 2000-2099 range, so any value less than 100 is invalid.
-	*/
-	if (tm->tm_year < 100)
-		return -EINVAL;
-
 	/* Activate all the alarms with AE_x bit */
 	regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
 	regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
@@ -442,14 +434,6 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 	u8 regs[8];
 	int ret;
 
-	/*
-	 * The clock has an 8 bit wide bcd-coded register (they never learn)
-	 * for the year. tm_year is an offset from 1900 and we are interested
-	 * in the 2000-2099 range, so any value less than 100 is invalid.
-	*/
-	if (tm->tm_year < 100)
-		return -EINVAL;
-
 	regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
 	regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
 	regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
@@ -751,6 +735,8 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 	}
 
 	rv3029->rtc->ops = &rv3029_rtc_ops;
+	rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+	rv3029->rtc->range_max = RTC_TIMESTAMP_END_2079;
 
 	return rtc_register_device(rv3029->rtc);
 }
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 4e9d3c71addb..23990bd29040 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -167,6 +167,7 @@ struct rtc_device {
 #define RTC_TIMESTAMP_BEGIN_1900	-2208988800LL /* 1900-01-01 00:00:00 */
 #define RTC_TIMESTAMP_BEGIN_2000	946684800LL /* 2000-01-01 00:00:00 */
 #define RTC_TIMESTAMP_END_2063		2966371199LL /* 2063-12-31 23:59:59 */
+#define RTC_TIMESTAMP_END_2079		3471292799LL /* 2079-12-31 23:59:59 */
 #define RTC_TIMESTAMP_END_2099		4102444799LL /* 2099-12-31 23:59:59 */
 #define RTC_TIMESTAMP_END_2199		7258118399LL /* 2199-12-31 23:59:59 */
 #define RTC_TIMESTAMP_END_9999		253402300799LL /* 9999-12-31 23:59:59 */
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 14/16] rtc: rv3029: remove useless error messages
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (12 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 13/16] rtc: rv3029: let the core handle rtc range Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 15/16] rtc: rv3029: annotate init and exit functions Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 16/16] rtc: rv3029: add nvram support Alexandre Belloni
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Remove redundant messages or messages that would not add any value because
the information is already conveyed properly using errno.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 37 +++++++++----------------------------
 1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 001d98aa33cc..b8d501abf2a7 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -320,10 +320,8 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 
 	ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
-	if (ret < 0) {
-		dev_err(dev, "%s: reading RTC section failed\n", __func__);
+	if (ret < 0)
 		return ret;
-	}
 
 	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
 	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
@@ -359,21 +357,16 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 
 	ret = regmap_bulk_read(rv3029->regmap, RV3029_A_SC, regs,
 			       RV3029_ALARM_SECTION_LEN);
-	if (ret < 0) {
-		dev_err(dev, "%s: reading alarm section failed\n", __func__);
+	if (ret < 0)
 		return ret;
-	}
 
 	ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
-	if (ret) {
-		dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+	if (ret)
 		return ret;
-	}
+
 	ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
-	if (ret < 0) {
-		dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+	if (ret < 0)
 		return ret;
-	}
 
 	tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
 	tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
@@ -776,11 +769,8 @@ static int rv3029_i2c_probe(struct i2c_client *client,
 	}
 
 	regmap = devm_regmap_init_i2c(client, &config);
-	if (IS_ERR(regmap)) {
-		dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
-			__func__, PTR_ERR(regmap));
+	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
-	}
 
 	return rv3029_probe(&client->dev, regmap, client->irq, client->name);
 }
@@ -837,11 +827,8 @@ static int rv3049_probe(struct spi_device *spi)
 	struct regmap *regmap;
 
 	regmap = devm_regmap_init_spi(spi, &config);
-	if (IS_ERR(regmap)) {
-		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
-			__func__, PTR_ERR(regmap));
+	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
-	}
 
 	return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
 }
@@ -881,16 +868,10 @@ static int __init rv30x9_init(void)
 	int ret;
 
 	ret = rv3029_register_driver();
-	if (ret) {
-		pr_err("Failed to register rv3029 driver: %d\n", ret);
+	if (ret)
 		return ret;
-	}
 
-	ret = rv3049_register_driver();
-	if (ret) {
-		pr_err("Failed to register rv3049 driver: %d\n", ret);
-		rv3029_unregister_driver();
-	}
+	return rv3049_register_driver();
 
 	return ret;
 }
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 15/16] rtc: rv3029: annotate init and exit functions
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (13 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 14/16] rtc: rv3029: remove useless error messages Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  2019-12-14 22:10 ` [PATCH 16/16] rtc: rv3029: add nvram support Alexandre Belloni
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

rv30{2,4}9_register_driver and rv30{2,4}9_unregister_driver are only called
from the init and exit functions of the module. Annotate them properly.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index b8d501abf2a7..5610ff562652 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -797,24 +797,24 @@ static struct i2c_driver rv3029_driver = {
 	.id_table	= rv3029_id,
 };
 
-static int rv3029_register_driver(void)
+static int __init rv3029_register_driver(void)
 {
 	return i2c_add_driver(&rv3029_driver);
 }
 
-static void rv3029_unregister_driver(void)
+static void __exit rv3029_unregister_driver(void)
 {
 	i2c_del_driver(&rv3029_driver);
 }
 
 #else
 
-static int rv3029_register_driver(void)
+static int __init rv3029_register_driver(void)
 {
 	return 0;
 }
 
-static void rv3029_unregister_driver(void)
+static void __exit rv3029_unregister_driver(void)
 {
 }
 
@@ -840,24 +840,24 @@ static struct spi_driver rv3049_driver = {
 	.probe   = rv3049_probe,
 };
 
-static int rv3049_register_driver(void)
+static int __init rv3049_register_driver(void)
 {
 	return spi_register_driver(&rv3049_driver);
 }
 
-static void rv3049_unregister_driver(void)
+static void __exit rv3049_unregister_driver(void)
 {
 	spi_unregister_driver(&rv3049_driver);
 }
 
 #else
 
-static int rv3049_register_driver(void)
+static int __init rv3049_register_driver(void)
 {
 	return 0;
 }
 
-static void rv3049_unregister_driver(void)
+static void __exit rv3049_unregister_driver(void)
 {
 }
 
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 16/16] rtc: rv3029: add nvram support
  2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
                   ` (14 preceding siblings ...)
  2019-12-14 22:10 ` [PATCH 15/16] rtc: rv3029: annotate init and exit functions Alexandre Belloni
@ 2019-12-14 22:10 ` Alexandre Belloni
  15 siblings, 0 replies; 17+ messages in thread
From: Alexandre Belloni @ 2019-12-14 22:10 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Export the 8 byte RAM using nvmem.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
 drivers/rtc/rtc-rv3029c2.c | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 5610ff562652..4eda0db72b66 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -109,10 +109,8 @@
 #define RV3029_CONTROL_E2P_TOV_MASK	0x3F /* XTAL turnover temp mask */
 
 /* user ram section */
-#define RV3029_USR1_RAM_PAGE		0x38
-#define RV3029_USR1_SECTION_LEN		0x04
-#define RV3029_USR2_RAM_PAGE		0x3C
-#define RV3029_USR2_SECTION_LEN		0x04
+#define RV3029_RAM_PAGE			0x38
+#define RV3029_RAM_SECTION_LEN		8
 
 struct rv3029_data {
 	struct device		*dev;
@@ -474,6 +472,18 @@ static int rv3029_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 	}
 }
 
+static int rv3029_nvram_write(void *priv, unsigned int offset, void *val,
+			      size_t bytes)
+{
+	return regmap_bulk_write(priv, RV3029_RAM_PAGE + offset, val, bytes);
+}
+
+static int rv3029_nvram_read(void *priv, unsigned int offset, void *val,
+			     size_t bytes)
+{
+	return regmap_bulk_read(priv, RV3029_RAM_PAGE + offset, val, bytes);
+}
+
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -694,6 +704,15 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 			const char *name)
 {
 	struct rv3029_data *rv3029;
+	struct nvmem_config nvmem_cfg = {
+		.name = "rv3029_nvram",
+		.word_size = 1,
+		.stride = 1,
+		.size = RV3029_RAM_SECTION_LEN,
+		.type = NVMEM_TYPE_BATTERY_BACKED,
+		.reg_read = rv3029_nvram_read,
+		.reg_write = rv3029_nvram_write,
+	};
 	int rc = 0;
 
 	rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
@@ -731,7 +750,14 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 	rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 	rv3029->rtc->range_max = RTC_TIMESTAMP_END_2079;
 
-	return rtc_register_device(rv3029->rtc);
+	rc = rtc_register_device(rv3029->rtc);
+	if (rc)
+		return rc;
+
+	nvmem_cfg.priv = rv3029->regmap;
+	rtc_nvmem_register(rv3029->rtc, &nvmem_cfg);
+
+	return 0;
 }
 
 static const struct regmap_range rv3029_holes_range[] = {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-12-14 22:11 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-14 22:10 [PATCH 00/16] rtc: rv3029: cleanup and features Alexandre Belloni
2019-12-14 22:10 ` [PATCH 01/16] rtc: rv3029: use proper name for the driver Alexandre Belloni
2019-12-14 22:10 ` [PATCH 02/16] rtc: rv3029: let regmap validate the register ranges Alexandre Belloni
2019-12-14 22:10 ` [PATCH 03/16] rtc: rv3029: remove open coded regmap_update_bits Alexandre Belloni
2019-12-14 22:10 ` [PATCH 04/16] rtc: rv3029: remove race condition when update STATUS Alexandre Belloni
2019-12-14 22:10 ` [PATCH 05/16] rtc: rv3029: avoid reading the status register uselessly Alexandre Belloni
2019-12-14 22:10 ` [PATCH 06/16] rtc: rv3029: get rid of rv3029_get_sr Alexandre Belloni
2019-12-14 22:10 ` [PATCH 07/16] rtc: rv3029: simplify rv3029_alarm_irq_enable Alexandre Belloni
2019-12-14 22:10 ` [PATCH 08/16] rtc: rv3029: simplify rv3029_set_alarm Alexandre Belloni
2019-12-14 22:10 ` [PATCH 09/16] rtc: rv3029: drop rv3029_read_regs and rv3029_write_regs Alexandre Belloni
2019-12-14 22:10 ` [PATCH 10/16] rtc: rv3029: add RTC_VL_READ and RTC_VL_CLEAR support Alexandre Belloni
2019-12-14 22:10 ` [PATCH 11/16] rtc: rv3029: correctly handle PON and VLOW2 Alexandre Belloni
2019-12-14 22:10 ` [PATCH 12/16] rtc: rv3029: convert to devm_rtc_allocate_device Alexandre Belloni
2019-12-14 22:10 ` [PATCH 13/16] rtc: rv3029: let the core handle rtc range Alexandre Belloni
2019-12-14 22:10 ` [PATCH 14/16] rtc: rv3029: remove useless error messages Alexandre Belloni
2019-12-14 22:10 ` [PATCH 15/16] rtc: rv3029: annotate init and exit functions Alexandre Belloni
2019-12-14 22:10 ` [PATCH 16/16] rtc: rv3029: add nvram support Alexandre Belloni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).