All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] rtc: ds1343: set range
@ 2019-10-19 20:49 Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 2/9] rtc: ds1343: remove dead code Alexandre Belloni
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

This is a standard BCD rtc with a useless century bit (no leap year
correction after 2099).

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index fa6de31d5793..b45d1b8fd631 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -520,6 +520,8 @@ static int ds1343_probe(struct spi_device *spi)
 
 	priv->rtc->nvram_old_abi = true;
 	priv->rtc->ops = &ds1343_rtc_ops;
+	priv->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+	priv->rtc->range_max = RTC_TIMESTAMP_END_2099;
 
 	res = rtc_register_device(priv->rtc);
 	if (res)
-- 
2.21.0


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

* [PATCH 2/9] rtc: ds1343: remove dead code
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 3/9] rtc: ds1343: use burst write to set time Alexandre Belloni
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

RTC_SET_CHARGE doesn't exist, the ioctl code is never used.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index b45d1b8fd631..9d7d571e722b 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -87,26 +87,6 @@ struct ds1343_priv {
 	int alarm_mday;
 };
 
-static int ds1343_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
-{
-	switch (cmd) {
-#ifdef RTC_SET_CHARGE
-	case RTC_SET_CHARGE:
-	{
-		int val;
-
-		if (copy_from_user(&val, (int __user *)arg, sizeof(int)))
-			return -EFAULT;
-
-		return regmap_write(priv->map, DS1343_TRICKLE_REG, val);
-	}
-	break;
-#endif
-	}
-
-	return -ENOIOCTLCMD;
-}
-
 static ssize_t ds1343_show_glitchfilter(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -452,7 +432,6 @@ static irqreturn_t ds1343_thread(int irq, void *dev_id)
 }
 
 static const struct rtc_class_ops ds1343_rtc_ops = {
-	.ioctl		= ds1343_ioctl,
 	.read_time	= ds1343_read_time,
 	.set_time	= ds1343_set_time,
 	.read_alarm	= ds1343_read_alarm,
-- 
2.21.0


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

* [PATCH 3/9] rtc: ds1343: use burst write to set time
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 2/9] rtc: ds1343: remove dead code Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 4/9] rtc: ds1343: use rtc_add_group Alexandre Belloni
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

To avoid possible race condition, use regmap_bulk_write to write all the
date/time registers at once instead of sequentially.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index 9d7d571e722b..8a4f1fbb57fd 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -236,46 +236,18 @@ static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
 static int ds1343_set_time(struct device *dev, struct rtc_time *dt)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev);
-	int res;
-
-	res = regmap_write(priv->map, DS1343_SECONDS_REG,
-				bin2bcd(dt->tm_sec));
-	if (res)
-		return res;
-
-	res = regmap_write(priv->map, DS1343_MINUTES_REG,
-				bin2bcd(dt->tm_min));
-	if (res)
-		return res;
-
-	res = regmap_write(priv->map, DS1343_HOURS_REG,
-				bin2bcd(dt->tm_hour) & 0x3F);
-	if (res)
-		return res;
-
-	res = regmap_write(priv->map, DS1343_DAY_REG,
-				bin2bcd(dt->tm_wday + 1));
-	if (res)
-		return res;
-
-	res = regmap_write(priv->map, DS1343_DATE_REG,
-				bin2bcd(dt->tm_mday));
-	if (res)
-		return res;
-
-	res = regmap_write(priv->map, DS1343_MONTH_REG,
-				bin2bcd(dt->tm_mon + 1));
-	if (res)
-		return res;
-
-	dt->tm_year %= 100;
-
-	res = regmap_write(priv->map, DS1343_YEAR_REG,
-				bin2bcd(dt->tm_year));
-	if (res)
-		return res;
-
-	return 0;
+	u8 buf[7];
+
+	buf[0] = bin2bcd(dt->tm_sec);
+	buf[1] = bin2bcd(dt->tm_min);
+	buf[2] = bin2bcd(dt->tm_hour) & 0x3F;
+	buf[3] = bin2bcd(dt->tm_wday + 1);
+	buf[4] = bin2bcd(dt->tm_mday);
+	buf[5] = bin2bcd(dt->tm_mon + 1);
+	buf[6] = bin2bcd(dt->tm_year - 100);
+
+	return regmap_bulk_write(priv->map, DS1343_SECONDS_REG,
+				 buf, sizeof(buf));
 }
 
 static int ds1343_update_alarm(struct device *dev)
