All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] Introduce STM32MP1 RTC
@ 2018-05-17 12:04 ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This series introduces STM32MP1 RTC.
On STM32MP1:
- two clocks are needed, plck and rtc_ck;
- to wakeup the system, a wakeup alarm interrupt is needed;
- some registers or bits have moved, but the operation is the same;
- the Backup Domain Protection (DBP) is not managed by RTC driver.

---
Changes in v3:
* Move cleanup changes in a separate patch
* Replace regs and evts by pointers to ensure no copy is made
* Set all registers offset as u16 instead of u8 and u16
* Fix Kbuild smatch warning:
  drivers/rtc/rtc-stm32.c:827 stm32_rtc_probe()
  warn: always true condition '(regs.verr != ~0) => (0-u16max != (-1))'

Changes in v2:
* One compatible per line in bindings file
* Remove unnecessary comment under rtc_ck as this clock is required for all
* Remove interrupts-extended and add stm32mp1 rtc alarm wakeup interrupt in
  interrupts property description

Amelie Delaunay (4):
  rtc: stm32: fix misspelling and misalignment issues
  rtc: stm32: rework register management to prepare other version of RTC
  dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  rtc: stm32: add stm32mp1 rtc support

 .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
 drivers/rtc/rtc-stm32.c                            | 273 ++++++++++++++++-----
 2 files changed, 229 insertions(+), 71 deletions(-)

-- 
2.7.4

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

* [PATCH v3 0/4] Introduce STM32MP1 RTC
@ 2018-05-17 12:04 ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This series introduces STM32MP1 RTC.
On STM32MP1:
- two clocks are needed, plck and rtc_ck;
- to wakeup the system, a wakeup alarm interrupt is needed;
- some registers or bits have moved, but the operation is the same;
- the Backup Domain Protection (DBP) is not managed by RTC driver.

---
Changes in v3:
* Move cleanup changes in a separate patch
* Replace regs and evts by pointers to ensure no copy is made
* Set all registers offset as u16 instead of u8 and u16
* Fix Kbuild smatch warning:
  drivers/rtc/rtc-stm32.c:827 stm32_rtc_probe()
  warn: always true condition '(regs.verr != ~0) => (0-u16max != (-1))'

Changes in v2:
* One compatible per line in bindings file
* Remove unnecessary comment under rtc_ck as this clock is required for all
* Remove interrupts-extended and add stm32mp1 rtc alarm wakeup interrupt in
  interrupts property description

Amelie Delaunay (4):
  rtc: stm32: fix misspelling and misalignment issues
  rtc: stm32: rework register management to prepare other version of RTC
  dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  rtc: stm32: add stm32mp1 rtc support

 .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
 drivers/rtc/rtc-stm32.c                            | 273 ++++++++++++++++-----
 2 files changed, 229 insertions(+), 71 deletions(-)

-- 
2.7.4

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

* [PATCH v3 0/4] Introduce STM32MP1 RTC
@ 2018-05-17 12:04 ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

This series introduces STM32MP1 RTC.
On STM32MP1:
- two clocks are needed, plck and rtc_ck;
- to wakeup the system, a wakeup alarm interrupt is needed;
- some registers or bits have moved, but the operation is the same;
- the Backup Domain Protection (DBP) is not managed by RTC driver.

---
Changes in v3:
* Move cleanup changes in a separate patch
* Replace regs and evts by pointers to ensure no copy is made
* Set all registers offset as u16 instead of u8 and u16
* Fix Kbuild smatch warning:
  drivers/rtc/rtc-stm32.c:827 stm32_rtc_probe()
  warn: always true condition '(regs.verr != ~0) => (0-u16max != (-1))'

Changes in v2:
* One compatible per line in bindings file
* Remove unnecessary comment under rtc_ck as this clock is required for all
* Remove interrupts-extended and add stm32mp1 rtc alarm wakeup interrupt in
  interrupts property description

Amelie Delaunay (4):
  rtc: stm32: fix misspelling and misalignment issues
  rtc: stm32: rework register management to prepare other version of RTC
  dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  rtc: stm32: add stm32mp1 rtc support

 .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
 drivers/rtc/rtc-stm32.c                            | 273 ++++++++++++++++-----
 2 files changed, 229 insertions(+), 71 deletions(-)

-- 
2.7.4

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

* [PATCH v3 1/4] rtc: stm32: fix misspelling and misalignment issues
  2018-05-17 12:04 ` Amelie Delaunay
  (?)
@ 2018-05-17 12:04   ` Amelie Delaunay
  -1 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch cleans the following checkpatch complaints:

CHECK: 'initalized' may be misspelled - perhaps 'initialized'?
#644: FILE: drivers/rtc/rtc-stm32.c:644:
+	 * the calendar has been initalized or not. INITS flag is reset by a

CHECK: Alignment should match open parenthesis
#669: FILE: drivers/rtc/rtc-stm32.c:669:
+	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
+			&stm32_rtc_ops, THIS_MODULE);

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index de49b5b..d41f804 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -641,7 +641,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	/*
 	 * After a system reset, RTC_ISR.INITS flag can be read to check if
-	 * the calendar has been initalized or not. INITS flag is reset by a
+	 * the calendar has been initialized or not. INITS flag is reset by a
 	 * power-on reset (no vbat, no power-supply). It is not reset if
 	 * rtc_ck parent clock has changed (so RTC prescalers need to be
 	 * changed). That's why we cannot rely on this flag to know if RTC
@@ -666,7 +666,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 			 "alarm won't be able to wake up the system");
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-			&stm32_rtc_ops, THIS_MODULE);
+						&stm32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
 		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
-- 
2.7.4

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

* [PATCH v3 1/4] rtc: stm32: fix misspelling and misalignment issues
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch cleans the following checkpatch complaints:

CHECK: 'initalized' may be misspelled - perhaps 'initialized'?
#644: FILE: drivers/rtc/rtc-stm32.c:644:
+	 * the calendar has been initalized or not. INITS flag is reset by a

CHECK: Alignment should match open parenthesis
#669: FILE: drivers/rtc/rtc-stm32.c:669:
+	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
+			&stm32_rtc_ops, THIS_MODULE);

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index de49b5b..d41f804 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -641,7 +641,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	/*
 	 * After a system reset, RTC_ISR.INITS flag can be read to check if
-	 * the calendar has been initalized or not. INITS flag is reset by a
+	 * the calendar has been initialized or not. INITS flag is reset by a
 	 * power-on reset (no vbat, no power-supply). It is not reset if
 	 * rtc_ck parent clock has changed (so RTC prescalers need to be
 	 * changed). That's why we cannot rely on this flag to know if RTC
@@ -666,7 +666,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 			 "alarm won't be able to wake up the system");
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-			&stm32_rtc_ops, THIS_MODULE);
+						&stm32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
 		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
-- 
2.7.4

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

* [PATCH v3 1/4] rtc: stm32: fix misspelling and misalignment issues
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch cleans the following checkpatch complaints:

CHECK: 'initalized' may be misspelled - perhaps 'initialized'?
#644: FILE: drivers/rtc/rtc-stm32.c:644:
+	 * the calendar has been initalized or not. INITS flag is reset by a

CHECK: Alignment should match open parenthesis
#669: FILE: drivers/rtc/rtc-stm32.c:669:
+	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
+			&stm32_rtc_ops, THIS_MODULE);

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index de49b5b..d41f804 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -641,7 +641,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	/*
 	 * After a system reset, RTC_ISR.INITS flag can be read to check if
-	 * the calendar has been initalized or not. INITS flag is reset by a
+	 * the calendar has been initialized or not. INITS flag is reset by a
 	 * power-on reset (no vbat, no power-supply). It is not reset if
 	 * rtc_ck parent clock has changed (so RTC prescalers need to be
 	 * changed). That's why we cannot rely on this flag to know if RTC
@@ -666,7 +666,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 			 "alarm won't be able to wake up the system");
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-			&stm32_rtc_ops, THIS_MODULE);
+						&stm32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
 		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
-- 
2.7.4

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

* [PATCH v3 2/4] rtc: stm32: rework register management to prepare other version of RTC
  2018-05-17 12:04 ` Amelie Delaunay
  (?)
@ 2018-05-17 12:04   ` Amelie Delaunay
  -1 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch reworks register/bits management because next version of RTC
uses the same way of working but with different register's offset or bits
moved in new registers.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 184 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 127 insertions(+), 57 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index d41f804..8254e38 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -16,15 +16,6 @@
 
 #define DRIVER_NAME "stm32_rtc"
 
-/* STM32 RTC registers */
-#define STM32_RTC_TR		0x00
-#define STM32_RTC_DR		0x04
-#define STM32_RTC_CR		0x08
-#define STM32_RTC_ISR		0x0C
-#define STM32_RTC_PRER		0x10
-#define STM32_RTC_ALRMAR	0x1C
-#define STM32_RTC_WPR		0x24
-
 /* STM32_RTC_TR bit fields  */
 #define STM32_RTC_TR_SEC_SHIFT		0
 #define STM32_RTC_TR_SEC		GENMASK(6, 0)
