Linux RTC
 help / color / mirror / Atom feed
* Re: [PATCH] rtc: sun6i: Add support for the external oscillator gate
From: Alexandre Belloni @ 2017-08-24 14:36 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: Chen-Yu Tsai, linux-rtc, linux-arm-kernel, linux-kernel
In-Reply-To: <20170824121854.23995-1-maxime.ripard@free-electrons.com>

Hi,

On 24/08/2017 at 14:18:54 +0200, Maxime Ripard wrote:
> 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 <maxime.ripard@free-electrons.com>
> ---
>  .../devicetree/bindings/rtc/sun6i-rtc.txt          |  4 ++--
>  drivers/rtc/rtc-sun6i.c                            | 24 +++++++++++++++++++---
>  2 files changed, 23 insertions(+), 5 deletions(-)
> 

It doesn't apply cleanly, can you rebase on top of -next?

> diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
> index 945934918b71..d5e26d313f62 100644
> --- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
> +++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
> @@ -10,7 +10,7 @@ Required properties:
>  
>  Required properties for new device trees
>  - clocks	: phandle to the 32kHz external oscillator
> -- clock-output-names : name of the LOSC clock created
> +- clock-output-names : names of the LOSC and its external output clocks created
>  - #clock-cells  : must be equals to 1. The RTC provides two clocks: the
>  		  LOSC and its external output, with index 0 and 1
>  		  respectively.
> @@ -21,7 +21,7 @@ rtc: rtc@01f00000 {
>  	compatible = "allwinner,sun6i-a31-rtc";
>  	reg = <0x01f00000 0x54>;
>  	interrupts = <0 40 4>, <0 41 4>;
> -	clock-output-names = "osc32k";
> +	clock-output-names = "osc32k", "osc32k-out";
>  	clocks = <&ext_osc32k>;
>  	#clock-cells = <1>;
>  };
> diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
> index 39cbc1238b92..d4a6ddbfd872 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,6 +192,7 @@ 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);
> @@ -195,7 +200,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
>  		return;
>  	spin_lock_init(&rtc->lock);
>  
> -	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);
>  }
>  CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
> -- 
> 2.13.5
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* Re: [PATCH] rtc: mxc: avoid disabling interrupts on device close
From: Fabio Estevam @ 2017-08-24 14:16 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: linux-rtc, linux-kernel, Sascha Hauer, Fabio Estevam, Shawn Guo,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20170823220024.22861-1-alexandre.belloni@free-electrons.com>

On Wed, Aug 23, 2017 at 7:00 PM, Alexandre Belloni
<alexandre.belloni@free-electrons.com> wrote:
> 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
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Makes sense, thanks:

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

^ permalink raw reply

* [PATCH] rtc: sun6i: Add support for the external oscillator gate
From: Maxime Ripard @ 2017-08-24 12:18 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Chen-Yu Tsai, Maxime Ripard, linux-rtc, linux-arm-kernel,
	linux-kernel

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 <maxime.ripard@free-electrons.com>
---
 .../devicetree/bindings/rtc/sun6i-rtc.txt          |  4 ++--
 drivers/rtc/rtc-sun6i.c                            | 24 +++++++++++++++++++---
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
index 945934918b71..d5e26d313f62 100644
--- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
@@ -10,7 +10,7 @@ Required properties:
 
 Required properties for new device trees
 - clocks	: phandle to the 32kHz external oscillator
-- clock-output-names : name of the LOSC clock created
+- clock-output-names : names of the LOSC and its external output clocks created
 - #clock-cells  : must be equals to 1. The RTC provides two clocks: the
 		  LOSC and its external output, with index 0 and 1
 		  respectively.
@@ -21,7 +21,7 @@ rtc: rtc@01f00000 {
 	compatible = "allwinner,sun6i-a31-rtc";
 	reg = <0x01f00000 0x54>;
 	interrupts = <0 40 4>, <0 41 4>;
-	clock-output-names = "osc32k";
+	clock-output-names = "osc32k", "osc32k-out";
 	clocks = <&ext_osc32k>;
 	#clock-cells = <1>;
 };
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 39cbc1238b92..d4a6ddbfd872 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,6 +192,7 @@ 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);
@@ -195,7 +200,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node)
 		return;
 	spin_lock_init(&rtc->lock);
 