-- 
2.21.0


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

* [PATCH 4/9] rtc: ds1343: use rtc_add_group
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 2/9] rtc: ds1343: remove dead code Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 3/9] rtc: ds1343: use burst write to set time Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 5/9] rtc: ds1343: use regmap_update_bits for glitch filter Alexandre Belloni
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Use rtc_add_group to add the sysfs group in a race free manner.
This has the side effect of moving the files to their proper location.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index 8a4f1fbb57fd..ec8d1e82d7ac 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -90,7 +90,7 @@ struct ds1343_priv {
 static ssize_t ds1343_show_glitchfilter(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	struct ds1343_priv *priv = dev_get_drvdata(dev);
+	struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
 	int glitch_filt_status, data;
 
 	regmap_read(priv->map, DS1343_CONTROL_REG, &data);
@@ -107,7 +107,7 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 {
-	struct ds1343_priv *priv = dev_get_drvdata(dev);
+	struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
 	int data;
 
 	regmap_read(priv->map, DS1343_CONTROL_REG, &data);
@@ -148,7 +148,7 @@ static int ds1343_nvram_read(void *priv, unsigned int off, void *val,
 static ssize_t ds1343_show_tricklecharger(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	struct ds1343_priv *priv = dev_get_drvdata(dev);
+	struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
 	int data;
 	char *diodes = "disabled", *resistors = " ";
 
@@ -189,28 +189,15 @@ static ssize_t ds1343_show_tricklecharger(struct device *dev,
 
 static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL);
 
-static int ds1343_sysfs_register(struct device *dev)
-{
-	int err;
-
-	err = device_create_file(dev, &dev_attr_glitch_filter);
-	if (err)
-		return err;
-
-	err = device_create_file(dev, &dev_attr_trickle_charger);
-	if (!err)
-		return 0;
-
-	device_remove_file(dev, &dev_attr_glitch_filter);
-
-	return err;
-}
+static struct attribute *ds1343_attrs[] = {
+	&dev_attr_glitch_filter.attr,
+	&dev_attr_trickle_charger.attr,
+	NULL
+};
 
-static void ds1343_sysfs_unregister(struct device *dev)
-{
-	device_remove_file(dev, &dev_attr_glitch_filter);
-	device_remove_file(dev, &dev_attr_trickle_charger);
-}
+static const struct attribute_group ds1343_attr_group = {
+	.attrs  = ds1343_attrs,
+};
 
 static int ds1343_read_time(struct device *dev, struct rtc_time *dt)
 {
@@ -474,6 +461,11 @@ static int ds1343_probe(struct spi_device *spi)
 	priv->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
 	priv->rtc->range_max = RTC_TIMESTAMP_END_2099;
 
+	res = rtc_add_group(priv->rtc, &ds1343_attr_group);
+	if (res)
+		dev_err(&spi->dev,
+			"unable to create sysfs entries for rtc ds1343\n");
+
 	res = rtc_register_device(priv->rtc);
 	if (res)
 		return res;
@@ -497,11 +489,6 @@ static int ds1343_probe(struct spi_device *spi)
 		}
 	}
 
-	res = ds1343_sysfs_register(&spi->dev);
-	if (res)
-		dev_err(&spi->dev,
-			"unable to create sysfs entries for rtc ds1343\n");
-
 	return 0;
 }
 
@@ -521,8 +508,6 @@ static int ds1343_remove(struct spi_device *spi)
 
 	spi_set_drvdata(spi, NULL);
 
-	ds1343_sysfs_unregister(&spi->dev);
-
 	return 0;
 }
 
-- 
2.21.0


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

* [PATCH 5/9] rtc: ds1343: use regmap_update_bits for glitch filter
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
                   ` (2 preceding siblings ...)
  2019-10-19 20:49 ` [PATCH 4/9] rtc: ds1343: use rtc_add_group Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 6/9] rtc: ds1343: check regmap_read return value Alexandre Belloni
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Use regmap_update_bits to update DS1343_CONTROL_REG in a race free manner
when setting the glitch filter.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index ec8d1e82d7ac..7532a2e8407e 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -108,20 +108,18 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev,
 					const char *buf, size_t count)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