@@ -85,7 +76,26 @@
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+struct stm32_rtc;
+
+struct stm32_rtc_registers {
+	u8 tr;
+	u8 dr;
+	u8 cr;
+	u8 isr;
+	u8 prer;
+	u8 alrmar;
+	u8 wpr;
+};
+
+struct stm32_rtc_events {
+	u32 alra;
+};
+
 struct stm32_rtc_data {
+	const struct stm32_rtc_registers regs;
+	const struct stm32_rtc_events events;
+	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
 };
@@ -96,30 +106,35 @@ struct stm32_rtc {
 	struct regmap *dbp;
 	unsigned int dbp_reg;
 	unsigned int dbp_mask;
-	struct stm32_rtc_data *data;
 	struct clk *pclk;
 	struct clk *rtc_ck;
+	const struct stm32_rtc_data *data;
 	int irq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
-	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs->wpr);
+	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs->wpr);
 }
 
 static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
 }
 
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	if (!(isr & STM32_RTC_ISR_INITF)) {
 		isr |= STM32_RTC_ISR_INIT;
-		writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+		writel_relaxed(isr, rtc->base + regs->isr);
 
 		/*
 		 * It takes around 2 rtc_ck clock cycles to enter in
@@ -128,7 +143,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 		 * 1MHz, we poll every 10 us with a timeout of 100ms.
 		 */
 		return readl_relaxed_poll_timeout_atomic(
-					rtc->base + STM32_RTC_ISR,
+					rtc->base + regs->isr,
 					isr, (isr & STM32_RTC_ISR_INITF),
 					10, 100000);
 	}
@@ -138,40 +153,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 
 static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	isr &= ~STM32_RTC_ISR_INIT;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs->isr);
 }
 
 static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	isr &= ~STM32_RTC_ISR_RSF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs->isr);
 
 	/*
 	 * Wait for RSF to be set to ensure the calendar registers are
 	 * synchronised, it takes around 2 rtc_ck clock cycles
 	 */
-	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
 						 isr,
 						 (isr & STM32_RTC_ISR_RSF),
 						 10, 100000);
 }
 
+static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
+					unsigned int flags)
+{
+	rtc->data->clear_events(rtc, flags);
+}
+
 static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 {
 	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
-	unsigned int isr, cr;
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
+	unsigned int status, cr;
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	status = readl_relaxed(rtc->base + regs->isr);
+	cr = readl_relaxed(rtc->base + regs->cr);
 
-	if ((isr & STM32_RTC_ISR_ALRAF) &&
+	if ((status & evts->alra) &&
 	    (cr & STM32_RTC_CR_ALRAIE)) {
 		/* Alarm A flag - Alarm interrupt */
 		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@@ -179,9 +204,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 		/* Pass event to the kernel */
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
 
-		/* Clear event flag, otherwise new events won't be received */
-		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
-			       rtc->base + STM32_RTC_ISR);
+		/* Clear event flags, otherwise new events won't be received */
+		stm32_rtc_clear_event_flags(rtc, evts->alra);
 	}
 
 	mutex_unlock(&rtc->rtc_dev->ops_lock);
@@ -228,11 +252,12 @@ static void bcd2tm(struct rtc_time *tm)
 static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int tr, dr;
 
 	/* Time and Date in BCD format */
-	tr = readl_relaxed(rtc->base + STM32_RTC_TR);
-	dr = readl_relaxed(rtc->base + STM32_RTC_DR);
+	tr = readl_relaxed(rtc->base + regs->tr);
+	dr = readl_relaxed(rtc->base + regs->dr);
 
 	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
 	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@@ -253,6 +278,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int tr, dr;
 	int ret = 0;
 
@@ -277,8 +303,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		goto end;
 	}
 
-	writel_relaxed(tr, rtc->base + STM32_RTC_TR);
-	writel_relaxed(dr, rtc->base + STM32_RTC_DR);
+	writel_relaxed(tr, rtc->base + regs->tr);
+	writel_relaxed(dr, rtc->base + regs->dr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -292,12 +318,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
 	struct rtc_time *tm = &alrm->time;
-	unsigned int alrmar, cr, isr;
+	unsigned int alrmar, cr, status;
 
-	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	alrmar = readl_relaxed(rtc->base + regs->alrmar);
+	cr = readl_relaxed(rtc->base + regs->cr);
+	status = readl_relaxed(rtc->base + regs->isr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -350,7 +378,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	bcd2tm(tm);
 
 	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
-	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+	alrm->pending = (status & evts->alra) ? 1 : 0;
 
 	return 0;
 }
@@ -358,9 +386,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
-	unsigned int isr, cr;
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
+	unsigned int cr;
 
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 
 	stm32_rtc_wpr_unlock(rtc);
 
@@ -369,12 +399,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
 	else
 		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
-	/* Clear event flag, otherwise new events won't be received */
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	isr &= ~STM32_RTC_ISR_ALRAF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	/* Clear event flags, otherwise new events won't be received */
+	stm32_rtc_clear_event_flags(rtc, evts->alra);
 
 	stm32_rtc_wpr_lock(rtc);
 
@@ -383,9 +411,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 {
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
-	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
-	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
+	unsigned int dr = readl_relaxed(rtc->base + regs->dr);
+	unsigned int tr = readl_relaxed(rtc->base + regs->tr);
 
 	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
 	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@@ -419,6 +448,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	struct rtc_time *tm = &alrm->time;
 	unsigned int cr, isr, alrmar;
 	int ret = 0;
@@ -450,15 +480,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	stm32_rtc_wpr_unlock(rtc);
 
 	/* Disable Alarm */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_ALRAE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
 	/*
 	 * Poll Alarm write flag to be sure that Alarm update is allowed: it
 	 * takes around 2 rtc_ck clock cycles
 	 */
-	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
 						isr,
 						(isr & STM32_RTC_ISR_ALRAWF),
 						10, 100000);
@@ -469,7 +499,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	}
 
 	/* Write to Alarm register */
-	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
+	writel_relaxed(alrmar, rtc->base + regs->alrmar);
 
 	if (alrm->enabled)
 		stm32_rtc_alarm_irq_enable(dev, 1);
@@ -490,14 +520,50 @@ static const struct rtc_class_ops stm32_rtc_ops = {
 	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
 };
 