-	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);
 }
 CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
-- 
2.13.5

^ permalink raw reply related

* [PATCH] rtc: ds1307: call the platform's logic for handle IRQs.
From: Enric Balletbo i Serra @ 2017-08-24 10:30 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, linux-rtc, linux-kernel

On some systems the nIRQ pin is often connect to a GPIO, then, if a given
interrupt line is supposed to wake up the system, the corresponding input
of that interrupt controller need to be enabled to receive signal from the
line in question. Before this commit such systems would not wake up
because are not marked as wakeup IRQs in the IRQ subsystem.

This commit calls enable_irq_wake() on suspend and disables that input to
prevent the dedicated controller from triggering interrupts unnecessarily
after wakeup.

After this commit a system composed by a RTC DS1339 chip connected to a
GPIO line on a AM335x SoC is able to wakeup from suspend-to-RAM, otherwise
the line is ignored.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
---
 drivers/rtc/rtc-ds1307.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 4b43aa6..c4b0f6a 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1711,11 +1711,36 @@ static int ds1307_probe(struct i2c_client *client,
 	return err;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int ds1307_suspend(struct device *dev)
+{
+	struct ds1307 *ds1307 = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(ds1307->irq);
+
+	return 0;
+}
+
+static int ds1307_resume(struct device *dev)
+{
+	struct ds1307 *ds1307 = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(ds1307->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ds1307_pm_ops, ds1307_suspend, ds1307_resume);
+
 static struct i2c_driver ds1307_driver = {
 	.driver = {
 		.name	= "rtc-ds1307",
 		.of_match_table = of_match_ptr(ds1307_of_match),
 		.acpi_match_table = ACPI_PTR(ds1307_acpi_ids),
+		.pm	= &ds1307_pm_ops,
 	},
 	.probe		= ds1307_probe,
 	.id_table	= ds1307_id,
-- 
2.9.3

^ permalink raw reply related

* [rtc-linux] Re: [RESEND v9 06/12] rtc: Kconfig: Name RK805 in Kconfig for RTC_DRV_RK808
From: Alexandre Belloni @ 2017-08-24  9:17 UTC (permalink / raw)
  To: Joseph Chen
  Cc: gnurou, linus.walleij, dmitry.torokhov, lee.jones, linux-kernel,
	huangtao, devicetree, linux-gpio, broonie, zhangqing, robh+dt,
	lgirdwood, linux-rockchip, wdc, tony.xie, linux-input,
	mark.rutland, w.egorov, linux-clk, a.zummo, rtc-linux
In-Reply-To: <1502848835-24800-1-git-send-email-chenjh@rock-chips.com>

On 16/08/2017 at 10:00:35 +0800, Joseph Chen wrote:
> From: Elaine Zhang <zhangqing@rock-chips.com>
> 
> 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 <zhangqing@rock-chips.com>
> Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
> ---
>  drivers/rtc/Kconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [PATCH 0/4] constify rtc i2c_device_id
From: Alexandre Belloni @ 2017-08-24  9:01 UTC (permalink / raw)
  To: Arvind Yadav; +Cc: a.zummo, linux-kernel, linux-rtc
In-Reply-To: <1503169678-18078-1-git-send-email-arvind.yadav.cs@gmail.com>

On 20/08/2017 at 00:37:54 +0530, Arvind Yadav wrote:
> i2c_device_id are not supposed to change at runtime. All functions
> working with i2c_device_id provided by <linux/i2c.h> work with
> const i2c_device_id. So mark the non-const structs as const.
> 
> Arvind Yadav (4):
>   [PATCH 1/4] rtc: ds1672: constify i2c_device_id
>   [PATCH 2/4] rtc: em3027: constify i2c_device_id
>   [PATCH 3/4] rtc: max6900: constify i2c_device_id
>   [PATCH 4/4] rtc: rv3029c2: constify i2c_device_id
> 
>  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(-)
> 

All applied.

> -- 
> 2.7.4
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH v2] rtc: remove .open() and .release()
From: Alexandre Belloni @ 2017-08-24  8:52 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

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 <alexandre.belloni@free-electrons.com>
---
Changes in v2:
 - remove warning


 drivers/rtc/rtc-dev.c | 19 ++++---------------
 include/linux/rtc.h   |  2 --
 2 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 794bc4fa4937..2f5f6d6aa79a 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -27,25 +27,17 @@ 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 +430,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;
 }
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 0a0f0d14a5fb..e6d0f9c1cafd 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -72,8 +72,6 @@ extern struct class *rtc_class;
  * issued through ioctl() ...
  */
 struct rtc_class_ops {
-	int (*open)(struct device *);
-	void (*release)(struct device *);
 	int (*ioctl)(struct device *, unsigned int, unsigned long);
 	int (*read_time)(struct device *, struct rtc_time *);
 	int (*set_time)(struct device *, struct rtc_time *);
-- 
2.14.1

^ permalink raw reply related

* [PATCH v2] rtc: ds1307: add basic support for ds1341 chip
From: Nikita Yushchenko @ 2017-08-24  6:32 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Heiner Kallweit,
	Linus Walleij, Arnaud Ebalard, David Lowe,
	Javier Martinez Canillas, Marek Vasut, Tin Huynh
  Cc: linux-rtc, linux-kernel, Andrey Smirnov, Aleksander Morgado,
	Chris Healy, Nikita Yushchenko

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 <nikita.yoush@cogentembedded.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Aleksander Morgado <aleksander@aleksander.es>
---
 drivers/rtc/Kconfig      | 10 +++++-----
 drivers/rtc/rtc-ds1307.c | 13 +++++++++++++
 2 files changed, 18 insertions(+), 5 deletions(-)
===
Changes from v1:
- added information on why support was limited to date/time only to commit
  message, as suggested by Linus Walleij
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 72419ac2c52a..db63592a0f57 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 4fac49e55d47..1d11f8000f8a 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,
@@ -179,6 +180,10 @@ static 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] = {
 		.trickle_charger_reg = 0x0a,
 	},
@@ -209,6 +214,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 },
@@ -253,6 +259,10 @@ static const struct of_device_id ds1307_of_match[] = {
 		.data = (void *)ds_1340
 	},
 	{
+		.compatible = "dallas,ds1341",
+		.data = (void *)ds_1341
+	},
+	{
 		.compatible = "maxim,ds3231",
 		.data = (void *)ds_3231
 	},
