All of lore.kernel.org
 help / color / mirror / Atom feed
* [rtc-linux] [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-23 10:41 ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree, Maxime Ripard

Hi,

The RTC used in the A31 and later SoC has an accuracy issue, which is
already significant even after a couple of hours.

This is due to the fact that the oscillator used by default is an internal
and very inaccurate one.

A first attempt at fixing that by switching to the external oscillator was
done in the patch "rtc: sun6i: Switch to the external oscillator". However,
it turned out to be problematic since it was tracked properly in the clock
framework, which might lead to some clocks being disabled, even though
their devices were not notified.

This is a second attempt, this time by making it part of the CCF. It
turned out to be a bit more complicated than one would expect since the mux
found inside the RTC also controls one of the input of the main clock unit.
Therefore, it needs to be probed before the main clock unit driver.

Let me know what you think,
Maxime

Changes from v1:
  - Force the muxing to the external oscillator even for old DT
  - Make the patches a bit more stable friendly
  - Change the bindings to have a cell of 1, to account for the external
    output of the oscillator
  - Split the driver remove() removal into a separate patch and switched to
    devm
  - Reordered the patches

Maxime Ripard (7):
  rtc: sun6i: Disable the build as a module
  rtc: sun6i: Add some locking
  rtc: sun6i: Switch to the external oscillator
  rtc: sun6i: Expose the 32kHz oscillator
  rtc: sun6i: Switch to devm_rtc_device_register
  ARM: sun8i: a23/a33: Enable the real LOSC and use it
  ARM: sun8i: a23/a33: Add the oscillators accuracy

 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi                |  15 +-
 drivers/rtc/Kconfig                                 |   2 +-
 drivers/rtc/rtc-sun6i.c                             | 182 ++++++++++---
 4 files changed, 174 insertions(+), 35 deletions(-)

base-commit: 99cef370ac9939df2aeb16c96d07e842b2fa8201
-- 
git-series 0.8.11

-- 
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	[flat|nested] 35+ messages in thread

* [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-23 10:41 ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard

Hi,

The RTC used in the A31 and later SoC has an accuracy issue, which is
already significant even after a couple of hours.

This is due to the fact that the oscillator used by default is an internal
and very inaccurate one.

A first attempt at fixing that by switching to the external oscillator was
done in the patch "rtc: sun6i: Switch to the external oscillator". However,
it turned out to be problematic since it was tracked properly in the clock
framework, which might lead to some clocks being disabled, even though
their devices were not notified.

This is a second attempt, this time by making it part of the CCF. It
turned out to be a bit more complicated than one would expect since the mux
found inside the RTC also controls one of the input of the main clock unit.
Therefore, it needs to be probed before the main clock unit driver.

Let me know what you think,
Maxime

Changes from v1:
  - Force the muxing to the external oscillator even for old DT
  - Make the patches a bit more stable friendly
  - Change the bindings to have a cell of 1, to account for the external
    output of the oscillator
  - Split the driver remove() removal into a separate patch and switched to
    devm
  - Reordered the patches

Maxime Ripard (7):
  rtc: sun6i: Disable the build as a module
  rtc: sun6i: Add some locking
  rtc: sun6i: Switch to the external oscillator
  rtc: sun6i: Expose the 32kHz oscillator
  rtc: sun6i: Switch to devm_rtc_device_register
  ARM: sun8i: a23/a33: Enable the real LOSC and use it
  ARM: sun8i: a23/a33: Add the oscillators accuracy

 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi                |  15 +-
 drivers/rtc/Kconfig                                 |   2 +-
 drivers/rtc/rtc-sun6i.c                             | 182 ++++++++++---
 4 files changed, 174 insertions(+), 35 deletions(-)

base-commit: 99cef370ac9939df2aeb16c96d07e842b2fa8201
-- 
git-series 0.8.11

-- 
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-23 10:41 ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

The RTC used in the A31 and later SoC has an accuracy issue, which is
already significant even after a couple of hours.

This is due to the fact that the oscillator used by default is an internal
and very inaccurate one.

A first attempt at fixing that by switching to the external oscillator was
done in the patch "rtc: sun6i: Switch to the external oscillator". However,
it turned out to be problematic since it was tracked properly in the clock
framework, which might lead to some clocks being disabled, even though
their devices were not notified.

This is a second attempt, this time by making it part of the CCF. It
turned out to be a bit more complicated than one would expect since the mux
found inside the RTC also controls one of the input of the main clock unit.
Therefore, it needs to be probed before the main clock unit driver.

Let me know what you think,
Maxime

Changes from v1:
  - Force the muxing to the external oscillator even for old DT
  - Make the patches a bit more stable friendly
  - Change the bindings to have a cell of 1, to account for the external
    output of the oscillator
  - Split the driver remove() removal into a separate patch and switched to
    devm
  - Reordered the patches

Maxime Ripard (7):
  rtc: sun6i: Disable the build as a module
  rtc: sun6i: Add some locking
  rtc: sun6i: Switch to the external oscillator
  rtc: sun6i: Expose the 32kHz oscillator
  rtc: sun6i: Switch to devm_rtc_device_register
  ARM: sun8i: a23/a33: Enable the real LOSC and use it
  ARM: sun8i: a23/a33: Add the oscillators accuracy

 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi                |  15 +-
 drivers/rtc/Kconfig                                 |   2 +-
 drivers/rtc/rtc-sun6i.c                             | 182 ++++++++++---
 4 files changed, 174 insertions(+), 35 deletions(-)

base-commit: 99cef370ac9939df2aeb16c96d07e842b2fa8201
-- 
git-series 0.8.11

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

* [rtc-linux] [PATCH v2 1/7] rtc: sun6i: Disable the build as a module
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree,
	Maxime Ripard, stable

Since we have to provide the clock very early on, the RTC driver cannot be
built as a module. Make sure that won't happen.

Cc: stable@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/Kconfig     | 2 +-
 drivers/rtc/rtc-sun6i.c | 7 +------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index c93c5a8fba32..53e35c138ff3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1434,7 +1434,7 @@ config RTC_DRV_SUN4V
 	  based RTC on SUN4V systems.
 
 config RTC_DRV_SUN6I
-	tristate "Allwinner A31 RTC"
+	bool "Allwinner A31 RTC"
 	default MACH_SUN6I || MACH_SUN8I || COMPILE_TEST
 	depends on ARCH_SUNXI
 	help
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c169a2cd4727..a6136cb99851 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -439,9 +439,4 @@ static struct platform_driver sun6i_rtc_driver = {
 		.of_match_table = sun6i_rtc_dt_ids,
 	},
 };
-
-module_platform_driver(sun6i_rtc_driver);
-
-MODULE_DESCRIPTION("sun6i RTC driver");
-MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun6i_rtc_driver);
-- 
git-series 0.8.11

-- 
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 related	[flat|nested] 35+ messages in thread

* [PATCH v2 1/7] rtc: sun6i: Disable the build as a module
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
	stable-u79uwXL29TY76Z2rM5mHXA

Since we have to provide the clock very early on, the RTC driver cannot be
built as a module. Make sure that won't happen.

Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/rtc/Kconfig     | 2 +-
 drivers/rtc/rtc-sun6i.c | 7 +------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index c93c5a8fba32..53e35c138ff3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1434,7 +1434,7 @@ config RTC_DRV_SUN4V
 	  based RTC on SUN4V systems.
 
 config RTC_DRV_SUN6I
-	tristate "Allwinner A31 RTC"
+	bool "Allwinner A31 RTC"
 	default MACH_SUN6I || MACH_SUN8I || COMPILE_TEST
 	depends on ARCH_SUNXI
 	help
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c169a2cd4727..a6136cb99851 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -439,9 +439,4 @@ static struct platform_driver sun6i_rtc_driver = {
 		.of_match_table = sun6i_rtc_dt_ids,
 	},
 };
-
-module_platform_driver(sun6i_rtc_driver);
-
-MODULE_DESCRIPTION("sun6i RTC driver");
-MODULE_AUTHOR("Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun6i_rtc_driver);
-- 
git-series 0.8.11

-- 
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 1/7] rtc: sun6i: Disable the build as a module
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree,
	Maxime Ripard, stable

Since we have to provide the clock very early on, the RTC driver cannot be
built as a module. Make sure that won't happen.

Cc: stable@vger.kernel.org
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/Kconfig     | 2 +-
 drivers/rtc/rtc-sun6i.c | 7 +------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index c93c5a8fba32..53e35c138ff3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1434,7 +1434,7 @@ config RTC_DRV_SUN4V
 	  based RTC on SUN4V systems.
 
 config RTC_DRV_SUN6I
-	tristate "Allwinner A31 RTC"
+	bool "Allwinner A31 RTC"
 	default MACH_SUN6I || MACH_SUN8I || COMPILE_TEST
 	depends on ARCH_SUNXI
 	help
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c169a2cd4727..a6136cb99851 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -439,9 +439,4 @@ static struct platform_driver sun6i_rtc_driver = {
 		.of_match_table = sun6i_rtc_dt_ids,
 	},
 };
-
-module_platform_driver(sun6i_rtc_driver);
-
-MODULE_DESCRIPTION("sun6i RTC driver");
-MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun6i_rtc_driver);
-- 
git-series 0.8.11

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

* [PATCH v2 1/7] rtc: sun6i: Disable the build as a module
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Since we have to provide the clock very early on, the RTC driver cannot be
built as a module. Make sure that won't happen.

Cc: stable at vger.kernel.org
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/Kconfig     | 2 +-
 drivers/rtc/rtc-sun6i.c | 7 +------
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index c93c5a8fba32..53e35c138ff3 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1434,7 +1434,7 @@ config RTC_DRV_SUN4V
 	  based RTC on SUN4V systems.
 
 config RTC_DRV_SUN6I