+static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
+				   unsigned int flags)
+{
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	/* Flags are cleared by writing 0 in RTC_ISR */
+	writel_relaxed(readl_relaxed(rtc->base + regs->isr) & ~flags,
+		       rtc->base + regs->isr);
+}
+
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct of_device_id stm32_rtc_of_match[] = {
@@ -510,6 +576,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
 static int stm32_rtc_init(struct platform_device *pdev,
 			  struct stm32_rtc *rtc)
 {
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
 	unsigned int rate;
 	int ret = 0;
@@ -550,14 +617,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
 	}
 
 	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs->prer);
 	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs->prer);
 
 	/* Force 24h time format */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_FMT;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -571,6 +638,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 static int stm32_rtc_probe(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc;
+	const struct stm32_rtc_registers *regs;
 	struct resource *res;
 	int ret;
 
@@ -585,6 +653,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	rtc->data = (struct stm32_rtc_data *)
 		    of_device_get_match_data(&pdev->dev);
+	regs = &rtc->data->regs;
 
 	if (rtc->data->need_dbp) {
 		rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
@@ -688,7 +757,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
 	 */
-	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
+	if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
 	return 0;
@@ -708,13 +777,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 static int stm32_rtc_remove(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int cr;
 
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_ALRAIE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 	stm32_rtc_wpr_lock(rtc);
 
 	clk_disable_unprepare(rtc->rtc_ck);
-- 
2.7.4

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

* [PATCH v3 2/4] rtc: stm32: rework register management to prepare other version of RTC
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, Amelie Delaunay, linux-kernel, linux-arm-kernel

This patch reworks register/bits management because next version of RTC
uses the same way of working but with different register's offset or bits
moved in new registers.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 184 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 127 insertions(+), 57 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index d41f804..8254e38 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -16,15 +16,6 @@
 
 #define DRIVER_NAME "stm32_rtc"
 
-/* STM32 RTC registers */
-#define STM32_RTC_TR		0x00
-#define STM32_RTC_DR		0x04
-#define STM32_RTC_CR		0x08
-#define STM32_RTC_ISR		0x0C
-#define STM32_RTC_PRER		0x10
-#define STM32_RTC_ALRMAR	0x1C
-#define STM32_RTC_WPR		0x24
-
 /* STM32_RTC_TR bit fields  */
 #define STM32_RTC_TR_SEC_SHIFT		0
 #define STM32_RTC_TR_SEC		GENMASK(6, 0)
@@ -85,7 +76,26 @@
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+struct stm32_rtc;
+
+struct stm32_rtc_registers {
+	u8 tr;
+	u8 dr;
+	u8 cr;
+	u8 isr;
+	u8 prer;
+	u8 alrmar;
+	u8 wpr;
+};
+
+struct stm32_rtc_events {
+	u32 alra;
+};
+
 struct stm32_rtc_data {
+	const struct stm32_rtc_registers regs;
+	const struct stm32_rtc_events events;
+	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
 };
@@ -96,30 +106,35 @@ struct stm32_rtc {
 	struct regmap *dbp;
 	unsigned int dbp_reg;
 	unsigned int dbp_mask;
-	struct stm32_rtc_data *data;
 	struct clk *pclk;
 	struct clk *rtc_ck;
+	const struct stm32_rtc_data *data;
 	int irq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
-	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs->wpr);
+	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs->wpr);
 }
 
 static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
 }
 
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	if (!(isr & STM32_RTC_ISR_INITF)) {
 		isr |= STM32_RTC_ISR_INIT;
-		writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+		writel_relaxed(isr, rtc->base + regs->isr);
 
 		/*
 		 * It takes around 2 rtc_ck clock cycles to enter in
@@ -128,7 +143,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 		 * 1MHz, we poll every 10 us with a timeout of 100ms.
 		 */
 		return readl_relaxed_poll_timeout_atomic(
-					rtc->base + STM32_RTC_ISR,
+					rtc->base + regs->isr,
 					isr, (isr & STM32_RTC_ISR_INITF),
 					10, 100000);
 	}
@@ -138,40 +153,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 
 static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	isr &= ~STM32_RTC_ISR_INIT;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs->isr);
 }
 
 static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	isr &= ~STM32_RTC_ISR_RSF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs->isr);
 
 	/*
 	 * Wait for RSF to be set to ensure the calendar registers are
 	 * synchronised, it takes around 2 rtc_ck clock cycles
 	 */
-	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
 						 isr,
 						 (isr & STM32_RTC_ISR_RSF),
 						 10, 100000);
 }
 
+static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
+					unsigned int flags)
+{
+	rtc->data->clear_events(rtc, flags);
+}
+
 static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 {
 	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
-	unsigned int isr, cr;
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
+	unsigned int status, cr;
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	status = readl_relaxed(rtc->base + regs->isr);
+	cr = readl_relaxed(rtc->base + regs->cr);
 
-	if ((isr & STM32_RTC_ISR_ALRAF) &&
+	if ((status & evts->alra) &&
 	    (cr & STM32_RTC_CR_ALRAIE)) {
 		/* Alarm A flag - Alarm interrupt */
 		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@@ -179,9 +204,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 		/* Pass event to the kernel */
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
 
-		/* Clear event flag, otherwise new events won't be received */
-		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
-			       rtc->base + STM32_RTC_ISR);
+		/* Clear event flags, otherwise new events won't be received */
+		stm32_rtc_clear_event_flags(rtc, evts->alra);
 	}
 
 	mutex_unlock(&rtc->rtc_dev->ops_lock);
@@ -228,11 +252,12 @@ static void bcd2tm(struct rtc_time *tm)
 static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int tr, dr;
 
 	/* Time and Date in BCD format */
-	tr = readl_relaxed(rtc->base + STM32_RTC_TR);
-	dr = readl_relaxed(rtc->base + STM32_RTC_DR);
+	tr = readl_relaxed(rtc->base + regs->tr);
+	dr = readl_relaxed(rtc->base + regs->dr);
 
 	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
 	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@@ -253,6 +278,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int tr, dr;
 	int ret = 0;
 
@@ -277,8 +303,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		goto end;
 	}
 
-	writel_relaxed(tr, rtc->base + STM32_RTC_TR);
-	writel_relaxed(dr, rtc->base + STM32_RTC_DR);
+	writel_relaxed(tr, rtc->base + regs->tr);
+	writel_relaxed(dr, rtc->base + regs->dr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -292,12 +318,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
 	struct rtc_time *tm = &alrm->time;
-	unsigned int alrmar, cr, isr;
+	unsigned int alrmar, cr, status;
 
-	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	alrmar = readl_relaxed(rtc->base + regs->alrmar);
+	cr = readl_relaxed(rtc->base + regs->cr);
+	status = readl_relaxed(rtc->base + regs->isr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -350,7 +378,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	bcd2tm(tm);
 
 	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
-	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+	alrm->pending = (status & evts->alra) ? 1 : 0;
 
 	return 0;
 }
@@ -358,9 +386,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
-	unsigned int isr, cr;
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
+	unsigned int cr;
 
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 
 	stm32_rtc_wpr_unlock(rtc);
 
@@ -369,12 +399,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
 	else
 		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
-	/* Clear event flag, otherwise new events won't be received */
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	isr &= ~STM32_RTC_ISR_ALRAF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	/* Clear event flags, otherwise new events won't be received */
+	stm32_rtc_clear_event_flags(rtc, evts->alra);
 
 	stm32_rtc_wpr_lock(rtc);
 
@@ -383,9 +411,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 {
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
-	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
-	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
+	unsigned int dr = readl_relaxed(rtc->base + regs->dr);
+	unsigned int tr = readl_relaxed(rtc->base + regs->tr);
 
 	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
 	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@@ -419,6 +448,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	struct rtc_time *tm = &alrm->time;
 	unsigned int cr, isr, alrmar;
 	int ret = 0;
@@ -450,15 +480,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	stm32_rtc_wpr_unlock(rtc);
 
 	/* Disable Alarm */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_ALRAE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
 	/*
 	 * Poll Alarm write flag to be sure that Alarm update is allowed: it
 	 * takes around 2 rtc_ck clock cycles
 	 */
-	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
 						isr,
 						(isr & STM32_RTC_ISR_ALRAWF),
 						10, 100000);
@@ -469,7 +499,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	}
 
 	/* Write to Alarm register */