@@ -298,6 +308,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 },
@@ -1323,6 +1334,7 @@ static int ds1307_probe(struct i2c_client *client,
 	static const int	bbsqi_bitpos[] = {
 		[ds_1337] = 0,
 		[ds_1339] = DS1339_BIT_BBSQI,
+		[ds_1341] = 0,
 		[ds_3231] = DS3231_BIT_BBSQW,
 	};
 	const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops;
@@ -1401,6 +1413,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,
-- 
2.11.0

^ permalink raw reply related

* [PATCH] rtc: mxc: avoid disabling interrupts on device close
From: Alexandre Belloni @ 2017-08-23 22:00 UTC (permalink / raw)
  To: linux-rtc
  Cc: Shawn Guo, Sascha Hauer, Fabio Estevam, linux-kernel,
	linux-arm-kernel, Alexandre Belloni

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

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

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,
-- 
2.14.1

^ permalink raw reply related

* [PATCH] rtc: vr41xx: make alarms useful
From: Alexandre Belloni @ 2017-08-23 20:44 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

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 <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-vr41xx.c | 18 ------------------
 1 file changed, 18 deletions(-)

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,
-- 
2.14.1

^ permalink raw reply related

* Re: [PATCH] rtc: sa1100: fix unbalanced clk_prepare_enable/clk_disable_unprepare
From: Robert Jarzmik @ 2017-08-23 19:33 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: linux-rtc, Rob Herring, linux-arm-kernel, linux-kernel
In-Reply-To: <20170821160038.22650-1-alexandre.belloni@free-electrons.com>

Alexandre Belloni <alexandre.belloni@free-electrons.com> writes:

> 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")
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

Cheers.

--
Robert

^ permalink raw reply

* Re: [PATCH] rtc: pxa: fix possible race condition
From: Robert Jarzmik @ 2017-08-23 19:32 UTC (permalink / raw)
  To: Alexandre Belloni; +Cc: linux-rtc, linux-kernel
In-Reply-To: <20170821155742.22290-1-alexandre.belloni@free-electrons.com>

Alexandre Belloni <alexandre.belloni@free-electrons.com> writes:

> 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().
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

Cheers.

--
Robert

^ permalink raw reply

* Re: [PATCH] rtc: ds1307: add basic support for ds1341 chip
From: Aleksander Morgado @ 2017-08-23 15:12 UTC (permalink / raw)
  To: Nikita Yushchenko, Alessandro Zummo, Alexandre Belloni,
	Heiner Kallweit, Linus Walleij, Arnaud Ebalard, David Lowe,
	Javier Martinez Canillas, Marek Vasut, Tin Huynh
  Cc: linux-rtc, linux-kernel, Andrey Smirnov, Chris Healy
In-Reply-To: <20170823053825.19841-1-nikita.yoush@cogentembedded.com>

On 23/08/17 07:38, Nikita Yushchenko wrote:
> This adds support for reading and writing date/time from/to ds1314 chip.
> 
> Other functionality (alarms, inout clock, output clock) is not added
> yet, because availability of that depends on chip connections.
> 
> Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>

Tested this patch on a ZII RDU2 and it seems to work properly.

Tested-by: Aleksander Morgado <aleksander@aleksander.es

> ---
>  drivers/rtc/Kconfig      | 10 +++++-----
>  drivers/rtc/rtc-ds1307.c | 13 +++++++++++++
>  2 files changed, 18 insertions(+), 5 deletions(-)
> ===
> DS1341/1342 chips have additional features, namely
> - 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 requires hardware setups
> for testing, and also is somewhat cumbersome. Additional complexity is
> caused by 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.
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 72419ac2c52a..db63592a0f57 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 4fac49e55d47..1d11f8000f8a 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,
> @@ -179,6 +180,10 @@ static 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] = {
>  		.trickle_charger_reg = 0x0a,
>  	},
> @@ -209,6 +214,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 },
> @@ -253,6 +259,10 @@ static const struct of_device_id ds1307_of_match[] = {
>  		.data = (void *)ds_1340
>  	},
>  	{
> +		.compatible = "dallas,ds1341",
> +		.data = (void *)ds_1341
> +	},
> +	{
>  		.compatible = "maxim,ds3231",
>  		.data = (void *)ds_3231
>  	},
> @@ -298,6 +308,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 },
> @@ -1323,6 +1334,7 @@ static int ds1307_probe(struct i2c_client *client,
>  	static const int	bbsqi_bitpos[] = {
>  		[ds_1337] = 0,
>  		[ds_1339] = DS1339_BIT_BBSQI,
> +		[ds_1341] = 0,
>  		[ds_3231] = DS3231_BIT_BBSQW,
>  	};
>  	const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops;
> @@ -1401,6 +1413,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,
> 


-- 
Aleksander
https://aleksander.es

^ permalink raw reply

* [PATCH v2] rtc: sa1100: make alarms useful
From: Alexandre Belloni @ 2017-08-23  9:49 UTC (permalink / raw)
  To: linux-rtc; +Cc: Rob Herring, linux-kernel, Alexandre Belloni

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 <alexandre.belloni@free-electrons.com>
---
Changes in v2:
 - Fix build issues


 drivers/rtc/rtc-sa1100.c | 63 +++++++++++++++++-------------------------------
 1 file changed, 22 insertions(+), 41 deletions(-)

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;
 }