-	tristate "Allwinner A31 RTC"
+	bool "Allwinner A31 RTC"
 	default MACH_SUN6I || MACH_SUN8I || COMPILE_TEST
 	depends on ARCH_SUNXI
 	help
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c169a2cd4727..a6136cb99851 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -439,9 +439,4 @@ static struct platform_driver sun6i_rtc_driver = {
 		.of_match_table = sun6i_rtc_dt_ids,
 	},
 };
-
-module_platform_driver(sun6i_rtc_driver);
-
-MODULE_DESCRIPTION("sun6i RTC driver");
-MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
-MODULE_LICENSE("GPL");
+builtin_platform_driver(sun6i_rtc_driver);
-- 
git-series 0.8.11

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

* [rtc-linux] [PATCH v2 2/7] rtc: sun6i: Add some locking
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree,
	Maxime Ripard, stable

Some registers have a read-modify-write access pattern that are not atomic.

Add some locking to prevent from concurrent accesses.

Cc: stable@vger.kernel.org
Acked-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index a6136cb99851..5527f5eb597b 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -114,13 +114,17 @@ struct sun6i_rtc_dev {
 	void __iomem *base;
 	int irq;
 	unsigned long alarm;
+
+	spinlock_t lock;
 };
 
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
+	irqreturn_t ret = IRQ_NONE;
 	u32 val;
 
+	spin_lock(&chip->lock);
 	val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
 
 	if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
@@ -129,10 +133,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 
 		rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
 
-		return IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
+	spin_unlock(&chip->lock);
 
-	return IRQ_NONE;
+	return ret;
 }
 
 static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
@@ -140,6 +145,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 	u32 alrm_val = 0;
 	u32 alrm_irq_val = 0;
 	u32 alrm_wake_val = 0;
+	unsigned long flags;
 
 	if (to) {
 		alrm_val = SUN6I_ALRM_EN_CNT_EN;
@@ -150,9 +156,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 		       chip->base + SUN6I_ALRM_IRQ_STA);
 	}
 
+	spin_lock_irqsave(&chip->lock, flags);
 	writel(alrm_val, chip->base + SUN6I_ALRM_EN);
 	writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
 	writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
+	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
 static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
@@ -191,11 +199,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 {
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+	unsigned long flags;
 	u32 alrm_st;
 	u32 alrm_en;
 
+	spin_lock_irqsave(&chip->lock, flags);
 	alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
 	alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
+	spin_unlock_irqrestore(&chip->lock, flags);
+
 	wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
 	wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
 	rtc_time_to_tm(chip->alarm, &wkalrm->time);
@@ -356,6 +368,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
+	spin_lock_init(&rtc->lock);
 
 	platform_set_drvdata(pdev, chip);
 	chip->dev = &pdev->dev;
-- 
git-series 0.8.11

-- 
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 related	[flat|nested] 35+ messages in thread

* [PATCH v2 2/7] rtc: sun6i: Add some locking
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard,
	stable-u79uwXL29TY76Z2rM5mHXA

Some registers have a read-modify-write access pattern that are not atomic.

Add some locking to prevent from concurrent accesses.

Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Acked-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/rtc/rtc-sun6i.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index a6136cb99851..5527f5eb597b 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -114,13 +114,17 @@ struct sun6i_rtc_dev {
 	void __iomem *base;
 	int irq;
 	unsigned long alarm;
+
+	spinlock_t lock;
 };
 
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
+	irqreturn_t ret = IRQ_NONE;
 	u32 val;
 
+	spin_lock(&chip->lock);
 	val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
 
 	if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
@@ -129,10 +133,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 
 		rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
 
-		return IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
+	spin_unlock(&chip->lock);
 
-	return IRQ_NONE;
+	return ret;
 }
 
 static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
@@ -140,6 +145,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 	u32 alrm_val = 0;
 	u32 alrm_irq_val = 0;
 	u32 alrm_wake_val = 0;
+	unsigned long flags;
 
 	if (to) {
 		alrm_val = SUN6I_ALRM_EN_CNT_EN;
@@ -150,9 +156,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 		       chip->base + SUN6I_ALRM_IRQ_STA);
 	}
 
+	spin_lock_irqsave(&chip->lock, flags);
 	writel(alrm_val, chip->base + SUN6I_ALRM_EN);
 	writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
 	writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
+	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
 static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
@@ -191,11 +199,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 {
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+	unsigned long flags;
 	u32 alrm_st;
 	u32 alrm_en;
 
+	spin_lock_irqsave(&chip->lock, flags);
 	alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
 	alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
+	spin_unlock_irqrestore(&chip->lock, flags);
+
 	wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
 	wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
 	rtc_time_to_tm(chip->alarm, &wkalrm->time);
@@ -356,6 +368,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
+	spin_lock_init(&rtc->lock);
 
 	platform_set_drvdata(pdev, chip);
 	chip->dev = &pdev->dev;
-- 
git-series 0.8.11

-- 
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 2/7] rtc: sun6i: Add some locking
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree,
	Maxime Ripard, stable

Some registers have a read-modify-write access pattern that are not atomic.

Add some locking to prevent from concurrent accesses.

Cc: stable@vger.kernel.org
Acked-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index a6136cb99851..5527f5eb597b 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -114,13 +114,17 @@ struct sun6i_rtc_dev {
 	void __iomem *base;
 	int irq;
 	unsigned long alarm;
+
+	spinlock_t lock;
 };
 
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
+	irqreturn_t ret = IRQ_NONE;
 	u32 val;
 
+	spin_lock(&chip->lock);
 	val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
 
 	if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
@@ -129,10 +133,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 
 		rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
 
-		return IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
+	spin_unlock(&chip->lock);
 
-	return IRQ_NONE;
+	return ret;
 }
 
 static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
@@ -140,6 +145,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 	u32 alrm_val = 0;
 	u32 alrm_irq_val = 0;
 	u32 alrm_wake_val = 0;
+	unsigned long flags;
 
 	if (to) {
 		alrm_val = SUN6I_ALRM_EN_CNT_EN;
@@ -150,9 +156,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 		       chip->base + SUN6I_ALRM_IRQ_STA);
 	}
 
+	spin_lock_irqsave(&chip->lock, flags);
 	writel(alrm_val, chip->base + SUN6I_ALRM_EN);
 	writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
 	writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
+	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
 static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
@@ -191,11 +199,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 {
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+	unsigned long flags;
 	u32 alrm_st;
 	u32 alrm_en;
 
+	spin_lock_irqsave(&chip->lock, flags);
 	alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
 	alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
+	spin_unlock_irqrestore(&chip->lock, flags);
+
 	wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
 	wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
 	rtc_time_to_tm(chip->alarm, &wkalrm->time);
@@ -356,6 +368,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
+	spin_lock_init(&rtc->lock);
 
 	platform_set_drvdata(pdev, chip);
 	chip->dev = &pdev->dev;
-- 
git-series 0.8.11

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

* [PATCH v2 2/7] rtc: sun6i: Add some locking
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Some registers have a read-modify-write access pattern that are not atomic.

Add some locking to prevent from concurrent accesses.

Cc: stable at vger.kernel.org
Acked-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index a6136cb99851..5527f5eb597b 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -114,13 +114,17 @@ struct sun6i_rtc_dev {
 	void __iomem *base;
 	int irq;
 	unsigned long alarm;
+
+	spinlock_t lock;
 };
 
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
+	irqreturn_t ret = IRQ_NONE;
 	u32 val;
 
+	spin_lock(&chip->lock);
 	val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
 
 	if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
@@ -129,10 +133,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 
 		rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
 
-		return IRQ_HANDLED;
+		ret = IRQ_HANDLED;
 	}
+	spin_unlock(&chip->lock);
 
-	return IRQ_NONE;
+	return ret;
 }
 
 static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
@@ -140,6 +145,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 	u32 alrm_val = 0;
 	u32 alrm_irq_val = 0;
 	u32 alrm_wake_val = 0;
+	unsigned long flags;
 
 	if (to) {
 		alrm_val = SUN6I_ALRM_EN_CNT_EN;
@@ -150,9 +156,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
 		       chip->base + SUN6I_ALRM_IRQ_STA);
 	}
 
+	spin_lock_irqsave(&chip->lock, flags);
 	writel(alrm_val, chip->base + SUN6I_ALRM_EN);
 	writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
 	writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
+	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
 static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