-	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
+	writel_relaxed(alrmar, rtc->base + regs->alrmar);
 
 	if (alrm->enabled)
 		stm32_rtc_alarm_irq_enable(dev, 1);
@@ -490,14 +520,50 @@ static const struct rtc_class_ops stm32_rtc_ops = {
 	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
 };
 
+static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
+				   unsigned int flags)
+{
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	/* Flags are cleared by writing 0 in RTC_ISR */
+	writel_relaxed(readl_relaxed(rtc->base + regs->isr) & ~flags,
+		       rtc->base + regs->isr);
+}
+
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct of_device_id stm32_rtc_of_match[] = {
@@ -510,6 +576,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
 static int stm32_rtc_init(struct platform_device *pdev,
 			  struct stm32_rtc *rtc)
 {
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
 	unsigned int rate;
 	int ret = 0;
@@ -550,14 +617,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
 	}
 
 	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs->prer);
 	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs->prer);
 
 	/* Force 24h time format */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_FMT;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -571,6 +638,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 static int stm32_rtc_probe(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc;
+	const struct stm32_rtc_registers *regs;
 	struct resource *res;
 	int ret;
 
@@ -585,6 +653,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	rtc->data = (struct stm32_rtc_data *)
 		    of_device_get_match_data(&pdev->dev);
+	regs = &rtc->data->regs;
 
 	if (rtc->data->need_dbp) {
 		rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
@@ -688,7 +757,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
 	 */
-	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
+	if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
 	return 0;
@@ -708,13 +777,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 static int stm32_rtc_remove(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int cr;
 
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_ALRAIE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 	stm32_rtc_wpr_lock(rtc);
 
 	clk_disable_unprepare(rtc->rtc_ck);
-- 
2.7.4

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

* [PATCH v3 2/4] rtc: stm32: rework register management to prepare other version of RTC
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch reworks register/bits management because next version of RTC
uses the same way of working but with different register's offset or bits
moved in new registers.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 184 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 127 insertions(+), 57 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index d41f804..8254e38 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -16,15 +16,6 @@
 
 #define DRIVER_NAME "stm32_rtc"
 
-/* STM32 RTC registers */
-#define STM32_RTC_TR		0x00
-#define STM32_RTC_DR		0x04
-#define STM32_RTC_CR		0x08
-#define STM32_RTC_ISR		0x0C
-#define STM32_RTC_PRER		0x10
-#define STM32_RTC_ALRMAR	0x1C
-#define STM32_RTC_WPR		0x24
-
 /* STM32_RTC_TR bit fields  */
 #define STM32_RTC_TR_SEC_SHIFT		0
 #define STM32_RTC_TR_SEC		GENMASK(6, 0)
@@ -85,7 +76,26 @@
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+struct stm32_rtc;
+
+struct stm32_rtc_registers {
+	u8 tr;
+	u8 dr;
+	u8 cr;
+	u8 isr;
+	u8 prer;
+	u8 alrmar;
+	u8 wpr;
+};
+
+struct stm32_rtc_events {
+	u32 alra;
+};
+
 struct stm32_rtc_data {
+	const struct stm32_rtc_registers regs;
+	const struct stm32_rtc_events events;
+	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
 };
@@ -96,30 +106,35 @@ struct stm32_rtc {
 	struct regmap *dbp;
 	unsigned int dbp_reg;
 	unsigned int dbp_mask;
-	struct stm32_rtc_data *data;
 	struct clk *pclk;
 	struct clk *rtc_ck;
+	const struct stm32_rtc_data *data;
 	int irq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
-	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs->wpr);
+	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs->wpr);
 }
 
 static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
 }
 
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	if (!(isr & STM32_RTC_ISR_INITF)) {
 		isr |= STM32_RTC_ISR_INIT;
-		writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+		writel_relaxed(isr, rtc->base + regs->isr);
 
 		/*
 		 * It takes around 2 rtc_ck clock cycles to enter in
@@ -128,7 +143,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 		 * 1MHz, we poll every 10 us with a timeout of 100ms.
 		 */
 		return readl_relaxed_poll_timeout_atomic(
-					rtc->base + STM32_RTC_ISR,
+					rtc->base + regs->isr,
 					isr, (isr & STM32_RTC_ISR_INITF),
 					10, 100000);
 	}
@@ -138,40 +153,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 
 static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	isr &= ~STM32_RTC_ISR_INIT;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs->isr);
 }
 
 static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs->isr);
 
 	isr &= ~STM32_RTC_ISR_RSF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs->isr);
 
 	/*
 	 * Wait for RSF to be set to ensure the calendar registers are
 	 * synchronised, it takes around 2 rtc_ck clock cycles
 	 */
-	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	return readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
 						 isr,
 						 (isr & STM32_RTC_ISR_RSF),
 						 10, 100000);
 }
 
+static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
+					unsigned int flags)
+{
+	rtc->data->clear_events(rtc, flags);
+}
+
 static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 {
 	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
-	unsigned int isr, cr;
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
+	unsigned int status, cr;
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	status = readl_relaxed(rtc->base + regs->isr);
+	cr = readl_relaxed(rtc->base + regs->cr);
 
-	if ((isr & STM32_RTC_ISR_ALRAF) &&
+	if ((status & evts->alra) &&
 	    (cr & STM32_RTC_CR_ALRAIE)) {
 		/* Alarm A flag - Alarm interrupt */
 		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@@ -179,9 +204,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 		/* Pass event to the kernel */
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
 
-		/* Clear event flag, otherwise new events won't be received */
-		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
-			       rtc->base + STM32_RTC_ISR);
+		/* Clear event flags, otherwise new events won't be received */
+		stm32_rtc_clear_event_flags(rtc, evts->alra);
 	}
 
 	mutex_unlock(&rtc->rtc_dev->ops_lock);
@@ -228,11 +252,12 @@ static void bcd2tm(struct rtc_time *tm)
 static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int tr, dr;
 
 	/* Time and Date in BCD format */
-	tr = readl_relaxed(rtc->base + STM32_RTC_TR);
-	dr = readl_relaxed(rtc->base + STM32_RTC_DR);
+	tr = readl_relaxed(rtc->base + regs->tr);
+	dr = readl_relaxed(rtc->base + regs->dr);
 
 	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
 	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@@ -253,6 +278,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int tr, dr;
 	int ret = 0;
 
@@ -277,8 +303,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		goto end;
 	}
 