-- 
2.14.1

^ permalink raw reply related

* Re: [PATCH] rtc: ds1307: add basic support for ds1341 chip
From: Linus Walleij @ 2017-08-23  8:25 UTC (permalink / raw)
  To: Nikita Yushchenko
  Cc: Alessandro Zummo, Alexandre Belloni, Heiner Kallweit,
	Arnaud Ebalard, David Lowe, Javier Martinez Canillas, Marek Vasut,
	Tin Huynh, linux-rtc, linux-kernel@vger.kernel.org,
	Andrey Smirnov, Aleksander Morgado, Chris Healy
In-Reply-To: <20170823053825.19841-1-nikita.yoush@cogentembedded.com>

On Wed, Aug 23, 2017 at 7:38 AM, Nikita Yushchenko
<nikita.yoush@cogentembedded.com> wrote:

> This adds support for reading and writing date/time from/to ds1314 chip.
>
> Other functionality (alarms, inout clock, output clock) is not added
> yet, because availability of that depends on chip connections.
>
> Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>

Overall this looks fine.

> ---
>  drivers/rtc/Kconfig      | 10 +++++-----
>  drivers/rtc/rtc-ds1307.c | 13 +++++++++++++
>  2 files changed, 18 insertions(+), 5 deletions(-)
> ===
> DS1341/1342 chips have additional features, namely
> - alarms,
> - input clock (can be used instead of intercal oscillator for better
>   accuracy),
> - output clock ("square wave generation")