@@ -191,11 +199,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
 static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 {
 	struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+	unsigned long flags;
 	u32 alrm_st;
 	u32 alrm_en;
 
+	spin_lock_irqsave(&chip->lock, flags);
 	alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
 	alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
+	spin_unlock_irqrestore(&chip->lock, flags);
+
 	wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
 	wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
 	rtc_time_to_tm(chip->alarm, &wkalrm->time);
@@ -356,6 +368,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
+	spin_lock_init(&rtc->lock);
 
 	platform_set_drvdata(pdev, chip);
 	chip->dev = &pdev->dev;
-- 
git-series 0.8.11

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

* [rtc-linux] [PATCH v2 3/7] rtc: sun6i: Switch to the external oscillator
  2017-01-23 10:41 ` Maxime Ripard
  (?)
@ 2017-01-23 10:41   ` Maxime Ripard
  -1 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree,
	Maxime Ripard, stable

The RTC is clocked from either an internal, imprecise, oscillator or an
external one, which is usually much more accurate.

The difference perceived between the time elapsed and the time reported by
the RTC is in a 10% scale, which prevents the RTC from being useful at all.

Fortunately, the external oscillator is reported to be mandatory in the
Allwinner datasheet, so we can just switch to it.

Cc: stable@vger.kernel.org
Fixes: 9765d2d94309 ("rtc: sun6i: Add sun6i RTC driver")
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 6 ++++++
 1 file changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 5527f5eb597b..47f2022948a6 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -37,9 +37,11 @@
 
 /* Control register */
 #define SUN6I_LOSC_CTRL				0x0000
+#define SUN6I_LOSC_CTRL_KEY			(0x16aa << 16)
 #define SUN6I_LOSC_CTRL_ALM_DHMS_ACC		BIT(9)
 #define SUN6I_LOSC_CTRL_RTC_HMS_ACC		BIT(8)
 #define SUN6I_LOSC_CTRL_RTC_YMD_ACC		BIT(7)
+#define SUN6I_LOSC_CTRL_EXT_OSC			BIT(0)
 #define SUN6I_LOSC_CTRL_ACC_MASK		GENMASK(9, 7)
 
 /* RTC */
@@ -417,6 +419,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	/* disable alarm wakeup */
 	writel(0, chip->base + SUN6I_ALARM_CONFIG);
 
+	/* switch to the external, more precise, oscillator */
+	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
+	       chip->base + SUN6I_LOSC_CTRL);
+
 	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
 					&sun6i_rtc_ops, THIS_MODULE);
 	if (IS_ERR(chip->rtc)) {
-- 
git-series 0.8.11

-- 
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 related	[flat|nested] 35+ messages in thread

* [PATCH v2 3/7] rtc: sun6i: Switch to the external oscillator
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree,
	Maxime Ripard, stable

The RTC is clocked from either an internal, imprecise, oscillator or an
external one, which is usually much more accurate.

The difference perceived between the time elapsed and the time reported by
the RTC is in a 10% scale, which prevents the RTC from being useful at all.

Fortunately, the external oscillator is reported to be mandatory in the
Allwinner datasheet, so we can just switch to it.

Cc: stable@vger.kernel.org
Fixes: 9765d2d94309 ("rtc: sun6i: Add sun6i RTC driver")
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 6 ++++++
 1 file changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 5527f5eb597b..47f2022948a6 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -37,9 +37,11 @@
 
 /* Control register */
 #define SUN6I_LOSC_CTRL				0x0000
+#define SUN6I_LOSC_CTRL_KEY			(0x16aa << 16)
 #define SUN6I_LOSC_CTRL_ALM_DHMS_ACC		BIT(9)
 #define SUN6I_LOSC_CTRL_RTC_HMS_ACC		BIT(8)
 #define SUN6I_LOSC_CTRL_RTC_YMD_ACC		BIT(7)
+#define SUN6I_LOSC_CTRL_EXT_OSC			BIT(0)
 #define SUN6I_LOSC_CTRL_ACC_MASK		GENMASK(9, 7)
 
 /* RTC */
@@ -417,6 +419,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	/* disable alarm wakeup */
 	writel(0, chip->base + SUN6I_ALARM_CONFIG);
 
+	/* switch to the external, more precise, oscillator */
+	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
+	       chip->base + SUN6I_LOSC_CTRL);
+
 	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
 					&sun6i_rtc_ops, THIS_MODULE);
 	if (IS_ERR(chip->rtc)) {
-- 
git-series 0.8.11

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

* [PATCH v2 3/7] rtc: sun6i: Switch to the external oscillator
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

The RTC is clocked from either an internal, imprecise, oscillator or an
external one, which is usually much more accurate.

The difference perceived between the time elapsed and the time reported by
the RTC is in a 10% scale, which prevents the RTC from being useful at all.

Fortunately, the external oscillator is reported to be mandatory in the
Allwinner datasheet, so we can just switch to it.

Cc: stable at vger.kernel.org
Fixes: 9765d2d94309 ("rtc: sun6i: Add sun6i RTC driver")
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 6 ++++++
 1 file changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 5527f5eb597b..47f2022948a6 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -37,9 +37,11 @@
 
 /* Control register */
 #define SUN6I_LOSC_CTRL				0x0000
+#define SUN6I_LOSC_CTRL_KEY			(0x16aa << 16)
 #define SUN6I_LOSC_CTRL_ALM_DHMS_ACC		BIT(9)
 #define SUN6I_LOSC_CTRL_RTC_HMS_ACC		BIT(8)
 #define SUN6I_LOSC_CTRL_RTC_YMD_ACC		BIT(7)
+#define SUN6I_LOSC_CTRL_EXT_OSC			BIT(0)
 #define SUN6I_LOSC_CTRL_ACC_MASK		GENMASK(9, 7)
 
 /* RTC */
@@ -417,6 +419,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	/* disable alarm wakeup */
 	writel(0, chip->base + SUN6I_ALARM_CONFIG);
 
+	/* switch to the external, more precise, oscillator */
+	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
+	       chip->base + SUN6I_LOSC_CTRL);
+
 	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
 					&sun6i_rtc_ops, THIS_MODULE);
 	if (IS_ERR(chip->rtc)) {
-- 
git-series 0.8.11

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

* [rtc-linux] [PATCH v2 4/7] rtc: sun6i: Expose the 32kHz oscillator
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree, Maxime Ripard

The RTC controls the input source of the main 32kHz oscillator in the
system, feeding it to the clock unit too.

By default, this is using an internal, very inaccurate (+/- 30%)
oscillator with a divider to make it roughly around 32kHz. This is however
quite impractical for the RTC, since our time will not be tracked properly.

Since this oscillator is an input of the main clock unit, and since that
clock unit will be probed using CLK_OF_DECLARE, we have to use it as well,
leading to a two stage probe: one to enable the clock, the other one to
enable the RTC.

There is also a slight change in the binding that is required (and should
have been from the beginning), since we'll need a phandle to the external
oscillator used on that board. We support the old binding by not allowing
to switch to the external oscillator and only using the internal one (which
was the previous behaviour) in the case where we're missing that phandle.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-
 drivers/rtc/rtc-sun6i.c                             | 146 +++++++++++--
 2 files changed, 143 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
index f007e428a1ab..945934918b71 100644
--- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
@@ -8,10 +8,20 @@ Required properties:
 		  memory mapped region.
 - interrupts	: IRQ lines for the RTC alarm 0 and alarm 1, in that order.
 
+Required properties for new device trees
+- clocks	: phandle to the 32kHz external oscillator
+- clock-output-names : name of the LOSC clock 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.
+
 Example:
 
 rtc: rtc@01f00000 {
 	compatible = "allwinner,sun6i-a31-rtc";
 	reg = <0x01f00000 0x54>;
 	interrupts = <0 40 4>, <0 41 4>;
+	clock-output-names = "osc32k";
+	clocks = <&ext_osc32k>;
+	#clock-cells = <1>;
 };
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 47f2022948a6..37f65c50ab2d 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -20,6 +20,8 @@
  * more details.
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/fs.h>
@@ -33,6 +35,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 /* Control register */
@@ -44,6 +47,8 @@
 #define SUN6I_LOSC_CTRL_EXT_OSC			BIT(0)
 #define SUN6I_LOSC_CTRL_ACC_MASK		GENMASK(9, 7)
 
+#define SUN6I_LOSC_CLK_PRESCAL			0x0008
+
 /* RTC */
 #define SUN6I_RTC_YMD				0x0010
 #define SUN6I_RTC_HMS				0x0014
@@ -117,9 +122,134 @@ struct sun6i_rtc_dev {
 	int irq;
 	unsigned long alarm;
 
+	struct clk_hw hw;
+	struct clk_hw *int_osc;
+	struct clk *losc;
+
 	spinlock_t lock;
 };
 
+static struct sun6i_rtc_dev *sun6i_rtc;
+
+static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+	u32 val;
+
+	val = readl(rtc->base + SUN6I_LOSC_CTRL);
+	if (val & SUN6I_LOSC_CTRL_EXT_OSC)
+		return parent_rate;
+
+	val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL);
+	val &= GENMASK(4, 0);
+
+	return parent_rate / (val + 1);
+}
+
+static u8 sun6i_rtc_osc_get_parent(struct clk_hw *hw)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+
+	return readl(rtc->base + SUN6I_LOSC_CTRL) & SUN6I_LOSC_CTRL_EXT_OSC;
+}
+
+static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+	unsigned long flags;
+	u32 val;
+
+	if (index > 1)
+		return -EINVAL;
+
+	spin_lock_irqsave(&rtc->lock, flags);
+	val = readl(rtc->base + SUN6I_LOSC_CTRL);
+	val &= ~SUN6I_LOSC_CTRL_EXT_OSC;
+	val |= SUN6I_LOSC_CTRL_KEY;
+	val |= index ? SUN6I_LOSC_CTRL_EXT_OSC : 0;
+	writel(val, rtc->base + SUN6I_LOSC_CTRL);
+	spin_unlock_irqrestore(&rtc->lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops sun6i_rtc_osc_ops = {
+	.recalc_rate	= sun6i_rtc_osc_recalc_rate,
+
+	.get_parent	= sun6i_rtc_osc_get_parent,
+	.set_parent	= sun6i_rtc_osc_set_parent,
+};
+
+static void __init sun6i_rtc_clk_init(struct device_node *node)
+{
+	struct clk_hw_onecell_data *clk_data;
+	struct sun6i_rtc_dev *rtc;
+	struct clk_init_data init = {
+		.ops		= &sun6i_rtc_osc_ops,
+	};
+	const char *parents[2];
+
+	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));
+	if (!rtc->base) {
+		pr_crit("Can't map RTC registers");
+		return;
+	}
+
+	/* Switch to the external, more precise, oscillator */
+	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
+	       rtc->base + SUN6I_LOSC_CTRL);
+
+	/* Deal with old DTs */
+	if (!of_get_property(node, "clocks", NULL))
+		return;
+
+	rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
+								"rtc-int-osc",
+								NULL, 0,
+								667000,
+								300000000);
+	if (IS_ERR(rtc->int_osc)) {
+		pr_crit("Couldn't register the internal oscillator\n");
+		return;
+	}
+
+	parents[0] = clk_hw_get_name(rtc->int_osc);
+	parents[1] = of_clk_get_parent_name(node, 0);
+
+	rtc->hw.init = &init;
+
+	init.parent_names = parents;
+	init.num_parents = of_clk_get_parent_count(node) + 1;
+	of_property_read_string(node, "clock-output-names", &init.name);
+
+	rtc->losc = clk_register(NULL, &rtc->hw);
+	if (IS_ERR(rtc->losc)) {
+		pr_crit("Couldn't register the LOSC clock\n");
+		return;
+	}
+
+	clk_data->num = 1;
+	clk_data->hws[0] = &rtc->hw;
+	of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+
+	/* Yes, I know, this is ugly. */
+	sun6i_rtc = rtc;
+}
+CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
+		      sun6i_rtc_clk_init);
+
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
@@ -363,23 +493,15 @@ static const struct rtc_class_ops sun6i_rtc_ops = {
 
 static int sun6i_rtc_probe(struct platform_device *pdev)
 {
-	struct sun6i_rtc_dev *chip;
-	struct resource *res;
+	struct sun6i_rtc_dev *chip = sun6i_rtc;
 	int ret;
 
-	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
-		return -ENOMEM;
-	spin_lock_init(&rtc->lock);
+		return -ENODEV;
 
 	platform_set_drvdata(pdev, chip);
 	chip->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	chip->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(chip->base))
-		return PTR_ERR(chip->base);
-
 	chip->irq = platform_get_irq(pdev, 0);
 	if (chip->irq < 0) {
 		dev_err(&pdev->dev, "No IRQ resource\n");
@@ -419,9 +541,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	/* disable alarm wakeup */
 	writel(0, chip->base + SUN6I_ALARM_CONFIG);
 
-	/* switch to the external, more precise, oscillator */
-	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
-	       chip->base + SUN6I_LOSC_CTRL);
+	clk_prepare_enable(chip->losc);
 
 	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
 					&sun6i_rtc_ops, THIS_MODULE);