-	writel_relaxed(tr, rtc->base + STM32_RTC_TR);
-	writel_relaxed(dr, rtc->base + STM32_RTC_DR);
+	writel_relaxed(tr, rtc->base + regs->tr);
+	writel_relaxed(dr, rtc->base + regs->dr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -292,12 +318,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
 	struct rtc_time *tm = &alrm->time;
-	unsigned int alrmar, cr, isr;
+	unsigned int alrmar, cr, status;
 
-	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	alrmar = readl_relaxed(rtc->base + regs->alrmar);
+	cr = readl_relaxed(rtc->base + regs->cr);
+	status = readl_relaxed(rtc->base + regs->isr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -350,7 +378,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	bcd2tm(tm);
 
 	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
-	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+	alrm->pending = (status & evts->alra) ? 1 : 0;
 
 	return 0;
 }
@@ -358,9 +386,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
-	unsigned int isr, cr;
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+	const struct stm32_rtc_events *evts = &rtc->data->events;
+	unsigned int cr;
 
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 
 	stm32_rtc_wpr_unlock(rtc);
 
@@ -369,12 +399,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
 	else
 		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
-	/* Clear event flag, otherwise new events won't be received */
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	isr &= ~STM32_RTC_ISR_ALRAF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	/* Clear event flags, otherwise new events won't be received */
+	stm32_rtc_clear_event_flags(rtc, evts->alra);
 
 	stm32_rtc_wpr_lock(rtc);
 
@@ -383,9 +411,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 {
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
-	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
-	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
+	unsigned int dr = readl_relaxed(rtc->base + regs->dr);
+	unsigned int tr = readl_relaxed(rtc->base + regs->tr);
 
 	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
 	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@@ -419,6 +448,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	struct rtc_time *tm = &alrm->time;
 	unsigned int cr, isr, alrmar;
 	int ret = 0;
@@ -450,15 +480,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	stm32_rtc_wpr_unlock(rtc);
 
 	/* Disable Alarm */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_ALRAE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
 	/*
 	 * Poll Alarm write flag to be sure that Alarm update is allowed: it
 	 * takes around 2 rtc_ck clock cycles
 	 */
-	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs->isr,
 						isr,
 						(isr & STM32_RTC_ISR_ALRAWF),
 						10, 100000);
@@ -469,7 +499,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	}
 
 	/* Write to Alarm register */
-	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
+	writel_relaxed(alrmar, rtc->base + regs->alrmar);
 
 	if (alrm->enabled)
 		stm32_rtc_alarm_irq_enable(dev, 1);
@@ -490,14 +520,50 @@ static const struct rtc_class_ops stm32_rtc_ops = {
 	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
 };
 
+static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
+				   unsigned int flags)
+{
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
+
+	/* Flags are cleared by writing 0 in RTC_ISR */
+	writel_relaxed(readl_relaxed(rtc->base + regs->isr) & ~flags,
+		       rtc->base + regs->isr);
+}
+
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct of_device_id stm32_rtc_of_match[] = {
@@ -510,6 +576,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
 static int stm32_rtc_init(struct platform_device *pdev,
 			  struct stm32_rtc *rtc)
 {
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
 	unsigned int rate;
 	int ret = 0;
@@ -550,14 +617,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
 	}
 
 	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs->prer);
 	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs->prer);
 
 	/* Force 24h time format */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_FMT;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -571,6 +638,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 static int stm32_rtc_probe(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc;
+	const struct stm32_rtc_registers *regs;
 	struct resource *res;
 	int ret;
 
@@ -585,6 +653,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	rtc->data = (struct stm32_rtc_data *)
 		    of_device_get_match_data(&pdev->dev);
+	regs = &rtc->data->regs;
 
 	if (rtc->data->need_dbp) {
 		rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
@@ -688,7 +757,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
 	 */
-	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
+	if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
 	return 0;
@@ -708,13 +777,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 static int stm32_rtc_remove(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int cr;
 
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs->cr);
 	cr &= ~STM32_RTC_CR_ALRAIE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs->cr);
 	stm32_rtc_wpr_lock(rtc);
 
 	clk_disable_unprepare(rtc->rtc_ck);
-- 
2.7.4

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

* [PATCH v3 3/4] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  2018-05-17 12:04 ` Amelie Delaunay
  (?)
@ 2018-05-17 12:04   ` Amelie Delaunay
  -1 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
doesn't require to disable backup domain write protection, and rtc_ck
parent clock assignment isn't allowed.
To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
alarm interrupt.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 ++++++++++++++++------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
index 00f8b5d..c920e27 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -1,25 +1,29 @@
 STM32 Real Time Clock
 
 Required properties:
-- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
-  the device is compatible with stm32(f4/f7) or stm32h7.
+- compatible: can be one of the following:
+  - "st,stm32-rtc" for devices compatible with stm32(f4/f7).
+  - "st,stm32h7-rtc" for devices compatible with stm32h7.
+  - "st,stm32mp1-rtc" for devices compatible with stm32mp1.
 - reg: address range of rtc register set.
 - clocks: can use up to two clocks, depending on part used:
   - "rtc_ck": RTC clock source.
-    It is required on stm32(f4/f7) and stm32h7.
   - "pclk": RTC APB interface clock.
     It is not present on stm32(f4/f7).
-    It is required on stm32h7.
+    It is required on stm32(h7/mp1).
 - clock-names: must be "rtc_ck" and "pclk".
-    It is required only on stm32h7.
+    It is required on stm32(h7/mp1).
 - interrupt-parent: phandle for the interrupt controller.
-- interrupts: rtc alarm interrupt.
+    It is required on stm32(f4/f7/h7).
+- interrupts: rtc alarm interrupt. On stm32mp1, a second interrupt is required
+  for rtc alarm wakeup interrupt.
 - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
   access control register at offset, and change the dbp (Disable Backup
   Protection) bit represented by the mask, mandatory to disable/enable backup
   domain (RTC registers) write protection.
+    It is required on stm32(f4/f7/h7).
 
-Optional properties (to override default rtc_ck parent clock):
+Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
 - assigned-clocks: reference to the rtc_ck clock entry.
 - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
 
@@ -48,3 +52,12 @@ Example:
 		interrupt-names = "alarm";
 		st,syscfg = <&pwrcfg 0x00 0x100>;
 	};
+
+	rtc: rtc@5c004000 {
+		compatible = "st,stm32mp1-rtc";
+		reg = <0x5c004000 0x400>;
+		clocks = <&rcc RTCAPB>, <&rcc RTC>;
+		clock-names = "pclk", "rtc_ck";
+		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
+				      <&exti 19 1>;
+	};
-- 
2.7.4

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

* [PATCH v3 3/4] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
doesn't require to disable backup domain write protection, and rtc_ck
parent clock assignment isn't allowed.
To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
alarm interrupt.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 ++++++++++++++++------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
index 00f8b5d..c920e27 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -1,25 +1,29 @@
 STM32 Real Time Clock
 
 Required properties:
-- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
-  the device is compatible with stm32(f4/f7) or stm32h7.
+- compatible: can be one of the following:
+  - "st,stm32-rtc" for devices compatible with stm32(f4/f7).
+  - "st,stm32h7-rtc" for devices compatible with stm32h7.
+  - "st,stm32mp1-rtc" for devices compatible with stm32mp1.
 - reg: address range of rtc register set.
 - clocks: can use up to two clocks, depending on part used:
   - "rtc_ck": RTC clock source.
-    It is required on stm32(f4/f7) and stm32h7.
   - "pclk": RTC APB interface clock.
     It is not present on stm32(f4/f7).
-    It is required on stm32h7.
+    It is required on stm32(h7/mp1).
 - clock-names: must be "rtc_ck" and "pclk".
-    It is required only on stm32h7.
+    It is required on stm32(h7/mp1).
 - interrupt-parent: phandle for the interrupt controller.
-- interrupts: rtc alarm interrupt.
+    It is required on stm32(f4/f7/h7).
+- interrupts: rtc alarm interrupt. On stm32mp1, a second interrupt is required
+  for rtc alarm wakeup interrupt.
 - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
   access control register at offset, and change the dbp (Disable Backup
   Protection) bit represented by the mask, mandatory to disable/enable backup
   domain (RTC registers) write protection.
+    It is required on stm32(f4/f7/h7).
 
-Optional properties (to override default rtc_ck parent clock):
+Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
 - assigned-clocks: reference to the rtc_ck clock entry.
 - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
 
@@ -48,3 +52,12 @@ Example:
 		interrupt-names = "alarm";
 		st,syscfg = <&pwrcfg 0x00 0x100>;
 	};
+
+	rtc: rtc@5c004000 {
+		compatible = "st,stm32mp1-rtc";
+		reg = <0x5c004000 0x400>;
+		clocks = <&rcc RTCAPB>, <&rcc RTC>;
+		clock-names = "pclk", "rtc_ck";
+		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
+				      <&exti 19 1>;
+	};
-- 
2.7.4

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