-	int data;
-
-	regmap_read(priv->map, DS1343_CONTROL_REG, &data);
+	int data = 0;
+	int res;
 
 	if (strncmp(buf, "enabled", 7) == 0)
-		data |= DS1343_EGFIL;
-
-	else if (strncmp(buf, "disabled", 8) == 0)
-		data &= ~(DS1343_EGFIL);
-
-	else
+		data = DS1343_EGFIL;
+	else if (strncmp(buf, "disabled", 8))
 		return -EINVAL;
 
-	regmap_write(priv->map, DS1343_CONTROL_REG, data);
+	res = regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+				 DS1343_EGFIL, data);
+	if (res)
+		return res;
 
 	return count;
 }
-- 
2.21.0


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

* [PATCH 6/9] rtc: ds1343: check regmap_read return value
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
                   ` (3 preceding siblings ...)
  2019-10-19 20:49 ` [PATCH 5/9] rtc: ds1343: use regmap_update_bits for glitch filter Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 7/9] rtc: ds1343: remove unnecessary mutex Alexandre Belloni
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Check whether regmap_read fails before continuing in the sysfs .show
callbacks.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index 7532a2e8407e..c96a505972e6 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -92,8 +92,11 @@ static ssize_t ds1343_show_glitchfilter(struct device *dev,
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
 	int glitch_filt_status, data;
+	int res;
 
-	regmap_read(priv->map, DS1343_CONTROL_REG, &data);
+	res = regmap_read(priv->map, DS1343_CONTROL_REG, &data);
+	if (res)
+		return res;
 
 	glitch_filt_status = !!(data & DS1343_EGFIL);
 
@@ -147,10 +150,12 @@ static ssize_t ds1343_show_tricklecharger(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev->parent);
-	int data;
+	int res, data;
 	char *diodes = "disabled", *resistors = " ";
 
-	regmap_read(priv->map, DS1343_TRICKLE_REG, &data);
+	res = regmap_read(priv->map, DS1343_TRICKLE_REG, &data);
+	if (res)
+		return res;
 
 	if ((data & 0xf0) == DS1343_TRICKLE_MAGIC) {
 		switch (data & 0x0c) {
-- 
2.21.0


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

* [PATCH 7/9] rtc: ds1343: remove unnecessary mutex
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
                   ` (4 preceding siblings ...)
  2019-10-19 20:49 ` [PATCH 6/9] rtc: ds1343: check regmap_read return value Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 8/9] rtc: ds1343: rework interrupt handling Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 9/9] rtc: ds1343: cleanup .remove Alexandre Belloni
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Use rtc_lock and rtc_unlock to lock the rtc from the interrupt handler.
This removes the need for a driver specific lock.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index c96a505972e6..867187325d41 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -78,7 +78,6 @@ struct ds1343_priv {
 	struct spi_device *spi;
 	struct rtc_device *rtc;
 	struct regmap *map;
-	struct mutex mutex;
 	unsigned int irqen;
 	int irq;
 	int alarm_sec;
@@ -290,17 +289,15 @@ static int ds1343_update_alarm(struct device *dev)
 static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev);
-	int res = 0;
+	int res;
 	unsigned int stat;
 
 	if (priv->irq <= 0)
 		return -EINVAL;
 
-	mutex_lock(&priv->mutex);
-
 	res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
 	if (res)
-		goto out;
+		return res;
 
 	alarm->enabled = !!(priv->irqen & RTC_AF);
 	alarm->pending = !!(stat & DS1343_IRQF0);
@@ -310,21 +307,16 @@ static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour;
 	alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday;
 
-out:
-	mutex_unlock(&priv->mutex);
-	return res;
+	return 0;
 }
 
 static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev);
-	int res = 0;
 
 	if (priv->irq <= 0)
 		return -EINVAL;
 
-	mutex_lock(&priv->mutex);
-
 	priv->alarm_sec = alarm->time.tm_sec;
 	priv->alarm_min = alarm->time.tm_min;
 	priv->alarm_hour = alarm->time.tm_hour;
@@ -333,33 +325,22 @@ static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (alarm->enabled)
 		priv->irqen |= RTC_AF;
 