-- 
git-series 0.8.11

-- 
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 related	[flat|nested] 35+ messages in thread

* [PATCH v2 4/7] rtc: sun6i: Expose the 32kHz oscillator
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard

The RTC controls the input source of the main 32kHz oscillator in the
system, feeding it to the clock unit too.

By default, this is using an internal, very inaccurate (+/- 30%)
oscillator with a divider to make it roughly around 32kHz. This is however
quite impractical for the RTC, since our time will not be tracked properly.

Since this oscillator is an input of the main clock unit, and since that
clock unit will be probed using CLK_OF_DECLARE, we have to use it as well,
leading to a two stage probe: one to enable the clock, the other one to
enable the RTC.

There is also a slight change in the binding that is required (and should
have been from the beginning), since we'll need a phandle to the external
oscillator used on that board. We support the old binding by not allowing
to switch to the external oscillator and only using the internal one (which
was the previous behaviour) in the case where we're missing that phandle.

Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-
 drivers/rtc/rtc-sun6i.c                             | 146 +++++++++++--
 2 files changed, 143 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
index f007e428a1ab..945934918b71 100644
--- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
@@ -8,10 +8,20 @@ Required properties:
 		  memory mapped region.
 - interrupts	: IRQ lines for the RTC alarm 0 and alarm 1, in that order.
 
+Required properties for new device trees
+- clocks	: phandle to the 32kHz external oscillator
+- clock-output-names : name of the LOSC clock 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.
+
 Example:
 
 rtc: rtc@01f00000 {
 	compatible = "allwinner,sun6i-a31-rtc";
 	reg = <0x01f00000 0x54>;
 	interrupts = <0 40 4>, <0 41 4>;
+	clock-output-names = "osc32k";
+	clocks = <&ext_osc32k>;
+	#clock-cells = <1>;
 };
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 47f2022948a6..37f65c50ab2d 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -20,6 +20,8 @@
  * more details.
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/fs.h>
@@ -33,6 +35,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 /* Control register */
@@ -44,6 +47,8 @@
 #define SUN6I_LOSC_CTRL_EXT_OSC			BIT(0)
 #define SUN6I_LOSC_CTRL_ACC_MASK		GENMASK(9, 7)
 
+#define SUN6I_LOSC_CLK_PRESCAL			0x0008
+
 /* RTC */
 #define SUN6I_RTC_YMD				0x0010
 #define SUN6I_RTC_HMS				0x0014
@@ -117,9 +122,134 @@ struct sun6i_rtc_dev {
 	int irq;
 	unsigned long alarm;
 
+	struct clk_hw hw;
+	struct clk_hw *int_osc;
+	struct clk *losc;
+
 	spinlock_t lock;
 };
 
+static struct sun6i_rtc_dev *sun6i_rtc;
+
+static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+	u32 val;
+
+	val = readl(rtc->base + SUN6I_LOSC_CTRL);
+	if (val & SUN6I_LOSC_CTRL_EXT_OSC)
+		return parent_rate;
+
+	val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL);
+	val &= GENMASK(4, 0);
+
+	return parent_rate / (val + 1);
+}
+
+static u8 sun6i_rtc_osc_get_parent(struct clk_hw *hw)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+
+	return readl(rtc->base + SUN6I_LOSC_CTRL) & SUN6I_LOSC_CTRL_EXT_OSC;
+}
+
+static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+	unsigned long flags;
+	u32 val;
+
+	if (index > 1)
+		return -EINVAL;
+
+	spin_lock_irqsave(&rtc->lock, flags);
+	val = readl(rtc->base + SUN6I_LOSC_CTRL);
+	val &= ~SUN6I_LOSC_CTRL_EXT_OSC;
+	val |= SUN6I_LOSC_CTRL_KEY;
+	val |= index ? SUN6I_LOSC_CTRL_EXT_OSC : 0;
+	writel(val, rtc->base + SUN6I_LOSC_CTRL);
+	spin_unlock_irqrestore(&rtc->lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops sun6i_rtc_osc_ops = {
+	.recalc_rate	= sun6i_rtc_osc_recalc_rate,
+
+	.get_parent	= sun6i_rtc_osc_get_parent,
+	.set_parent	= sun6i_rtc_osc_set_parent,
+};
+
+static void __init sun6i_rtc_clk_init(struct device_node *node)
+{
+	struct clk_hw_onecell_data *clk_data;
+	struct sun6i_rtc_dev *rtc;
+	struct clk_init_data init = {
+		.ops		= &sun6i_rtc_osc_ops,
+	};
+	const char *parents[2];
+
+	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));
+	if (!rtc->base) {
+		pr_crit("Can't map RTC registers");
+		return;
+	}
+
+	/* Switch to the external, more precise, oscillator */
+	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
+	       rtc->base + SUN6I_LOSC_CTRL);
+
+	/* Deal with old DTs */
+	if (!of_get_property(node, "clocks", NULL))
+		return;
+
+	rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
+								"rtc-int-osc",
+								NULL, 0,
+								667000,
+								300000000);
+	if (IS_ERR(rtc->int_osc)) {
+		pr_crit("Couldn't register the internal oscillator\n");
+		return;
+	}
+
+	parents[0] = clk_hw_get_name(rtc->int_osc);
+	parents[1] = of_clk_get_parent_name(node, 0);
+
+	rtc->hw.init = &init;
+
+	init.parent_names = parents;
+	init.num_parents = of_clk_get_parent_count(node) + 1;
+	of_property_read_string(node, "clock-output-names", &init.name);
+
+	rtc->losc = clk_register(NULL, &rtc->hw);
+	if (IS_ERR(rtc->losc)) {
+		pr_crit("Couldn't register the LOSC clock\n");
+		return;
+	}
+
+	clk_data->num = 1;
+	clk_data->hws[0] = &rtc->hw;
+	of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+
+	/* Yes, I know, this is ugly. */
+	sun6i_rtc = rtc;
+}
+CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
+		      sun6i_rtc_clk_init);
+
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
@@ -363,23 +493,15 @@ static const struct rtc_class_ops sun6i_rtc_ops = {
 
 static int sun6i_rtc_probe(struct platform_device *pdev)
 {
-	struct sun6i_rtc_dev *chip;
-	struct resource *res;
+	struct sun6i_rtc_dev *chip = sun6i_rtc;
 	int ret;
 
-	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
-		return -ENOMEM;
-	spin_lock_init(&rtc->lock);
+		return -ENODEV;
 
 	platform_set_drvdata(pdev, chip);
 	chip->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	chip->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(chip->base))
-		return PTR_ERR(chip->base);
-
 	chip->irq = platform_get_irq(pdev, 0);
 	if (chip->irq < 0) {
 		dev_err(&pdev->dev, "No IRQ resource\n");
@@ -419,9 +541,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	/* disable alarm wakeup */
 	writel(0, chip->base + SUN6I_ALARM_CONFIG);
 
-	/* switch to the external, more precise, oscillator */
-	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
-	       chip->base + SUN6I_LOSC_CTRL);
+	clk_prepare_enable(chip->losc);
 
 	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
 					&sun6i_rtc_ops, THIS_MODULE);