* [PATCH v3 3/4] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
doesn't require to disable backup domain write protection, and rtc_ck
parent clock assignment isn't allowed.
To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
alarm interrupt.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 ++++++++++++++++------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
index 00f8b5d..c920e27 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -1,25 +1,29 @@
 STM32 Real Time Clock
 
 Required properties:
-- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
-  the device is compatible with stm32(f4/f7) or stm32h7.
+- compatible: can be one of the following:
+  - "st,stm32-rtc" for devices compatible with stm32(f4/f7).
+  - "st,stm32h7-rtc" for devices compatible with stm32h7.
+  - "st,stm32mp1-rtc" for devices compatible with stm32mp1.
 - reg: address range of rtc register set.
 - clocks: can use up to two clocks, depending on part used:
   - "rtc_ck": RTC clock source.
-    It is required on stm32(f4/f7) and stm32h7.
   - "pclk": RTC APB interface clock.
     It is not present on stm32(f4/f7).
-    It is required on stm32h7.
+    It is required on stm32(h7/mp1).
 - clock-names: must be "rtc_ck" and "pclk".
-    It is required only on stm32h7.
+    It is required on stm32(h7/mp1).
 - interrupt-parent: phandle for the interrupt controller.
-- interrupts: rtc alarm interrupt.
+    It is required on stm32(f4/f7/h7).
+- interrupts: rtc alarm interrupt. On stm32mp1, a second interrupt is required
+  for rtc alarm wakeup interrupt.
 - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
   access control register at offset, and change the dbp (Disable Backup
   Protection) bit represented by the mask, mandatory to disable/enable backup
   domain (RTC registers) write protection.
+    It is required on stm32(f4/f7/h7).
 
-Optional properties (to override default rtc_ck parent clock):
+Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
 - assigned-clocks: reference to the rtc_ck clock entry.
 - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
 
@@ -48,3 +52,12 @@ Example:
 		interrupt-names = "alarm";
 		st,syscfg = <&pwrcfg 0x00 0x100>;
 	};
+
+	rtc: rtc at 5c004000 {
+		compatible = "st,stm32mp1-rtc";
+		reg = <0x5c004000 0x400>;
+		clocks = <&rcc RTCAPB>, <&rcc RTC>;
+		clock-names = "pclk", "rtc_ck";
+		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
+				      <&exti 19 1>;
+	};
-- 
2.7.4

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

* [PATCH v3 4/4] rtc: stm32: add stm32mp1 rtc support
  2018-05-17 12:04 ` Amelie Delaunay
  (?)
@ 2018-05-17 12:04   ` Amelie Delaunay
  -1 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch adds support for stm32mp1 RTC.
Some common registers with previous RTC version have a different offset.
It is the case for Control Register (CR) and ALaRMA Register (ALRMAR).
There are also new registers regarding event flags: now, Alarm event flag
is in Status Register (SR) and write 1 in Status Clear Register (SCR) is
required to clear the event.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 103 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 89 insertions(+), 14 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 8254e38..c5908cf 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -11,6 +11,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
@@ -39,7 +40,7 @@
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
 
-/* STM32_RTC_ISR bit fields */
+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
 #define STM32_RTC_ISR_INITS		BIT(4)
 #define STM32_RTC_ISR_RSF		BIT(5)
@@ -71,21 +72,36 @@
 #define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)
 #define STM32_RTC_ALRMXR_DATE_MASK	BIT(31)
 
