From 16486d0c1c659d4ab502c5bea408654287edcb74 Mon Sep 17 00:00:00 2001 From: Fabien Lahoudere Date: Wed, 5 Jul 2017 10:02:29 +0200 Subject: rtc: s35390a: handle invalid RTC time If RTC time have been altered by low voltage, we notify users that RTC time is invalid by returning -EINVAL. The RTC time needs to be set correctly to clear the invalid flag. Signed-off-by: Fabien Lahoudere Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 72 +++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 449820eeefe8..3aec3b225bc4 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -106,33 +106,12 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) return 0; } -/* - * Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset. - * To keep the information if an irq is pending, pass the value read from - * STATUS1 to the caller. - */ -static int s35390a_reset(struct s35390a *s35390a, char *status1) +static int s35390a_init(struct s35390a *s35390a) { char buf; int ret; unsigned initcount = 0; - ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1); - if (ret < 0) - return ret; - - if (*status1 & S35390A_FLAG_POC) - /* - * Do not communicate for 0.5 seconds since the power-on - * detection circuit is in operation. - */ - msleep(500); - else if (!(*status1 & S35390A_FLAG_BLD)) - /* - * If both POC and BLD are unset everything is fine. - */ - return 0; - /* * At least one of POC and BLD are set, so reinitialise chip. Keeping * this information in the hardware to know later that the time isn't @@ -142,7 +121,6 @@ static int s35390a_reset(struct s35390a *s35390a, char *status1) * The 24H bit is kept over reset, so set it already here. */ initialize: - *status1 = S35390A_FLAG_24H; buf = S35390A_FLAG_RESET | S35390A_FLAG_24H; ret = s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, &buf, 1); @@ -165,6 +143,34 @@ initialize: return 1; } +/* + * Returns <0 on error, 0 if rtc is setup fine and 1 if the chip was reset. + * To keep the information if an irq is pending, pass the value read from + * STATUS1 to the caller. + */ +static int s35390a_read_status(struct s35390a *s35390a, char *status1) +{ + int ret; + + ret = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, status1, 1); + if (ret < 0) + return ret; + + if (*status1 & S35390A_FLAG_POC) { + /* + * Do not communicate for 0.5 seconds since the power-on + * detection circuit is in operation. + */ + msleep(500); + return 1; + } else if (*status1 & S35390A_FLAG_BLD) + return 1; + /* + * If both POC and BLD are unset everything is fine. + */ + return 0; +} + static int s35390a_disable_test_mode(struct s35390a *s35390a) { char buf[1]; @@ -208,13 +214,16 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm) { struct s35390a *s35390a = i2c_get_clientdata(client); int i, err; - char buf[7]; + char buf[7], status; dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, " "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + if (s35390a_read_status(s35390a, &status) == 1) + s35390a_init(s35390a); + buf[S35390A_BYTE_YEAR] = bin2bcd(tm->tm_year - 100); buf[S35390A_BYTE_MONTH] = bin2bcd(tm->tm_mon + 1); buf[S35390A_BYTE_DAY] = bin2bcd(tm->tm_mday); @@ -235,9 +244,12 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm) static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) { struct s35390a *s35390a = i2c_get_clientdata(client); - char buf[7]; + char buf[7], status; int i, err; + if (s35390a_read_status(s35390a, &status) == 1) + return -EINVAL; + err = s35390a_get_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); if (err < 0) return err; @@ -405,7 +417,7 @@ static struct i2c_driver s35390a_driver; static int s35390a_probe(struct i2c_client *client, const struct i2c_device_id *id) { - int err, err_reset; + int err, err_read; unsigned int i; struct s35390a *s35390a; struct rtc_time tm; @@ -438,9 +450,9 @@ static int s35390a_probe(struct i2c_client *client, } } - err_reset = s35390a_reset(s35390a, &status1); - if (err_reset < 0) { - err = err_reset; + err_read = s35390a_read_status(s35390a, &status1); + if (err_read < 0) { + err = err_read; dev_err(&client->dev, "error resetting chip\n"); goto exit_dummy; } @@ -466,7 +478,7 @@ static int s35390a_probe(struct i2c_client *client, } } - if (err_reset > 0 || s35390a_get_datetime(client, &tm) < 0) + if (err_read > 0 || s35390a_get_datetime(client, &tm) < 0) dev_warn(&client->dev, "clock needs to be set\n"); device_set_wakeup_capable(&client->dev, 1); -- cgit From 7a1fe407fc2a4bbe32a8473c92e2988bc9d25fc3 Mon Sep 17 00:00:00 2001 From: Fabien Lahoudere Date: Wed, 5 Jul 2017 10:02:30 +0200 Subject: rtc: s35390a: implement ioctls Implements RTC_VL_READ and RTC_VL_CLR ioctls. Signed-off-by: Fabien Lahoudere Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 3aec3b225bc4..7067bca5c20d 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -404,12 +404,42 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) return s35390a_set_datetime(to_i2c_client(dev), tm); } +static int s35390a_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) +{ + struct i2c_client *client = to_i2c_client(dev); + struct s35390a *s35390a = i2c_get_clientdata(client); + char sts; + int err; + + switch (cmd) { + case RTC_VL_READ: + /* s35390a_reset set lowvoltage flag and init RTC if needed */ + err = s35390a_read_status(s35390a, &sts); + if (err < 0) + return err; + if (copy_to_user((void __user *)arg, &err, sizeof(int))) + return -EFAULT; + break; + case RTC_VL_CLR: + /* update flag and clear register */ + err = s35390a_init(s35390a); + if (err < 0) + return err; + break; + default: + return -ENOIOCTLCMD; + } + + return 0; +} + static const struct rtc_class_ops s35390a_rtc_ops = { .read_time = s35390a_rtc_read_time, .set_time = s35390a_rtc_set_time, .set_alarm = s35390a_rtc_set_alarm, .read_alarm = s35390a_rtc_read_alarm, - + .ioctl = s35390a_rtc_ioctl, }; static struct i2c_driver s35390a_driver; -- cgit From 11909f0be799585f606a70b7e0a9541736848a2e Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 6 Jul 2017 22:40:03 +0200 Subject: rtc: ds1307: remove legacy check for "isil, irq2-can-wakeup-machine" property Commit 8b44f5be20fd ("ARM: dts: armada: replace isil,irq2-can-wakeup-machine with wakeup-source property") removed the last usage of "isil,irq2-can-wakeup-machine" almost two years ago. So I think we can get rid of supporting this legacy binding. Signed-off-by: Heiner Kallweit Acked-by: Rob Herring Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 4fac49e55d47..1cedb21ba792 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1388,14 +1388,8 @@ static int ds1307_probe(struct i2c_client *client, * This will guarantee the 'wakealarm' sysfs entry is available on the device, * if supported by the RTC. */ - if (of_property_read_bool(client->dev.of_node, "wakeup-source")) { + if (of_property_read_bool(client->dev.of_node, "wakeup-source")) ds1307_can_wakeup_device = true; - } - /* Intersil ISL12057 DT backward compatibility */ - if (of_property_read_bool(client->dev.of_node, - "isil,irq2-can-wakeup-machine")) { - ds1307_can_wakeup_device = true; - } #endif switch (ds1307->type) { -- cgit From 319ff835d6136842c660011047a480119bd7cba8 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Wed, 12 Jul 2017 11:59:48 +0100 Subject: rtc: sun6i: Remove double init of spinlock in sun6i_rtc_clk_init() Remove double init of spinlock in sun6i_rtc_clk_init() Fixes: 847b8bf62eb4 ("rtc: sun6i: Expose the 32kHz oscillator") Signed-off-by: Alexey Klimov Reviewed-by: Chen-Yu Tsai Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 39cbc1238b92..7e7da604682b 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -193,12 +193,12 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); if (!rtc) return; - spin_lock_init(&rtc->lock); clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws), GFP_KERNEL); if (!clk_data) return; + spin_lock_init(&rtc->lock); rtc->base = of_io_request_and_map(node, 0, of_node_full_name(node)); -- cgit From 1a37c34811f6d115063042a17211cd70ab560ddd Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 19 Jul 2017 17:57:02 +0100 Subject: rtc: sun6i: ensure clk_data is kfree'd on error There are two error return paths that do not kfree clk_data and we end up with a memory leak. Fix these with a kfree error exit path. Detected by CoverityScan, CID#1402959 ("Resource Leak") Signed-off-by: Colin Ian King Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 7e7da604682b..305c4d043f61 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -204,7 +204,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) rtc->base = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(rtc->base)) { pr_crit("Can't map RTC registers"); - return; + goto err; } /* Switch to the external, more precise, oscillator */ @@ -216,7 +216,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) /* Deal with old DTs */ if (!of_get_property(node, "clocks", NULL)) - return; + goto err; rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL, "rtc-int-osc", @@ -246,6 +246,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) clk_data->num = 1; clk_data->hws[0] = &rtc->hw; of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + return; + +err: + kfree(clk_data); } CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc", sun6i_rtc_clk_init); -- cgit From 2f7f1b780dd60278819d396b67db8c41db6a3b1f Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 7 Jun 2017 16:26:15 +0100 Subject: rtc: max8925: remove redundant check on ret The check on ret < 0 is redundant as the goto destination is the next statment. Remove this redudant check and goto. Detected by CoverityScan, CID#1268785 ("Identical code for different branches") Signed-off-by: Colin Ian King Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-max8925.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index 16d129a0bb3b..67d6fc2d23e6 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c @@ -234,8 +234,6 @@ static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77); else ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x0); - if (ret < 0) - goto out; out: return ret; } -- cgit From 5539ba54b3ea3952b14bd8692122543d1e31b5ae Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 22 Aug 2017 11:48:41 +0200 Subject: rtc: puv3: switch to devm_rtc_allocate_device()/rtc_register_device() Use managed RTC device allocation as this allows for further cleanup. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-puv3.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index c0a6e638c672..4f495dee2f48 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -222,10 +222,6 @@ static void puv3_rtc_enable(struct device *dev, int en) static int puv3_rtc_remove(struct platform_device *dev) { - struct rtc_device *rtc = platform_get_drvdata(dev); - - rtc_device_unregister(rtc); - puv3_rtc_setpie(&dev->dev, 0); puv3_rtc_setaie(&dev->dev, 0); @@ -259,6 +255,10 @@ static int puv3_rtc_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "PKUnity_rtc: tick irq %d, alarm irq %d\n", puv3_rtc_tickno, puv3_rtc_alarmno); + rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { @@ -278,12 +278,10 @@ static int puv3_rtc_probe(struct platform_device *pdev) puv3_rtc_enable(&pdev->dev, 1); /* register RTC and exit */ - rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops, - THIS_MODULE); - - if (IS_ERR(rtc)) { + rtc->ops = &puv3_rtcops; + ret = rtc_register_device(rtc); + if (ret) { dev_err(&pdev->dev, "cannot attach rtc\n"); - ret = PTR_ERR(rtc); goto err_nortc; } -- cgit From 60d345521143ed73b7acc4d99d3ad1afb2890520 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 22 Aug 2017 11:59:07 +0200 Subject: rtc: puv3: make alarms useful Currently, the driver unregisters the IRQs when the rtc character device is closed. This means that the device needs to stay open to get alarms while the usual use case will open the device, set the alarm and close the device. Move the IRQ requests to puv3_rtc_probe() and use the devm managed versions so we don't need to free them. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-puv3.c | 56 +++++++++++++------------------------------------- 1 file changed, 14 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index 4f495dee2f48..9e83be32ff43 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -157,49 +157,7 @@ static int puv3_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -static int puv3_rtc_open(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - int ret; - - ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq, - 0, "pkunity-rtc alarm", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret); - return ret; - } - - ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq, - 0, "pkunity-rtc tick", rtc_dev); - - if (ret) { - dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret); - goto tick_err; - } - - return ret; - - tick_err: - free_irq(puv3_rtc_alarmno, rtc_dev); - return ret; -} - -static void puv3_rtc_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_device *rtc_dev = platform_get_drvdata(pdev); - - /* do not clear AIE here, it may be needed for wake */ - puv3_rtc_setpie(dev, 0); - free_irq(puv3_rtc_alarmno, rtc_dev); - free_irq(puv3_rtc_tickno, rtc_dev); -} - static const struct rtc_class_ops puv3_rtcops = { - .open = puv3_rtc_open, - .release = puv3_rtc_release, .read_time = puv3_rtc_gettime, .set_time = puv3_rtc_settime, .read_alarm = puv3_rtc_getalarm, @@ -259,6 +217,20 @@ static int puv3_rtc_probe(struct platform_device *pdev) if (IS_ERR(rtc)) return PTR_ERR(rtc); + ret = devm_request_irq(&pdev->dev, puv3_rtc_alarmno, puv3_rtc_alarmirq, + 0, "pkunity-rtc alarm", rtc); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret); + return ret; + } + + ret = devm_request_irq(&pdev->dev, puv3_rtc_tickno, puv3_rtc_tickirq, + 0, "pkunity-rtc tick", rtc); + if (ret) { + dev_err(&pdev->dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret); + return ret; + } + /* get the memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { -- cgit From d4473b9b778f39f0b5da870a9a96b5778861c60b Mon Sep 17 00:00:00 2001 From: Eric Cooper Date: Sat, 29 Jul 2017 20:10:54 -0400 Subject: rtc: m41t80: enable wakealarm when "wakeup-source" is specified Don't require an IRQ if the wakeup-source device-tree property is present. Signed-off-by: Eric Cooper Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 8940e9e43ea0..412a4e04de79 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -927,6 +927,7 @@ static int m41t80_probe(struct i2c_client *client, struct rtc_device *rtc = NULL; struct rtc_time tm; struct m41t80_data *m41t80_data = NULL; + bool wakeup_source = false; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -947,6 +948,10 @@ static int m41t80_probe(struct i2c_client *client, m41t80_data->features = id->driver_data; i2c_set_clientdata(client, m41t80_data); +#ifdef CONFIG_OF + wakeup_source = of_property_read_bool(client->dev.of_node, + "wakeup-source"); +#endif if (client->irq > 0) { rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, m41t80_handle_irq, @@ -955,14 +960,16 @@ static int m41t80_probe(struct i2c_client *client, if (rc) { dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); client->irq = 0; - } else { - m41t80_rtc_ops.read_alarm = m41t80_read_alarm; - m41t80_rtc_ops.set_alarm = m41t80_set_alarm; - m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable; - /* Enable the wakealarm */ - device_init_wakeup(&client->dev, true); + wakeup_source = false; } } + if (client->irq > 0 || wakeup_source) { + m41t80_rtc_ops.read_alarm = m41t80_read_alarm; + m41t80_rtc_ops.set_alarm = m41t80_set_alarm; + m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable; + /* Enable the wakealarm */ + device_init_wakeup(&client->dev, true); + } rtc = devm_rtc_device_register(&client->dev, client->name, &m41t80_rtc_ops, THIS_MODULE); @@ -970,6 +977,10 @@ static int m41t80_probe(struct i2c_client *client, return PTR_ERR(rtc); m41t80_data->rtc = rtc; + if (client->irq <= 0) { + /* We cannot support UIE mode if we do not have an IRQ line */ + rtc->uie_unsupported = 1; + } /* Make sure HT (Halt Update) bit is cleared */ rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); -- cgit From be8e2746462b11e92a882e45317fafcd2c0dc50b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 23 Aug 2017 01:15:42 +0200 Subject: rtc: m41t80: remove debug sysfs attribute The last remaining sysfs attribute is undocumented and useless as it can only be used to debug the driver. Remove it. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 44 -------------------------------------------- 1 file changed, 44 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 412a4e04de79..f4c070ea8384 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -440,28 +440,6 @@ static int m41t80_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(m41t80_pm, m41t80_suspend, m41t80_resume); -static ssize_t flags_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - int val; - - val = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS); - if (val < 0) - return val; - return sprintf(buf, "%#x\n", val); -} -static DEVICE_ATTR_RO(flags); - -static struct attribute *attrs[] = { - &dev_attr_flags.attr, - NULL, -}; - -static struct attribute_group attr_group = { - .attrs = attrs, -}; - #ifdef CONFIG_COMMON_CLK #define sqw_to_m41t80_data(_hw) container_of(_hw, struct m41t80_data, sqw) @@ -912,13 +890,6 @@ static struct notifier_block wdt_notifier = { ***************************************************************************** */ -static void m41t80_remove_sysfs_group(void *_dev) -{ - struct device *dev = _dev; - - sysfs_remove_group(&dev->kobj, &attr_group); -} - static int m41t80_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1015,21 +986,6 @@ static int m41t80_probe(struct i2c_client *client, return rc; } - /* Export sysfs entries */ - rc = sysfs_create_group(&(&client->dev)->kobj, &attr_group); - if (rc) { - dev_err(&client->dev, "Failed to create sysfs group: %d\n", rc); - return rc; - } - - rc = devm_add_action_or_reset(&client->dev, m41t80_remove_sysfs_group, - &client->dev); - if (rc) { - dev_err(&client->dev, - "Failed to add sysfs cleanup action: %d\n", rc); - return rc; - } - #ifdef CONFIG_RTC_DRV_M41T80_WDT if (m41t80_data->features & M41T80_FEATURE_HT) { save_client = client; -- cgit From 56c0c529848c853bc1049e271975917e8c9f4389 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 21 Aug 2017 17:57:42 +0200 Subject: rtc: pxa: fix possible race condition pxa_rtc_open() registers the interrupt handler which will access the RTC registers. However, pxa_rtc_open() is called before the register range is ioremapped. Instead, call it after devm_ioremap(). Acked-by: Robert Jarzmik Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pxa.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index fe4985b54608..47304f5664d8 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -348,7 +348,7 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) dev_err(dev, "No alarm IRQ resource defined\n"); return -ENXIO; } - pxa_rtc_open(dev); + pxa_rtc->base = devm_ioremap(dev, pxa_rtc->ress->start, resource_size(pxa_rtc->ress)); if (!pxa_rtc->base) { @@ -356,6 +356,8 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) return -ENOMEM; } + pxa_rtc_open(dev); + sa1100_rtc->rcnr = pxa_rtc->base + 0x0; sa1100_rtc->rtsr = pxa_rtc->base + 0x8; sa1100_rtc->rtar = pxa_rtc->base + 0x4; -- cgit From 1cf85b2327a9b03bde5266e72ee64a38d085256d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 21 Aug 2017 18:00:38 +0200 Subject: rtc: sa1100: fix unbalanced clk_prepare_enable/clk_disable_unprepare In the error path of sa1100_rtc_open(), info->clk is disabled which will happen again in sa1100_rtc_remove() when the module is removed whereas it is only enabled once in sa1100_rtc_init(). Fixes: 0cc0c38e9139 ("drivers/rtc/rtc-sa1100.c: move clock enable/disable to probe/remove") Acked-by: Robert Jarzmik Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sa1100.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index c2187bf6c7e4..fe8ebf47bbe5 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -104,7 +104,7 @@ static int sa1100_rtc_open(struct device *dev) ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); if (ret) { dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz); - goto fail_ui; + return ret; } ret = request_irq(info->irq_alarm, sa1100_rtc_interrupt, 0, "rtc Alrm", dev); if (ret) { @@ -118,8 +118,6 @@ static int sa1100_rtc_open(struct device *dev) fail_ai: free_irq(info->irq_1hz, dev); - fail_ui: - clk_disable_unprepare(info->clk); return ret; } -- cgit From 512053a43d95d4da65565fc74c63906083d419bb Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 23 Aug 2017 01:48:35 +0200 Subject: rtc: sa1100: make alarms useful Currently, the driver unregisters the IRQs when the rtc character device is closed. This means that the device needs to stay open to get alarms while the usual use case will open the device, set the alarm and close the device. Move the IRQ requests to sa1100_rtc_probe() and use the devm managed versions so we don't need to free them. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sa1100.c | 63 +++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index fe8ebf47bbe5..ed71d1113627 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -95,44 +95,6 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int sa1100_rtc_open(struct device *dev) -{ - struct sa1100_rtc *info = dev_get_drvdata(dev); - struct rtc_device *rtc = info->rtc; - int ret; - - ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", dev); - if (ret) { - dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz); - return ret; - } - ret = request_irq(info->irq_alarm, sa1100_rtc_interrupt, 0, "rtc Alrm", dev); - if (ret) { - dev_err(dev, "IRQ %d already in use.\n", info->irq_alarm); - goto fail_ai; - } - rtc->max_user_freq = RTC_FREQ; - rtc_irq_set_freq(rtc, NULL, RTC_FREQ); - - return 0; - - fail_ai: - free_irq(info->irq_1hz, dev); - return ret; -} - -static void sa1100_rtc_release(struct device *dev) -{ - struct sa1100_rtc *info = dev_get_drvdata(dev); - - spin_lock_irq(&info->lock); - writel_relaxed(0, info->rtsr); - spin_unlock_irq(&info->lock); - - free_irq(info->irq_alarm, dev); - free_irq(info->irq_1hz, dev); -} - static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { u32 rtsr; @@ -214,8 +176,6 @@ static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) } static const struct rtc_class_ops sa1100_rtc_ops = { - .open = sa1100_rtc_open, - .release = sa1100_rtc_release, .read_time = sa1100_rtc_read_time, .set_time = sa1100_rtc_set_time, .read_alarm = sa1100_rtc_read_alarm, @@ -263,6 +223,9 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info) } info->rtc = rtc; + rtc->max_user_freq = RTC_FREQ; + rtc_irq_set_freq(rtc, NULL, RTC_FREQ); + /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_interrupt(). * @@ -297,6 +260,7 @@ static int sa1100_rtc_probe(struct platform_device *pdev) struct resource *iores; void __iomem *base; int irq_1hz, irq_alarm; + int ret; irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz"); irq_alarm = platform_get_irq_byname(pdev, "rtc alarm"); @@ -309,6 +273,19 @@ static int sa1100_rtc_probe(struct platform_device *pdev) info->irq_1hz = irq_1hz; info->irq_alarm = irq_alarm; + ret = devm_request_irq(&pdev->dev, irq_1hz, sa1100_rtc_interrupt, 0, + "rtc 1Hz", &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "IRQ %d already in use.\n", irq_1hz); + return ret; + } + ret = devm_request_irq(&pdev->dev, irq_alarm, sa1100_rtc_interrupt, 0, + "rtc Alrm", &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "IRQ %d already in use.\n", irq_alarm); + return ret; + } + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, iores); if (IS_ERR(base)) @@ -337,8 +314,12 @@ static int sa1100_rtc_remove(struct platform_device *pdev) { struct sa1100_rtc *info = platform_get_drvdata(pdev); - if (info) + if (info) { + spin_lock_irq(&info->lock); + writel_relaxed(0, info->rtsr); + spin_unlock_irq(&info->lock); clk_disable_unprepare(info->clk); + } return 0; } -- cgit From 0a53a167224d1c8cb90166f7cce96631b635f33c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 23 Aug 2017 22:37:22 +0200 Subject: rtc: vr41xx: make alarms useful Currently, the IRQs are disabled when the rtc character device is closed. This means that the device needs to stay open to get alarms while the usual use case will open the device, set the alarm and close the device. Keep the alarms functional on character device release. Note that the PIE are never enabled and would anyway be disabled by the core. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-vr41xx.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index e1b86bb01062..7ce22967fd16 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -119,23 +119,6 @@ static inline void write_elapsed_second(unsigned long sec) spin_unlock_irq(&rtc_lock); } -static void vr41xx_rtc_release(struct device *dev) -{ - - spin_lock_irq(&rtc_lock); - - rtc1_write(ECMPLREG, 0); - rtc1_write(ECMPMREG, 0); - rtc1_write(ECMPHREG, 0); - rtc1_write(RTCL1LREG, 0); - rtc1_write(RTCL1HREG, 0); - - spin_unlock_irq(&rtc_lock); - - disable_irq(aie_irq); - disable_irq(pie_irq); -} - static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time) { unsigned long epoch_sec, elapsed_sec; @@ -272,7 +255,6 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id) } static const struct rtc_class_ops vr41xx_rtc_ops = { - .release = vr41xx_rtc_release, .ioctl = vr41xx_rtc_ioctl, .read_time = vr41xx_rtc_read_time, .set_time = vr41xx_rtc_set_time, -- cgit From 604c78235a35202e2150866dcf12f27eed5c6a04 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 23 Aug 2017 23:45:19 +0200 Subject: rtc: mxc: avoid disabling interrupts on device close Currently, the IRQs are disabled when the rtc character device is closed. This means that the device needs to stay open to get alarms while the usual use case will open the device, set the alarm and close the device as is done in rtcwake. Keep the alarm functional on character device release so the platform can actually wakeup. Reviewed-by: Fabio Estevam Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mxc.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 401f46d8f21b..bce427d202ee 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -238,26 +238,6 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -/* - * Clear all interrupts and release the IRQ - */ -static void mxc_rtc_release(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - void __iomem *ioaddr = pdata->ioaddr; - - spin_lock_irq(&pdata->rtc->irq_lock); - - /* Disable all rtc interrupts */ - writew(0, ioaddr + RTC_RTCIENR); - - /* Clear all interrupt status */ - writew(0xffffffff, ioaddr + RTC_RTCISR); - - spin_unlock_irq(&pdata->rtc->irq_lock); -} - static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { mxc_rtc_irq_enable(dev, RTC_ALM_BIT, enabled); @@ -343,7 +323,6 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) /* RTC layer */ static const struct rtc_class_ops mxc_rtc_ops = { - .release = mxc_rtc_release, .read_time = mxc_rtc_read_time, .set_mmss64 = mxc_rtc_set_mmss, .read_alarm = mxc_rtc_read_alarm, -- cgit From ea369ea6d828930c0cf0cacf81f6fd9dff61992d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 23 Aug 2017 02:33:04 +0200 Subject: rtc: remove .open() and .release() There are no driver left using .open and .release. There is no good use case for them as there is nothing the character device interface does that should not be done in the sysfs interface or in-kernel interface. Remove those callbacks now to avoid future confusion. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-dev.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 794bc4fa4937..00efe24a6063 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -24,28 +24,19 @@ static dev_t rtc_devt; static int rtc_dev_open(struct inode *inode, struct file *file) { - int err; struct rtc_device *rtc = container_of(inode->i_cdev, struct rtc_device, char_dev); - const struct rtc_class_ops *ops = rtc->ops; if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) return -EBUSY; file->private_data = rtc; - err = ops->open ? ops->open(rtc->dev.parent) : 0; - if (err == 0) { - spin_lock_irq(&rtc->irq_lock); - rtc->irq_data = 0; - spin_unlock_irq(&rtc->irq_lock); - - return 0; - } + spin_lock_irq(&rtc->irq_lock); + rtc->irq_data = 0; + spin_unlock_irq(&rtc->irq_lock); - /* something has gone wrong */ - clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); - return err; + return 0; } #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL @@ -438,9 +429,6 @@ static int rtc_dev_release(struct inode *inode, struct file *file) rtc_update_irq_enable(rtc, 0); rtc_irq_set_state(rtc, NULL, 0); - if (rtc->ops->release) - rtc->ops->release(rtc->dev.parent); - clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); return 0; } -- cgit From 45a63518493ac33506247227d5758bf2318cfbdc Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sun, 20 Aug 2017 00:37:55 +0530 Subject: rtc: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1672.c | 2 +- drivers/rtc/rtc-em3027.c | 2 +- drivers/rtc/rtc-max6900.c | 2 +- drivers/rtc/rtc-rv3029c2.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 7bf46bfe11a4..9caaccccaa57 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -190,7 +190,7 @@ static int ds1672_probe(struct i2c_client *client, return 0; } -static struct i2c_device_id ds1672_id[] = { +static const struct i2c_device_id ds1672_id[] = { { "ds1672", 0 }, { } }; diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index 4f4930a2004c..b0ef8cfe742d 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -132,7 +132,7 @@ static int em3027_probe(struct i2c_client *client, return 0; } -static struct i2c_device_id em3027_id[] = { +static const struct i2c_device_id em3027_id[] = { { "em3027", 0 }, { } }; diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 48b6b411f8b2..cbdc86a560ba 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -226,7 +226,7 @@ max6900_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; } -static struct i2c_device_id max6900_id[] = { +static const struct i2c_device_id max6900_id[] = { { "max6900", 0 }, { } }; diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index 85fa1da03762..aa09771de04f 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -868,7 +868,7 @@ static int rv3029_i2c_probe(struct i2c_client *client, return rv3029_probe(&client->dev, regmap, client->irq, client->name); } -static struct i2c_device_id rv3029_id[] = { +static const struct i2c_device_id rv3029_id[] = { { "rv3029", 0 }, { "rv3029c2", 0 }, { } -- cgit From 79c676c4e31e7d31b5adfbac996dd167766cf4ab Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Wed, 16 Aug 2017 10:00:35 +0800 Subject: rtc: rk808: Name RK805 in Kconfig for RTC_DRV_RK808 The RK808 and RK805 PMICs are using a similar register map. We can reuse the rtc driver for the RK805 PMIC. So let's add the RK805 in the Kconfig description. Signed-off-by: Elaine Zhang Signed-off-by: Joseph Chen Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 72419ac2c52a..f9bad853deeb 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -371,11 +371,11 @@ config RTC_DRV_MAX77686 will be called rtc-max77686. config RTC_DRV_RK808 - tristate "Rockchip RK808/RK818 RTC" + tristate "Rockchip RK805/RK808/RK818 RTC" depends on MFD_RK808 help If you say yes here you will get support for the - RTC of RK808 and RK818 PMIC. + RTC of RK805, RK808 and RK818 PMIC. This driver can also be built as a module. If so, the module will be called rk808-rtc. -- cgit From 340fd7bce08af00f97d07d5d09d1a9822379efec Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:14 +0200 Subject: rtc: ds1307: remove member irq from struct ds1307 The irq number is used in the probe function only, so we don't have to store it in struct ds1307. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 1cedb21ba792..adc90f188dae 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -126,7 +126,6 @@ struct ds1307 { struct device *dev; struct regmap *regmap; const char *name; - int irq; struct rtc_device *rtc; #ifdef CONFIG_COMMON_CLK struct clk_hw clks[2]; @@ -1334,7 +1333,6 @@ static int ds1307_probe(struct i2c_client *client, dev_set_drvdata(&client->dev, ds1307); ds1307->dev = &client->dev; ds1307->name = client->name; - ds1307->irq = client->irq; ds1307->regmap = devm_regmap_init_i2c(client, ®map_config); if (IS_ERR(ds1307->regmap)) { @@ -1414,7 +1412,7 @@ static int ds1307_probe(struct i2c_client *client, * For some variants, be sure alarms can trigger when we're * running on Vbackup (BBSQI/BBSQW) */ - if (chip->alarm && (ds1307->irq > 0 || + if (chip->alarm && (client->irq > 0 || ds1307_can_wakeup_device)) { ds1307->regs[0] |= DS1337_BIT_INTCN | bbsqi_bitpos[ds1307->type]; @@ -1499,7 +1497,7 @@ static int ds1307_probe(struct i2c_client *client, case rx_8130: ds1307->offset = 0x10; /* Seconds starts at 0x10 */ rtc_ops = &rx8130_rtc_ops; - if (chip->alarm && ds1307->irq > 0) { + if (chip->alarm && client->irq > 0) { irq_handler = rx8130_irq; want_irq = true; } @@ -1509,7 +1507,7 @@ static int ds1307_probe(struct i2c_client *client, break; case mcp794xx: rtc_ops = &mcp794xx_rtc_ops; - if (chip->alarm && (ds1307->irq > 0 || + if (chip->alarm && (client->irq > 0 || ds1307_can_wakeup_device)) { irq_handler = mcp794xx_irq; want_irq = true; @@ -1655,7 +1653,7 @@ read_rtc: return PTR_ERR(ds1307->rtc); } - if (ds1307_can_wakeup_device && ds1307->irq <= 0) { + if (ds1307_can_wakeup_device && client->irq <= 0) { /* Disable request for an IRQ */ want_irq = false; dev_info(ds1307->dev, @@ -1666,7 +1664,7 @@ read_rtc: if (want_irq) { err = devm_request_threaded_irq(ds1307->dev, - ds1307->irq, NULL, irq_handler, + client->irq, NULL, irq_handler, IRQF_SHARED | IRQF_ONESHOT, ds1307->name, ds1307); if (err) { -- cgit From 0b6ee8059448003591cc67fa1ee7db4d979a5bab Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:22 +0200 Subject: rtc: ds1307: factor out bbsqi bit to struct chip_desc Factor out the bbsqi bit to struct chip_desc. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index adc90f188dae..eecf6b272d3f 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -139,6 +139,7 @@ struct chip_desc { u8 century_reg; u8 century_enable_bit; u8 century_bit; + u8 bbsqi_bit; u16 trickle_charger_reg; u8 trickle_charger_setup; u8 (*do_trickle_setup)(struct ds1307 *, uint32_t, @@ -169,6 +170,7 @@ static struct chip_desc chips[last_ds_type] = { .alarm = 1, .century_reg = DS1307_REG_MONTH, .century_bit = DS1337_BIT_CENTURY, + .bbsqi_bit = DS1339_BIT_BBSQI, .trickle_charger_reg = 0x10, .do_trickle_setup = &do_trickle_setup_ds1339, }, @@ -185,6 +187,7 @@ static struct chip_desc chips[last_ds_type] = { .alarm = 1, .century_reg = DS1307_REG_MONTH, .century_bit = DS1337_BIT_CENTURY, + .bbsqi_bit = DS3231_BIT_BBSQW, }, [rx_8130] = { .alarm = 1, @@ -1319,11 +1322,6 @@ static int ds1307_probe(struct i2c_client *client, irq_handler_t irq_handler = ds1307_irq; - static const int bbsqi_bitpos[] = { - [ds_1337] = 0, - [ds_1339] = DS1339_BIT_BBSQI, - [ds_3231] = DS3231_BIT_BBSQW, - }; const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops; ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL); @@ -1414,8 +1412,7 @@ static int ds1307_probe(struct i2c_client *client, */ if (chip->alarm && (client->irq > 0 || ds1307_can_wakeup_device)) { - ds1307->regs[0] |= DS1337_BIT_INTCN - | bbsqi_bitpos[ds1307->type]; + ds1307->regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit; ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); want_irq = true; -- cgit From d8490fd55ab90e0039242a5f53acf8a6c2c5e961 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:28 +0200 Subject: rtc: ds1307: improve trickle charger initialization Instead of storing the trickle_charger_setup value in struct chip_desc we can let function ds1307_trickle_init return it because it's used in the probe function only. This allows us to constify struct chip_desc variables in a next step. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index eecf6b272d3f..5a3c563fc1e6 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -141,7 +141,6 @@ struct chip_desc { u8 century_bit; u8 bbsqi_bit; u16 trickle_charger_reg; - u8 trickle_charger_setup; u8 (*do_trickle_setup)(struct ds1307 *, uint32_t, bool); }; @@ -941,23 +940,23 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, return setup; } -static void ds1307_trickle_init(struct ds1307 *ds1307, - struct chip_desc *chip) +static u8 ds1307_trickle_init(struct ds1307 *ds1307, + struct chip_desc *chip) { - uint32_t ohms = 0; + uint32_t ohms; bool diode = true; if (!chip->do_trickle_setup) - goto out; + return 0; + if (device_property_read_u32(ds1307->dev, "trickle-resistor-ohms", &ohms)) - goto out; + return 0; + if (device_property_read_bool(ds1307->dev, "trickle-diode-disable")) diode = false; - chip->trickle_charger_setup = chip->do_trickle_setup(ds1307, - ohms, diode); -out: - return; + + return chip->do_trickle_setup(ds1307, ohms, diode); } /*----------------------------------------------------------------------*/ @@ -1319,6 +1318,7 @@ static int ds1307_probe(struct i2c_client *client, struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); struct rtc_time tm; unsigned long timestamp; + u8 trickle_charger_setup = 0; irq_handler_t irq_handler = ds1307_irq; @@ -1359,18 +1359,17 @@ static int ds1307_probe(struct i2c_client *client, } if (!pdata) - ds1307_trickle_init(ds1307, chip); + trickle_charger_setup = ds1307_trickle_init(ds1307, chip); else if (pdata->trickle_charger_setup) - chip->trickle_charger_setup = pdata->trickle_charger_setup; + trickle_charger_setup = pdata->trickle_charger_setup; - if (chip->trickle_charger_setup && chip->trickle_charger_reg) { + if (trickle_charger_setup && chip->trickle_charger_reg) { + trickle_charger_setup |= DS13XX_TRICKLE_CHARGER_MAGIC; dev_dbg(ds1307->dev, "writing trickle charger info 0x%x to 0x%x\n", - DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup, - chip->trickle_charger_reg); + trickle_charger_setup, chip->trickle_charger_reg); regmap_write(ds1307->regmap, chip->trickle_charger_reg, - DS13XX_TRICKLE_CHARGER_MAGIC | - chip->trickle_charger_setup); + trickle_charger_setup); } buf = ds1307->regs; -- cgit From 7624df482d7aba599a92ebe1a1fab3e27749b658 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:33 +0200 Subject: rtc: ds1307: constify struct chip_desc variables Constify struct chip_desc variables. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 5a3c563fc1e6..73d2084f0f3e 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -147,7 +147,7 @@ struct chip_desc { static u8 do_trickle_setup_ds1339(struct ds1307 *, uint32_t ohms, bool diode); -static struct chip_desc chips[last_ds_type] = { +static const struct chip_desc chips[last_ds_type] = { [ds_1307] = { .nvram_offset = 8, .nvram_size = 56, @@ -941,7 +941,7 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, } static u8 ds1307_trickle_init(struct ds1307 *ds1307, - struct chip_desc *chip) + const struct chip_desc *chip) { uint32_t ohms; bool diode = true; @@ -1311,7 +1311,7 @@ static int ds1307_probe(struct i2c_client *client, struct ds1307 *ds1307; int err = -ENODEV; int tmp, wday; - struct chip_desc *chip; + const struct chip_desc *chip; bool want_irq = false; bool ds1307_can_wakeup_device = false; unsigned char *buf; -- cgit From 82e2d43f6315d7ae8cca1d00c94f25df0f17eb85 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:37 +0200 Subject: rtc: ds1307: improve irq setup Change the usage of variable want_irq to reflect its name. Don't set it to true in case wakeup is enabled but no interrupt number is given. In addition set variable ds1307_can_wakeup_device if chip->alarm is set only. This allows to simplify the code and make it better understandable. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 73d2084f0f3e..9cb2924e1828 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1312,7 +1312,7 @@ static int ds1307_probe(struct i2c_client *client, int err = -ENODEV; int tmp, wday; const struct chip_desc *chip; - bool want_irq = false; + bool want_irq; bool ds1307_can_wakeup_device = false; unsigned char *buf; struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); @@ -1358,6 +1358,8 @@ static int ds1307_probe(struct i2c_client *client, ds1307->type = acpi_id->driver_data; } + want_irq = client->irq > 0 && chip->alarm; + if (!pdata) trickle_charger_setup = ds1307_trickle_init(ds1307, chip); else if (pdata->trickle_charger_setup) @@ -1383,7 +1385,8 @@ static int ds1307_probe(struct i2c_client *client, * This will guarantee the 'wakealarm' sysfs entry is available on the device, * if supported by the RTC. */ - if (of_property_read_bool(client->dev.of_node, "wakeup-source")) + if (chip->alarm && of_property_read_bool(client->dev.of_node, + "wakeup-source")) ds1307_can_wakeup_device = true; #endif @@ -1409,12 +1412,9 @@ static int ds1307_probe(struct i2c_client *client, * For some variants, be sure alarms can trigger when we're * running on Vbackup (BBSQI/BBSQW) */ - if (chip->alarm && (client->irq > 0 || - ds1307_can_wakeup_device)) { + if (want_irq || ds1307_can_wakeup_device) { ds1307->regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit; ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); - - want_irq = true; } regmap_write(ds1307->regmap, DS1337_REG_CONTROL, @@ -1493,21 +1493,16 @@ static int ds1307_probe(struct i2c_client *client, case rx_8130: ds1307->offset = 0x10; /* Seconds starts at 0x10 */ rtc_ops = &rx8130_rtc_ops; - if (chip->alarm && client->irq > 0) { + if (want_irq) irq_handler = rx8130_irq; - want_irq = true; - } break; case ds_1388: ds1307->offset = 1; /* Seconds starts at 1 */ break; case mcp794xx: rtc_ops = &mcp794xx_rtc_ops; - if (chip->alarm && (client->irq > 0 || - ds1307_can_wakeup_device)) { + if (want_irq || ds1307_can_wakeup_device) irq_handler = mcp794xx_irq; - want_irq = true; - } break; default: break; @@ -1639,7 +1634,7 @@ read_rtc: MCP794XX_REG_WEEKDAY_WDAY_MASK, tm.tm_wday + 1); - if (want_irq) { + if (want_irq || ds1307_can_wakeup_device) { device_set_wakeup_capable(ds1307->dev, true); set_bit(HAS_ALARM, &ds1307->flags); } @@ -1649,9 +1644,7 @@ read_rtc: return PTR_ERR(ds1307->rtc); } - if (ds1307_can_wakeup_device && client->irq <= 0) { - /* Disable request for an IRQ */ - want_irq = false; + if (ds1307_can_wakeup_device && !want_irq) { dev_info(ds1307->dev, "'wakeup-source' is set, request for an IRQ is disabled!\n"); /* We cannot support UIE mode if we do not have an IRQ line */ -- cgit From 45947127054efb95e128ba130d0768640765dae7 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:41 +0200 Subject: rtc: ds1307: factor out irq_handler to struct chip_desc Factor out irq_handler to struct chip_desc and use ds1307_irq as default. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 9cb2924e1828..dd244d6fb9c5 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -140,12 +140,15 @@ struct chip_desc { u8 century_enable_bit; u8 century_bit; u8 bbsqi_bit; + irq_handler_t irq_handler; u16 trickle_charger_reg; u8 (*do_trickle_setup)(struct ds1307 *, uint32_t, bool); }; static u8 do_trickle_setup_ds1339(struct ds1307 *, uint32_t ohms, bool diode); +static irqreturn_t rx8130_irq(int irq, void *dev_id); +static irqreturn_t mcp794xx_irq(int irq, void *dev_id); static const struct chip_desc chips[last_ds_type] = { [ds_1307] = { @@ -193,12 +196,14 @@ static const struct chip_desc chips[last_ds_type] = { /* this is battery backed SRAM */ .nvram_offset = 0x20, .nvram_size = 4, /* 32bit (4 word x 8 bit) */ + .irq_handler = rx8130_irq, }, [mcp794xx] = { .alarm = 1, /* this is battery backed SRAM */ .nvram_offset = 0x20, .nvram_size = 0x40, + .irq_handler = mcp794xx_irq, }, }; @@ -1320,8 +1325,6 @@ static int ds1307_probe(struct i2c_client *client, unsigned long timestamp; u8 trickle_charger_setup = 0; - irq_handler_t irq_handler = ds1307_irq; - const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops; ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL); @@ -1493,16 +1496,12 @@ static int ds1307_probe(struct i2c_client *client, case rx_8130: ds1307->offset = 0x10; /* Seconds starts at 0x10 */ rtc_ops = &rx8130_rtc_ops; - if (want_irq) - irq_handler = rx8130_irq; break; case ds_1388: ds1307->offset = 1; /* Seconds starts at 1 */ break; case mcp794xx: rtc_ops = &mcp794xx_rtc_ops; - if (want_irq || ds1307_can_wakeup_device) - irq_handler = mcp794xx_irq; break; default: break; @@ -1652,8 +1651,8 @@ read_rtc: } if (want_irq) { - err = devm_request_threaded_irq(ds1307->dev, - client->irq, NULL, irq_handler, + err = devm_request_threaded_irq(ds1307->dev, client->irq, NULL, + chip->irq_handler ?: ds1307_irq, IRQF_SHARED | IRQF_ONESHOT, ds1307->name, ds1307); if (err) { -- cgit From 1efb98ba5ea57c4be5a1698f745abff382e17151 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:44 +0200 Subject: rtc: ds1307: factor out rtc_ops to struct chip_desc Factor out rtc_ops to struct chip_desc and use ds13xx_rtc_ops as default. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 51 ++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index dd244d6fb9c5..57a194eca491 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -141,14 +141,39 @@ struct chip_desc { u8 century_bit; u8 bbsqi_bit; irq_handler_t irq_handler; + const struct rtc_class_ops *rtc_ops; u16 trickle_charger_reg; u8 (*do_trickle_setup)(struct ds1307 *, uint32_t, bool); }; +static int ds1307_get_time(struct device *dev, struct rtc_time *t); +static int ds1307_set_time(struct device *dev, struct rtc_time *t); static u8 do_trickle_setup_ds1339(struct ds1307 *, uint32_t ohms, bool diode); static irqreturn_t rx8130_irq(int irq, void *dev_id); +static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t); +static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t); +static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled); static irqreturn_t mcp794xx_irq(int irq, void *dev_id); +static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t); +static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t); +static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled); + +static const struct rtc_class_ops rx8130_rtc_ops = { + .read_time = ds1307_get_time, + .set_time = ds1307_set_time, + .read_alarm = rx8130_read_alarm, + .set_alarm = rx8130_set_alarm, + .alarm_irq_enable = rx8130_alarm_irq_enable, +}; + +static const struct rtc_class_ops mcp794xx_rtc_ops = { + .read_time = ds1307_get_time, + .set_time = ds1307_set_time, + .read_alarm = mcp794xx_read_alarm, + .set_alarm = mcp794xx_set_alarm, + .alarm_irq_enable = mcp794xx_alarm_irq_enable, +}; static const struct chip_desc chips[last_ds_type] = { [ds_1307] = { @@ -197,6 +222,7 @@ static const struct chip_desc chips[last_ds_type] = { .nvram_offset = 0x20, .nvram_size = 4, /* 32bit (4 word x 8 bit) */ .irq_handler = rx8130_irq, + .rtc_ops = &rx8130_rtc_ops, }, [mcp794xx] = { .alarm = 1, @@ -204,6 +230,7 @@ static const struct chip_desc chips[last_ds_type] = { .nvram_offset = 0x20, .nvram_size = 0x40, .irq_handler = mcp794xx_irq, + .rtc_ops = &mcp794xx_rtc_ops, }, }; @@ -731,14 +758,6 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled) return regmap_write(ds1307->regmap, RX8130_REG_CONTROL0, reg); } -static const struct rtc_class_ops rx8130_rtc_ops = { - .read_time = ds1307_get_time, - .set_time = ds1307_set_time, - .read_alarm = rx8130_read_alarm, - .set_alarm = rx8130_set_alarm, - .alarm_irq_enable = rx8130_alarm_irq_enable, -}; - /*----------------------------------------------------------------------*/ /* @@ -891,14 +910,6 @@ static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled) enabled ? MCP794XX_BIT_ALM0_EN : 0); } -static const struct rtc_class_ops mcp794xx_rtc_ops = { - .read_time = ds1307_get_time, - .set_time = ds1307_set_time, - .read_alarm = mcp794xx_read_alarm, - .set_alarm = mcp794xx_set_alarm, - .alarm_irq_enable = mcp794xx_alarm_irq_enable, -}; - /*----------------------------------------------------------------------*/ static int ds1307_nvram_read(void *priv, unsigned int offset, void *val, @@ -1325,8 +1336,6 @@ static int ds1307_probe(struct i2c_client *client, unsigned long timestamp; u8 trickle_charger_setup = 0; - const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops; - ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL); if (!ds1307) return -ENOMEM; @@ -1495,14 +1504,10 @@ static int ds1307_probe(struct i2c_client *client, break; case rx_8130: ds1307->offset = 0x10; /* Seconds starts at 0x10 */ - rtc_ops = &rx8130_rtc_ops; break; case ds_1388: ds1307->offset = 1; /* Seconds starts at 1 */ break; - case mcp794xx: - rtc_ops = &mcp794xx_rtc_ops; - break; default: break; } @@ -1678,7 +1683,7 @@ read_rtc: ds1307->rtc->nvram_old_abi = true; } - ds1307->rtc->ops = rtc_ops; + ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops; err = rtc_register_device(ds1307->rtc); if (err) return err; -- cgit From e553170a597e30ceb39bdf602f33421dc348017a Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:47 +0200 Subject: rtc: ds1307: factor out offset to struct chip_desc Factor out offset to struct chip_desc and remove it from struct ds1307. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 57a194eca491..1179c8760de2 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -115,7 +115,6 @@ enum ds_type { struct ds1307 { - u8 offset; /* register's offset */ u8 regs[11]; u16 nvram_offset; struct nvmem_config nvmem_cfg; @@ -136,6 +135,7 @@ struct chip_desc { unsigned alarm:1; u16 nvram_offset; u16 nvram_size; + u8 offset; /* register's offset */ u8 century_reg; u8 century_enable_bit; u8 century_bit; @@ -208,6 +208,7 @@ static const struct chip_desc chips[last_ds_type] = { .trickle_charger_reg = 0x08, }, [ds_1388] = { + .offset = 1, .trickle_charger_reg = 0x0a, }, [ds_3231] = { @@ -221,6 +222,7 @@ static const struct chip_desc chips[last_ds_type] = { /* this is battery backed SRAM */ .nvram_offset = 0x20, .nvram_size = 4, /* 32bit (4 word x 8 bit) */ + .offset = 0x10, .irq_handler = rx8130_irq, .rtc_ops = &rx8130_rtc_ops, }, @@ -387,7 +389,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) const struct chip_desc *chip = &chips[ds1307->type]; /* read the RTC date and time registers all at once */ - ret = regmap_bulk_read(ds1307->regmap, ds1307->offset, ds1307->regs, 7); + ret = regmap_bulk_read(ds1307->regmap, chip->offset, ds1307->regs, 7); if (ret) { dev_err(dev, "%s error %d\n", "read", ret); return ret; @@ -479,7 +481,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) dev_dbg(dev, "%s: %7ph\n", "write", buf); - result = regmap_bulk_write(ds1307->regmap, ds1307->offset, buf, 7); + result = regmap_bulk_write(ds1307->regmap, chip->offset, buf, 7); if (result) { dev_err(dev, "%s error %d\n", "write", result); return result; @@ -1502,19 +1504,13 @@ static int ds1307_probe(struct i2c_client *client, DS1307_REG_HOUR << 4 | 0x08, hour); } break; - case rx_8130: - ds1307->offset = 0x10; /* Seconds starts at 0x10 */ - break; - case ds_1388: - ds1307->offset = 1; /* Seconds starts at 1 */ - break; default: break; } read_rtc: /* read RTC registers */ - err = regmap_bulk_read(ds1307->regmap, ds1307->offset, buf, 8); + err = regmap_bulk_read(ds1307->regmap, chip->offset, buf, 8); if (err) { dev_dbg(ds1307->dev, "read error %d\n", err); goto exit; @@ -1615,7 +1611,7 @@ read_rtc: tmp = 0; if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) tmp += 12; - regmap_write(ds1307->regmap, ds1307->offset + DS1307_REG_HOUR, + regmap_write(ds1307->regmap, chip->offset + DS1307_REG_HOUR, bin2bcd(tmp)); } -- cgit From 969fa07b9479f435bc4363e4ff75db99fc9b24fb Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 12 Jul 2017 07:49:54 +0200 Subject: rtc: ds1307: remove member nvram_offset from struct ds1307 Remove member nvram_offset from struct ds1307 and use the value stored in struct chip_desc directly. Signed-off-by: Heiner Kallweit Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 1179c8760de2..3e82ddce620e 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -116,7 +116,6 @@ enum ds_type { struct ds1307 { u8 regs[11]; - u16 nvram_offset; struct nvmem_config nvmem_cfg; enum ds_type type; unsigned long flags; @@ -918,8 +917,9 @@ static int ds1307_nvram_read(void *priv, unsigned int offset, void *val, size_t bytes) { struct ds1307 *ds1307 = priv; + const struct chip_desc *chip = &chips[ds1307->type]; - return regmap_bulk_read(ds1307->regmap, ds1307->nvram_offset + offset, + return regmap_bulk_read(ds1307->regmap, chip->nvram_offset + offset, val, bytes); } @@ -927,8 +927,9 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val, size_t bytes) { struct ds1307 *ds1307 = priv; + const struct chip_desc *chip = &chips[ds1307->type]; - return regmap_bulk_write(ds1307->regmap, ds1307->nvram_offset + offset, + return regmap_bulk_write(ds1307->regmap, chip->nvram_offset + offset, val, bytes); } @@ -1673,7 +1674,6 @@ read_rtc: ds1307->nvmem_cfg.reg_read = ds1307_nvram_read; ds1307->nvmem_cfg.reg_write = ds1307_nvram_write; ds1307->nvmem_cfg.priv = ds1307; - ds1307->nvram_offset = chip->nvram_offset; ds1307->rtc->nvmem_config = &ds1307->nvmem_cfg; ds1307->rtc->nvram_old_abi = true; -- cgit From 0759c886f4fbaadd1ea6a67a1e442207d6215f0d Mon Sep 17 00:00:00 2001 From: Nikita Yushchenko Date: Thu, 24 Aug 2017 09:32:11 +0300 Subject: rtc: ds1307: add basic support for ds1341 chip This adds support for reading and writing date/time from/to ds1341 chip. ds1341 chip has other features - alarms, input clock (can be used instead of intercal oscillator for better accuracy), output clock ("square wave generation"). However, not all of that is available at the same time. Same chip pins, CLKIN/nINTA and SQW/nINTB, can be used either for input/output clocks, or for alarm interrupts. Role of these pins on particular board depends on hardware wiring. We can add device tree properties that describe if each of pins is wired as clock, or as interrupt, or left unconnected, and enable support for corresponding functionality based on that. But that is cumbersome, requires hardware for testing, and has to deal with bit enabling/disabling output clock also affects which pins alarm interrupts are routed to. Another factor is that there are hardware setups (i.e. ZII RDU2) that power DS1341 from SuperCap, which makes power saving critical. For such setups, kernel driver should leave register bits that control mentioned pins in the state configured by bootloader. Given all that, it was decided to limit support to "only date/time" for now. That is enough for common use case. Full (and cumbersome) implementation can be added later if ever needed. Signed-off-by: Nikita Yushchenko Reviewed-by: Linus Walleij Tested-by: Aleksander Morgado Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 10 +++++----- drivers/rtc/rtc-ds1307.c | 12 ++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f9bad853deeb..22efa21b1d81 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -227,14 +227,14 @@ config RTC_DRV_AS3722 will be called rtc-as3722. config RTC_DRV_DS1307 - tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025, ISL12057" + tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057" help If you say yes here you get support for various compatible RTC chips (often with battery backup) connected with I2C. This driver - should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, - EPSON RX-8025, Intersil ISL12057 and probably other chips. In some - cases the RTC must already have been initialized (by manufacturing or - a bootloader). + should handle DS1307, DS1337, DS1338, DS1339, DS1340, DS1341, + ST M41T00, EPSON RX-8025, Intersil ISL12057 and probably other chips. + In some cases the RTC must already have been initialized (by + manufacturing or a bootloader). The first seven registers on these chips hold an RTC, and other registers may add features such as NVRAM, a trickle charger for diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 3e82ddce620e..6038c49ed68a 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -39,6 +39,7 @@ enum ds_type { ds_1338, ds_1339, ds_1340, + ds_1341, ds_1388, ds_3231, m41t0, @@ -206,6 +207,10 @@ static const struct chip_desc chips[last_ds_type] = { .century_bit = DS1340_BIT_CENTURY, .trickle_charger_reg = 0x08, }, + [ds_1341] = { + .century_reg = DS1307_REG_MONTH, + .century_bit = DS1337_BIT_CENTURY, + }, [ds_1388] = { .offset = 1, .trickle_charger_reg = 0x0a, @@ -243,6 +248,7 @@ static const struct i2c_device_id ds1307_id[] = { { "ds1339", ds_1339 }, { "ds1388", ds_1388 }, { "ds1340", ds_1340 }, + { "ds1341", ds_1341 }, { "ds3231", ds_3231 }, { "m41t0", m41t0 }, { "m41t00", m41t00 }, @@ -286,6 +292,10 @@ static const struct of_device_id ds1307_of_match[] = { .compatible = "dallas,ds1340", .data = (void *)ds_1340 }, + { + .compatible = "dallas,ds1341", + .data = (void *)ds_1341 + }, { .compatible = "maxim,ds3231", .data = (void *)ds_3231 @@ -332,6 +342,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = { { .id = "DS1339", .driver_data = ds_1339 }, { .id = "DS1388", .driver_data = ds_1388 }, { .id = "DS1340", .driver_data = ds_1340 }, + { .id = "DS1341", .driver_data = ds_1341 }, { .id = "DS3231", .driver_data = ds_3231 }, { .id = "M41T0", .driver_data = m41t0 }, { .id = "M41T00", .driver_data = m41t00 }, @@ -1408,6 +1419,7 @@ static int ds1307_probe(struct i2c_client *client, switch (ds1307->type) { case ds_1337: case ds_1339: + case ds_1341: case ds_3231: /* get registers that the "rtc" read below won't read... */ err = regmap_bulk_read(ds1307->regmap, DS1337_REG_CONTROL, -- cgit From f22d9cdcb5eb7ed1c4629a167474d68df0003a3d Mon Sep 17 00:00:00 2001 From: Miodrag Dinic Date: Fri, 18 Aug 2017 15:08:54 +0200 Subject: rtc: goldfish: Add RTC driver for Android emulator Add device driver for a virtual RTC device in Android emulator. The compatible string used by OS for binding the driver is defined as "google,goldfish-rtc". Signed-off-by: Miodrag Dinic Signed-off-by: Goran Ferenc Signed-off-by: Aleksandar Markovic Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 8 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-goldfish.c | 237 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 drivers/rtc/rtc-goldfish.c (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 22efa21b1d81..a76a26e2292a 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1780,5 +1780,13 @@ config RTC_DRV_HID_SENSOR_TIME If this driver is compiled as a module, it will be named rtc-hid-sensor-time. +config RTC_DRV_GOLDFISH + tristate "Goldfish Real Time Clock" + depends on MIPS && (GOLDFISH || COMPILE_TEST) + help + Say yes to enable RTC driver for the Goldfish based virtual platform. + + Goldfish is a code name for the virtual platform developed by Google + for Android emulation. endif # RTC_CLASS diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index acd366b41c85..d995d49d8218 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -170,3 +170,4 @@ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o +obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c new file mode 100644 index 000000000000..d67769265185 --- /dev/null +++ b/drivers/rtc/rtc-goldfish.c @@ -0,0 +1,237 @@ +/* drivers/rtc/rtc-goldfish.c + * + * Copyright (C) 2007 Google, Inc. + * Copyright (C) 2017 Imagination Technologies Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include + +#define TIMER_TIME_LOW 0x00 /* get low bits of current time */ + /* and update TIMER_TIME_HIGH */ +#define TIMER_TIME_HIGH 0x04 /* get high bits of time at last */ + /* TIMER_TIME_LOW read */ +#define TIMER_ALARM_LOW 0x08 /* set low bits of alarm and */ + /* activate it */ +#define TIMER_ALARM_HIGH 0x0c /* set high bits of next alarm */ +#define TIMER_IRQ_ENABLED 0x10 +#define TIMER_CLEAR_ALARM 0x14 +#define TIMER_ALARM_STATUS 0x18 +#define TIMER_CLEAR_INTERRUPT 0x1c + +struct goldfish_rtc { + void __iomem *base; + int irq; + struct rtc_device *rtc; +}; + +static int goldfish_rtc_read_alarm(struct device *dev, + struct rtc_wkalrm *alrm) +{ + u64 rtc_alarm; + u64 rtc_alarm_low; + u64 rtc_alarm_high; + void __iomem *base; + struct goldfish_rtc *rtcdrv; + + rtcdrv = dev_get_drvdata(dev); + base = rtcdrv->base; + + rtc_alarm_low = readl(base + TIMER_ALARM_LOW); + rtc_alarm_high = readl(base + TIMER_ALARM_HIGH); + rtc_alarm = (rtc_alarm_high << 32) | rtc_alarm_low; + + do_div(rtc_alarm, NSEC_PER_SEC); + memset(alrm, 0, sizeof(struct rtc_wkalrm)); + + rtc_time_to_tm(rtc_alarm, &alrm->time); + + if (readl(base + TIMER_ALARM_STATUS)) + alrm->enabled = 1; + else + alrm->enabled = 0; + + return 0; +} + +static int goldfish_rtc_set_alarm(struct device *dev, + struct rtc_wkalrm *alrm) +{ + struct goldfish_rtc *rtcdrv; + unsigned long rtc_alarm; + u64 rtc_alarm64; + u64 rtc_status_reg; + void __iomem *base; + int ret = 0; + + rtcdrv = dev_get_drvdata(dev); + base = rtcdrv->base; + + if (alrm->enabled) { + ret = rtc_tm_to_time(&alrm->time, &rtc_alarm); + if (ret != 0) + return ret; + + rtc_alarm64 = rtc_alarm * NSEC_PER_SEC; + writel((rtc_alarm64 >> 32), base + TIMER_ALARM_HIGH); + writel(rtc_alarm64, base + TIMER_ALARM_LOW); + } else { + /* + * if this function was called with enabled=0 + * then it could mean that the application is + * trying to cancel an ongoing alarm + */ + rtc_status_reg = readl(base + TIMER_ALARM_STATUS); + if (rtc_status_reg) + writel(1, base + TIMER_CLEAR_ALARM); + } + + return ret; +} + +static int goldfish_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + void __iomem *base; + struct goldfish_rtc *rtcdrv; + + rtcdrv = dev_get_drvdata(dev); + base = rtcdrv->base; + + if (enabled) + writel(1, base + TIMER_IRQ_ENABLED); + else + writel(0, base + TIMER_IRQ_ENABLED); + + return 0; +} + +static irqreturn_t goldfish_rtc_interrupt(int irq, void *dev_id) +{ + struct goldfish_rtc *rtcdrv = dev_id; + void __iomem *base = rtcdrv->base; + + writel(1, base + TIMER_CLEAR_INTERRUPT); + + rtc_update_irq(rtcdrv->rtc, 1, RTC_IRQF | RTC_AF); + + return IRQ_HANDLED; +} + +static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct goldfish_rtc *rtcdrv; + void __iomem *base; + u64 time_high; + u64 time_low; + u64 time; + + rtcdrv = dev_get_drvdata(dev); + base = rtcdrv->base; + + time_low = readl(base + TIMER_TIME_LOW); + time_high = readl(base + TIMER_TIME_HIGH); + time = (time_high << 32) | time_low; + + do_div(time, NSEC_PER_SEC); + + rtc_time_to_tm(time, tm); + + return 0; +} + +static int goldfish_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct goldfish_rtc *rtcdrv; + void __iomem *base; + unsigned long now; + u64 now64; + int ret; + + rtcdrv = dev_get_drvdata(dev); + base = rtcdrv->base; + + ret = rtc_tm_to_time(tm, &now); + if (ret == 0) { + now64 = now * NSEC_PER_SEC; + writel((now64 >> 32), base + TIMER_TIME_HIGH); + writel(now64, base + TIMER_TIME_LOW); + } + + return ret; +} + +static const struct rtc_class_ops goldfish_rtc_ops = { + .read_time = goldfish_rtc_read_time, + .set_time = goldfish_rtc_set_time, + .read_alarm = goldfish_rtc_read_alarm, + .set_alarm = goldfish_rtc_set_alarm, + .alarm_irq_enable = goldfish_rtc_alarm_irq_enable +}; + +static int goldfish_rtc_probe(struct platform_device *pdev) +{ + struct goldfish_rtc *rtcdrv; + struct resource *r; + int err; + + rtcdrv = devm_kzalloc(&pdev->dev, sizeof(*rtcdrv), GFP_KERNEL); + if (!rtcdrv) + return -ENOMEM; + + platform_set_drvdata(pdev, rtcdrv); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + + rtcdrv->base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(rtcdrv->base)) + return -ENODEV; + + rtcdrv->irq = platform_get_irq(pdev, 0); + if (rtcdrv->irq < 0) + return -ENODEV; + + rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, + &goldfish_rtc_ops, + THIS_MODULE); + if (IS_ERR(rtcdrv->rtc)) + return PTR_ERR(rtcdrv->rtc); + + err = devm_request_irq(&pdev->dev, rtcdrv->irq, + goldfish_rtc_interrupt, + 0, pdev->name, rtcdrv); + if (err) + return err; + + return 0; +} + +static const struct of_device_id goldfish_rtc_of_match[] = { + { .compatible = "google,goldfish-rtc", }, + {}, +}; +MODULE_DEVICE_TABLE(of, goldfish_rtc_of_match); + +static struct platform_driver goldfish_rtc = { + .probe = goldfish_rtc_probe, + .driver = { + .name = "goldfish_rtc", + .of_match_table = goldfish_rtc_of_match, + } +}; + +module_platform_driver(goldfish_rtc); -- cgit From 17ecd246414b3a0fe0cb248c86977a8bda465b7b Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 25 Aug 2017 09:42:02 +0200 Subject: rtc: sun6i: Add support for the external oscillator gate The RTC can output its 32kHz clock outside of the SoC, for example to clock a WiFi chip. Create a new clock that other devices will be able to retrieve, while maintaining the DT stability by providing a default name for that clock if clock-output-names doesn't list one. Signed-off-by: Maxime Ripard Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 305c4d043f61..3d2216ccd860 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -73,6 +73,9 @@ #define SUN6I_ALARM_CONFIG 0x0050 #define SUN6I_ALARM_CONFIG_WAKEUP BIT(0) +#define SUN6I_LOSC_OUT_GATING 0x0060 +#define SUN6I_LOSC_OUT_GATING_EN BIT(0) + /* * Get date values */ @@ -125,6 +128,7 @@ struct sun6i_rtc_dev { struct clk_hw hw; struct clk_hw *int_osc; struct clk *losc; + struct clk *ext_losc; spinlock_t lock; }; @@ -188,13 +192,14 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) struct clk_init_data init = { .ops = &sun6i_rtc_osc_ops, }; + const char *clkout_name = "osc32k-out"; const char *parents[2]; rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); if (!rtc) return; - clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws), + clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2), GFP_KERNEL); if (!clk_data) return; @@ -235,7 +240,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) init.parent_names = parents; init.num_parents = of_clk_get_parent_count(node) + 1; - of_property_read_string(node, "clock-output-names", &init.name); + of_property_read_string_index(node, "clock-output-names", 0, + &init.name); rtc->losc = clk_register(NULL, &rtc->hw); if (IS_ERR(rtc->losc)) { @@ -243,8 +249,20 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) return; } - clk_data->num = 1; + of_property_read_string_index(node, "clock-output-names", 1, + &clkout_name); + rtc->ext_losc = clk_register_gate(NULL, clkout_name, rtc->hw.init->name, + 0, rtc->base + SUN6I_LOSC_OUT_GATING, + SUN6I_LOSC_OUT_GATING_EN, 0, + &rtc->lock); + if (IS_ERR(rtc->ext_losc)) { + pr_crit("Couldn't register the LOSC external gate\n"); + return; + } + + clk_data->num = 2; clk_data->hws[0] = &rtc->hw; + clk_data->hws[1] = __clk_get_hw(rtc->ext_losc); of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); return; -- cgit From ae930c912b3274d79319179c1f5ddd9423dd0a7d Mon Sep 17 00:00:00 2001 From: Andreas Färber Date: Tue, 5 Sep 2017 00:53:23 +0200 Subject: rtc: Add Realtek RTD1295 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on QNAP's arch/arm/mach-rtk119x/driver/rtk_rtc_drv.c code and mach-rtk119x/driver/dc2vo/fpga/include/mis_reg.h register definitions. The base year 2014 was observed on all of Zidoo X9S, ProBox2 Ava and Beelink Lake I. Signed-off-by: Andreas Färber Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 8 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-rtd119x.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 drivers/rtc/rtc-rtd119x.c (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index a76a26e2292a..e0e58f3b1420 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1765,6 +1765,14 @@ config RTC_DRV_CPCAP Say y here for CPCAP rtc found on some Motorola phones and tablets such as Droid 4. +config RTC_DRV_RTD119X + bool "Realtek RTD129x RTC" + depends on ARCH_REALTEK || COMPILE_TEST + default ARCH_REALTEK + help + If you say yes here, you get support for the RTD1295 SoC + Real Time Clock. + comment "HID Sensor RTC drivers" config RTC_DRV_HID_SENSOR_TIME diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index d995d49d8218..7230014c92af 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -131,6 +131,7 @@ obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o +obj-$(CONFIG_RTC_DRV_RTD119X) += rtc-rtd119x.o obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o diff --git a/drivers/rtc/rtc-rtd119x.c b/drivers/rtc/rtc-rtd119x.c new file mode 100644 index 000000000000..b233559d950b --- /dev/null +++ b/drivers/rtc/rtc-rtd119x.c @@ -0,0 +1,242 @@ +/* + * Realtek RTD129x RTC + * + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTD_RTCSEC 0x00 +#define RTD_RTCMIN 0x04 +#define RTD_RTCHR 0x08 +#define RTD_RTCDATE1 0x0c +#define RTD_RTCDATE2 0x10 +#define RTD_RTCACR 0x28 +#define RTD_RTCEN 0x2c +#define RTD_RTCCR 0x30 + +#define RTD_RTCSEC_RTCSEC_MASK 0x7f + +#define RTD_RTCMIN_RTCMIN_MASK 0x3f + +#define RTD_RTCHR_RTCHR_MASK 0x1f + +#define RTD_RTCDATE1_RTCDATE1_MASK 0xff + +#define RTD_RTCDATE2_RTCDATE2_MASK 0x7f + +#define RTD_RTCACR_RTCPWR BIT(7) + +#define RTD_RTCEN_RTCEN_MASK 0xff + +#define RTD_RTCCR_RTCRST BIT(6) + +struct rtd119x_rtc { + void __iomem *base; + struct clk *clk; + struct rtc_device *rtcdev; + unsigned int base_year; +}; + +static inline int rtd119x_rtc_days_in_year(int year) +{ + return 365 + (is_leap_year(year) ? 1 : 0); +} + +static void rtd119x_rtc_reset(struct device *dev) +{ + struct rtd119x_rtc *data = dev_get_drvdata(dev); + u32 val; + + val = readl_relaxed(data->base + RTD_RTCCR); + val |= RTD_RTCCR_RTCRST; + writel_relaxed(val, data->base + RTD_RTCCR); + + val &= ~RTD_RTCCR_RTCRST; + writel(val, data->base + RTD_RTCCR); +} + +static void rtd119x_rtc_set_enabled(struct device *dev, bool enable) +{ + struct rtd119x_rtc *data = dev_get_drvdata(dev); + u32 val; + + val = readl_relaxed(data->base + RTD_RTCEN); + if (enable) { + if ((val & RTD_RTCEN_RTCEN_MASK) == 0x5a) + return; + writel_relaxed(0x5a, data->base + RTD_RTCEN); + } else { + writel_relaxed(0, data->base + RTD_RTCEN); + } +} + +static int rtd119x_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct rtd119x_rtc *data = dev_get_drvdata(dev); + s32 day; + u32 sec; + unsigned int year; + int tries = 0; + + while (true) { + tm->tm_sec = (readl_relaxed(data->base + RTD_RTCSEC) & RTD_RTCSEC_RTCSEC_MASK) >> 1; + tm->tm_min = readl_relaxed(data->base + RTD_RTCMIN) & RTD_RTCMIN_RTCMIN_MASK; + tm->tm_hour = readl_relaxed(data->base + RTD_RTCHR) & RTD_RTCHR_RTCHR_MASK; + day = readl_relaxed(data->base + RTD_RTCDATE1) & RTD_RTCDATE1_RTCDATE1_MASK; + day |= (readl_relaxed(data->base + RTD_RTCDATE2) & RTD_RTCDATE2_RTCDATE2_MASK) << 8; + sec = (readl_relaxed(data->base + RTD_RTCSEC) & RTD_RTCSEC_RTCSEC_MASK) >> 1; + tries++; + + if (sec == tm->tm_sec) + break; + + if (tries >= 3) + return -EINVAL; + } + if (tries > 1) + dev_dbg(dev, "%s: needed %i tries\n", __func__, tries); + + year = data->base_year; + while (day >= rtd119x_rtc_days_in_year(year)) { + day -= rtd119x_rtc_days_in_year(year); + year++; + } + tm->tm_year = year - 1900; + tm->tm_yday = day; + + tm->tm_mon = 0; + while (day >= rtc_month_days(tm->tm_mon, year)) { + day -= rtc_month_days(tm->tm_mon, year); + tm->tm_mon++; + } + tm->tm_mday = day + 1; + + return 0; +} + +static int rtd119x_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct rtd119x_rtc *data = dev_get_drvdata(dev); + unsigned int day; + int i; + + if (1900 + tm->tm_year < data->base_year) + return -EINVAL; + + day = 0; + for (i = data->base_year; i < 1900 + tm->tm_year; i++) + day += rtd119x_rtc_days_in_year(i); + + day += tm->tm_yday; + if (day > 0x7fff) + return -EINVAL; + + rtd119x_rtc_set_enabled(dev, false); + + writel_relaxed((tm->tm_sec << 1) & RTD_RTCSEC_RTCSEC_MASK, data->base + RTD_RTCSEC); + writel_relaxed(tm->tm_min & RTD_RTCMIN_RTCMIN_MASK, data->base + RTD_RTCMIN); + writel_relaxed(tm->tm_hour & RTD_RTCHR_RTCHR_MASK, data->base + RTD_RTCHR); + writel_relaxed(day & RTD_RTCDATE1_RTCDATE1_MASK, data->base + RTD_RTCDATE1); + writel_relaxed((day >> 8) & RTD_RTCDATE2_RTCDATE2_MASK, data->base + RTD_RTCDATE2); + + rtd119x_rtc_set_enabled(dev, true); + + return 0; +} + +static const struct rtc_class_ops rtd119x_rtc_ops = { + .read_time = rtd119x_rtc_read_time, + .set_time = rtd119x_rtc_set_time, +}; + +static const struct of_device_id rtd119x_rtc_dt_ids[] = { + { .compatible = "realtek,rtd1295-rtc" }, + { } +}; + +static int rtd119x_rtc_probe(struct platform_device *pdev) +{ + struct rtd119x_rtc *data; + struct resource *res; + u32 val; + int ret; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + platform_set_drvdata(pdev, data); + data->base_year = 2014; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(data->base)) + return PTR_ERR(data->base); + + data->clk = of_clk_get(pdev->dev.of_node, 0); + if (IS_ERR(data->clk)) + return PTR_ERR(data->clk); + + ret = clk_prepare_enable(data->clk); + if (ret) { + clk_put(data->clk); + return ret; + } + + val = readl_relaxed(data->base + RTD_RTCACR); + if (!(val & RTD_RTCACR_RTCPWR)) { + writel_relaxed(RTD_RTCACR_RTCPWR, data->base + RTD_RTCACR); + + rtd119x_rtc_reset(&pdev->dev); + + writel_relaxed(0, data->base + RTD_RTCMIN); + writel_relaxed(0, data->base + RTD_RTCHR); + writel_relaxed(0, data->base + RTD_RTCDATE1); + writel_relaxed(0, data->base + RTD_RTCDATE2); + } + + rtd119x_rtc_set_enabled(&pdev->dev, true); + + data->rtcdev = devm_rtc_device_register(&pdev->dev, "rtc", + &rtd119x_rtc_ops, THIS_MODULE); + if (IS_ERR(data->rtcdev)) { + dev_err(&pdev->dev, "failed to register rtc device"); + clk_disable_unprepare(data->clk); + clk_put(data->clk); + return PTR_ERR(data->rtcdev); + } + + return 0; +} + +static int rtd119x_rtc_remove(struct platform_device *pdev) +{ + struct rtd119x_rtc *data = platform_get_drvdata(pdev); + + rtd119x_rtc_set_enabled(&pdev->dev, false); + + clk_disable_unprepare(data->clk); + clk_put(data->clk); + + return 0; +} + +static struct platform_driver rtd119x_rtc_driver = { + .probe = rtd119x_rtc_probe, + .remove = rtd119x_rtc_remove, + .driver = { + .name = "rtd1295-rtc", + .of_match_table = rtd119x_rtc_dt_ids, + }, +}; +builtin_platform_driver(rtd119x_rtc_driver); -- cgit From 042fa8c7c04dd43b21be3ec5104681574a4f8f8c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 4 Sep 2017 22:46:02 +0200 Subject: rtc: ds1307: remove regs member ds1307->regs is never used before being read or initialized locally. There is no point in keeping a copy in memory. Also limit the size of the read buffer to what is really used, rename buf to regs for consistency and use sizeof() where possible. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 207 ++++++++++++++++++++++++----------------------- 1 file changed, 107 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 6038c49ed68a..8de1d7116461 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -116,7 +116,6 @@ enum ds_type { struct ds1307 { - u8 regs[11]; struct nvmem_config nvmem_cfg; enum ds_type type; unsigned long flags; @@ -397,34 +396,36 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) struct ds1307 *ds1307 = dev_get_drvdata(dev); int tmp, ret; const struct chip_desc *chip = &chips[ds1307->type]; + u8 regs[7]; /* read the RTC date and time registers all at once */ - ret = regmap_bulk_read(ds1307->regmap, chip->offset, ds1307->regs, 7); + ret = regmap_bulk_read(ds1307->regmap, chip->offset, regs, + sizeof(regs)); if (ret) { dev_err(dev, "%s error %d\n", "read", ret); return ret; } - dev_dbg(dev, "%s: %7ph\n", "read", ds1307->regs); + dev_dbg(dev, "%s: %7ph\n", "read", regs); /* if oscillator fail bit is set, no data can be trusted */ if (ds1307->type == m41t0 && - ds1307->regs[DS1307_REG_MIN] & M41T0_BIT_OF) { + regs[DS1307_REG_MIN] & M41T0_BIT_OF) { dev_warn_once(dev, "oscillator failed, set time!\n"); return -EINVAL; } - t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f); - t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); - tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f; + t->tm_sec = bcd2bin(regs[DS1307_REG_SECS] & 0x7f); + t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f); + tmp = regs[DS1307_REG_HOUR] & 0x3f; t->tm_hour = bcd2bin(tmp); - t->tm_wday = bcd2bin(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1; - t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f); - tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f; + t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1; + t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f); + tmp = regs[DS1307_REG_MONTH] & 0x1f; t->tm_mon = bcd2bin(tmp) - 1; - t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100; + t->tm_year = bcd2bin(regs[DS1307_REG_YEAR]) + 100; - if (ds1307->regs[chip->century_reg] & chip->century_bit && + if (regs[chip->century_reg] & chip->century_bit && IS_ENABLED(CONFIG_RTC_DRV_DS1307_CENTURY)) t->tm_year += 100; @@ -444,7 +445,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) const struct chip_desc *chip = &chips[ds1307->type]; int result; int tmp; - u8 *buf = ds1307->regs; + u8 regs[7]; dev_dbg(dev, "%s secs=%d, mins=%d, " "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", @@ -463,35 +464,36 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) return -EINVAL; #endif - buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec); - buf[DS1307_REG_MIN] = bin2bcd(t->tm_min); - buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); - buf[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); - buf[DS1307_REG_MDAY] = bin2bcd(t->tm_mday); - buf[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1); + regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec); + regs[DS1307_REG_MIN] = bin2bcd(t->tm_min); + regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); + regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); + regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday); + regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1); /* assume 20YY not 19YY */ tmp = t->tm_year - 100; - buf[DS1307_REG_YEAR] = bin2bcd(tmp); + regs[DS1307_REG_YEAR] = bin2bcd(tmp); if (chip->century_enable_bit) - buf[chip->century_reg] |= chip->century_enable_bit; + regs[chip->century_reg] |= chip->century_enable_bit; if (t->tm_year > 199 && chip->century_bit) - buf[chip->century_reg] |= chip->century_bit; + regs[chip->century_reg] |= chip->century_bit; if (ds1307->type == mcp794xx) { /* * these bits were cleared when preparing the date/time * values and need to be set again before writing the - * buffer out to the device. + * regsfer out to the device. */ - buf[DS1307_REG_SECS] |= MCP794XX_BIT_ST; - buf[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN; + regs[DS1307_REG_SECS] |= MCP794XX_BIT_ST; + regs[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN; } - dev_dbg(dev, "%s: %7ph\n", "write", buf); + dev_dbg(dev, "%s: %7ph\n", "write", regs); - result = regmap_bulk_write(ds1307->regmap, chip->offset, buf, 7); + result = regmap_bulk_write(ds1307->regmap, chip->offset, regs, + sizeof(regs)); if (result) { dev_err(dev, "%s error %d\n", "write", result); return result; @@ -503,33 +505,34 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) { struct ds1307 *ds1307 = dev_get_drvdata(dev); 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, - ds1307->regs, 9); + regs, sizeof(regs)); if (ret) { dev_err(dev, "%s error %d\n", "alarm read", ret); return ret; } dev_dbg(dev, "%s: %4ph, %3ph, %2ph\n", "alarm read", - &ds1307->regs[0], &ds1307->regs[4], &ds1307->regs[7]); + ®s[0], ®s[4], ®s[7]); /* * report alarm time (ALARM1); assume 24 hour and day-of-month modes, * and that all four fields are checked matches */ - t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f); - t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f); - t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f); - t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f); + t->time.tm_sec = bcd2bin(regs[0] & 0x7f); + t->time.tm_min = bcd2bin(regs[1] & 0x7f); + t->time.tm_hour = bcd2bin(regs[2] & 0x3f); + t->time.tm_mday = bcd2bin(regs[3] & 0x3f); /* ... and status */ - t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE); - t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I); + t->enabled = !!(regs[7] & DS1337_BIT_A1IE); + t->pending = !!(regs[8] & DS1337_BIT_A1I); dev_dbg(dev, "%s secs=%d, mins=%d, " "hours=%d, mday=%d, enabled=%d, pending=%d\n", @@ -543,7 +546,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t) static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) { struct ds1307 *ds1307 = dev_get_drvdata(dev); - unsigned char *buf = ds1307->regs; + unsigned char regs[9]; u8 control, status; int ret; @@ -557,33 +560,35 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) t->enabled, t->pending); /* read current status of both alarms and the chip */ - ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9); + ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, regs, + sizeof(regs)); if (ret) { dev_err(dev, "%s error %d\n", "alarm write", ret); return ret; } - control = ds1307->regs[7]; - status = ds1307->regs[8]; + control = regs[7]; + status = regs[8]; dev_dbg(dev, "%s: %4ph, %3ph, %02x %02x\n", "alarm set (old status)", - &ds1307->regs[0], &ds1307->regs[4], control, status); + ®s[0], ®s[4], control, status); /* set ALARM1, using 24 hour and day-of-month modes */ - buf[0] = bin2bcd(t->time.tm_sec); - buf[1] = bin2bcd(t->time.tm_min); - buf[2] = bin2bcd(t->time.tm_hour); - buf[3] = bin2bcd(t->time.tm_mday); + regs[0] = bin2bcd(t->time.tm_sec); + regs[1] = bin2bcd(t->time.tm_min); + regs[2] = bin2bcd(t->time.tm_hour); + regs[3] = bin2bcd(t->time.tm_mday); /* set ALARM2 to non-garbage */ - buf[4] = 0; - buf[5] = 0; - buf[6] = 0; + regs[4] = 0; + regs[5] = 0; + regs[6] = 0; /* disable alarms */ - buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE); - buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); + regs[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE); + regs[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I); - ret = regmap_bulk_write(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9); + ret = regmap_bulk_write(ds1307->regmap, DS1339_REG_ALARM1_SECS, regs, + sizeof(regs)); if (ret) { dev_err(dev, "can't set alarm time\n"); return ret; @@ -592,8 +597,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) /* optionally enable ALARM1 */ if (t->enabled) { dev_dbg(dev, "alarm IRQ armed\n"); - buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */ - regmap_write(ds1307->regmap, DS1337_REG_CONTROL, buf[7]); + regs[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */ + regmap_write(ds1307->regmap, DS1337_REG_CONTROL, regs[7]); } return 0; @@ -830,26 +835,27 @@ out: static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) { struct ds1307 *ds1307 = dev_get_drvdata(dev); - u8 *regs = ds1307->regs; + 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, 10); + ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, + sizeof(regs)); if (ret) return ret; t->enabled = !!(regs[0] & MCP794XX_BIT_ALM0_EN); /* Report alarm 0 time assuming 24-hour and day-of-month modes. */ - t->time.tm_sec = bcd2bin(ds1307->regs[3] & 0x7f); - t->time.tm_min = bcd2bin(ds1307->regs[4] & 0x7f); - t->time.tm_hour = bcd2bin(ds1307->regs[5] & 0x3f); - t->time.tm_wday = bcd2bin(ds1307->regs[6] & 0x7) - 1; - t->time.tm_mday = bcd2bin(ds1307->regs[7] & 0x3f); - t->time.tm_mon = bcd2bin(ds1307->regs[8] & 0x1f) - 1; + t->time.tm_sec = bcd2bin(regs[3] & 0x7f); + t->time.tm_min = bcd2bin(regs[4] & 0x7f); + t->time.tm_hour = bcd2bin(regs[5] & 0x3f); + t->time.tm_wday = bcd2bin(regs[6] & 0x7) - 1; + t->time.tm_mday = bcd2bin(regs[7] & 0x3f); + t->time.tm_mon = bcd2bin(regs[8] & 0x1f) - 1; t->time.tm_year = -1; t->time.tm_yday = -1; t->time.tm_isdst = -1; @@ -858,9 +864,9 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) "enabled=%d polarity=%d irq=%d match=%d\n", __func__, t->time.tm_sec, t->time.tm_min, t->time.tm_hour, t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled, - !!(ds1307->regs[6] & MCP794XX_BIT_ALMX_POL), - !!(ds1307->regs[6] & MCP794XX_BIT_ALMX_IF), - (ds1307->regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4); + !!(regs[6] & MCP794XX_BIT_ALMX_POL), + !!(regs[6] & MCP794XX_BIT_ALMX_IF), + (regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4); return 0; } @@ -868,7 +874,7 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) { struct ds1307 *ds1307 = dev_get_drvdata(dev); - unsigned char *regs = ds1307->regs; + unsigned char regs[10]; int ret; if (!test_bit(HAS_ALARM, &ds1307->flags)) @@ -881,7 +887,8 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) t->enabled, t->pending); /* Read control and alarm 0 registers. */ - ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10); + ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, + sizeof(regs)); if (ret) return ret; @@ -900,7 +907,8 @@ static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t) /* Disable interrupt. We will not enable until completely programmed */ regs[0] &= ~MCP794XX_BIT_ALM0_EN; - ret = regmap_bulk_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10); + ret = regmap_bulk_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs, + sizeof(regs)); if (ret) return ret; @@ -1344,7 +1352,7 @@ static int ds1307_probe(struct i2c_client *client, const struct chip_desc *chip; bool want_irq; bool ds1307_can_wakeup_device = false; - unsigned char *buf; + unsigned char regs[8]; struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev); struct rtc_time tm; unsigned long timestamp; @@ -1400,8 +1408,6 @@ static int ds1307_probe(struct i2c_client *client, trickle_charger_setup); } - buf = ds1307->regs; - #ifdef CONFIG_OF /* * For devices with no IRQ directly connected to the SoC, the RTC chip @@ -1423,15 +1429,15 @@ static int ds1307_probe(struct i2c_client *client, case ds_3231: /* get registers that the "rtc" read below won't read... */ err = regmap_bulk_read(ds1307->regmap, DS1337_REG_CONTROL, - buf, 2); + regs, 2); if (err) { dev_dbg(ds1307->dev, "read error %d\n", err); goto exit; } /* oscillator off? turn it on, so clock can tick. */ - if (ds1307->regs[0] & DS1337_BIT_nEOSC) - ds1307->regs[0] &= ~DS1337_BIT_nEOSC; + if (regs[0] & DS1337_BIT_nEOSC) + regs[0] &= ~DS1337_BIT_nEOSC; /* * Using IRQ or defined as wakeup-source? @@ -1440,77 +1446,77 @@ static int ds1307_probe(struct i2c_client *client, * running on Vbackup (BBSQI/BBSQW) */ if (want_irq || ds1307_can_wakeup_device) { - ds1307->regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit; - ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); + regs[0] |= DS1337_BIT_INTCN | chip->bbsqi_bit; + regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE); } regmap_write(ds1307->regmap, DS1337_REG_CONTROL, - ds1307->regs[0]); + regs[0]); /* oscillator fault? clear flag, and warn */ - if (ds1307->regs[1] & DS1337_BIT_OSF) { + if (regs[1] & DS1337_BIT_OSF) { regmap_write(ds1307->regmap, DS1337_REG_STATUS, - ds1307->regs[1] & ~DS1337_BIT_OSF); + regs[1] & ~DS1337_BIT_OSF); dev_warn(ds1307->dev, "SET TIME!\n"); } break; case rx_8025: err = regmap_bulk_read(ds1307->regmap, - RX8025_REG_CTRL1 << 4 | 0x08, buf, 2); + RX8025_REG_CTRL1 << 4 | 0x08, regs, 2); if (err) { dev_dbg(ds1307->dev, "read error %d\n", err); goto exit; } /* oscillator off? turn it on, so clock can tick. */ - if (!(ds1307->regs[1] & RX8025_BIT_XST)) { - ds1307->regs[1] |= RX8025_BIT_XST; + if (!(regs[1] & RX8025_BIT_XST)) { + regs[1] |= RX8025_BIT_XST; regmap_write(ds1307->regmap, RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); + regs[1]); dev_warn(ds1307->dev, "oscillator stop detected - SET TIME!\n"); } - if (ds1307->regs[1] & RX8025_BIT_PON) { - ds1307->regs[1] &= ~RX8025_BIT_PON; + if (regs[1] & RX8025_BIT_PON) { + regs[1] &= ~RX8025_BIT_PON; regmap_write(ds1307->regmap, RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); + regs[1]); dev_warn(ds1307->dev, "power-on detected\n"); } - if (ds1307->regs[1] & RX8025_BIT_VDET) { - ds1307->regs[1] &= ~RX8025_BIT_VDET; + if (regs[1] & RX8025_BIT_VDET) { + regs[1] &= ~RX8025_BIT_VDET; regmap_write(ds1307->regmap, RX8025_REG_CTRL2 << 4 | 0x08, - ds1307->regs[1]); + regs[1]); dev_warn(ds1307->dev, "voltage drop detected\n"); } /* make sure we are running in 24hour mode */ - if (!(ds1307->regs[0] & RX8025_BIT_2412)) { + if (!(regs[0] & RX8025_BIT_2412)) { u8 hour; /* switch to 24 hour mode */ regmap_write(ds1307->regmap, RX8025_REG_CTRL1 << 4 | 0x08, - ds1307->regs[0] | RX8025_BIT_2412); + regs[0] | RX8025_BIT_2412); err = regmap_bulk_read(ds1307->regmap, RX8025_REG_CTRL1 << 4 | 0x08, - buf, 2); + regs, 2); if (err) { dev_dbg(ds1307->dev, "read error %d\n", err); goto exit; } /* correct hour */ - hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]); + hour = bcd2bin(regs[DS1307_REG_HOUR]); if (hour == 12) hour = 0; - if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) + if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM) hour += 12; regmap_write(ds1307->regmap, @@ -1523,7 +1529,8 @@ static int ds1307_probe(struct i2c_client *client, read_rtc: /* read RTC registers */ - err = regmap_bulk_read(ds1307->regmap, chip->offset, buf, 8); + err = regmap_bulk_read(ds1307->regmap, chip->offset, regs, + sizeof(regs)); if (err) { dev_dbg(ds1307->dev, "read error %d\n", err); goto exit; @@ -1534,7 +1541,7 @@ read_rtc: * specify the extra bits as must-be-zero, but there are * still a few values that are clearly out-of-range. */ - tmp = ds1307->regs[DS1307_REG_SECS]; + tmp = regs[DS1307_REG_SECS]; switch (ds1307->type) { case ds_1307: case m41t0: @@ -1553,9 +1560,9 @@ read_rtc: regmap_write(ds1307->regmap, DS1307_REG_SECS, 0); /* oscillator fault? clear flag, and warn */ - if (ds1307->regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) { + if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) { regmap_write(ds1307->regmap, DS1307_REG_CONTROL, - ds1307->regs[DS1307_REG_CONTROL] & + regs[DS1307_REG_CONTROL] & ~DS1338_BIT_OSF); dev_warn(ds1307->dev, "SET TIME!\n"); goto read_rtc; @@ -1580,9 +1587,9 @@ read_rtc: break; case mcp794xx: /* make sure that the backup battery is enabled */ - if (!(ds1307->regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) { + if (!(regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) { regmap_write(ds1307->regmap, DS1307_REG_WDAY, - ds1307->regs[DS1307_REG_WDAY] | + regs[DS1307_REG_WDAY] | MCP794XX_BIT_VBATEN); } @@ -1599,7 +1606,7 @@ read_rtc: break; } - tmp = ds1307->regs[DS1307_REG_HOUR]; + tmp = regs[DS1307_REG_HOUR]; switch (ds1307->type) { case ds_1340: case m41t0: @@ -1622,7 +1629,7 @@ read_rtc: tmp = bcd2bin(tmp & 0x1f); if (tmp == 12) tmp = 0; - if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) + if (regs[DS1307_REG_HOUR] & DS1307_BIT_PM) tmp += 12; regmap_write(ds1307->regmap, chip->offset + DS1307_REG_HOUR, bin2bcd(tmp)); -- cgit From f2b4801201a46eaa9a00a39a1e2d5aa8c9864991 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 4 Sep 2017 22:46:03 +0200 Subject: rtc: ds1307: use sizeof Use sizeof where possible to ensure we don't read/write more than the allocated buffer. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 8de1d7116461..93fb08452159 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -650,7 +650,8 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id) mutex_lock(lock); /* Read control registers. */ - ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3); + ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, + sizeof(ctl)); if (ret < 0) goto out; if (!(ctl[1] & RX8130_REG_FLAG_AF)) @@ -658,7 +659,8 @@ static irqreturn_t rx8130_irq(int irq, void *dev_id) ctl[1] &= ~RX8130_REG_FLAG_AF; ctl[2] &= ~RX8130_REG_CONTROL0_AIE; - ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3); + ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, + sizeof(ctl)); if (ret < 0) goto out; @@ -680,12 +682,14 @@ static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t) return -EINVAL; /* Read alarm registers. */ - ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, 3); + ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, + sizeof(ald)); if (ret < 0) return ret; /* Read control registers. */ - ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3); + ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, + sizeof(ctl)); if (ret < 0) return ret; @@ -726,7 +730,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t) t->enabled, t->pending); /* Read control registers. */ - ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3); + ret = regmap_bulk_read(ds1307->regmap, RX8130_REG_EXTENSION, ctl, + sizeof(ctl)); if (ret < 0) return ret; @@ -734,7 +739,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t) ctl[1] |= RX8130_REG_FLAG_AF; ctl[2] &= ~RX8130_REG_CONTROL0_AIE; - ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3); + ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, + sizeof(ctl)); if (ret < 0) return ret; @@ -743,7 +749,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t) ald[1] = bin2bcd(t->time.tm_hour); ald[2] = bin2bcd(t->time.tm_mday); - ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, 3); + ret = regmap_bulk_write(ds1307->regmap, RX8130_REG_ALARM_MIN, ald, + sizeof(ald)); if (ret < 0) return ret; @@ -752,7 +759,8 @@ static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t) ctl[2] |= RX8130_REG_CONTROL0_AIE; - return regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, 3); + return regmap_bulk_write(ds1307->regmap, RX8130_REG_EXTENSION, ctl, + sizeof(ctl)); } static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled) -- cgit From 57ec2d9580760ce35d7c54b57f8e5f7e98049b8e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 4 Sep 2017 22:46:04 +0200 Subject: rtc: ds1307: use u32 u32 should be used instead of uint32_t Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 93fb08452159..328183e0e121 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -142,13 +142,13 @@ struct chip_desc { irq_handler_t irq_handler; const struct rtc_class_ops *rtc_ops; u16 trickle_charger_reg; - u8 (*do_trickle_setup)(struct ds1307 *, uint32_t, + u8 (*do_trickle_setup)(struct ds1307 *, u32, bool); }; static int ds1307_get_time(struct device *dev, struct rtc_time *t); static int ds1307_set_time(struct device *dev, struct rtc_time *t); -static u8 do_trickle_setup_ds1339(struct ds1307 *, uint32_t ohms, bool diode); +static u8 do_trickle_setup_ds1339(struct ds1307 *, u32 ohms, bool diode); static irqreturn_t rx8130_irq(int irq, void *dev_id); static int rx8130_read_alarm(struct device *dev, struct rtc_wkalrm *t); static int rx8130_set_alarm(struct device *dev, struct rtc_wkalrm *t); @@ -963,7 +963,7 @@ static int ds1307_nvram_write(void *priv, unsigned int offset, void *val, /*----------------------------------------------------------------------*/ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, - uint32_t ohms, bool diode) + u32 ohms, bool diode) { u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE : DS1307_TRICKLE_CHARGER_NO_DIODE; @@ -989,7 +989,7 @@ static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307, static u8 ds1307_trickle_init(struct ds1307 *ds1307, const struct chip_desc *chip) { - uint32_t ohms; + u32 ohms; bool diode = true; if (!chip->do_trickle_setup) -- cgit From eb4fd19005b73be8d7f51b564aa87a59a7fb4328 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 4 Sep 2017 22:46:05 +0200 Subject: rtc: ds1307: use BIT Use the BIT macro were possbiel. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 328183e0e121..5b2fe3579e45 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -634,11 +634,11 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { #define RX8130_REG_ALARM_HOUR 0x08 #define RX8130_REG_ALARM_WEEK_OR_DAY 0x09 #define RX8130_REG_EXTENSION 0x0c -#define RX8130_REG_EXTENSION_WADA (1 << 3) +#define RX8130_REG_EXTENSION_WADA BIT(3) #define RX8130_REG_FLAG 0x0d -#define RX8130_REG_FLAG_AF (1 << 3) +#define RX8130_REG_FLAG_AF BIT(3) #define RX8130_REG_CONTROL0 0x0e -#define RX8130_REG_CONTROL0_AIE (1 << 3) +#define RX8130_REG_CONTROL0_AIE BIT(3) static irqreturn_t rx8130_irq(int irq, void *dev_id) { @@ -798,11 +798,11 @@ static int rx8130_alarm_irq_enable(struct device *dev, unsigned int enabled) #define MCP794XX_REG_ALARM0_CTRL 0x0d #define MCP794XX_REG_ALARM1_BASE 0x11 #define MCP794XX_REG_ALARM1_CTRL 0x14 -# define MCP794XX_BIT_ALMX_IF (1 << 3) -# define MCP794XX_BIT_ALMX_C0 (1 << 4) -# define MCP794XX_BIT_ALMX_C1 (1 << 5) -# define MCP794XX_BIT_ALMX_C2 (1 << 6) -# define MCP794XX_BIT_ALMX_POL (1 << 7) +# define MCP794XX_BIT_ALMX_IF BIT(3) +# define MCP794XX_BIT_ALMX_C0 BIT(4) +# define MCP794XX_BIT_ALMX_C1 BIT(5) +# define MCP794XX_BIT_ALMX_C2 BIT(6) +# define MCP794XX_BIT_ALMX_POL BIT(7) # define MCP794XX_MSK_ALMX_MATCH (MCP794XX_BIT_ALMX_C0 | \ MCP794XX_BIT_ALMX_C1 | \ MCP794XX_BIT_ALMX_C2) @@ -869,7 +869,7 @@ static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t) t->time.tm_isdst = -1; dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d " - "enabled=%d polarity=%d irq=%d match=%d\n", __func__, + "enabled=%d polarity=%d irq=%d match=%lu\n", __func__, t->time.tm_sec, t->time.tm_min, t->time.tm_hour, t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled, !!(regs[6] & MCP794XX_BIT_ALMX_POL), -- cgit From 4057a66e5333bf487c35a37119e3012a4b318e22 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 4 Sep 2017 22:46:06 +0200 Subject: rtc: ds1307: fix alignments and blank lines Alignment should always match open parenthesis. Also remove two unnecessary blank lines Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 5b2fe3579e45..bac0f9ec9351 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -51,7 +51,6 @@ enum ds_type { /* rs5c372 too? different address... */ }; - /* RTC registers don't differ much, except for the century flag */ #define DS1307_REG_SECS 0x00 /* 00-59 */ # define DS1307_BIT_CH 0x80 @@ -114,7 +113,6 @@ enum ds_type { # define RX8025_BIT_VDET 0x40 # define RX8025_BIT_XST 0x20 - struct ds1307 { struct nvmem_config nvmem_cfg; enum ds_type type; @@ -1042,7 +1040,7 @@ static int ds3231_hwmon_read_temp(struct device *dev, s32 *mC) } static ssize_t ds3231_hwmon_show_temp(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { int ret; s32 temp; @@ -1054,7 +1052,7 @@ static ssize_t ds3231_hwmon_show_temp(struct device *dev, return sprintf(buf, "%d\n", temp); } static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ds3231_hwmon_show_temp, - NULL, 0); + NULL, 0); static struct attribute *ds3231_hwmon_attrs[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, @@ -1070,7 +1068,8 @@ static void ds1307_hwmon_register(struct ds1307 *ds1307) return; dev = devm_hwmon_device_register_with_groups(ds1307->dev, ds1307->name, - ds1307, ds3231_hwmon_groups); + ds1307, + ds3231_hwmon_groups); if (IS_ERR(dev)) { dev_warn(ds1307->dev, "unable to register hwmon device %ld\n", PTR_ERR(dev)); @@ -1142,7 +1141,7 @@ static unsigned long ds3231_clk_sqw_recalc_rate(struct clk_hw *hw, } static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) + unsigned long *prate) { int i; @@ -1155,7 +1154,7 @@ static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate, } static int ds3231_clk_sqw_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) + unsigned long parent_rate) { struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw); int control = 0; @@ -1215,7 +1214,7 @@ static const struct clk_ops ds3231_clk_sqw_ops = { }; static unsigned long ds3231_clk_32khz_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) + unsigned long parent_rate) { return 32768; } @@ -1306,7 +1305,7 @@ static int ds3231_clks_register(struct ds1307 *ds1307) /* optional override of the clockname */ of_property_read_string_index(node, "clock-output-names", i, - &init.name); + &init.name); ds1307->clks[i].init = &init; onecell->clks[i] = devm_clk_register(ds1307->dev, @@ -1570,8 +1569,8 @@ read_rtc: /* oscillator fault? clear flag, and warn */ if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) { regmap_write(ds1307->regmap, DS1307_REG_CONTROL, - regs[DS1307_REG_CONTROL] & - ~DS1338_BIT_OSF); + regs[DS1307_REG_CONTROL] & + ~DS1338_BIT_OSF); dev_warn(ds1307->dev, "SET TIME!\n"); goto read_rtc; } -- cgit From e69c056714974733aeb3ff114e9d434ea864d818 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 4 Sep 2017 22:46:07 +0200 Subject: rtc: ds1307: fix braces Fix unnecessary or unbalanced braces. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index bac0f9ec9351..9df50db228c6 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1667,9 +1667,8 @@ read_rtc: } ds1307->rtc = devm_rtc_allocate_device(ds1307->dev); - if (IS_ERR(ds1307->rtc)) { + if (IS_ERR(ds1307->rtc)) return PTR_ERR(ds1307->rtc); - } if (ds1307_can_wakeup_device && !want_irq) { dev_info(ds1307->dev, @@ -1688,8 +1687,9 @@ read_rtc: device_set_wakeup_capable(ds1307->dev, false); clear_bit(HAS_ALARM, &ds1307->flags); dev_err(ds1307->dev, "unable to request IRQ!\n"); - } else + } else { dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq); + } } if (chip->nvram_size) { -- cgit From b4be271cebb6f8b475f8bf2199091be8fe4c4278 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 4 Sep 2017 22:46:08 +0200 Subject: rtc: ds1307: use octal permissions Octal permissions are preferred over symbolic permissions. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 9df50db228c6..9d680d36afc0 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1051,7 +1051,7 @@ static ssize_t ds3231_hwmon_show_temp(struct device *dev, return sprintf(buf, "%d\n", temp); } -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ds3231_hwmon_show_temp, +static SENSOR_DEVICE_ATTR(temp1_input, 0444, ds3231_hwmon_show_temp, NULL, 0); static struct attribute *ds3231_hwmon_attrs[] = { -- cgit