-- 
git-series 0.8.11

-- 
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 4/7] rtc: sun6i: Expose the 32kHz oscillator
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

The RTC controls the input source of the main 32kHz oscillator in the
system, feeding it to the clock unit too.

By default, this is using an internal, very inaccurate (+/- 30%)
oscillator with a divider to make it roughly around 32kHz. This is however
quite impractical for the RTC, since our time will not be tracked properly.

Since this oscillator is an input of the main clock unit, and since that
clock unit will be probed using CLK_OF_DECLARE, we have to use it as well,
leading to a two stage probe: one to enable the clock, the other one to
enable the RTC.

There is also a slight change in the binding that is required (and should
have been from the beginning), since we'll need a phandle to the external
oscillator used on that board. We support the old binding by not allowing
to switch to the external oscillator and only using the internal one (which
was the previous behaviour) in the case where we're missing that phandle.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-
 drivers/rtc/rtc-sun6i.c                             | 146 +++++++++++--
 2 files changed, 143 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
index f007e428a1ab..945934918b71 100644
--- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
@@ -8,10 +8,20 @@ Required properties:
 		  memory mapped region.
 - interrupts	: IRQ lines for the RTC alarm 0 and alarm 1, in that order.
 
+Required properties for new device trees
+- clocks	: phandle to the 32kHz external oscillator
+- clock-output-names : name of the LOSC clock 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.
+
 Example:
 
 rtc: rtc at 01f00000 {
 	compatible = "allwinner,sun6i-a31-rtc";
 	reg = <0x01f00000 0x54>;
 	interrupts = <0 40 4>, <0 41 4>;
+	clock-output-names = "osc32k";
+	clocks = <&ext_osc32k>;
+	#clock-cells = <1>;
 };
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 47f2022948a6..37f65c50ab2d 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -20,6 +20,8 @@
  * more details.
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/fs.h>
@@ -33,6 +35,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 /* Control register */
@@ -44,6 +47,8 @@
 #define SUN6I_LOSC_CTRL_EXT_OSC			BIT(0)
 #define SUN6I_LOSC_CTRL_ACC_MASK		GENMASK(9, 7)
 
+#define SUN6I_LOSC_CLK_PRESCAL			0x0008
+
 /* RTC */
 #define SUN6I_RTC_YMD				0x0010
 #define SUN6I_RTC_HMS				0x0014
@@ -117,9 +122,134 @@ struct sun6i_rtc_dev {
 	int irq;
 	unsigned long alarm;
 
+	struct clk_hw hw;
+	struct clk_hw *int_osc;
+	struct clk *losc;
+
 	spinlock_t lock;
 };
 