+/* STM32_RTC_SR/_SCR bit fields */
+#define STM32_RTC_SR_ALRA		BIT(0)
+
+/* STM32_RTC_VERR bit fields */
+#define STM32_RTC_VERR_MINREV_SHIFT	0
+#define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
+#define STM32_RTC_VERR_MAJREV_SHIFT	4
+#define STM32_RTC_VERR_MAJREV		GENMASK(7, 4)
+
 /* STM32_RTC_WPR key constants */
 #define RTC_WPR_1ST_KEY			0xCA
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+/* Max STM32 RTC register offset is 0x3FC */
+#define UNDEF_REG			0xFFFF
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
-	u8 tr;
-	u8 dr;
-	u8 cr;
-	u8 isr;
-	u8 prer;
-	u8 alrmar;
-	u8 wpr;
+	u16 tr;
+	u16 dr;
+	u16 cr;
+	u16 isr;
+	u16 prer;
+	u16 alrmar;
+	u16 wpr;
+	u16 sr;
+	u16 scr;
+	u16 verr;
 };
 
 struct stm32_rtc_events {
@@ -98,6 +114,7 @@ struct stm32_rtc_data {
 	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
+	bool has_wakeirq;
 };
 
 struct stm32_rtc {
@@ -110,6 +127,7 @@ struct stm32_rtc {
 	struct clk *rtc_ck;
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
+	int wakeirq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -193,7 +211,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	status = readl_relaxed(rtc->base + regs->isr);
+	status = readl_relaxed(rtc->base + regs->sr);
 	cr = readl_relaxed(rtc->base + regs->cr);
 
 	if ((status & evts->alra) &&
@@ -325,7 +343,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 	alrmar = readl_relaxed(rtc->base + regs->alrmar);
 	cr = readl_relaxed(rtc->base + regs->cr);
-	status = readl_relaxed(rtc->base + regs->isr);
+	status = readl_relaxed(rtc->base + regs->sr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -533,6 +551,7 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -541,6 +560,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -551,6 +573,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -559,6 +582,9 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -566,9 +592,41 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.clear_events = stm32_rtc_clear_events,
 };
 
+static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
+				      unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 1 in RTC_SCR */
+	writel_relaxed(flags, rtc->base + regs.scr);
+}
+
+static const struct stm32_rtc_data stm32mp1_data = {
+	.has_pclk = true,
+	.need_dbp = false,
+	.has_wakeirq = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x18,
+		.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
+		.prer = 0x10,
+		.alrmar = 0x40,
+		.wpr = 0x24,
+		.sr = 0x50,
+		.scr = 0x5C,
+		.verr = 0x3F4,
+	},
+	.events = {
+		.alra = STM32_RTC_SR_ALRA,
+	},
+	.clear_events = stm32mp1_rtc_clear_events,
+};
+
 static const struct of_device_id stm32_rtc_of_match[] = {
 	{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
 	{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
+	{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@@ -727,12 +785,19 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	platform_set_drvdata(pdev, rtc);
-
 	ret = device_init_wakeup(&pdev->dev, true);
+	if (rtc->data->has_wakeirq) {
+		rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
+		if (rtc->wakeirq_alarm <= 0)
+			ret = rtc->wakeirq_alarm;
+		else
+			ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+							    rtc->wakeirq_alarm);
+	}
 	if (ret)
-		dev_warn(&pdev->dev,
-			 "alarm won't be able to wake up the system");
+		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+
+	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
 						&stm32_rtc_ops, THIS_MODULE);
@@ -760,6 +825,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
+	if (regs->verr != UNDEF_REG) {
+		u32 ver = readl_relaxed(rtc->base + regs->verr);
+
+		dev_info(&pdev->dev, "registered rev:%d.%d\n",
+			 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
+			 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
+	}
+
 	return 0;
 err:
 	if (rtc->data->has_pclk)
@@ -769,6 +842,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return ret;
@@ -795,6 +869,7 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return 0;
-- 
2.7.4

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

* [PATCH v3 4/4] rtc: stm32: add stm32mp1 rtc support
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch adds support for stm32mp1 RTC.
Some common registers with previous RTC version have a different offset.
It is the case for Control Register (CR) and ALaRMA Register (ALRMAR).
There are also new registers regarding event flags: now, Alarm event flag
is in Status Register (SR) and write 1 in Status Clear Register (SCR) is
required to clear the event.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 103 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 89 insertions(+), 14 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 8254e38..c5908cf 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -11,6 +11,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
@@ -39,7 +40,7 @@
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
 
-/* STM32_RTC_ISR bit fields */
+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
 #define STM32_RTC_ISR_INITS		BIT(4)
 #define STM32_RTC_ISR_RSF		BIT(5)
@@ -71,21 +72,36 @@
 #define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)
 #define STM32_RTC_ALRMXR_DATE_MASK	BIT(31)
 
+/* STM32_RTC_SR/_SCR bit fields */
+#define STM32_RTC_SR_ALRA		BIT(0)
+
+/* STM32_RTC_VERR bit fields */
+#define STM32_RTC_VERR_MINREV_SHIFT	0
+#define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
+#define STM32_RTC_VERR_MAJREV_SHIFT	4
+#define STM32_RTC_VERR_MAJREV		GENMASK(7, 4)
+
 /* STM32_RTC_WPR key constants */
 #define RTC_WPR_1ST_KEY			0xCA
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+/* Max STM32 RTC register offset is 0x3FC */
+#define UNDEF_REG			0xFFFF
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
-	u8 tr;
-	u8 dr;
-	u8 cr;
-	u8 isr;
-	u8 prer;
-	u8 alrmar;
-	u8 wpr;
+	u16 tr;
+	u16 dr;
+	u16 cr;
+	u16 isr;
+	u16 prer;
+	u16 alrmar;
+	u16 wpr;
+	u16 sr;
+	u16 scr;
+	u16 verr;
 };
 
 struct stm32_rtc_events {
@@ -98,6 +114,7 @@ struct stm32_rtc_data {
 	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
+	bool has_wakeirq;
 };
 
 struct stm32_rtc {
@@ -110,6 +127,7 @@ struct stm32_rtc {
 	struct clk *rtc_ck;
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
+	int wakeirq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -193,7 +211,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	status = readl_relaxed(rtc->base + regs->isr);
+	status = readl_relaxed(rtc->base + regs->sr);
 	cr = readl_relaxed(rtc->base + regs->cr);
 
 	if ((status & evts->alra) &&
@@ -325,7 +343,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 	alrmar = readl_relaxed(rtc->base + regs->alrmar);
 	cr = readl_relaxed(rtc->base + regs->cr);
-	status = readl_relaxed(rtc->base + regs->isr);
+	status = readl_relaxed(rtc->base + regs->sr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -533,6 +551,7 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -541,6 +560,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -551,6 +573,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -559,6 +582,9 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -566,9 +592,41 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.clear_events = stm32_rtc_clear_events,
 };
 
+static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
+				      unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 1 in RTC_SCR */
+	writel_relaxed(flags, rtc->base + regs.scr);
+}
+
+static const struct stm32_rtc_data stm32mp1_data = {
+	.has_pclk = true,
+	.need_dbp = false,
+	.has_wakeirq = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x18,
+		.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
+		.prer = 0x10,
+		.alrmar = 0x40,
+		.wpr = 0x24,
+		.sr = 0x50,
+		.scr = 0x5C,
+		.verr = 0x3F4,
+	},
+	.events = {
+		.alra = STM32_RTC_SR_ALRA,
+	},
+	.clear_events = stm32mp1_rtc_clear_events,
+};
+
 static const struct of_device_id stm32_rtc_of_match[] = {
 	{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
 	{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
+	{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@@ -727,12 +785,19 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	platform_set_drvdata(pdev, rtc);
-
 	ret = device_init_wakeup(&pdev->dev, true);
+	if (rtc->data->has_wakeirq) {
+		rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
+		if (rtc->wakeirq_alarm <= 0)
+			ret = rtc->wakeirq_alarm;
+		else
+			ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+							    rtc->wakeirq_alarm);
+	}
 	if (ret)
-		dev_warn(&pdev->dev,
-			 "alarm won't be able to wake up the system");
+		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+
+	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
 						&stm32_rtc_ops, THIS_MODULE);
@@ -760,6 +825,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
+	if (regs->verr != UNDEF_REG) {
+		u32 ver = readl_relaxed(rtc->base + regs->verr);
+
+		dev_info(&pdev->dev, "registered rev:%d.%d\n",
+			 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
+			 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
+	}
+
 	return 0;
 err:
 	if (rtc->data->has_pclk)
@@ -769,6 +842,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return ret;
@@ -795,6 +869,7 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return 0;
-- 
2.7.4

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

* [PATCH v3 4/4] rtc: stm32: add stm32mp1 rtc support
@ 2018-05-17 12:04   ` Amelie Delaunay
  0 siblings, 0 replies; 19+ messages in thread
From: Amelie Delaunay @ 2018-05-17 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for stm32mp1 RTC.
Some common registers with previous RTC version have a different offset.
It is the case for Control Register (CR) and ALaRMA Register (ALRMAR).
There are also new registers regarding event flags: now, Alarm event flag
is in Status Register (SR) and write 1 in Status Clear Register (SCR) is
required to clear the event.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 103 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 89 insertions(+), 14 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 8254e38..c5908cf 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -11,6 +11,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
@@ -39,7 +40,7 @@
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
 
-/* STM32_RTC_ISR bit fields */
+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
 #define STM32_RTC_ISR_INITS		BIT(4)
 #define STM32_RTC_ISR_RSF		BIT(5)
@@ -71,21 +72,36 @@
 #define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)
 #define STM32_RTC_ALRMXR_DATE_MASK	BIT(31)
 
+/* STM32_RTC_SR/_SCR bit fields */
+#define STM32_RTC_SR_ALRA		BIT(0)
+
+/* STM32_RTC_VERR bit fields */
+#define STM32_RTC_VERR_MINREV_SHIFT	0
+#define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
+#define STM32_RTC_VERR_MAJREV_SHIFT	4
+#define STM32_RTC_VERR_MAJREV		GENMASK(7, 4)
+
 /* STM32_RTC_WPR key constants */
 #define RTC_WPR_1ST_KEY			0xCA
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+/* Max STM32 RTC register offset is 0x3FC */
+#define UNDEF_REG			0xFFFF
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
-	u8 tr;
-	u8 dr;
-	u8 cr;
-	u8 isr;
-	u8 prer;
-	u8 alrmar;
-	u8 wpr;
+	u16 tr;
+	u16 dr;
+	u16 cr;
+	u16 isr;
+	u16 prer;
+	u16 alrmar;
+	u16 wpr;
+	u16 sr;
+	u16 scr;
+	u16 verr;
 };
 
 struct stm32_rtc_events {
@@ -98,6 +114,7 @@ struct stm32_rtc_data {
 	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
+	bool has_wakeirq;
 };
 
 struct stm32_rtc {
@@ -110,6 +127,7 @@ struct stm32_rtc {
 	struct clk *rtc_ck;
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
+	int wakeirq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -193,7 +211,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	status = readl_relaxed(rtc->base + regs->isr);
+	status = readl_relaxed(rtc->base + regs->sr);
 	cr = readl_relaxed(rtc->base + regs->cr);
 
 	if ((status & evts->alra) &&
@@ -325,7 +343,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 	alrmar = readl_relaxed(rtc->base + regs->alrmar);
 	cr = readl_relaxed(rtc->base + regs->cr);
-	status = readl_relaxed(rtc->base + regs->isr);
+	status = readl_relaxed(rtc->base + regs->sr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -533,6 +551,7 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -541,6 +560,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -551,6 +573,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -559,6 +582,9 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -566,9 +592,41 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.clear_events = stm32_rtc_clear_events,
 };
 
+static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
+				      unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 1 in RTC_SCR */
+	writel_relaxed(flags, rtc->base + regs.scr);
+}
+
+static const struct stm32_rtc_data stm32mp1_data = {
+	.has_pclk = true,
+	.need_dbp = false,
+	.has_wakeirq = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x18,
+		.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
+		.prer = 0x10,
+		.alrmar = 0x40,
+		.wpr = 0x24,
+		.sr = 0x50,
+		.scr = 0x5C,
+		.verr = 0x3F4,
+	},
+	.events = {
+		.alra = STM32_RTC_SR_ALRA,
+	},
+	.clear_events = stm32mp1_rtc_clear_events,
+};
+
 static const struct of_device_id stm32_rtc_of_match[] = {
 	{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
 	{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
+	{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@@ -727,12 +785,19 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	platform_set_drvdata(pdev, rtc);
-
 	ret = device_init_wakeup(&pdev->dev, true);
+	if (rtc->data->has_wakeirq) {
+		rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
+		if (rtc->wakeirq_alarm <= 0)
+			ret = rtc->wakeirq_alarm;
+		else
+			ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+							    rtc->wakeirq_alarm);
+	}
 	if (ret)
-		dev_warn(&pdev->dev,
-			 "alarm won't be able to wake up the system");
+		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+
+	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
 						&stm32_rtc_ops, THIS_MODULE);
@@ -760,6 +825,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (!(readl_relaxed(rtc->base + regs->isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
+	if (regs->verr != UNDEF_REG) {
+		u32 ver = readl_relaxed(rtc->base + regs->verr);
+
+		dev_info(&pdev->dev, "registered rev:%d.%d\n",
+			 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
+			 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
+	}
+
 	return 0;
 err:
 	if (rtc->data->has_pclk)
@@ -769,6 +842,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return ret;
@@ -795,6 +869,7 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return 0;
-- 
2.7.4

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

* Re: [PATCH v3 3/4] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  2018-05-17 12:04   ` Amelie Delaunay
@ 2018-05-22 17:17     ` Rob Herring
  -1 siblings, 0 replies; 19+ messages in thread
From: Rob Herring @ 2018-05-22 17:17 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Alessandro Zummo, Alexandre Belloni, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue, linux-rtc, devicetree,
	linux-arm-kernel, linux-kernel

On Thu, May 17, 2018 at 02:04:25PM +0200, Amelie Delaunay wrote:
> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
> doesn't require to disable backup domain write protection, and rtc_ck
> parent clock assignment isn't allowed.
> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
> alarm interrupt.
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
> ---
>  .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 ++++++++++++++++------
>  1 file changed, 20 insertions(+), 7 deletions(-)

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

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

* [PATCH v3 3/4] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-05-22 17:17     ` Rob Herring
  0 siblings, 0 replies; 19+ messages in thread
From: Rob Herring @ 2018-05-22 17:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, May 17, 2018 at 02:04:25PM +0200, Amelie Delaunay wrote:
> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
> doesn't require to disable backup domain write protection, and rtc_ck
> parent clock assignment isn't allowed.
> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
> alarm interrupt.
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
> ---
>  .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 ++++++++++++++++------
>  1 file changed, 20 insertions(+), 7 deletions(-)

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

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

* Re: [PATCH v3 0/4] Introduce STM32MP1 RTC
  2018-05-17 12:04 ` Amelie Delaunay
@ 2018-05-22 18:11   ` Alexandre Belloni
  -1 siblings, 0 replies; 19+ messages in thread
From: Alexandre Belloni @ 2018-05-22 18:11 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Alessandro Zummo, Rob Herring, Mark Rutland, Maxime Coquelin,
	Alexandre Torgue, linux-rtc, devicetree, linux-arm-kernel,
	linux-kernel

On 17/05/2018 14:04:22+0200, Amelie Delaunay wrote:
> This series introduces STM32MP1 RTC.
> On STM32MP1:
> - two clocks are needed, plck and rtc_ck;
> - to wakeup the system, a wakeup alarm interrupt is needed;
> - some registers or bits have moved, but the operation is the same;
> - the Backup Domain Protection (DBP) is not managed by RTC driver.
> 
> ---
> Changes in v3:
> * Move cleanup changes in a separate patch
> * Replace regs and evts by pointers to ensure no copy is made
> * Set all registers offset as u16 instead of u8 and u16
> * Fix Kbuild smatch warning:
>   drivers/rtc/rtc-stm32.c:827 stm32_rtc_probe()
>   warn: always true condition '(regs.verr != ~0) => (0-u16max != (-1))'
> 
> Changes in v2:
> * One compatible per line in bindings file
> * Remove unnecessary comment under rtc_ck as this clock is required for all
> * Remove interrupts-extended and add stm32mp1 rtc alarm wakeup interrupt in
>   interrupts property description
> 
> Amelie Delaunay (4):
>   rtc: stm32: fix misspelling and misalignment issues
>   rtc: stm32: rework register management to prepare other version of RTC
>   dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
>   rtc: stm32: add stm32mp1 rtc support
> 
>  .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
>  drivers/rtc/rtc-stm32.c                            | 273 ++++++++++++++++-----
>  2 files changed, 229 insertions(+), 71 deletions(-)
> 

Applied, thanks.

-- 
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

* [PATCH v3 0/4] Introduce STM32MP1 RTC
@ 2018-05-22 18:11   ` Alexandre Belloni
  0 siblings, 0 replies; 19+ messages in thread
From: Alexandre Belloni @ 2018-05-22 18:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/05/2018 14:04:22+0200, Amelie Delaunay wrote:
> This series introduces STM32MP1 RTC.
> On STM32MP1:
> - two clocks are needed, plck and rtc_ck;
> - to wakeup the system, a wakeup alarm interrupt is needed;
> - some registers or bits have moved, but the operation is the same;
> - the Backup Domain Protection (DBP) is not managed by RTC driver.
> 
> ---
> Changes in v3:
> * Move cleanup changes in a separate patch
> * Replace regs and evts by pointers to ensure no copy is made
> * Set all registers offset as u16 instead of u8 and u16
> * Fix Kbuild smatch warning:
>   drivers/rtc/rtc-stm32.c:827 stm32_rtc_probe()
>   warn: always true condition '(regs.verr != ~0) => (0-u16max != (-1))'
> 
> Changes in v2:
> * One compatible per line in bindings file
> * Remove unnecessary comment under rtc_ck as this clock is required for all
> * Remove interrupts-extended and add stm32mp1 rtc alarm wakeup interrupt in
>   interrupts property description
> 
> Amelie Delaunay (4):
>   rtc: stm32: fix misspelling and misalignment issues
>   rtc: stm32: rework register management to prepare other version of RTC
>   dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
>   rtc: stm32: add stm32mp1 rtc support
> 
>  .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
>  drivers/rtc/rtc-stm32.c                            | 273 ++++++++++++++++-----
>  2 files changed, 229 insertions(+), 71 deletions(-)
> 

Applied, thanks.

-- 
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

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

end of thread, other threads:[~2018-05-22 18:11 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-17 12:04 [PATCH v3 0/4] Introduce STM32MP1 RTC Amelie Delaunay
2018-05-17 12:04 ` Amelie Delaunay
2018-05-17 12:04 ` Amelie Delaunay
2018-05-17 12:04 ` [PATCH v3 1/4] rtc: stm32: fix misspelling and misalignment issues Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-17 12:04 ` [PATCH v3 2/4] rtc: stm32: rework register management to prepare other version of RTC Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-17 12:04 ` [PATCH v3 3/4] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-22 17:17   ` Rob Herring
2018-05-22 17:17     ` Rob Herring
2018-05-17 12:04 ` [PATCH v3 4/4] rtc: stm32: add stm32mp1 rtc support Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-17 12:04   ` Amelie Delaunay
2018-05-22 18:11 ` [PATCH v3 0/4] Introduce STM32MP1 RTC Alexandre Belloni
2018-05-22 18:11   ` Alexandre Belloni

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