-	res = ds1343_update_alarm(dev);
-
-	mutex_unlock(&priv->mutex);
-
-	return res;
+	return ds1343_update_alarm(dev);
 }
 
 static int ds1343_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev);
-	int res = 0;
 
 	if (priv->irq <= 0)
 		return -EINVAL;
 
-	mutex_lock(&priv->mutex);
-
 	if (enabled)
 		priv->irqen |= RTC_AF;
 	else
 		priv->irqen &= ~RTC_AF;
 
-	res = ds1343_update_alarm(dev);
-
-	mutex_unlock(&priv->mutex);
-
-	return res;
+	return ds1343_update_alarm(dev);
 }
 
 static irqreturn_t ds1343_thread(int irq, void *dev_id)
@@ -368,7 +349,7 @@ static irqreturn_t ds1343_thread(int irq, void *dev_id)
 	unsigned int stat, control;
 	int res = 0;
 
-	mutex_lock(&priv->mutex);
+	rtc_lock(priv->rtc);
 
 	res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
 	if (res)
@@ -389,7 +370,7 @@ static irqreturn_t ds1343_thread(int irq, void *dev_id)
 	}
 
 out:
-	mutex_unlock(&priv->mutex);
+	rtc_unlock(priv->rtc);
 	return IRQ_HANDLED;
 }
 
@@ -422,7 +403,6 @@ static int ds1343_probe(struct spi_device *spi)
 		return -ENOMEM;
 
 	priv->spi = spi;