+static struct sun6i_rtc_dev *sun6i_rtc;
+
+static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+	u32 val;
+
+	val = readl(rtc->base + SUN6I_LOSC_CTRL);
+	if (val & SUN6I_LOSC_CTRL_EXT_OSC)
+		return parent_rate;
+
+	val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL);
+	val &= GENMASK(4, 0);
+
+	return parent_rate / (val + 1);
+}
+
+static u8 sun6i_rtc_osc_get_parent(struct clk_hw *hw)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+
+	return readl(rtc->base + SUN6I_LOSC_CTRL) & SUN6I_LOSC_CTRL_EXT_OSC;
+}
+
+static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
+	unsigned long flags;
+	u32 val;
+
+	if (index > 1)
+		return -EINVAL;
+
+	spin_lock_irqsave(&rtc->lock, flags);
+	val = readl(rtc->base + SUN6I_LOSC_CTRL);
+	val &= ~SUN6I_LOSC_CTRL_EXT_OSC;
+	val |= SUN6I_LOSC_CTRL_KEY;
+	val |= index ? SUN6I_LOSC_CTRL_EXT_OSC : 0;
+	writel(val, rtc->base + SUN6I_LOSC_CTRL);
+	spin_unlock_irqrestore(&rtc->lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops sun6i_rtc_osc_ops = {
+	.recalc_rate	= sun6i_rtc_osc_recalc_rate,
+
+	.get_parent	= sun6i_rtc_osc_get_parent,
+	.set_parent	= sun6i_rtc_osc_set_parent,
+};
+
+static void __init sun6i_rtc_clk_init(struct device_node *node)
+{
+	struct clk_hw_onecell_data *clk_data;
+	struct sun6i_rtc_dev *rtc;
+	struct clk_init_data init = {
+		.ops		= &sun6i_rtc_osc_ops,
+	};
+	const char *parents[2];
+
+	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));
+	if (!rtc->base) {
+		pr_crit("Can't map RTC registers");
+		return;
+	}
+
+	/* Switch to the external, more precise, oscillator */
+	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
+	       rtc->base + SUN6I_LOSC_CTRL);
+
+	/* Deal with old DTs */
+	if (!of_get_property(node, "clocks", NULL))
+		return;
+
+	rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL,
+								"rtc-int-osc",
+								NULL, 0,
+								667000,
+								300000000);
+	if (IS_ERR(rtc->int_osc)) {
+		pr_crit("Couldn't register the internal oscillator\n");
+		return;
+	}
+
+	parents[0] = clk_hw_get_name(rtc->int_osc);
+	parents[1] = of_clk_get_parent_name(node, 0);
+
+	rtc->hw.init = &init;
+
+	init.parent_names = parents;
+	init.num_parents = of_clk_get_parent_count(node) + 1;
+	of_property_read_string(node, "clock-output-names", &init.name);
+
+	rtc->losc = clk_register(NULL, &rtc->hw);
+	if (IS_ERR(rtc->losc)) {
+		pr_crit("Couldn't register the LOSC clock\n");
+		return;
+	}
+
+	clk_data->num = 1;
+	clk_data->hws[0] = &rtc->hw;
+	of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+
+	/* Yes, I know, this is ugly. */
+	sun6i_rtc = rtc;
+}
+CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc",
+		      sun6i_rtc_clk_init);
+
 static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
 {
 	struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
@@ -363,23 +493,15 @@ static const struct rtc_class_ops sun6i_rtc_ops = {
 
 static int sun6i_rtc_probe(struct platform_device *pdev)
 {
-	struct sun6i_rtc_dev *chip;
-	struct resource *res;
+	struct sun6i_rtc_dev *chip = sun6i_rtc;
 	int ret;
 
-	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
-		return -ENOMEM;
-	spin_lock_init(&rtc->lock);
+		return -ENODEV;
 
 	platform_set_drvdata(pdev, chip);
 	chip->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	chip->base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(chip->base))
-		return PTR_ERR(chip->base);
-
 	chip->irq = platform_get_irq(pdev, 0);
 	if (chip->irq < 0) {
 		dev_err(&pdev->dev, "No IRQ resource\n");
@@ -419,9 +541,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	/* disable alarm wakeup */
 	writel(0, chip->base + SUN6I_ALARM_CONFIG);
 
-	/* switch to the external, more precise, oscillator */
-	writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
-	       chip->base + SUN6I_LOSC_CTRL);
+	clk_prepare_enable(chip->losc);
 
 	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
 					&sun6i_rtc_ops, THIS_MODULE);
-- 
git-series 0.8.11

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

* [rtc-linux] [PATCH v2 5/7] rtc: sun6i: Switch to devm_rtc_device_register
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree, Maxime Ripard

Now that we have a devm variant of rtc_device_register, switch to it.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 37f65c50ab2d..613f42ade533 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -543,8 +543,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 
 	clk_prepare_enable(chip->losc);
 
-	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
-					&sun6i_rtc_ops, THIS_MODULE);
+	chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i",
+					     &sun6i_rtc_ops, THIS_MODULE);
 	if (IS_ERR(chip->rtc)) {
 		dev_err(&pdev->dev, "unable to register device\n");
 		return PTR_ERR(chip->rtc);
@@ -555,15 +555,6 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int sun6i_rtc_remove(struct platform_device *pdev)
-{
-	struct sun6i_rtc_dev *chip = platform_get_drvdata(pdev);
-
-	rtc_device_unregister(chip->rtc);
-
-	return 0;
-}
-
 static const struct of_device_id sun6i_rtc_dt_ids[] = {
 	{ .compatible = "allwinner,sun6i-a31-rtc" },
 	{ /* sentinel */ },
@@ -572,7 +563,6 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
 
 static struct platform_driver sun6i_rtc_driver = {
 	.probe		= sun6i_rtc_probe,
-	.remove		= sun6i_rtc_remove,
 	.driver		= {
 		.name		= "sun6i-rtc",
 		.of_match_table = sun6i_rtc_dt_ids,
-- 
git-series 0.8.11

-- 
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 related	[flat|nested] 35+ messages in thread

* [PATCH v2 5/7] rtc: sun6i: Switch to devm_rtc_device_register
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard

Now that we have a devm variant of rtc_device_register, switch to it.

Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 drivers/rtc/rtc-sun6i.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 37f65c50ab2d..613f42ade533 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -543,8 +543,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 
 	clk_prepare_enable(chip->losc);
 
-	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
-					&sun6i_rtc_ops, THIS_MODULE);
+	chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i",
+					     &sun6i_rtc_ops, THIS_MODULE);
 	if (IS_ERR(chip->rtc)) {
 		dev_err(&pdev->dev, "unable to register device\n");
 		return PTR_ERR(chip->rtc);
@@ -555,15 +555,6 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int sun6i_rtc_remove(struct platform_device *pdev)
-{
-	struct sun6i_rtc_dev *chip = platform_get_drvdata(pdev);
-
-	rtc_device_unregister(chip->rtc);
-
-	return 0;
-}
-
 static const struct of_device_id sun6i_rtc_dt_ids[] = {
 	{ .compatible = "allwinner,sun6i-a31-rtc" },
 	{ /* sentinel */ },
@@ -572,7 +563,6 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
 
 static struct platform_driver sun6i_rtc_driver = {
 	.probe		= sun6i_rtc_probe,
-	.remove		= sun6i_rtc_remove,
 	.driver		= {
 		.name		= "sun6i-rtc",
 		.of_match_table = sun6i_rtc_dt_ids,
-- 
git-series 0.8.11
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 5/7] rtc: sun6i: Switch to devm_rtc_device_register
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have a devm variant of rtc_device_register, switch to it.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/rtc/rtc-sun6i.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index 37f65c50ab2d..613f42ade533 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -543,8 +543,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 
 	clk_prepare_enable(chip->losc);
 
-	chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
-					&sun6i_rtc_ops, THIS_MODULE);
+	chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i",
+					     &sun6i_rtc_ops, THIS_MODULE);
 	if (IS_ERR(chip->rtc)) {
 		dev_err(&pdev->dev, "unable to register device\n");
 		return PTR_ERR(chip->rtc);
@@ -555,15 +555,6 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int sun6i_rtc_remove(struct platform_device *pdev)
-{
-	struct sun6i_rtc_dev *chip = platform_get_drvdata(pdev);
-
-	rtc_device_unregister(chip->rtc);
-
-	return 0;
-}
-
 static const struct of_device_id sun6i_rtc_dt_ids[] = {
 	{ .compatible = "allwinner,sun6i-a31-rtc" },
 	{ /* sentinel */ },
@@ -572,7 +563,6 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
 
 static struct platform_driver sun6i_rtc_driver = {
 	.probe		= sun6i_rtc_probe,
-	.remove		= sun6i_rtc_remove,
 	.driver		= {
 		.name		= "sun6i-rtc",
 		.of_match_table = sun6i_rtc_dt_ids,
-- 
git-series 0.8.11

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

* [rtc-linux] [PATCH v2 6/7] ARM: sun8i: a23/a33: Enable the real LOSC and use it
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree, Maxime Ripard

So far, the LOSC was generated through the RTC internal oscillator, which
was a pretty poor and inaccurate choice.

Now that the RTC properly exposes its internal mux between its oscillator
and the external oscillator, we can use it were relevant.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 597f2fce6c31..da7f2476bc6c 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -109,11 +109,11 @@
 			clock-output-names = "osc24M";
 		};
 
-		osc32k: osc32k_clk {
+		ext_osc32k: ext_osc32k_clk {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
-			clock-output-names = "osc32k";
+			clock-output-names = "ext-osc32k";
 		};
 	};
 
@@ -256,7 +256,7 @@
 
 		ccu: clock@01c20000 {
 			reg = <0x01c20000 0x400>;
-			clocks = <&osc24M>, <&osc32k>;
+			clocks = <&osc24M>, <&rtc 0>;
 			clock-names = "hosc", "losc";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
@@ -266,7 +266,7 @@
 			/* compatible gets set in SoC specific dtsi file */
 			reg = <0x01c20800 0x400>;
 			/* interrupts get set in SoC specific dtsi file */
-			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
+			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
 			clock-names = "apb", "hosc", "losc";
 			gpio-controller;
 			interrupt-controller;
@@ -486,6 +486,9 @@
 			reg = <0x01f00000 0x54>;
 			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			clock-output-names = "osc32k";
+			clocks = <&ext_osc32k>;
+			#clock-cells = <1>;
 		};
 
 		nmi_intc: interrupt-controller@01f00c0c {
@@ -564,7 +567,7 @@
 			compatible = "allwinner,sun8i-a23-r-pinctrl";
 			reg = <0x01f02c00 0x400>;
 			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+			clocks = <&apb0_gates 0>, <&osc24M>, <&rtc 0>;
 			clock-names = "apb", "hosc", "losc";
 			resets = <&apb0_rst 0>;
 			gpio-controller;
-- 
git-series 0.8.11

-- 
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 related	[flat|nested] 35+ messages in thread

* [PATCH v2 6/7] ARM: sun8i: a23/a33: Enable the real LOSC and use it
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard

So far, the LOSC was generated through the RTC internal oscillator, which
was a pretty poor and inaccurate choice.

Now that the RTC properly exposes its internal mux between its oscillator
and the external oscillator, we can use it were relevant.

Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 597f2fce6c31..da7f2476bc6c 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -109,11 +109,11 @@
 			clock-output-names = "osc24M";
 		};
 
-		osc32k: osc32k_clk {
+		ext_osc32k: ext_osc32k_clk {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
-			clock-output-names = "osc32k";
+			clock-output-names = "ext-osc32k";
 		};
 	};
 
@@ -256,7 +256,7 @@
 
 		ccu: clock@01c20000 {
 			reg = <0x01c20000 0x400>;
-			clocks = <&osc24M>, <&osc32k>;
+			clocks = <&osc24M>, <&rtc 0>;
 			clock-names = "hosc", "losc";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
@@ -266,7 +266,7 @@
 			/* compatible gets set in SoC specific dtsi file */
 			reg = <0x01c20800 0x400>;
 			/* interrupts get set in SoC specific dtsi file */
-			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
+			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
 			clock-names = "apb", "hosc", "losc";
 			gpio-controller;
 			interrupt-controller;
@@ -486,6 +486,9 @@
 			reg = <0x01f00000 0x54>;
 			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			clock-output-names = "osc32k";
+			clocks = <&ext_osc32k>;
+			#clock-cells = <1>;
 		};
 
 		nmi_intc: interrupt-controller@01f00c0c {
@@ -564,7 +567,7 @@
 			compatible = "allwinner,sun8i-a23-r-pinctrl";
 			reg = <0x01f02c00 0x400>;
 			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+			clocks = <&apb0_gates 0>, <&osc24M>, <&rtc 0>;
 			clock-names = "apb", "hosc", "losc";
 			resets = <&apb0_rst 0>;
 			gpio-controller;
-- 
git-series 0.8.11

-- 
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 6/7] ARM: sun8i: a23/a33: Enable the real LOSC and use it
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

So far, the LOSC was generated through the RTC internal oscillator, which
was a pretty poor and inaccurate choice.

Now that the RTC properly exposes its internal mux between its oscillator
and the external oscillator, we can use it were relevant.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 597f2fce6c31..da7f2476bc6c 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -109,11 +109,11 @@
 			clock-output-names = "osc24M";
 		};
 
-		osc32k: osc32k_clk {
+		ext_osc32k: ext_osc32k_clk {
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
-			clock-output-names = "osc32k";
+			clock-output-names = "ext-osc32k";
 		};
 	};
 
@@ -256,7 +256,7 @@
 
 		ccu: clock at 01c20000 {
 			reg = <0x01c20000 0x400>;
-			clocks = <&osc24M>, <&osc32k>;
+			clocks = <&osc24M>, <&rtc 0>;
 			clock-names = "hosc", "losc";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
@@ -266,7 +266,7 @@
 			/* compatible gets set in SoC specific dtsi file */
 			reg = <0x01c20800 0x400>;
 			/* interrupts get set in SoC specific dtsi file */
-			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
+			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
 			clock-names = "apb", "hosc", "losc";
 			gpio-controller;
 			interrupt-controller;
@@ -486,6 +486,9 @@
 			reg = <0x01f00000 0x54>;
 			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			clock-output-names = "osc32k";
+			clocks = <&ext_osc32k>;
+			#clock-cells = <1>;
 		};
 
 		nmi_intc: interrupt-controller at 01f00c0c {
@@ -564,7 +567,7 @@
 			compatible = "allwinner,sun8i-a23-r-pinctrl";
 			reg = <0x01f02c00 0x400>;
 			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&apb0_gates 0>, <&osc24M>, <&osc32k>;
+			clocks = <&apb0_gates 0>, <&osc24M>, <&rtc 0>;
 			clock-names = "apb", "hosc", "losc";
 			resets = <&apb0_rst 0>;
 			gpio-controller;
-- 
git-series 0.8.11

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

* [rtc-linux] [PATCH v2 7/7] ARM: sun8i: a23/a33: Add the oscillators accuracy
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel, rtc-linux, Rob Herring, devicetree, Maxime Ripard

The datasheet provided by Allwinner requires oscillators with an accuracy
of 50ppm. Add it to our fixed clocks so that we can properly track the
accuracy chain.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 ++
 1 file changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index da7f2476bc6c..d92fdf5a7b26 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -106,6 +106,7 @@
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <24000000>;
+			clock-accuracy = <50000>;
 			clock-output-names = "osc24M";
 		};
 
@@ -113,6 +114,7 @@
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
+			clock-accuracy = <50000>;
 			clock-output-names = "ext-osc32k";
 		};
 	};
-- 
git-series 0.8.11

-- 
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 related	[flat|nested] 35+ messages in thread

* [PATCH v2 7/7] ARM: sun8i: a23/a33: Add the oscillators accuracy
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard

The datasheet provided by Allwinner requires oscillators with an accuracy
of 50ppm. Add it to our fixed clocks so that we can properly track the
accuracy chain.

Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 ++
 1 file changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index da7f2476bc6c..d92fdf5a7b26 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -106,6 +106,7 @@
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <24000000>;
+			clock-accuracy = <50000>;
 			clock-output-names = "osc24M";
 		};
 
@@ -113,6 +114,7 @@
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
+			clock-accuracy = <50000>;
 			clock-output-names = "ext-osc32k";
 		};
 	};
-- 
git-series 0.8.11

-- 
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 7/7] ARM: sun8i: a23/a33: Add the oscillators accuracy
@ 2017-01-23 10:41   ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-23 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