When you put all this useful information below the commit line
like this it gets lost and is not in the commit message in
git log.

Please live it into the commit blurb or even, if really useful,
as a comment in the driver itself.

With that:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH] rtc: ds1307: add basic support for ds1341 chip
From: Nikita Yushchenko @ 2017-08-23  5:38 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Heiner Kallweit,
	Linus Walleij, Arnaud Ebalard, David Lowe,
	Javier Martinez Canillas, Marek Vasut, Tin Huynh
  Cc: linux-rtc, linux-kernel, Andrey Smirnov, Aleksander Morgado,
	Chris Healy, Nikita Yushchenko

This adds support for reading and writing date/time from/to ds1314 chip.

Other functionality (alarms, inout clock, output clock) is not added
yet, because availability of that depends on chip connections.

Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
---
 drivers/rtc/Kconfig      | 10 +++++-----
 drivers/rtc/rtc-ds1307.c | 13 +++++++++++++
 2 files changed, 18 insertions(+), 5 deletions(-)
===
DS1341/1342 chips have additional features, namely
- 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 requires hardware setups
for testing, and also is somewhat cumbersome. Additional complexity is
caused by 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.

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 72419ac2c52a..db63592a0f57 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 4fac49e55d47..1d11f8000f8a 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,
@@ -179,6 +180,10 @@ static 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] = {
 		.trickle_charger_reg = 0x0a,
 	},
@@ -209,6 +214,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 },
@@ -253,6 +259,10 @@ static const struct of_device_id ds1307_of_match[] = {
 		.data = (void *)ds_1340
 	},
 	{
+		.compatible = "dallas,ds1341",
+		.data = (void *)ds_1341
+	},
+	{
 		.compatible = "maxim,ds3231",
 		.data = (void *)ds_3231
 	},