-	mutex_init(&priv->mutex);
 
 	/* RTC DS1347 works in spi mode 3 and
 	 * its chip select is active high
@@ -500,9 +480,7 @@ static int ds1343_remove(struct spi_device *spi)
 	struct ds1343_priv *priv = spi_get_drvdata(spi);
 
 	if (spi->irq) {
-		mutex_lock(&priv->mutex);
 		priv->irqen &= ~RTC_AF;
-		mutex_unlock(&priv->mutex);
 
 		dev_pm_clear_wake_irq(&spi->dev);
 		device_init_wakeup(&spi->dev, false);
-- 
2.21.0


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

* [PATCH 8/9] rtc: ds1343: rework interrupt handling
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
                   ` (5 preceding siblings ...)
  2019-10-19 20:49 ` [PATCH 7/9] rtc: ds1343: remove unnecessary mutex Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  2019-10-19 20:49 ` [PATCH 9/9] rtc: ds1343: cleanup .remove Alexandre Belloni
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

Rework the interrupt handling to avoid caching the values as the core is
already doing that. The core also always ensures the rtc_time passed for
the alarm is fully populated.

The only trick is in read_alarm where status needs to be read before the
alarm registers to ensure the potential irq is not cleared.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index 867187325d41..3e2957983703 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -78,12 +78,7 @@ struct ds1343_priv {
 	struct spi_device *spi;
 	struct rtc_device *rtc;
 	struct regmap *map;
-	unsigned int irqen;
 	int irq;
-	int alarm_sec;
-	int alarm_min;
-	int alarm_hour;
-	int alarm_mday;
 };
 
 static ssize_t ds1343_show_glitchfilter(struct device *dev,
@@ -239,93 +234,66 @@ static int ds1343_set_time(struct device *dev, struct rtc_time *dt)
 				 buf, sizeof(buf));
 }
 
-static int ds1343_update_alarm(struct device *dev)
+static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev);
-	unsigned int control, stat;
 	unsigned char buf[4];
-	int res = 0;
+	unsigned int val;
+	int res;
 
-	res = regmap_read(priv->map, DS1343_CONTROL_REG, &control);
-	if (res)
-		return res;
+	if (priv->irq <= 0)
+		return -EINVAL;
 
-	res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
+	res = regmap_read(priv->map, DS1343_STATUS_REG, &val);
 	if (res)
 		return res;
 
-	control &= ~(DS1343_A0IE);
-	stat &= ~(DS1343_IRQF0);
+	alarm->pending = !!(val & DS1343_IRQF0);
 
-	res = regmap_write(priv->map, DS1343_CONTROL_REG, control);
+	res = regmap_read(priv->map, DS1343_CONTROL_REG, &val);
 	if (res)
 		return res;
+	alarm->enabled = !!(val & DS1343_A0IE);
 
-	res = regmap_write(priv->map, DS1343_STATUS_REG, stat);
+	res = regmap_bulk_read(priv->map, DS1343_ALM0_SEC_REG, buf, 4);
 	if (res)
 		return res;
 
-	buf[0] = priv->alarm_sec < 0 || (priv->irqen & RTC_UF) ?
-		0x80 : bin2bcd(priv->alarm_sec) & 0x7F;
-	buf[1] = priv->alarm_min < 0 || (priv->irqen & RTC_UF) ?
-		0x80 : bin2bcd(priv->alarm_min) & 0x7F;
-	buf[2] = priv->alarm_hour < 0 || (priv->irqen & RTC_UF) ?
-		0x80 : bin2bcd(priv->alarm_hour) & 0x3F;
-	buf[3] = priv->alarm_mday < 0 || (priv->irqen & RTC_UF) ?
-		0x80 : bin2bcd(priv->alarm_mday) & 0x7F;
-
-	res = regmap_bulk_write(priv->map, DS1343_ALM0_SEC_REG, buf, 4);
-	if (res)
-		return res;
+	alarm->time.tm_sec = bcd2bin(buf[0]) & 0x7f;
+	alarm->time.tm_min = bcd2bin(buf[1]) & 0x7f;
+	alarm->time.tm_hour = bcd2bin(buf[2]) & 0x3f;
+	alarm->time.tm_mday = bcd2bin(buf[3]) & 0x3f;
 
-	if (priv->irqen) {
-		control |= DS1343_A0IE;
-		res = regmap_write(priv->map, DS1343_CONTROL_REG, control);
-	}
-
-	return res;
+	return 0;
 }
 
-static int ds1343_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct ds1343_priv *priv = dev_get_drvdata(dev);
-	int res;
-	unsigned int stat;
+	unsigned char buf[4];
+	int res = 0;
 
 	if (priv->irq <= 0)
 		return -EINVAL;
 
-	res = regmap_read(priv->map, DS1343_STATUS_REG, &stat);
+	res = regmap_update_bits(priv->map, DS1343_CONTROL_REG, DS1343_A0IE, 0);
 	if (res)
 		return res;
 
-	alarm->enabled = !!(priv->irqen & RTC_AF);
-	alarm->pending = !!(stat & DS1343_IRQF0);
+	buf[0] = bin2bcd(alarm->time.tm_sec);
+	buf[1] = bin2bcd(alarm->time.tm_min);
+	buf[2] = bin2bcd(alarm->time.tm_hour);
+	buf[3] = bin2bcd(alarm->time.tm_mday);
 
-	alarm->time.tm_sec = priv->alarm_sec < 0 ? 0 : priv->alarm_sec;
-	alarm->time.tm_min = priv->alarm_min < 0 ? 0 : priv->alarm_min;
-	alarm->time.tm_hour = priv->alarm_hour < 0 ? 0 : priv->alarm_hour;
-	alarm->time.tm_mday = priv->alarm_mday < 0 ? 0 : priv->alarm_mday;
-
-	return 0;
-}
-
-static int ds1343_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	struct ds1343_priv *priv = dev_get_drvdata(dev);
-
-	if (priv->irq <= 0)
-		return -EINVAL;
-
-	priv->alarm_sec = alarm->time.tm_sec;
-	priv->alarm_min = alarm->time.tm_min;
-	priv->alarm_hour = alarm->time.tm_hour;
-	priv->alarm_mday = alarm->time.tm_mday;
+	res = regmap_bulk_write(priv->map, DS1343_ALM0_SEC_REG, buf, 4);
+	if (res)
+		return res;
 
 	if (alarm->enabled)
-		priv->irqen |= RTC_AF;
+		res = regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+					 DS1343_A0IE, DS1343_A0IE);
 
-	return ds1343_update_alarm(dev);
+	return res;
 }
 
 static int ds1343_alarm_irq_enable(struct device *dev, unsigned int enabled)
@@ -335,18 +303,14 @@ static int ds1343_alarm_irq_enable(struct device *dev, unsigned int enabled)
 	if (priv->irq <= 0)
 		return -EINVAL;
 
-	if (enabled)
-		priv->irqen |= RTC_AF;
-	else
-		priv->irqen &= ~RTC_AF;
-
-	return ds1343_update_alarm(dev);
+	return regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+				  DS1343_A0IE, enabled ? DS1343_A0IE : 0);
 }
 
 static irqreturn_t ds1343_thread(int irq, void *dev_id)
 {
 	struct ds1343_priv *priv = dev_id;
-	unsigned int stat, control;
+	unsigned int stat;
 	int res = 0;
 
 	rtc_lock(priv->rtc);
@@ -359,14 +323,10 @@ static irqreturn_t ds1343_thread(int irq, void *dev_id)
 		stat &= ~DS1343_IRQF0;
 		regmap_write(priv->map, DS1343_STATUS_REG, stat);
 
-		res = regmap_read(priv->map, DS1343_CONTROL_REG, &control);
-		if (res)
-			goto out;
-
-		control &= ~DS1343_A0IE;
-		regmap_write(priv->map, DS1343_CONTROL_REG, control);
-
 		rtc_update_irq(priv->rtc, 1, RTC_AF | RTC_IRQF);
+
+		regmap_update_bits(priv->map, DS1343_CONTROL_REG,
+				   DS1343_A0IE, 0);
 	}
 
 out:
@@ -480,8 +440,6 @@ static int ds1343_remove(struct spi_device *spi)
 	struct ds1343_priv *priv = spi_get_drvdata(spi);
 
 	if (spi->irq) {
-		priv->irqen &= ~RTC_AF;
-
 		dev_pm_clear_wake_irq(&spi->dev);
 		device_init_wakeup(&spi->dev, false);
 		devm_free_irq(&spi->dev, spi->irq, priv);
-- 
2.21.0


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

* [PATCH 9/9] rtc: ds1343: cleanup .remove
  2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
                   ` (6 preceding siblings ...)
  2019-10-19 20:49 ` [PATCH 8/9] rtc: ds1343: rework interrupt handling Alexandre Belloni
@ 2019-10-19 20:49 ` Alexandre Belloni
  7 siblings, 0 replies; 9+ messages in thread
From: Alexandre Belloni @ 2019-10-19 20:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

It is not necessary to call device_init_wakeup(dev, false) in .remove as
device_del will take care of that. It is also not necessary to
devm_free_irq. Finally, dev_pm_clear_wake_irq can be called
unconditionally.

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

diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c
index 3e2957983703..73513688f6f7 100644
--- a/drivers/rtc/rtc-ds1343.c
+++ b/drivers/rtc/rtc-ds1343.c
@@ -437,15 +437,7 @@ static int ds1343_probe(struct spi_device *spi)
 
 static int ds1343_remove(struct spi_device *spi)
 {
-	struct ds1343_priv *priv = spi_get_drvdata(spi);
-
-	if (spi->irq) {
-		dev_pm_clear_wake_irq(&spi->dev);
-		device_init_wakeup(&spi->dev, false);
-		devm_free_irq(&spi->dev, spi->irq, priv);
-	}
-
-	spi_set_drvdata(spi, NULL);
+	dev_pm_clear_wake_irq(&spi->dev);
 
 	return 0;
 }
-- 
2.21.0


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

end of thread, other threads:[~2019-10-19 20:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-19 20:49 [PATCH 1/9] rtc: ds1343: set range Alexandre Belloni
2019-10-19 20:49 ` [PATCH 2/9] rtc: ds1343: remove dead code Alexandre Belloni
2019-10-19 20:49 ` [PATCH 3/9] rtc: ds1343: use burst write to set time Alexandre Belloni
2019-10-19 20:49 ` [PATCH 4/9] rtc: ds1343: use rtc_add_group Alexandre Belloni
2019-10-19 20:49 ` [PATCH 5/9] rtc: ds1343: use regmap_update_bits for glitch filter Alexandre Belloni
2019-10-19 20:49 ` [PATCH 6/9] rtc: ds1343: check regmap_read return value Alexandre Belloni
2019-10-19 20:49 ` [PATCH 7/9] rtc: ds1343: remove unnecessary mutex Alexandre Belloni
2019-10-19 20:49 ` [PATCH 8/9] rtc: ds1343: rework interrupt handling Alexandre Belloni
2019-10-19 20:49 ` [PATCH 9/9] rtc: ds1343: cleanup .remove Alexandre Belloni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.