The datasheet provided by Allwinner requires oscillators with an accuracy
of 50ppm. Add it to our fixed clocks so that we can properly track the
accuracy chain.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 2 ++
 1 file changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index da7f2476bc6c..d92fdf5a7b26 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -106,6 +106,7 @@
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <24000000>;
+			clock-accuracy = <50000>;
 			clock-output-names = "osc24M";
 		};
 
@@ -113,6 +114,7 @@
 			#clock-cells = <0>;
 			compatible = "fixed-clock";
 			clock-frequency = <32768>;
+			clock-accuracy = <50000>;
 			clock-output-names = "ext-osc32k";
 		};
 	};
-- 
git-series 0.8.11

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

* [rtc-linux] Re: [PATCH v2 4/7] rtc: sun6i: Expose the 32kHz oscillator
@ 2017-01-23 21:00     ` Rob Herring
  0 siblings, 0 replies; 35+ messages in thread
From: Rob Herring @ 2017-01-23 21:00 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai,
	linux-arm-kernel, rtc-linux, devicetree

On Mon, Jan 23, 2017 at 11:41:49AM +0100, Maxime Ripard wrote:
> The RTC controls the input source of the main 32kHz oscillator in the
> system, feeding it to the clock unit too.
> 
> By default, this is using an internal, very inaccurate (+/- 30%)
> oscillator with a divider to make it roughly around 32kHz. This is however
> quite impractical for the RTC, since our time will not be tracked properly.
> 
> Since this oscillator is an input of the main clock unit, and since that
> clock unit will be probed using CLK_OF_DECLARE, we have to use it as well,
> leading to a two stage probe: one to enable the clock, the other one to
> enable the RTC.
> 
> There is also a slight change in the binding that is required (and should
> have been from the beginning), since we'll need a phandle to the external
> oscillator used on that board. We support the old binding by not allowing
> to switch to the external oscillator and only using the internal one (which
> was the previous behaviour) in the case where we're missing that phandle.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-

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

>  drivers/rtc/rtc-sun6i.c                             | 146 +++++++++++--
>  2 files changed, 143 insertions(+), 13 deletions(-)

-- 
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	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 4/7] rtc: sun6i: Expose the 32kHz oscillator
@ 2017-01-23 21:00     ` Rob Herring
  0 siblings, 0 replies; 35+ messages in thread
From: Rob Herring @ 2017-01-23 21:00 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Alexandre Belloni, Alessandro Zummo, Chen-Yu Tsai,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Mon, Jan 23, 2017 at 11:41:49AM +0100, Maxime Ripard wrote:
> The RTC controls the input source of the main 32kHz oscillator in the
> system, feeding it to the clock unit too.
> 
> By default, this is using an internal, very inaccurate (+/- 30%)
> oscillator with a divider to make it roughly around 32kHz. This is however
> quite impractical for the RTC, since our time will not be tracked properly.
> 
> Since this oscillator is an input of the main clock unit, and since that
> clock unit will be probed using CLK_OF_DECLARE, we have to use it as well,
> leading to a two stage probe: one to enable the clock, the other one to
> enable the RTC.
> 
> There is also a slight change in the binding that is required (and should
> have been from the beginning), since we'll need a phandle to the external
> oscillator used on that board. We support the old binding by not allowing
> to switch to the external oscillator and only using the internal one (which
> was the previous behaviour) in the case where we're missing that phandle.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

>  drivers/rtc/rtc-sun6i.c                             | 146 +++++++++++--
>  2 files changed, 143 insertions(+), 13 deletions(-)

-- 
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 4/7] rtc: sun6i: Expose the 32kHz oscillator
@ 2017-01-23 21:00     ` Rob Herring
  0 siblings, 0 replies; 35+ messages in thread
From: Rob Herring @ 2017-01-23 21:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jan 23, 2017 at 11:41:49AM +0100, Maxime Ripard wrote:
> The RTC controls the input source of the main 32kHz oscillator in the
> system, feeding it to the clock unit too.
> 
> By default, this is using an internal, very inaccurate (+/- 30%)
> oscillator with a divider to make it roughly around 32kHz. This is however
> quite impractical for the RTC, since our time will not be tracked properly.
> 
> Since this oscillator is an input of the main clock unit, and since that
> clock unit will be probed using CLK_OF_DECLARE, we have to use it as well,
> leading to a two stage probe: one to enable the clock, the other one to
> enable the RTC.
> 
> There is also a slight change in the binding that is required (and should
> have been from the beginning), since we'll need a phandle to the external
> oscillator used on that board. We support the old binding by not allowing
> to switch to the external oscillator and only using the internal one (which
> was the previous behaviour) in the case where we're missing that phandle.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  Documentation/devicetree/bindings/rtc/sun6i-rtc.txt |  10 +-

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

>  drivers/rtc/rtc-sun6i.c                             | 146 +++++++++++--
>  2 files changed, 143 insertions(+), 13 deletions(-)

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

* [rtc-linux] Re: [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-24 17:49   ` Alexandre Belloni
  0 siblings, 0 replies; 35+ messages in thread
From: Alexandre Belloni @ 2017-01-24 17:49 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Alessandro Zummo, Chen-Yu Tsai, linux-arm-kernel, rtc-linux,
	Rob Herring, devicetree

Hi,

On 23/01/2017 at 11:41:45 +0100, Maxime Ripard wrote :
> Hi,
> 
> The RTC used in the A31 and later SoC has an accuracy issue, which is
> already significant even after a couple of hours.
> 
> This is due to the fact that the oscillator used by default is an internal
> and very inaccurate one.
> 
> A first attempt at fixing that by switching to the external oscillator was
> done in the patch "rtc: sun6i: Switch to the external oscillator". However,
> it turned out to be problematic since it was tracked properly in the clock
> framework, which might lead to some clocks being disabled, even though
> their devices were not notified.
> 
> This is a second attempt, this time by making it part of the CCF. It
> turned out to be a bit more complicated than one would expect since the mux
> found inside the RTC also controls one of the input of the main clock unit.
> Therefore, it needs to be probed before the main clock unit driver.
> 
> Let me know what you think,
> Maxime
> 
> Changes from v1:
>   - Force the muxing to the external oscillator even for old DT
>   - Make the patches a bit more stable friendly
>   - Change the bindings to have a cell of 1, to account for the external
>     output of the oscillator
>   - Split the driver remove() removal into a separate patch and switched to
>     devm
>   - Reordered the patches
> 
> Maxime Ripard (7):
>   rtc: sun6i: Disable the build as a module
>   rtc: sun6i: Add some locking
>   rtc: sun6i: Switch to the external oscillator
>   rtc: sun6i: Expose the 32kHz oscillator
>   rtc: sun6i: Switch to devm_rtc_device_register
>   ARM: sun8i: a23/a33: Enable the real LOSC and use it
>   ARM: sun8i: a23/a33: Add the oscillators accuracy
> 

I've applied 1/7 to 5/7. 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	[flat|nested] 35+ messages in thread

* Re: [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-24 17:49   ` Alexandre Belloni
  0 siblings, 0 replies; 35+ messages in thread
From: Alexandre Belloni @ 2017-01-24 17:49 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Alessandro Zummo, Chen-Yu Tsai,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA

Hi,

On 23/01/2017 at 11:41:45 +0100, Maxime Ripard wrote :
> Hi,
> 
> The RTC used in the A31 and later SoC has an accuracy issue, which is
> already significant even after a couple of hours.
> 
> This is due to the fact that the oscillator used by default is an internal
> and very inaccurate one.
> 
> A first attempt at fixing that by switching to the external oscillator was
> done in the patch "rtc: sun6i: Switch to the external oscillator". However,
> it turned out to be problematic since it was tracked properly in the clock
> framework, which might lead to some clocks being disabled, even though
> their devices were not notified.
> 
> This is a second attempt, this time by making it part of the CCF. It
> turned out to be a bit more complicated than one would expect since the mux
> found inside the RTC also controls one of the input of the main clock unit.
> Therefore, it needs to be probed before the main clock unit driver.
> 
> Let me know what you think,
> Maxime
> 
> Changes from v1:
>   - Force the muxing to the external oscillator even for old DT
>   - Make the patches a bit more stable friendly
>   - Change the bindings to have a cell of 1, to account for the external
>     output of the oscillator
>   - Split the driver remove() removal into a separate patch and switched to
>     devm
>   - Reordered the patches
> 
> Maxime Ripard (7):
>   rtc: sun6i: Disable the build as a module
>   rtc: sun6i: Add some locking
>   rtc: sun6i: Switch to the external oscillator
>   rtc: sun6i: Expose the 32kHz oscillator
>   rtc: sun6i: Switch to devm_rtc_device_register
>   ARM: sun8i: a23/a33: Enable the real LOSC and use it
>   ARM: sun8i: a23/a33: Add the oscillators accuracy
> 

I've applied 1/7 to 5/7. 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-24 17:49   ` Alexandre Belloni
  0 siblings, 0 replies; 35+ messages in thread
From: Alexandre Belloni @ 2017-01-24 17:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On 23/01/2017 at 11:41:45 +0100, Maxime Ripard wrote :
> Hi,
> 
> The RTC used in the A31 and later SoC has an accuracy issue, which is
> already significant even after a couple of hours.
> 
> This is due to the fact that the oscillator used by default is an internal
> and very inaccurate one.
> 
> A first attempt at fixing that by switching to the external oscillator was
> done in the patch "rtc: sun6i: Switch to the external oscillator". However,
> it turned out to be problematic since it was tracked properly in the clock
> framework, which might lead to some clocks being disabled, even though
> their devices were not notified.
> 
> This is a second attempt, this time by making it part of the CCF. It
> turned out to be a bit more complicated than one would expect since the mux
> found inside the RTC also controls one of the input of the main clock unit.
> Therefore, it needs to be probed before the main clock unit driver.
> 
> Let me know what you think,
> Maxime
> 
> Changes from v1:
>   - Force the muxing to the external oscillator even for old DT
>   - Make the patches a bit more stable friendly
>   - Change the bindings to have a cell of 1, to account for the external
>     output of the oscillator
>   - Split the driver remove() removal into a separate patch and switched to
>     devm
>   - Reordered the patches
> 
> Maxime Ripard (7):
>   rtc: sun6i: Disable the build as a module
>   rtc: sun6i: Add some locking
>   rtc: sun6i: Switch to the external oscillator
>   rtc: sun6i: Expose the 32kHz oscillator
>   rtc: sun6i: Switch to devm_rtc_device_register
>   ARM: sun8i: a23/a33: Enable the real LOSC and use it
>   ARM: sun8i: a23/a33: Add the oscillators accuracy
> 

I've applied 1/7 to 5/7. Thanks!

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

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

* [rtc-linux] Re: [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-25 15:36     ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-25 15:36 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Alessandro Zummo, Chen-Yu Tsai, linux-arm-kernel, rtc-linux,
	Rob Herring, devicetree

[-- Attachment #1: Type: text/plain, Size: 2565 bytes --]

On Tue, Jan 24, 2017 at 06:49:35PM +0100, Alexandre Belloni wrote:
> Hi,
> 
> On 23/01/2017 at 11:41:45 +0100, Maxime Ripard wrote :
> > Hi,
> > 
> > The RTC used in the A31 and later SoC has an accuracy issue, which is
> > already significant even after a couple of hours.
> > 
> > This is due to the fact that the oscillator used by default is an internal
> > and very inaccurate one.
> > 
> > A first attempt at fixing that by switching to the external oscillator was
> > done in the patch "rtc: sun6i: Switch to the external oscillator". However,
> > it turned out to be problematic since it was tracked properly in the clock
> > framework, which might lead to some clocks being disabled, even though
> > their devices were not notified.
> > 
> > This is a second attempt, this time by making it part of the CCF. It
> > turned out to be a bit more complicated than one would expect since the mux
> > found inside the RTC also controls one of the input of the main clock unit.
> > Therefore, it needs to be probed before the main clock unit driver.
> > 
> > Let me know what you think,
> > Maxime
> > 
> > Changes from v1:
> >   - Force the muxing to the external oscillator even for old DT
> >   - Make the patches a bit more stable friendly
> >   - Change the bindings to have a cell of 1, to account for the external
> >     output of the oscillator
> >   - Split the driver remove() removal into a separate patch and switched to
> >     devm
> >   - Reordered the patches
> > 
> > Maxime Ripard (7):
> >   rtc: sun6i: Disable the build as a module
> >   rtc: sun6i: Add some locking
> >   rtc: sun6i: Switch to the external oscillator
> >   rtc: sun6i: Expose the 32kHz oscillator
> >   rtc: sun6i: Switch to devm_rtc_device_register
> >   ARM: sun8i: a23/a33: Enable the real LOSC and use it
> >   ARM: sun8i: a23/a33: Add the oscillators accuracy
> > 
> 
> I've applied 1/7 to 5/7. Thanks!

And I just applied patches 6 and 7. Thanks!
Maxime

-- 
Maxime Ripard, 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.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-25 15:36     ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-25 15:36 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Alessandro Zummo, Chen-Yu Tsai,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	rtc-linux-/JYPxA39Uh5TLH3MbocFFw, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 2597 bytes --]

On Tue, Jan 24, 2017 at 06:49:35PM +0100, Alexandre Belloni wrote:
> Hi,
> 
> On 23/01/2017 at 11:41:45 +0100, Maxime Ripard wrote :
> > Hi,
> > 
> > The RTC used in the A31 and later SoC has an accuracy issue, which is
> > already significant even after a couple of hours.
> > 
> > This is due to the fact that the oscillator used by default is an internal
> > and very inaccurate one.
> > 
> > A first attempt at fixing that by switching to the external oscillator was
> > done in the patch "rtc: sun6i: Switch to the external oscillator". However,
> > it turned out to be problematic since it was tracked properly in the clock
> > framework, which might lead to some clocks being disabled, even though
> > their devices were not notified.
> > 
> > This is a second attempt, this time by making it part of the CCF. It
> > turned out to be a bit more complicated than one would expect since the mux
> > found inside the RTC also controls one of the input of the main clock unit.
> > Therefore, it needs to be probed before the main clock unit driver.
> > 
> > Let me know what you think,
> > Maxime
> > 
> > Changes from v1:
> >   - Force the muxing to the external oscillator even for old DT
> >   - Make the patches a bit more stable friendly
> >   - Change the bindings to have a cell of 1, to account for the external
> >     output of the oscillator
> >   - Split the driver remove() removal into a separate patch and switched to
> >     devm
> >   - Reordered the patches
> > 
> > Maxime Ripard (7):
> >   rtc: sun6i: Disable the build as a module
> >   rtc: sun6i: Add some locking
> >   rtc: sun6i: Switch to the external oscillator
> >   rtc: sun6i: Expose the 32kHz oscillator
> >   rtc: sun6i: Switch to devm_rtc_device_register
> >   ARM: sun8i: a23/a33: Enable the real LOSC and use it
> >   ARM: sun8i: a23/a33: Add the oscillators accuracy
> > 
> 
> I've applied 1/7 to 5/7. Thanks!

And I just applied patches 6 and 7. Thanks!
Maxime

-- 
Maxime Ripard, 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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy
@ 2017-01-25 15:36     ` Maxime Ripard
  0 siblings, 0 replies; 35+ messages in thread
From: Maxime Ripard @ 2017-01-25 15:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 24, 2017 at 06:49:35PM +0100, Alexandre Belloni wrote:
> Hi,
> 
> On 23/01/2017 at 11:41:45 +0100, Maxime Ripard wrote :
> > Hi,
> > 
> > The RTC used in the A31 and later SoC has an accuracy issue, which is
> > already significant even after a couple of hours.
> > 
> > This is due to the fact that the oscillator used by default is an internal
> > and very inaccurate one.
> > 
> > A first attempt at fixing that by switching to the external oscillator was
> > done in the patch "rtc: sun6i: Switch to the external oscillator". However,
> > it turned out to be problematic since it was tracked properly in the clock
> > framework, which might lead to some clocks being disabled, even though
> > their devices were not notified.
> > 
> > This is a second attempt, this time by making it part of the CCF. It
> > turned out to be a bit more complicated than one would expect since the mux
> > found inside the RTC also controls one of the input of the main clock unit.
> > Therefore, it needs to be probed before the main clock unit driver.
> > 
> > Let me know what you think,
> > Maxime
> > 
> > Changes from v1:
> >   - Force the muxing to the external oscillator even for old DT
> >   - Make the patches a bit more stable friendly
> >   - Change the bindings to have a cell of 1, to account for the external
> >     output of the oscillator
> >   - Split the driver remove() removal into a separate patch and switched to
> >     devm
> >   - Reordered the patches
> > 
> > Maxime Ripard (7):
> >   rtc: sun6i: Disable the build as a module
> >   rtc: sun6i: Add some locking
> >   rtc: sun6i: Switch to the external oscillator
> >   rtc: sun6i: Expose the 32kHz oscillator
> >   rtc: sun6i: Switch to devm_rtc_device_register
> >   ARM: sun8i: a23/a33: Enable the real LOSC and use it
> >   ARM: sun8i: a23/a33: Add the oscillators accuracy
> > 
> 
> I've applied 1/7 to 5/7. Thanks!

And I just applied patches 6 and 7. Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170125/54e8cc15/attachment.sig>

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

end of thread, other threads:[~2017-01-25 15:36 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-23 10:41 [rtc-linux] [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy Maxime Ripard
2017-01-23 10:41 ` Maxime Ripard
2017-01-23 10:41 ` Maxime Ripard
2017-01-23 10:41 ` [rtc-linux] [PATCH v2 1/7] rtc: sun6i: Disable the build as a module Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41 ` [rtc-linux] [PATCH v2 2/7] rtc: sun6i: Add some locking Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41 ` [rtc-linux] [PATCH v2 3/7] rtc: sun6i: Switch to the external oscillator Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41 ` [rtc-linux] [PATCH v2 4/7] rtc: sun6i: Expose the 32kHz oscillator Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 21:00   ` [rtc-linux] " Rob Herring
2017-01-23 21:00     ` Rob Herring
2017-01-23 21:00     ` Rob Herring
2017-01-23 10:41 ` [rtc-linux] [PATCH v2 5/7] rtc: sun6i: Switch to devm_rtc_device_register Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41 ` [rtc-linux] [PATCH v2 6/7] ARM: sun8i: a23/a33: Enable the real LOSC and use it Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41 ` [rtc-linux] [PATCH v2 7/7] ARM: sun8i: a23/a33: Add the oscillators accuracy Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-23 10:41   ` Maxime Ripard
2017-01-24 17:49 ` [rtc-linux] Re: [PATCH v2 0/7] rtc: sun6i: Fix the RTC accuracy Alexandre Belloni
2017-01-24 17:49   ` Alexandre Belloni
2017-01-24 17:49   ` Alexandre Belloni
2017-01-25 15:36   ` [rtc-linux] " Maxime Ripard
2017-01-25 15:36     ` Maxime Ripard
2017-01-25 15:36     ` Maxime Ripard

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