@@ -298,6 +308,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 },
@@ -1323,6 +1334,7 @@ static int ds1307_probe(struct i2c_client *client,
 	static const int	bbsqi_bitpos[] = {
 		[ds_1337] = 0,
 		[ds_1339] = DS1339_BIT_BBSQI,
+		[ds_1341] = 0,
 		[ds_3231] = DS3231_BIT_BBSQW,
 	};
 	const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops;
@@ -1401,6 +1413,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,
-- 
2.11.0

^ permalink raw reply related

* Re: [RFC 2/3] rtc: Add Realtek RTD1295
From: Alexandre Belloni @ 2017-08-23  1:18 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Alessandro Zummo, linux-rtc, linux-arm-kernel, linux-kernel,
	Roc He, 蒋丽琴
In-Reply-To: <3307d3ed-c8e0-a7b5-f0ee-d401f4b12a90@suse.de>

On 20/08/2017 at 23:10:16 +0200, Andreas Färber wrote:
> > Is RTD_RTCDATE_HIGH latched when RTD_RTCDATE_LOW is read?
> 
> I do not have an answer to that.
> 
> > If this is not
> > the case, you probably want to handle a possible update between both
> > readl_relaxed.
> 
> Are you proposing to disable the RTC while reading the registers, or
> something related to my choice of _relaxed? (it follows an explanation
> by Marc Zyngier on the irq mux series) Inconsistencies might not be
> limited to the date.
> 

A simple way to be sure would be to read RTD_RTCSEC first, then the
other registers and check RTD_RTCSEC didn't change. This will ensure the
other registers have not be updated in the meantime (unless it takes
one minute but I doubt this is the case). if RTD_RTCSEC changed, then
you can start over.

> >> +	t = mktime64(data->base_year, 1, 1, 0, 0, 0);
> >> +	t += day * 24 * 60 * 60;
> >> +	rtc_time64_to_tm(t, tm);
> 
> BTW is there any more efficient way to get from year+days to
> day/month/year without going via seconds?
> 

Completely untested:

for (y = data->base_year; (day - (365 + is_leap_year(y))) > 0; y++)
	day -= (365 + is_leap_year(y));

for (m = 0; (day - rtc_month_days(m, y)) > 0; m++)
	day -= rtc_month_days(m, y);


> >> +
> >> +	rtd119x_rtc_set_enabled(dev, true);
> >> +
> > 
> > This is certainly not what you want. The RTC device is usually not
> > opened so enabling the RTC when open and disabling it when closed will
> > not work on most systems. This is probably true for the clock too. i.e
> > what you do here should be done in probe.
> 
> I did test the probe path to work, but I can change it again. The
> downstream code had it in probe, but looking at rtc_class_ops I saw
> those hooks and thought they'd serve a purpose - what are they for then?
> (Any chance you can improve the documentation comments to avoid such
> misunderstandings? :))
> 

They are (were) used only when the rtc character device (/dev/rtcx) is
opened/released but the cdev interface is one of many interfaces to the
RTC sod it doesn't make sense to do something only in that case
(especially requesting IRQs).

To solve your concern, this is what I'm going to apply after fixing the
two remaining uses of .release:

http://patchwork.ozlabs.org/patch/804707/


-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH] rtc: remove .open() and .release()
From: Alexandre Belloni @ 2017-08-23  0:33 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

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 <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-dev.c | 18 ++++--------------
 include/linux/rtc.h   |  2 --
 2 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 794bc4fa4937..107e5ca95113 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -34,18 +34,11 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
 
 	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 +431,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;
 }
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 0a0f0d14a5fb..e6d0f9c1cafd 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -72,8 +72,6 @@ extern struct class *rtc_class;
  * issued through ioctl() ...
  */
 struct rtc_class_ops {
-	int (*open)(struct device *);
-	void (*release)(struct device *);
 	int (*ioctl)(struct device *, unsigned int, unsigned long);
 	int (*read_time)(struct device *, struct rtc_time *);
 	int (*set_time)(struct device *, struct rtc_time *);
-- 
2.14.1

^ permalink raw reply related

* Re: [RFC 1/3] dt-bindings: rtc: Add Realtek RTD1295
From: Rob Herring @ 2017-08-23  0:29 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Alessandro Zummo, Alexandre Belloni, linux-rtc, linux-arm-kernel,
	linux-kernel, Roc He, 蒋丽琴, Mark Rutland,
	devicetree
In-Reply-To: <20170820013632.18375-2-afaerber@suse.de>

On Sun, Aug 20, 2017 at 03:36:29AM +0200, Andreas Färber wrote:
> Add a binding for the RTC on the Realtek RTD119x/RTD129x SoC families.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  .../devicetree/bindings/rtc/realtek,rtd119x.txt          | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH] rtc: sa1100: make alarms useful
From: Alexandre Belloni @ 2017-08-22 23:53 UTC (permalink / raw)
  To: linux-rtc; +Cc: Rob Herring, linux-kernel, Alexandre Belloni

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 <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-sa1100.c | 61 ++++++++++++++++--------------------------------
 1 file changed, 20 insertions(+), 41 deletions(-)

diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index fe8ebf47bbe5..8e6cf4323267 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,
@@ -309,6 +269,21 @@ 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", 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", dev);
+	if (ret) {
+		dev_err(&pdev->dev, dev, "IRQ %d already in use.\n", irq_alarm);
+		return ret;
+	}
+
+	rtc->max_user_freq = RTC_FREQ;
+	rtc_irq_set_freq(rtc, NULL, RTC_FREQ);
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	base = devm_ioremap_resource(&pdev->dev, iores);
 	if (IS_ERR(base))
@@ -337,8 +312,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;
 }
-- 
2.14.1

^ permalink raw reply related

* [rtc-linux] Re: [PATCH] rtc: m41t80: enable wakealarm when "wakeup-source" is specified
From: Alexandre Belloni @ 2017-08-22 23:23 UTC (permalink / raw)
  To: Eric Cooper; +Cc: Alessandro Zummo, rtc-linux
In-Reply-To: <20170730001054.20118-1-ecc@cmu.edu>

On 29/07/2017 at 20:10:54 -0400, Eric Cooper wrote:
> Don't require an IRQ if the wakeup-source device-tree property is present.
> 
> Signed-off-by: Eric Cooper <ecc@cmu.edu>
> ---
>  drivers/rtc/rtc-m41t80.c | 23 +++++++++++++++++------
>  1 file changed, 17 insertions(+), 6 deletions(-)
> 

I've applied it but it didn't apply cleanly, please check rtc-next or
linux-next, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* [PATCH] rtc: m41t80: remove debug sysfs attribute
From: Alexandre Belloni @ 2017-08-22 23:17 UTC (permalink / raw)
  To: linux-rtc; +Cc: linux-kernel, Alexandre Belloni

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 <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-m41t80.c | 44 --------------------------------------------
 1 file changed, 44 deletions(-)

diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 3b6ef4b0f4ac..56fa6ca93c25 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;
-- 
2.14.1

^ permalink raw reply related

* [PATCH] rtc: m41t80: enable wakealarm when "wakeup-source" is specified
From: Eric Cooper @ 2017-07-30  0:10 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, rtc-linux; +Cc: Eric Cooper

Don't require an IRQ if the wakeup-source device-tree property is present.

Signed-off-by: Eric Cooper <ecc@cmu.edu>
---
 drivers/rtc/rtc-m41t80.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 58698d21c2c3..85ecb7043dc5 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -774,6 +774,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)) {
@@ -789,6 +790,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,
@@ -797,14 +802,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);
@@ -812,6 +819,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);
-- 
2.13.2

^ permalink raw reply related

* [PATCH 2/2] rtc: puv3: make alarms useful
From: Alexandre Belloni @ 2017-08-22 10:06 UTC (permalink / raw)
  To: Guan Xuetao; +Cc: linux-rtc, linux-kernel, Alexandre Belloni
In-Reply-To: <20170822100651.26590-1-alexandre.belloni@free-electrons.com>

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 <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-puv3.c | 56 +++++++++++++-------------------------------------
 1 file changed, 14 insertions(+), 42 deletions(-)

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) {
-- 
2.14.1

^ permalink raw reply related

* [PATCH 1/2] rtc: puv3: switch to devm_rtc_allocate_device()/rtc_register_device()
From: Alexandre Belloni @ 2017-08-22 10:06 UTC (permalink / raw)
  To: Guan Xuetao; +Cc: linux-rtc, linux-kernel, Alexandre Belloni

Use managed RTC device allocation as this allows for further cleanup.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/rtc/rtc-puv3.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

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;
 	}
 
-- 
2.14.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox