All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] Reintroduce i.MX EPIT Timer
@ 2018-05-29 17:04 ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Vladimir Zapolskiy

From: Clément Peron <clement.peron@devialet.com>

As suggested in the commit message we have added the device tree support,
proper bindings and we moved the driver into the correct folder.

Moreover we made some changes like use of relaxed IO accesor,
implement sched_clock, delay_timer and reduce the clockevents min_delta.

Changes since v2 (Thanks Fabio Estevam):
- Removed unused "ckil" clock
- Add out_iounmap
- Check and handle if clk_prepare_enable failed
- Fix comment typo

Changes since v1 (Thanks Vladimir Zapolskiy):
- Add OF dependency in Kconfig
- Sort header
- Use BIT macro
- Remove useless comments
- Fix incorrect indent
- Fix memory leak
- Add check and handle possible returned error

Clément Peron (2):
  ARM: imx: remove inexistant EPIT timer init
  Documentation: DT: add i.MX EPIT timer binding

Colin Didier (3):
  clk: imx6: add EPIT clock support
  clocksource: add driver for i.MX EPIT timer
  ARM: dts: imx6qdl: add missing compatible and clock properties for
    EPIT

 .../devicetree/bindings/clock/imx6q,epit.txt  |  24 ++
 arch/arm/boot/dts/imx6qdl.dtsi                |  10 +
 arch/arm/mach-imx/common.h                    |   1 -
 drivers/clk/imx/clk-imx6q.c                   |   2 +
 drivers/clocksource/Kconfig                   |  12 +
 drivers/clocksource/Makefile                  |   1 +
 drivers/clocksource/timer-imx-epit.c          | 283 ++++++++++++++++++
 include/dt-bindings/clock/imx6qdl-clock.h     |   4 +-
 8 files changed, 335 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
 create mode 100644 drivers/clocksource/timer-imx-epit.c

-- 
2.17.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 0/5] Reintroduce i.MX EPIT Timer
@ 2018-05-29 17:04 ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer, Rob Herring,
	NXP Linux Team, Pengutronix Kernel Team, Clément Peron

From: Clément Peron <clement.peron@devialet.com>

As suggested in the commit message we have added the device tree support,
proper bindings and we moved the driver into the correct folder.

Moreover we made some changes like use of relaxed IO accesor,
implement sched_clock, delay_timer and reduce the clockevents min_delta.

Changes since v2 (Thanks Fabio Estevam):
- Removed unused "ckil" clock
- Add out_iounmap
- Check and handle if clk_prepare_enable failed
- Fix comment typo

Changes since v1 (Thanks Vladimir Zapolskiy):
- Add OF dependency in Kconfig
- Sort header
- Use BIT macro
- Remove useless comments
- Fix incorrect indent
- Fix memory leak
- Add check and handle possible returned error

Clément Peron (2):
  ARM: imx: remove inexistant EPIT timer init
  Documentation: DT: add i.MX EPIT timer binding

Colin Didier (3):
  clk: imx6: add EPIT clock support
  clocksource: add driver for i.MX EPIT timer
  ARM: dts: imx6qdl: add missing compatible and clock properties for
    EPIT

 .../devicetree/bindings/clock/imx6q,epit.txt  |  24 ++
 arch/arm/boot/dts/imx6qdl.dtsi                |  10 +
 arch/arm/mach-imx/common.h                    |   1 -
 drivers/clk/imx/clk-imx6q.c                   |   2 +
 drivers/clocksource/Kconfig                   |  12 +
 drivers/clocksource/Makefile                  |   1 +
 drivers/clocksource/timer-imx-epit.c          | 283 ++++++++++++++++++
 include/dt-bindings/clock/imx6qdl-clock.h     |   4 +-
 8 files changed, 335 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
 create mode 100644 drivers/clocksource/timer-imx-epit.c

-- 
2.17.0


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

* [PATCH v3 0/5] Reintroduce i.MX EPIT Timer
@ 2018-05-29 17:04 ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Cl?ment Peron <clement.peron@devialet.com>

As suggested in the commit message we have added the device tree support,
proper bindings and we moved the driver into the correct folder.

Moreover we made some changes like use of relaxed IO accesor,
implement sched_clock, delay_timer and reduce the clockevents min_delta.

Changes since v2 (Thanks Fabio Estevam):
- Removed unused "ckil" clock
- Add out_iounmap
- Check and handle if clk_prepare_enable failed
- Fix comment typo

Changes since v1 (Thanks Vladimir Zapolskiy):
- Add OF dependency in Kconfig
- Sort header
- Use BIT macro
- Remove useless comments
- Fix incorrect indent
- Fix memory leak
- Add check and handle possible returned error

Cl?ment Peron (2):
  ARM: imx: remove inexistant EPIT timer init
  Documentation: DT: add i.MX EPIT timer binding

Colin Didier (3):
  clk: imx6: add EPIT clock support
  clocksource: add driver for i.MX EPIT timer
  ARM: dts: imx6qdl: add missing compatible and clock properties for
    EPIT

 .../devicetree/bindings/clock/imx6q,epit.txt  |  24 ++
 arch/arm/boot/dts/imx6qdl.dtsi                |  10 +
 arch/arm/mach-imx/common.h                    |   1 -
 drivers/clk/imx/clk-imx6q.c                   |   2 +
 drivers/clocksource/Kconfig                   |  12 +
 drivers/clocksource/Makefile                  |   1 +
 drivers/clocksource/timer-imx-epit.c          | 283 ++++++++++++++++++
 include/dt-bindings/clock/imx6qdl-clock.h     |   4 +-
 8 files changed, 335 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
 create mode 100644 drivers/clocksource/timer-imx-epit.c

-- 
2.17.0

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

* [PATCH v3 1/5] ARM: imx: remove inexistant EPIT timer init
  2018-05-29 17:04 ` Clément Péron
  (?)
@ 2018-05-29 17:04   ` Clément Péron
  -1 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Vladimir Zapolskiy

From: Clément Peron <clement.peron@devialet.com>

i.MX EPIT timer has been removed but not the init function declaration.

Signed-off-by: Clément Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 arch/arm/mach-imx/common.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index c8d68e918b2f..18aae76fa2da 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -38,7 +38,6 @@ void imx21_soc_init(void);
 void imx27_soc_init(void);
 void imx31_soc_init(void);
 void imx35_soc_init(void);
-void epit_timer_init(void __iomem *base, int irq);
 int mx21_clocks_init(unsigned long lref, unsigned long fref);
 int mx27_clocks_init(unsigned long fref);
 int mx31_clocks_init(unsigned long fref);
-- 
2.17.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 1/5] ARM: imx: remove inexistant EPIT timer init
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer, Rob Herring,
	NXP Linux Team, Pengutronix Kernel Team, Clément Peron

From: Clément Peron <clement.peron@devialet.com>

i.MX EPIT timer has been removed but not the init function declaration.

Signed-off-by: Clément Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 arch/arm/mach-imx/common.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index c8d68e918b2f..18aae76fa2da 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -38,7 +38,6 @@ void imx21_soc_init(void);
 void imx27_soc_init(void);
 void imx31_soc_init(void);
 void imx35_soc_init(void);
-void epit_timer_init(void __iomem *base, int irq);
 int mx21_clocks_init(unsigned long lref, unsigned long fref);
 int mx27_clocks_init(unsigned long fref);
 int mx31_clocks_init(unsigned long fref);
-- 
2.17.0


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

* [PATCH v3 1/5] ARM: imx: remove inexistant EPIT timer init
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Cl?ment Peron <clement.peron@devialet.com>

i.MX EPIT timer has been removed but not the init function declaration.

Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 arch/arm/mach-imx/common.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index c8d68e918b2f..18aae76fa2da 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -38,7 +38,6 @@ void imx21_soc_init(void);
 void imx27_soc_init(void);
 void imx31_soc_init(void);
 void imx35_soc_init(void);
-void epit_timer_init(void __iomem *base, int irq);
 int mx21_clocks_init(unsigned long lref, unsigned long fref);
 int mx27_clocks_init(unsigned long fref);
 int mx31_clocks_init(unsigned long fref);
-- 
2.17.0

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

* [PATCH v3 2/5] clk: imx6: add EPIT clock support
  2018-05-29 17:04 ` Clément Péron
  (?)
@ 2018-05-29 17:04   ` Clément Péron
  -1 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Vladimir Zapolskiy

From: Colin Didier <colin.didier@devialet.com>

Add EPIT clock support to the i.MX6Q clocking infrastructure.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Clément Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 drivers/clk/imx/clk-imx6q.c               | 2 ++
 include/dt-bindings/clock/imx6qdl-clock.h | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index 8d518ad5dc13..b9ea7037e193 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -753,6 +753,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	else
 		clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
 	clk[IMX6QDL_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
+	clk[IMX6QDL_CLK_EPIT1]        = imx_clk_gate2("epit1",         "ipg",               base + 0x6c, 12);
+	clk[IMX6QDL_CLK_EPIT2]        = imx_clk_gate2("epit2",         "ipg",               base + 0x6c, 14);
 	clk[IMX6QDL_CLK_ESAI_EXTAL]   = imx_clk_gate2_shared("esai_extal",   "esai_podf",   base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_ESAI_IPG]     = imx_clk_gate2_shared("esai_ipg",   "ahb",           base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_ESAI_MEM]     = imx_clk_gate2_shared("esai_mem", "ahb",             base + 0x6c, 16, &share_count_esai);
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index da59fd9cdb5e..7ad171b8f3bf 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -271,6 +271,8 @@
 #define IMX6QDL_CLK_PRE_AXI			258
 #define IMX6QDL_CLK_MLB_SEL			259
 #define IMX6QDL_CLK_MLB_PODF			260
-#define IMX6QDL_CLK_END				261
+#define IMX6QDL_CLK_EPIT1			261
+#define IMX6QDL_CLK_EPIT2			262
+#define IMX6QDL_CLK_END				263
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
2.17.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 2/5] clk: imx6: add EPIT clock support
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer, Rob Herring,
	NXP Linux Team, Pengutronix Kernel Team, Clément Peron

From: Colin Didier <colin.didier@devialet.com>

Add EPIT clock support to the i.MX6Q clocking infrastructure.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Clément Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 drivers/clk/imx/clk-imx6q.c               | 2 ++
 include/dt-bindings/clock/imx6qdl-clock.h | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index 8d518ad5dc13..b9ea7037e193 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -753,6 +753,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	else
 		clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
 	clk[IMX6QDL_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
+	clk[IMX6QDL_CLK_EPIT1]        = imx_clk_gate2("epit1",         "ipg",               base + 0x6c, 12);
+	clk[IMX6QDL_CLK_EPIT2]        = imx_clk_gate2("epit2",         "ipg",               base + 0x6c, 14);
 	clk[IMX6QDL_CLK_ESAI_EXTAL]   = imx_clk_gate2_shared("esai_extal",   "esai_podf",   base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_ESAI_IPG]     = imx_clk_gate2_shared("esai_ipg",   "ahb",           base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_ESAI_MEM]     = imx_clk_gate2_shared("esai_mem", "ahb",             base + 0x6c, 16, &share_count_esai);
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index da59fd9cdb5e..7ad171b8f3bf 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -271,6 +271,8 @@
 #define IMX6QDL_CLK_PRE_AXI			258
 #define IMX6QDL_CLK_MLB_SEL			259
 #define IMX6QDL_CLK_MLB_PODF			260
-#define IMX6QDL_CLK_END				261
+#define IMX6QDL_CLK_EPIT1			261
+#define IMX6QDL_CLK_EPIT2			262
+#define IMX6QDL_CLK_END				263
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
2.17.0


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

* [PATCH v3 2/5] clk: imx6: add EPIT clock support
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Colin Didier <colin.didier@devialet.com>

Add EPIT clock support to the i.MX6Q clocking infrastructure.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 drivers/clk/imx/clk-imx6q.c               | 2 ++
 include/dt-bindings/clock/imx6qdl-clock.h | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index 8d518ad5dc13..b9ea7037e193 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -753,6 +753,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	else
 		clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5",        "ecspi_root",        base + 0x6c, 8);
 	clk[IMX6QDL_CLK_ENET]         = imx_clk_gate2("enet",          "ipg",               base + 0x6c, 10);
+	clk[IMX6QDL_CLK_EPIT1]        = imx_clk_gate2("epit1",         "ipg",               base + 0x6c, 12);
+	clk[IMX6QDL_CLK_EPIT2]        = imx_clk_gate2("epit2",         "ipg",               base + 0x6c, 14);
 	clk[IMX6QDL_CLK_ESAI_EXTAL]   = imx_clk_gate2_shared("esai_extal",   "esai_podf",   base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_ESAI_IPG]     = imx_clk_gate2_shared("esai_ipg",   "ahb",           base + 0x6c, 16, &share_count_esai);
 	clk[IMX6QDL_CLK_ESAI_MEM]     = imx_clk_gate2_shared("esai_mem", "ahb",             base + 0x6c, 16, &share_count_esai);
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index da59fd9cdb5e..7ad171b8f3bf 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -271,6 +271,8 @@
 #define IMX6QDL_CLK_PRE_AXI			258
 #define IMX6QDL_CLK_MLB_SEL			259
 #define IMX6QDL_CLK_MLB_PODF			260
-#define IMX6QDL_CLK_END				261
+#define IMX6QDL_CLK_EPIT1			261
+#define IMX6QDL_CLK_EPIT2			262
+#define IMX6QDL_CLK_END				263
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
2.17.0

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

* [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
  2018-05-29 17:04 ` Clément Péron
  (?)
@ 2018-05-29 17:04   ` Clément Péron
  -1 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Vladimir Zapolskiy

From: Clément Peron <clement.peron@devialet.com>

Add devicetree binding document for NXP's i.MX SoC specific
EPIT timer driver.

Signed-off-by: Clément Peron <clement.peron@devialet.com>
---
 .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt

diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
new file mode 100644
index 000000000000..a84a60c6ae35
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
@@ -0,0 +1,24 @@
+Binding for the i.MX6 EPIT timer
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible: should be "fsl,imx6q-epit"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: Should contain EPIT controller interrupt
+- clocks: list of clock specifiers, must contain an entry for each required
+  entry in clock-names
+- clock-names : should include entries "ipg", "per"
+
+Example:
+	epit1: epit@20d0000 {
+		compatible = "fsl,imx6q-epit";
+		reg = <0x020d0000 0x4000>;
+		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks IMX6QDL_CLK_EPIT1>,
+			<&clks IMX6QDL_CLK_IPG_PER>;
+		clock-names = "ipg", "per";
+	};
-- 
2.17.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer, Rob Herring,
	NXP Linux Team, Pengutronix Kernel Team, Clément Peron

From: Clément Peron <clement.peron@devialet.com>

Add devicetree binding document for NXP's i.MX SoC specific
EPIT timer driver.

Signed-off-by: Clément Peron <clement.peron@devialet.com>
---
 .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt

diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
new file mode 100644
index 000000000000..a84a60c6ae35
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
@@ -0,0 +1,24 @@
+Binding for the i.MX6 EPIT timer
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible: should be "fsl,imx6q-epit"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: Should contain EPIT controller interrupt
+- clocks: list of clock specifiers, must contain an entry for each required
+  entry in clock-names
+- clock-names : should include entries "ipg", "per"
+
+Example:
+	epit1: epit@20d0000 {
+		compatible = "fsl,imx6q-epit";
+		reg = <0x020d0000 0x4000>;
+		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks IMX6QDL_CLK_EPIT1>,
+			<&clks IMX6QDL_CLK_IPG_PER>;
+		clock-names = "ipg", "per";
+	};
-- 
2.17.0


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

* [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Cl?ment Peron <clement.peron@devialet.com>

Add devicetree binding document for NXP's i.MX SoC specific
EPIT timer driver.

Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
---
 .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt

diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
new file mode 100644
index 000000000000..a84a60c6ae35
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
@@ -0,0 +1,24 @@
+Binding for the i.MX6 EPIT timer
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible: should be "fsl,imx6q-epit"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: Should contain EPIT controller interrupt
+- clocks: list of clock specifiers, must contain an entry for each required
+  entry in clock-names
+- clock-names : should include entries "ipg", "per"
+
+Example:
+	epit1: epit at 20d0000 {
+		compatible = "fsl,imx6q-epit";
+		reg = <0x020d0000 0x4000>;
+		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks IMX6QDL_CLK_EPIT1>,
+			<&clks IMX6QDL_CLK_IPG_PER>;
+		clock-names = "ipg", "per";
+	};
-- 
2.17.0

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

* [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
  2018-05-29 17:04 ` Clément Péron
  (?)
@ 2018-05-29 17:04   ` Clément Péron
  -1 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Vladimir Zapolskiy

From: Colin Didier <colin.didier@devialet.com>

Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Clément Peron <clement.peron@devialet.com>
---
 drivers/clocksource/Kconfig          |  12 ++
 drivers/clocksource/Makefile         |   1 +
 drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/clocksource/timer-imx-epit.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8e8a09755d10..920a0874f3a4 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -576,6 +576,18 @@ config H8300_TPU
 	  This enables the clocksource for the H8300 platform with the
 	  H8S2678 cpu.
 
+config CLKSRC_IMX_EPIT
+	bool "Clocksource using i.MX EPIT"
+	depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC || COMPILE_TEST)
+	select TIMER_OF
+	select CLKSRC_MMIO
+	help
+	  This enables EPIT support available on some i.MX platforms.
+	  Normally you don't have a reason to do so as the EPIT has
+	  the same features and uses the same clocks as the GPT.
+	  Anyway, on some systems the GPT may be in use for other
+	  purposes.
+
 config CLKSRC_IMX_GPT
 	bool "Clocksource using i.MX GPT" if COMPILE_TEST
 	depends on ARM && CLKDEV_LOOKUP
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 00caf37e52f9..d9426f69ec69 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= timer-integrator-ap.o
 obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
 obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
 obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= tango_xtal.o
+obj-$(CONFIG_CLKSRC_IMX_EPIT)		+= timer-imx-epit.o
 obj-$(CONFIG_CLKSRC_IMX_GPT)		+= timer-imx-gpt.o
 obj-$(CONFIG_CLKSRC_IMX_TPM)		+= timer-imx-tpm.o
 obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
diff --git a/drivers/clocksource/timer-imx-epit.c b/drivers/clocksource/timer-imx-epit.c
new file mode 100644
index 000000000000..87025d5f3a97
--- /dev/null
+++ b/drivers/clocksource/timer-imx-epit.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * i.MX EPIT Timer
+ *
+ * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
+ * Copyright (C) 2018 Clément Péron <clement.peron@devialet.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+
+#define EPITCR				0x00
+#define EPITSR				0x04
+#define EPITLR				0x08
+#define EPITCMPR			0x0c
+#define EPITCNR				0x10
+
+#define EPITCR_EN			BIT(0)
+#define EPITCR_ENMOD			BIT(1)
+#define EPITCR_OCIEN			BIT(2)
+#define EPITCR_RLD			BIT(3)
+#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
+#define EPITCR_SWR			BIT(16)
+#define EPITCR_IOVW			BIT(17)
+#define EPITCR_DBGEN			BIT(18)
+#define EPITCR_WAITEN			BIT(19)
+#define EPITCR_RES			BIT(20)
+#define EPITCR_STOPEN			BIT(21)
+#define EPITCR_OM_DISCON		(0 << 22)
+#define EPITCR_OM_TOGGLE		(1 << 22)
+#define EPITCR_OM_CLEAR			(2 << 22)
+#define EPITCR_OM_SET			(3 << 22)
+#define EPITCR_CLKSRC_OFF		(0 << 24)
+#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
+#define EPITCR_CLKSRC_REF_HIGH		(2 << 24)
+#define EPITCR_CLKSRC_REF_LOW		(3 << 24)
+
+#define EPITSR_OCIF			BIT(0)
+
+struct epit_timer {
+	void __iomem *base;
+	int irq;
+	struct clk *clk_per;
+	struct clock_event_device ced;
+	struct irqaction act;
+};
+
+static void __iomem *sched_clock_reg;
+
+static inline struct epit_timer *to_epit_timer(struct clock_event_device *ced)
+{
+	return container_of(ced, struct epit_timer, ced);
+}
+
+static inline void epit_irq_disable(struct epit_timer *epittm)
+{
+	u32 val;
+
+	val = readl_relaxed(epittm->base + EPITCR);
+	writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
+}
+
+static inline void epit_irq_enable(struct epit_timer *epittm)
+{
+	u32 val;
+
+	val = readl_relaxed(epittm->base + EPITCR);
+	writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
+}
+
+static void epit_irq_acknowledge(struct epit_timer *epittm)
+{
+	writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
+}
+
+static u64 notrace epit_read_sched_clock(void)
+{
+	return ~readl_relaxed(sched_clock_reg);
+}
+
+static int __init epit_clocksource_init(struct epit_timer *epittm)
+{
+	unsigned int c = clk_get_rate(epittm->clk_per);
+
+	sched_clock_reg = epittm->base + EPITCNR;
+	sched_clock_register(epit_read_sched_clock, 32, c);
+
+	return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c, 200, 32,
+			clocksource_mmio_readl_down);
+}
+
+static int epit_set_next_event(unsigned long cycles,
+			       struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long tcmp;
+
+	tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles;
+	writel_relaxed(tcmp, epittm->base + EPITCMPR);
+
+	return 0;
+}
+
+/* Left event sources disabled, no more interrupts appear */
+static int epit_shutdown(struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call epit_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in EPIT module */
+	epit_irq_disable(epittm);
+
+	/* Clear pending interrupt */
+	epit_irq_acknowledge(epittm);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static int epit_set_oneshot(struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call epit_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in EPIT module */
+	epit_irq_disable(epittm);
+
+	/* Clear pending interrupt, only while switching mode */
+	if (!clockevent_state_oneshot(ced))
+		epit_irq_acknowledge(epittm);
+
+	/*
+	 * Do not put overhead of interrupt enable/disable into
+	 * epit_set_next_event(), the core has about 4 minutes
+	 * to call epit_set_next_event() or shutdown clock after
+	 * mode switching
+	 */
+	epit_irq_enable(epittm);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *ced = dev_id;
+	struct epit_timer *epittm = to_epit_timer(ced);
+
+	epit_irq_acknowledge(epittm);
+
+	ced->event_handler(ced);
+
+	return IRQ_HANDLED;
+}
+
+static int __init epit_clockevent_init(struct epit_timer *epittm)
+{
+	struct clock_event_device *ced = &epittm->ced;
+	struct irqaction *act = &epittm->act;
+
+	ced->name = "epit";
+	ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
+	ced->set_state_shutdown = epit_shutdown;
+	ced->tick_resume = epit_shutdown;
+	ced->set_state_oneshot = epit_set_oneshot;
+	ced->set_next_event = epit_set_next_event;
+	ced->rating = 200;
+	ced->cpumask = cpumask_of(0);
+	ced->irq = epittm->irq;
+	clockevents_config_and_register(ced, clk_get_rate(epittm->clk_per),
+		0xff, 0xfffffffe);
+
+	act->name = "i.MX EPIT Timer Tick",
+	act->flags = IRQF_TIMER | IRQF_IRQPOLL;
+	act->handler = epit_timer_interrupt;
+	act->dev_id = ced;
+
+	/* Make irqs happen */
+	return setup_irq(epittm->irq, act);
+}
+
+static int __init epit_timer_init(struct device_node *np)
+{
+	struct epit_timer *epittm;
+	struct clk *clk_ipg;
+	int ret;
+
+	epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
+	if (!epittm)
+		return -ENOMEM;
+
+	epittm->base = of_iomap(np, 0);
+	if (!epittm->base) {
+		ret = -ENXIO;
+		goto out_kfree;
+	}
+
+	epittm->irq = irq_of_parse_and_map(np, 0);
+	if (!epittm->irq) {
+		ret = -EINVAL;
+		goto out_iounmap;
+	}
+
+	clk_ipg = of_clk_get_by_name(np, "ipg");
+	if (IS_ERR(clk_ipg)) {
+		pr_err("i.MX EPIT: unable to get clk_ipg\n");
+		ret = PTR_ERR(clk_ipg);
+		goto out_iounmap;
+	}
+
+	ret = clk_prepare_enable(clk_ipg);
+	if (ret) {
+		pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
+		goto out_clk_ipg_disable;
+	}
+
+	epittm->clk_per = of_clk_get_by_name(np, "per");
+	if (IS_ERR(epittm->clk_per)) {
+		pr_err("i.MX EPIT: unable to get clk_per\n");
+		ret = PTR_ERR(epittm->clk_per);
+		goto out_clk_ipg_disable;
+	}
+
+	ret = clk_prepare_enable(epittm->clk_per);
+	if (ret) {
+		pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
+		goto out_clk_ipg_disable;
+	}
+
+	/* Initialise to a known state (all timers off, and timing reset) */
+	writel_relaxed(0x0, epittm->base + EPITCR);
+	writel_relaxed(0xffffffff, epittm->base + EPITLR);
+	writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
+		       epittm->base + EPITCR);
+
+	ret = epit_clocksource_init(epittm);
+	if(ret) {
+		pr_err("i.MX EPIT: failed to init clocksource\n");
+		goto out_clk_per_disable;
+	}
+
+	ret = epit_clockevent_init(epittm);
+	if(ret) {
+		pr_err("i.MX EPIT: failed to init clockevent\n");
+		goto out_clk_per_disable;
+	}
+
+	return 0;
+
+out_clk_per_disable:
+	clk_disable_unprepare(epittm->clk_per);
+out_clk_ipg_disable:
+	clk_disable_unprepare(clk_ipg);
+out_iounmap:
+	iounmap(epittm->base);
+out_kfree:
+	kfree(epittm);
+
+	return ret;
+}
+TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
-- 
2.17.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer, Rob Herring,
	NXP Linux Team, Pengutronix Kernel Team, Clément Peron

From: Colin Didier <colin.didier@devialet.com>

Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Clément Peron <clement.peron@devialet.com>
---
 drivers/clocksource/Kconfig          |  12 ++
 drivers/clocksource/Makefile         |   1 +
 drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/clocksource/timer-imx-epit.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8e8a09755d10..920a0874f3a4 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -576,6 +576,18 @@ config H8300_TPU
 	  This enables the clocksource for the H8300 platform with the
 	  H8S2678 cpu.
 
+config CLKSRC_IMX_EPIT
+	bool "Clocksource using i.MX EPIT"
+	depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC || COMPILE_TEST)
+	select TIMER_OF
+	select CLKSRC_MMIO
+	help
+	  This enables EPIT support available on some i.MX platforms.
+	  Normally you don't have a reason to do so as the EPIT has
+	  the same features and uses the same clocks as the GPT.
+	  Anyway, on some systems the GPT may be in use for other
+	  purposes.
+
 config CLKSRC_IMX_GPT
 	bool "Clocksource using i.MX GPT" if COMPILE_TEST
 	depends on ARM && CLKDEV_LOOKUP
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 00caf37e52f9..d9426f69ec69 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= timer-integrator-ap.o
 obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
 obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
 obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= tango_xtal.o
+obj-$(CONFIG_CLKSRC_IMX_EPIT)		+= timer-imx-epit.o
 obj-$(CONFIG_CLKSRC_IMX_GPT)		+= timer-imx-gpt.o
 obj-$(CONFIG_CLKSRC_IMX_TPM)		+= timer-imx-tpm.o
 obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
diff --git a/drivers/clocksource/timer-imx-epit.c b/drivers/clocksource/timer-imx-epit.c
new file mode 100644
index 000000000000..87025d5f3a97
--- /dev/null
+++ b/drivers/clocksource/timer-imx-epit.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * i.MX EPIT Timer
+ *
+ * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
+ * Copyright (C) 2018 Clément Péron <clement.peron@devialet.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+
+#define EPITCR				0x00
+#define EPITSR				0x04
+#define EPITLR				0x08
+#define EPITCMPR			0x0c
+#define EPITCNR				0x10
+
+#define EPITCR_EN			BIT(0)
+#define EPITCR_ENMOD			BIT(1)
+#define EPITCR_OCIEN			BIT(2)
+#define EPITCR_RLD			BIT(3)
+#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
+#define EPITCR_SWR			BIT(16)
+#define EPITCR_IOVW			BIT(17)
+#define EPITCR_DBGEN			BIT(18)
+#define EPITCR_WAITEN			BIT(19)
+#define EPITCR_RES			BIT(20)
+#define EPITCR_STOPEN			BIT(21)
+#define EPITCR_OM_DISCON		(0 << 22)
+#define EPITCR_OM_TOGGLE		(1 << 22)
+#define EPITCR_OM_CLEAR			(2 << 22)
+#define EPITCR_OM_SET			(3 << 22)
+#define EPITCR_CLKSRC_OFF		(0 << 24)
+#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
+#define EPITCR_CLKSRC_REF_HIGH		(2 << 24)
+#define EPITCR_CLKSRC_REF_LOW		(3 << 24)
+
+#define EPITSR_OCIF			BIT(0)
+
+struct epit_timer {
+	void __iomem *base;
+	int irq;
+	struct clk *clk_per;
+	struct clock_event_device ced;
+	struct irqaction act;
+};
+
+static void __iomem *sched_clock_reg;
+
+static inline struct epit_timer *to_epit_timer(struct clock_event_device *ced)
+{
+	return container_of(ced, struct epit_timer, ced);
+}
+
+static inline void epit_irq_disable(struct epit_timer *epittm)
+{
+	u32 val;
+
+	val = readl_relaxed(epittm->base + EPITCR);
+	writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
+}
+
+static inline void epit_irq_enable(struct epit_timer *epittm)
+{
+	u32 val;
+
+	val = readl_relaxed(epittm->base + EPITCR);
+	writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
+}
+
+static void epit_irq_acknowledge(struct epit_timer *epittm)
+{
+	writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
+}
+
+static u64 notrace epit_read_sched_clock(void)
+{
+	return ~readl_relaxed(sched_clock_reg);
+}
+
+static int __init epit_clocksource_init(struct epit_timer *epittm)
+{
+	unsigned int c = clk_get_rate(epittm->clk_per);
+
+	sched_clock_reg = epittm->base + EPITCNR;
+	sched_clock_register(epit_read_sched_clock, 32, c);
+
+	return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c, 200, 32,
+			clocksource_mmio_readl_down);
+}
+
+static int epit_set_next_event(unsigned long cycles,
+			       struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long tcmp;
+
+	tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles;
+	writel_relaxed(tcmp, epittm->base + EPITCMPR);
+
+	return 0;
+}
+
+/* Left event sources disabled, no more interrupts appear */
+static int epit_shutdown(struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call epit_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in EPIT module */
+	epit_irq_disable(epittm);
+
+	/* Clear pending interrupt */
+	epit_irq_acknowledge(epittm);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static int epit_set_oneshot(struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call epit_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in EPIT module */
+	epit_irq_disable(epittm);
+
+	/* Clear pending interrupt, only while switching mode */
+	if (!clockevent_state_oneshot(ced))
+		epit_irq_acknowledge(epittm);
+
+	/*
+	 * Do not put overhead of interrupt enable/disable into
+	 * epit_set_next_event(), the core has about 4 minutes
+	 * to call epit_set_next_event() or shutdown clock after
+	 * mode switching
+	 */
+	epit_irq_enable(epittm);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *ced = dev_id;
+	struct epit_timer *epittm = to_epit_timer(ced);
+
+	epit_irq_acknowledge(epittm);
+
+	ced->event_handler(ced);
+
+	return IRQ_HANDLED;
+}
+
+static int __init epit_clockevent_init(struct epit_timer *epittm)
+{
+	struct clock_event_device *ced = &epittm->ced;
+	struct irqaction *act = &epittm->act;
+
+	ced->name = "epit";
+	ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
+	ced->set_state_shutdown = epit_shutdown;
+	ced->tick_resume = epit_shutdown;
+	ced->set_state_oneshot = epit_set_oneshot;
+	ced->set_next_event = epit_set_next_event;
+	ced->rating = 200;
+	ced->cpumask = cpumask_of(0);
+	ced->irq = epittm->irq;
+	clockevents_config_and_register(ced, clk_get_rate(epittm->clk_per),
+		0xff, 0xfffffffe);
+
+	act->name = "i.MX EPIT Timer Tick",
+	act->flags = IRQF_TIMER | IRQF_IRQPOLL;
+	act->handler = epit_timer_interrupt;
+	act->dev_id = ced;
+
+	/* Make irqs happen */
+	return setup_irq(epittm->irq, act);
+}
+
+static int __init epit_timer_init(struct device_node *np)
+{
+	struct epit_timer *epittm;
+	struct clk *clk_ipg;
+	int ret;
+
+	epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
+	if (!epittm)
+		return -ENOMEM;
+
+	epittm->base = of_iomap(np, 0);
+	if (!epittm->base) {
+		ret = -ENXIO;
+		goto out_kfree;
+	}
+
+	epittm->irq = irq_of_parse_and_map(np, 0);
+	if (!epittm->irq) {
+		ret = -EINVAL;
+		goto out_iounmap;
+	}
+
+	clk_ipg = of_clk_get_by_name(np, "ipg");
+	if (IS_ERR(clk_ipg)) {
+		pr_err("i.MX EPIT: unable to get clk_ipg\n");
+		ret = PTR_ERR(clk_ipg);
+		goto out_iounmap;
+	}
+
+	ret = clk_prepare_enable(clk_ipg);
+	if (ret) {
+		pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
+		goto out_clk_ipg_disable;
+	}
+
+	epittm->clk_per = of_clk_get_by_name(np, "per");
+	if (IS_ERR(epittm->clk_per)) {
+		pr_err("i.MX EPIT: unable to get clk_per\n");
+		ret = PTR_ERR(epittm->clk_per);
+		goto out_clk_ipg_disable;
+	}
+
+	ret = clk_prepare_enable(epittm->clk_per);
+	if (ret) {
+		pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
+		goto out_clk_ipg_disable;
+	}
+
+	/* Initialise to a known state (all timers off, and timing reset) */
+	writel_relaxed(0x0, epittm->base + EPITCR);
+	writel_relaxed(0xffffffff, epittm->base + EPITLR);
+	writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
+		       epittm->base + EPITCR);
+
+	ret = epit_clocksource_init(epittm);
+	if(ret) {
+		pr_err("i.MX EPIT: failed to init clocksource\n");
+		goto out_clk_per_disable;
+	}
+
+	ret = epit_clockevent_init(epittm);
+	if(ret) {
+		pr_err("i.MX EPIT: failed to init clockevent\n");
+		goto out_clk_per_disable;
+	}
+
+	return 0;
+
+out_clk_per_disable:
+	clk_disable_unprepare(epittm->clk_per);
+out_clk_ipg_disable:
+	clk_disable_unprepare(clk_ipg);
+out_iounmap:
+	iounmap(epittm->base);
+out_kfree:
+	kfree(epittm);
+
+	return ret;
+}
+TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
-- 
2.17.0


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

* [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Colin Didier <colin.didier@devialet.com>

Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
---
 drivers/clocksource/Kconfig          |  12 ++
 drivers/clocksource/Makefile         |   1 +
 drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/clocksource/timer-imx-epit.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8e8a09755d10..920a0874f3a4 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -576,6 +576,18 @@ config H8300_TPU
 	  This enables the clocksource for the H8300 platform with the
 	  H8S2678 cpu.
 
+config CLKSRC_IMX_EPIT
+	bool "Clocksource using i.MX EPIT"
+	depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC || COMPILE_TEST)
+	select TIMER_OF
+	select CLKSRC_MMIO
+	help
+	  This enables EPIT support available on some i.MX platforms.
+	  Normally you don't have a reason to do so as the EPIT has
+	  the same features and uses the same clocks as the GPT.
+	  Anyway, on some systems the GPT may be in use for other
+	  purposes.
+
 config CLKSRC_IMX_GPT
 	bool "Clocksource using i.MX GPT" if COMPILE_TEST
 	depends on ARM && CLKDEV_LOOKUP
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 00caf37e52f9..d9426f69ec69 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= timer-integrator-ap.o
 obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
 obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
 obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= tango_xtal.o
+obj-$(CONFIG_CLKSRC_IMX_EPIT)		+= timer-imx-epit.o
 obj-$(CONFIG_CLKSRC_IMX_GPT)		+= timer-imx-gpt.o
 obj-$(CONFIG_CLKSRC_IMX_TPM)		+= timer-imx-tpm.o
 obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
diff --git a/drivers/clocksource/timer-imx-epit.c b/drivers/clocksource/timer-imx-epit.c
new file mode 100644
index 000000000000..87025d5f3a97
--- /dev/null
+++ b/drivers/clocksource/timer-imx-epit.c
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * i.MX EPIT Timer
+ *
+ * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
+ * Copyright (C) 2018 Cl?ment P?ron <clement.peron@devialet.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+
+#define EPITCR				0x00
+#define EPITSR				0x04
+#define EPITLR				0x08
+#define EPITCMPR			0x0c
+#define EPITCNR				0x10
+
+#define EPITCR_EN			BIT(0)
+#define EPITCR_ENMOD			BIT(1)
+#define EPITCR_OCIEN			BIT(2)
+#define EPITCR_RLD			BIT(3)
+#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
+#define EPITCR_SWR			BIT(16)
+#define EPITCR_IOVW			BIT(17)
+#define EPITCR_DBGEN			BIT(18)
+#define EPITCR_WAITEN			BIT(19)
+#define EPITCR_RES			BIT(20)
+#define EPITCR_STOPEN			BIT(21)
+#define EPITCR_OM_DISCON		(0 << 22)
+#define EPITCR_OM_TOGGLE		(1 << 22)
+#define EPITCR_OM_CLEAR			(2 << 22)
+#define EPITCR_OM_SET			(3 << 22)
+#define EPITCR_CLKSRC_OFF		(0 << 24)
+#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
+#define EPITCR_CLKSRC_REF_HIGH		(2 << 24)
+#define EPITCR_CLKSRC_REF_LOW		(3 << 24)
+
+#define EPITSR_OCIF			BIT(0)
+
+struct epit_timer {
+	void __iomem *base;
+	int irq;
+	struct clk *clk_per;
+	struct clock_event_device ced;
+	struct irqaction act;
+};
+
+static void __iomem *sched_clock_reg;
+
+static inline struct epit_timer *to_epit_timer(struct clock_event_device *ced)
+{
+	return container_of(ced, struct epit_timer, ced);
+}
+
+static inline void epit_irq_disable(struct epit_timer *epittm)
+{
+	u32 val;
+
+	val = readl_relaxed(epittm->base + EPITCR);
+	writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
+}
+
+static inline void epit_irq_enable(struct epit_timer *epittm)
+{
+	u32 val;
+
+	val = readl_relaxed(epittm->base + EPITCR);
+	writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
+}
+
+static void epit_irq_acknowledge(struct epit_timer *epittm)
+{
+	writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
+}
+
+static u64 notrace epit_read_sched_clock(void)
+{
+	return ~readl_relaxed(sched_clock_reg);
+}
+
+static int __init epit_clocksource_init(struct epit_timer *epittm)
+{
+	unsigned int c = clk_get_rate(epittm->clk_per);
+
+	sched_clock_reg = epittm->base + EPITCNR;
+	sched_clock_register(epit_read_sched_clock, 32, c);
+
+	return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c, 200, 32,
+			clocksource_mmio_readl_down);
+}
+
+static int epit_set_next_event(unsigned long cycles,
+			       struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long tcmp;
+
+	tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles;
+	writel_relaxed(tcmp, epittm->base + EPITCMPR);
+
+	return 0;
+}
+
+/* Left event sources disabled, no more interrupts appear */
+static int epit_shutdown(struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call epit_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in EPIT module */
+	epit_irq_disable(epittm);
+
+	/* Clear pending interrupt */
+	epit_irq_acknowledge(epittm);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static int epit_set_oneshot(struct clock_event_device *ced)
+{
+	struct epit_timer *epittm = to_epit_timer(ced);
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call epit_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in EPIT module */
+	epit_irq_disable(epittm);
+
+	/* Clear pending interrupt, only while switching mode */
+	if (!clockevent_state_oneshot(ced))
+		epit_irq_acknowledge(epittm);
+
+	/*
+	 * Do not put overhead of interrupt enable/disable into
+	 * epit_set_next_event(), the core has about 4 minutes
+	 * to call epit_set_next_event() or shutdown clock after
+	 * mode switching
+	 */
+	epit_irq_enable(epittm);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *ced = dev_id;
+	struct epit_timer *epittm = to_epit_timer(ced);
+
+	epit_irq_acknowledge(epittm);
+
+	ced->event_handler(ced);
+
+	return IRQ_HANDLED;
+}
+
+static int __init epit_clockevent_init(struct epit_timer *epittm)
+{
+	struct clock_event_device *ced = &epittm->ced;
+	struct irqaction *act = &epittm->act;
+
+	ced->name = "epit";
+	ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
+	ced->set_state_shutdown = epit_shutdown;
+	ced->tick_resume = epit_shutdown;
+	ced->set_state_oneshot = epit_set_oneshot;
+	ced->set_next_event = epit_set_next_event;
+	ced->rating = 200;
+	ced->cpumask = cpumask_of(0);
+	ced->irq = epittm->irq;
+	clockevents_config_and_register(ced, clk_get_rate(epittm->clk_per),
+		0xff, 0xfffffffe);
+
+	act->name = "i.MX EPIT Timer Tick",
+	act->flags = IRQF_TIMER | IRQF_IRQPOLL;
+	act->handler = epit_timer_interrupt;
+	act->dev_id = ced;
+
+	/* Make irqs happen */
+	return setup_irq(epittm->irq, act);
+}
+
+static int __init epit_timer_init(struct device_node *np)
+{
+	struct epit_timer *epittm;
+	struct clk *clk_ipg;
+	int ret;
+
+	epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
+	if (!epittm)
+		return -ENOMEM;
+
+	epittm->base = of_iomap(np, 0);
+	if (!epittm->base) {
+		ret = -ENXIO;
+		goto out_kfree;
+	}
+
+	epittm->irq = irq_of_parse_and_map(np, 0);
+	if (!epittm->irq) {
+		ret = -EINVAL;
+		goto out_iounmap;
+	}
+
+	clk_ipg = of_clk_get_by_name(np, "ipg");
+	if (IS_ERR(clk_ipg)) {
+		pr_err("i.MX EPIT: unable to get clk_ipg\n");
+		ret = PTR_ERR(clk_ipg);
+		goto out_iounmap;
+	}
+
+	ret = clk_prepare_enable(clk_ipg);
+	if (ret) {
+		pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
+		goto out_clk_ipg_disable;
+	}
+
+	epittm->clk_per = of_clk_get_by_name(np, "per");
+	if (IS_ERR(epittm->clk_per)) {
+		pr_err("i.MX EPIT: unable to get clk_per\n");
+		ret = PTR_ERR(epittm->clk_per);
+		goto out_clk_ipg_disable;
+	}
+
+	ret = clk_prepare_enable(epittm->clk_per);
+	if (ret) {
+		pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
+		goto out_clk_ipg_disable;
+	}
+
+	/* Initialise to a known state (all timers off, and timing reset) */
+	writel_relaxed(0x0, epittm->base + EPITCR);
+	writel_relaxed(0xffffffff, epittm->base + EPITLR);
+	writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
+		       epittm->base + EPITCR);
+
+	ret = epit_clocksource_init(epittm);
+	if(ret) {
+		pr_err("i.MX EPIT: failed to init clocksource\n");
+		goto out_clk_per_disable;
+	}
+
+	ret = epit_clockevent_init(epittm);
+	if(ret) {
+		pr_err("i.MX EPIT: failed to init clockevent\n");
+		goto out_clk_per_disable;
+	}
+
+	return 0;
+
+out_clk_per_disable:
+	clk_disable_unprepare(epittm->clk_per);
+out_clk_ipg_disable:
+	clk_disable_unprepare(clk_ipg);
+out_iounmap:
+	iounmap(epittm->base);
+out_kfree:
+	kfree(epittm);
+
+	return ret;
+}
+TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
-- 
2.17.0

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

* [PATCH v3 5/5] ARM: dts: imx6qdl: add missing compatible and clock properties for EPIT
  2018-05-29 17:04 ` Clément Péron
  (?)
@ 2018-05-29 17:04   ` Clément Péron
  -1 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Vladimir Zapolskiy

From: Colin Didier <colin.didier@devialet.com>

Add missing compatible and clock properties for EPIT node.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Clément Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index c003e62bf290..75bbaca34cbc 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -844,13 +844,23 @@
 			};
 
 			epit1: epit@20d0000 { /* EPIT1 */
+				compatible = "fsl,imx6q-epit";
 				reg = <0x020d0000 0x4000>;
 				interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6QDL_CLK_EPIT1>,
+					<&clks IMX6QDL_CLK_IPG_PER>;
+				clock-names = "ipg", "per";
+				status = "disabled";
 			};
 
 			epit2: epit@20d4000 { /* EPIT2 */
+				compatible = "fsl,imx6q-epit";
 				reg = <0x020d4000 0x4000>;
 				interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6QDL_CLK_EPIT2>,
+					<&clks IMX6QDL_CLK_IPG_PER>;
+				clock-names = "ipg", "per";
+				status = "disabled";
 			};
 
 			src: src@20d8000 {
-- 
2.17.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 5/5] ARM: dts: imx6qdl: add missing compatible and clock properties for EPIT
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: Colin Didier, linux-arm-kernel, devicetree, linux-clk
  Cc: Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer, Rob Herring,
	NXP Linux Team, Pengutronix Kernel Team, Clément Peron

From: Colin Didier <colin.didier@devialet.com>

Add missing compatible and clock properties for EPIT node.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Clément Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index c003e62bf290..75bbaca34cbc 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -844,13 +844,23 @@
 			};
 
 			epit1: epit@20d0000 { /* EPIT1 */
+				compatible = "fsl,imx6q-epit";
 				reg = <0x020d0000 0x4000>;
 				interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6QDL_CLK_EPIT1>,
+					<&clks IMX6QDL_CLK_IPG_PER>;
+				clock-names = "ipg", "per";
+				status = "disabled";
 			};
 
 			epit2: epit@20d4000 { /* EPIT2 */
+				compatible = "fsl,imx6q-epit";
 				reg = <0x020d4000 0x4000>;
 				interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6QDL_CLK_EPIT2>,
+					<&clks IMX6QDL_CLK_IPG_PER>;
+				clock-names = "ipg", "per";
+				status = "disabled";
 			};
 
 			src: src@20d8000 {
-- 
2.17.0


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

* [PATCH v3 5/5] ARM: dts: imx6qdl: add missing compatible and clock properties for EPIT
@ 2018-05-29 17:04   ` Clément Péron
  0 siblings, 0 replies; 36+ messages in thread
From: Clément Péron @ 2018-05-29 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Colin Didier <colin.didier@devialet.com>

Add missing compatible and clock properties for EPIT node.

Signed-off-by: Colin Didier <colin.didier@devialet.com>
Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index c003e62bf290..75bbaca34cbc 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -844,13 +844,23 @@
 			};
 
 			epit1: epit at 20d0000 { /* EPIT1 */
+				compatible = "fsl,imx6q-epit";
 				reg = <0x020d0000 0x4000>;
 				interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6QDL_CLK_EPIT1>,
+					<&clks IMX6QDL_CLK_IPG_PER>;
+				clock-names = "ipg", "per";
+				status = "disabled";
 			};
 
 			epit2: epit at 20d4000 { /* EPIT2 */
+				compatible = "fsl,imx6q-epit";
 				reg = <0x020d4000 0x4000>;
 				interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6QDL_CLK_EPIT2>,
+					<&clks IMX6QDL_CLK_IPG_PER>;
+				clock-names = "ipg", "per";
+				status = "disabled";
 			};
 
 			src: src at 20d8000 {
-- 
2.17.0

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

* Re: [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
  2018-05-29 17:04   ` Clément Péron
  (?)
@ 2018-05-29 18:16     ` Fabio Estevam
  -1 siblings, 0 replies; 36+ messages in thread
From: Fabio Estevam @ 2018-05-29 18:16 UTC (permalink / raw)
  To: Clément Péron
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Rob Herring, Colin Didier, Sascha Hauer, Clément Peron,
	Vladimir Zapolskiy, Pengutronix Kernel Team, Fabio Estevam,
	linux-clk,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	NXP Linux Team

On Tue, May 29, 2018 at 2:04 PM, Clément Péron <peron.clem@gmail.com> wrote:

> +static int __init epit_timer_init(struct device_node *np)
> +{
> +       struct epit_timer *epittm;
> +       struct clk *clk_ipg;
> +       int ret;
> +
> +       epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
> +       if (!epittm)
> +               return -ENOMEM;
> +
> +       epittm->base = of_iomap(np, 0);
> +       if (!epittm->base) {
> +               ret = -ENXIO;
> +               goto out_kfree;
> +       }
> +
> +       epittm->irq = irq_of_parse_and_map(np, 0);
> +       if (!epittm->irq) {
> +               ret = -EINVAL;
> +               goto out_iounmap;
> +       }
> +
> +       clk_ipg = of_clk_get_by_name(np, "ipg");
> +       if (IS_ERR(clk_ipg)) {
> +               pr_err("i.MX EPIT: unable to get clk_ipg\n");
> +               ret = PTR_ERR(clk_ipg);
> +               goto out_iounmap;
> +       }
> +
> +       ret = clk_prepare_enable(clk_ipg);
> +       if (ret) {
> +               pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> +               goto out_clk_ipg_disable;

This should be: goto out_iounmap;

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-29 18:16     ` Fabio Estevam
  0 siblings, 0 replies; 36+ messages in thread
From: Fabio Estevam @ 2018-05-29 18:16 UTC (permalink / raw)
  To: Clément Péron
  Cc: Colin Didier,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	linux-clk, Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer,
	Rob Herring, NXP Linux Team, Pengutronix Kernel Team,
	Clément Peron

On Tue, May 29, 2018 at 2:04 PM, Cl=C3=A9ment P=C3=A9ron <peron.clem@gmail.=
com> wrote:

> +static int __init epit_timer_init(struct device_node *np)
> +{
> +       struct epit_timer *epittm;
> +       struct clk *clk_ipg;
> +       int ret;
> +
> +       epittm =3D kzalloc(sizeof(*epittm), GFP_KERNEL);
> +       if (!epittm)
> +               return -ENOMEM;
> +
> +       epittm->base =3D of_iomap(np, 0);
> +       if (!epittm->base) {
> +               ret =3D -ENXIO;
> +               goto out_kfree;
> +       }
> +
> +       epittm->irq =3D irq_of_parse_and_map(np, 0);
> +       if (!epittm->irq) {
> +               ret =3D -EINVAL;
> +               goto out_iounmap;
> +       }
> +
> +       clk_ipg =3D of_clk_get_by_name(np, "ipg");
> +       if (IS_ERR(clk_ipg)) {
> +               pr_err("i.MX EPIT: unable to get clk_ipg\n");
> +               ret =3D PTR_ERR(clk_ipg);
> +               goto out_iounmap;
> +       }
> +
> +       ret =3D clk_prepare_enable(clk_ipg);
> +       if (ret) {
> +               pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> +               goto out_clk_ipg_disable;

This should be: goto out_iounmap;

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

* [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-29 18:16     ` Fabio Estevam
  0 siblings, 0 replies; 36+ messages in thread
From: Fabio Estevam @ 2018-05-29 18:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 29, 2018 at 2:04 PM, Cl?ment P?ron <peron.clem@gmail.com> wrote:

> +static int __init epit_timer_init(struct device_node *np)
> +{
> +       struct epit_timer *epittm;
> +       struct clk *clk_ipg;
> +       int ret;
> +
> +       epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
> +       if (!epittm)
> +               return -ENOMEM;
> +
> +       epittm->base = of_iomap(np, 0);
> +       if (!epittm->base) {
> +               ret = -ENXIO;
> +               goto out_kfree;
> +       }
> +
> +       epittm->irq = irq_of_parse_and_map(np, 0);
> +       if (!epittm->irq) {
> +               ret = -EINVAL;
> +               goto out_iounmap;
> +       }
> +
> +       clk_ipg = of_clk_get_by_name(np, "ipg");
> +       if (IS_ERR(clk_ipg)) {
> +               pr_err("i.MX EPIT: unable to get clk_ipg\n");
> +               ret = PTR_ERR(clk_ipg);
> +               goto out_iounmap;
> +       }
> +
> +       ret = clk_prepare_enable(clk_ipg);
> +       if (ret) {
> +               pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> +               goto out_clk_ipg_disable;

This should be: goto out_iounmap;

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

* Re: [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
  2018-05-29 17:04   ` Clément Péron
  (?)
@ 2018-05-30  6:56     ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  6:56 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, linux-arm-kernel,
	devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam

Hi Clément,

please find some more review comments.

On 05/29/2018 08:04 PM, Clément Péron wrote:
> From: Colin Didier <colin.didier@devialet.com>
> 
> Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.
> 
> Signed-off-by: Colin Didier <colin.didier@devialet.com>
> Signed-off-by: Clément Peron <clement.peron@devialet.com>
> ---
>  drivers/clocksource/Kconfig          |  12 ++
>  drivers/clocksource/Makefile         |   1 +
>  drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
>  3 files changed, 296 insertions(+)
>  create mode 100644 drivers/clocksource/timer-imx-epit.c
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 8e8a09755d10..920a0874f3a4 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -576,6 +576,18 @@ config H8300_TPU
>  	  This enables the clocksource for the H8300 platform with the
>  	  H8S2678 cpu.
>  
> +config CLKSRC_IMX_EPIT
> +	bool "Clocksource using i.MX EPIT"
> +	depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC || COMPILE_TEST)

Here 'depends on ARM' can be removed, because ARCH_MXC implies it.

Also ARCH_MXC implies ARCH_MULTIPLATFORM, which implies USE_OF in turn,
so I would say that the following line is correct, sorry about a previous
comment asking to add an explicit OF dependency:

	depends on CLKDEV_LOOKUP && (ARCH_MXC || COMPILE_TEST)

However most of the clocksource drivers follow 'bool "..." if COMPILE_TEST'
pattern, and it might be preferable to maintainers.

> +	select TIMER_OF

The driver does not have this dependency.

> +	select CLKSRC_MMIO
> +	help
> +	  This enables EPIT support available on some i.MX platforms.
> +	  Normally you don't have a reason to do so as the EPIT has
> +	  the same features and uses the same clocks as the GPT.
> +	  Anyway, on some systems the GPT may be in use for other
> +	  purposes.
> +
>  config CLKSRC_IMX_GPT
>  	bool "Clocksource using i.MX GPT" if COMPILE_TEST
>  	depends on ARM && CLKDEV_LOOKUP
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 00caf37e52f9..d9426f69ec69 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= timer-integrator-ap.o
>  obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
>  obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
>  obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= tango_xtal.o
> +obj-$(CONFIG_CLKSRC_IMX_EPIT)		+= timer-imx-epit.o
>  obj-$(CONFIG_CLKSRC_IMX_GPT)		+= timer-imx-gpt.o
>  obj-$(CONFIG_CLKSRC_IMX_TPM)		+= timer-imx-tpm.o
>  obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
> diff --git a/drivers/clocksource/timer-imx-epit.c b/drivers/clocksource/timer-imx-epit.c
> new file mode 100644
> index 000000000000..87025d5f3a97
> --- /dev/null
> +++ b/drivers/clocksource/timer-imx-epit.c
> @@ -0,0 +1,283 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * i.MX EPIT Timer
> + *
> + * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
> + * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
> + * Copyright (C) 2018 Clément Péron <clement.peron@devialet.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/err.h>

The include above can be dropped.

> +#include <linux/interrupt.h>
> +#include <linux/irq.h>

The include above can be dropped.

> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of.h>

The include above can be dropped.

> +#include <linux/sched_clock.h>
> +#include <linux/slab.h>
> +
> +#define EPITCR				0x00
> +#define EPITSR				0x04
> +#define EPITLR				0x08
> +#define EPITCMPR			0x0c
> +#define EPITCNR				0x10
> +
> +#define EPITCR_EN			BIT(0)
> +#define EPITCR_ENMOD			BIT(1)
> +#define EPITCR_OCIEN			BIT(2)
> +#define EPITCR_RLD			BIT(3)
> +#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
> +#define EPITCR_SWR			BIT(16)
> +#define EPITCR_IOVW			BIT(17)
> +#define EPITCR_DBGEN			BIT(18)
> +#define EPITCR_WAITEN			BIT(19)
> +#define EPITCR_RES			BIT(20)
> +#define EPITCR_STOPEN			BIT(21)
> +#define EPITCR_OM_DISCON		(0 << 22)
> +#define EPITCR_OM_TOGGLE		(1 << 22)
> +#define EPITCR_OM_CLEAR			(2 << 22)
> +#define EPITCR_OM_SET			(3 << 22)
> +#define EPITCR_CLKSRC_OFF		(0 << 24)
> +#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
> +#define EPITCR_CLKSRC_REF_HIGH		(2 << 24)
> +#define EPITCR_CLKSRC_REF_LOW		(3 << 24)
> +
> +#define EPITSR_OCIF			BIT(0)
> +
> +struct epit_timer {
> +	void __iomem *base;
> +	int irq;
> +	struct clk *clk_per;
> +	struct clock_event_device ced;
> +	struct irqaction act;
> +};
> +
> +static void __iomem *sched_clock_reg;
> +
> +static inline struct epit_timer *to_epit_timer(struct clock_event_device *ced)
> +{
> +	return container_of(ced, struct epit_timer, ced);
> +}
> +
> +static inline void epit_irq_disable(struct epit_timer *epittm)
> +{
> +	u32 val;
> +
> +	val = readl_relaxed(epittm->base + EPITCR);
> +	writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
> +}
> +
> +static inline void epit_irq_enable(struct epit_timer *epittm)
> +{
> +	u32 val;
> +
> +	val = readl_relaxed(epittm->base + EPITCR);
> +	writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
> +}
> +
> +static void epit_irq_acknowledge(struct epit_timer *epittm)
> +{
> +	writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
> +}
> +
> +static u64 notrace epit_read_sched_clock(void)
> +{
> +	return ~readl_relaxed(sched_clock_reg);
> +}
> +
> +static int __init epit_clocksource_init(struct epit_timer *epittm)
> +{
> +	unsigned int c = clk_get_rate(epittm->clk_per);
> +
> +	sched_clock_reg = epittm->base + EPITCNR;
> +	sched_clock_register(epit_read_sched_clock, 32, c);
> +
> +	return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c, 200, 32,
> +			clocksource_mmio_readl_down);
> +}
> +

I would suggest to place epit_clocksource_init() function right before
epit_timer_init().

> +static int epit_set_next_event(unsigned long cycles,
> +			       struct clock_event_device *ced)
> +{
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +	unsigned long tcmp;
> +
> +	tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles;
> +	writel_relaxed(tcmp, epittm->base + EPITCMPR);
> +
> +	return 0;
> +}
> +
> +/* Left event sources disabled, no more interrupts appear */
> +static int epit_shutdown(struct clock_event_device *ced)
> +{
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +	unsigned long flags;
> +
> +	/*
> +	 * The timer interrupt generation is disabled at least
> +	 * for enough time to call epit_set_next_event()
> +	 */
> +	local_irq_save(flags);
> +
> +	/* Disable interrupt in EPIT module */
> +	epit_irq_disable(epittm);
> +
> +	/* Clear pending interrupt */
> +	epit_irq_acknowledge(epittm);
> +
> +	local_irq_restore(flags);
> +
> +	return 0;
> +}
> +
> +static int epit_set_oneshot(struct clock_event_device *ced)
> +{
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +	unsigned long flags;
> +
> +	/*
> +	 * The timer interrupt generation is disabled at least
> +	 * for enough time to call epit_set_next_event()
> +	 */
> +	local_irq_save(flags);
> +
> +	/* Disable interrupt in EPIT module */
> +	epit_irq_disable(epittm);
> +
> +	/* Clear pending interrupt, only while switching mode */
> +	if (!clockevent_state_oneshot(ced))
> +		epit_irq_acknowledge(epittm);
> +
> +	/*
> +	 * Do not put overhead of interrupt enable/disable into
> +	 * epit_set_next_event(), the core has about 4 minutes
> +	 * to call epit_set_next_event() or shutdown clock after
> +	 * mode switching
> +	 */
> +	epit_irq_enable(epittm);
> +	local_irq_restore(flags);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
> +{
> +	struct clock_event_device *ced = dev_id;
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +
> +	epit_irq_acknowledge(epittm);
> +
> +	ced->event_handler(ced);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int __init epit_clockevent_init(struct epit_timer *epittm)
> +{
> +	struct clock_event_device *ced = &epittm->ced;
> +	struct irqaction *act = &epittm->act;
> +
> +	ced->name = "epit";
> +	ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
> +	ced->set_state_shutdown = epit_shutdown;
> +	ced->tick_resume = epit_shutdown;
> +	ced->set_state_oneshot = epit_set_oneshot;
> +	ced->set_next_event = epit_set_next_event;
> +	ced->rating = 200;
> +	ced->cpumask = cpumask_of(0);
> +	ced->irq = epittm->irq;
> +	clockevents_config_and_register(ced, clk_get_rate(epittm->clk_per),
> +		0xff, 0xfffffffe);

Please indent the wrapped line.

> +
> +	act->name = "i.MX EPIT Timer Tick",
> +	act->flags = IRQF_TIMER | IRQF_IRQPOLL;
> +	act->handler = epit_timer_interrupt;
> +	act->dev_id = ced;
> +
> +	/* Make irqs happen */
> +	return setup_irq(epittm->irq, act);
> +}
> +
> +static int __init epit_timer_init(struct device_node *np)
> +{
> +	struct epit_timer *epittm;
> +	struct clk *clk_ipg;
> +	int ret;
> +
> +	epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
> +	if (!epittm)
> +		return -ENOMEM;
> +
> +	epittm->base = of_iomap(np, 0);
> +	if (!epittm->base) {
> +		ret = -ENXIO;
> +		goto out_kfree;
> +	}
> +
> +	epittm->irq = irq_of_parse_and_map(np, 0);
> +	if (!epittm->irq) {
> +		ret = -EINVAL;
> +		goto out_iounmap;
> +	}
> +
> +	clk_ipg = of_clk_get_by_name(np, "ipg");
> +	if (IS_ERR(clk_ipg)) {
> +		pr_err("i.MX EPIT: unable to get clk_ipg\n");
> +		ret = PTR_ERR(clk_ipg);
> +		goto out_iounmap;
> +	}
> +
> +	ret = clk_prepare_enable(clk_ipg);
> +	if (ret) {
> +		pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> +		goto out_clk_ipg_disable;
> +	}
> +
> +	epittm->clk_per = of_clk_get_by_name(np, "per");
> +	if (IS_ERR(epittm->clk_per)) {
> +		pr_err("i.MX EPIT: unable to get clk_per\n");
> +		ret = PTR_ERR(epittm->clk_per);
> +		goto out_clk_ipg_disable;
> +	}
> +
> +	ret = clk_prepare_enable(epittm->clk_per);
> +	if (ret) {
> +		pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
> +		goto out_clk_ipg_disable;
> +	}
> +
> +	/* Initialise to a known state (all timers off, and timing reset) */
> +	writel_relaxed(0x0, epittm->base + EPITCR);
> +	writel_relaxed(0xffffffff, epittm->base + EPITLR);
> +	writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
> +		       epittm->base + EPITCR);
> +
> +	ret = epit_clocksource_init(epittm);
> +	if(ret) {

Add a space before left parenthesis.

> +		pr_err("i.MX EPIT: failed to init clocksource\n");
> +		goto out_clk_per_disable;
> +	}
> +
> +	ret = epit_clockevent_init(epittm);
> +	if(ret) {

Add a space before left parenthesis.

> +		pr_err("i.MX EPIT: failed to init clockevent\n");
> +		goto out_clk_per_disable;
> +	}
> +
> +	return 0;
> +
> +out_clk_per_disable:
> +	clk_disable_unprepare(epittm->clk_per);
> +out_clk_ipg_disable:
> +	clk_disable_unprepare(clk_ipg);
> +out_iounmap:
> +	iounmap(epittm->base);
> +out_kfree:
> +	kfree(epittm);
> +
> +	return ret;
> +}
> +TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
> 

Here "fsl,imx31-epit" would be way better than "fsl,imx6q-epit", please
fix it in the documentation as well.

--
With best wishes,
Vladimir

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-30  6:56     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  6:56 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, linux-arm-kernel,
	devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam

SGkgQ2zDqW1lbnQsCgpwbGVhc2UgZmluZCBzb21lIG1vcmUgcmV2aWV3IGNvbW1lbnRzLgoKT24g
MDUvMjkvMjAxOCAwODowNCBQTSwgQ2zDqW1lbnQgUMOpcm9uIHdyb3RlOgo+IEZyb206IENvbGlu
IERpZGllciA8Y29saW4uZGlkaWVyQGRldmlhbGV0LmNvbT4KPiAKPiBBZGQgZHJpdmVyIGZvciBO
WFAncyBFUElUIHRpbWVyIHVzZWQgaW4gaS5NWCA2IGZhbWlseSBvZiBTb0MuCj4gCj4gU2lnbmVk
LW9mZi1ieTogQ29saW4gRGlkaWVyIDxjb2xpbi5kaWRpZXJAZGV2aWFsZXQuY29tPgo+IFNpZ25l
ZC1vZmYtYnk6IENsw6ltZW50IFBlcm9uIDxjbGVtZW50LnBlcm9uQGRldmlhbGV0LmNvbT4KPiAt
LS0KPiAgZHJpdmVycy9jbG9ja3NvdXJjZS9LY29uZmlnICAgICAgICAgIHwgIDEyICsrCj4gIGRy
aXZlcnMvY2xvY2tzb3VyY2UvTWFrZWZpbGUgICAgICAgICB8ICAgMSArCj4gIGRyaXZlcnMvY2xv
Y2tzb3VyY2UvdGltZXItaW14LWVwaXQuYyB8IDI4MyArKysrKysrKysrKysrKysrKysrKysrKysr
KysKPiAgMyBmaWxlcyBjaGFuZ2VkLCAyOTYgaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9kZSAx
MDA2NDQgZHJpdmVycy9jbG9ja3NvdXJjZS90aW1lci1pbXgtZXBpdC5jCj4gCj4gZGlmZiAtLWdp
dCBhL2RyaXZlcnMvY2xvY2tzb3VyY2UvS2NvbmZpZyBiL2RyaXZlcnMvY2xvY2tzb3VyY2UvS2Nv
bmZpZwo+IGluZGV4IDhlOGEwOTc1NWQxMC4uOTIwYTA4NzRmM2E0IDEwMDY0NAo+IC0tLSBhL2Ry
aXZlcnMvY2xvY2tzb3VyY2UvS2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvY2xvY2tzb3VyY2UvS2Nv
bmZpZwo+IEBAIC01NzYsNiArNTc2LDE4IEBAIGNvbmZpZyBIODMwMF9UUFUKPiAgCSAgVGhpcyBl
bmFibGVzIHRoZSBjbG9ja3NvdXJjZSBmb3IgdGhlIEg4MzAwIHBsYXRmb3JtIHdpdGggdGhlCj4g
IAkgIEg4UzI2NzggY3B1Lgo+ICAKPiArY29uZmlnIENMS1NSQ19JTVhfRVBJVAo+ICsJYm9vbCAi
Q2xvY2tzb3VyY2UgdXNpbmcgaS5NWCBFUElUIgo+ICsJZGVwZW5kcyBvbiBBUk0gJiYgQ0xLREVW
X0xPT0tVUCAmJiBPRiAmJiAoQVJDSF9NWEMgfHwgQ09NUElMRV9URVNUKQoKSGVyZSAnZGVwZW5k
cyBvbiBBUk0nIGNhbiBiZSByZW1vdmVkLCBiZWNhdXNlIEFSQ0hfTVhDIGltcGxpZXMgaXQuCgpB
bHNvIEFSQ0hfTVhDIGltcGxpZXMgQVJDSF9NVUxUSVBMQVRGT1JNLCB3aGljaCBpbXBsaWVzIFVT
RV9PRiBpbiB0dXJuLApzbyBJIHdvdWxkIHNheSB0aGF0IHRoZSBmb2xsb3dpbmcgbGluZSBpcyBj
b3JyZWN0LCBzb3JyeSBhYm91dCBhIHByZXZpb3VzCmNvbW1lbnQgYXNraW5nIHRvIGFkZCBhbiBl
eHBsaWNpdCBPRiBkZXBlbmRlbmN5OgoKCWRlcGVuZHMgb24gQ0xLREVWX0xPT0tVUCAmJiAoQVJD
SF9NWEMgfHwgQ09NUElMRV9URVNUKQoKSG93ZXZlciBtb3N0IG9mIHRoZSBjbG9ja3NvdXJjZSBk
cml2ZXJzIGZvbGxvdyAnYm9vbCAiLi4uIiBpZiBDT01QSUxFX1RFU1QnCnBhdHRlcm4sIGFuZCBp
dCBtaWdodCBiZSBwcmVmZXJhYmxlIHRvIG1haW50YWluZXJzLgoKPiArCXNlbGVjdCBUSU1FUl9P
RgoKVGhlIGRyaXZlciBkb2VzIG5vdCBoYXZlIHRoaXMgZGVwZW5kZW5jeS4KCj4gKwlzZWxlY3Qg
Q0xLU1JDX01NSU8KPiArCWhlbHAKPiArCSAgVGhpcyBlbmFibGVzIEVQSVQgc3VwcG9ydCBhdmFp
bGFibGUgb24gc29tZSBpLk1YIHBsYXRmb3Jtcy4KPiArCSAgTm9ybWFsbHkgeW91IGRvbid0IGhh
dmUgYSByZWFzb24gdG8gZG8gc28gYXMgdGhlIEVQSVQgaGFzCj4gKwkgIHRoZSBzYW1lIGZlYXR1
cmVzIGFuZCB1c2VzIHRoZSBzYW1lIGNsb2NrcyBhcyB0aGUgR1BULgo+ICsJICBBbnl3YXksIG9u
IHNvbWUgc3lzdGVtcyB0aGUgR1BUIG1heSBiZSBpbiB1c2UgZm9yIG90aGVyCj4gKwkgIHB1cnBv
c2VzLgo+ICsKPiAgY29uZmlnIENMS1NSQ19JTVhfR1BUCj4gIAlib29sICJDbG9ja3NvdXJjZSB1
c2luZyBpLk1YIEdQVCIgaWYgQ09NUElMRV9URVNUCj4gIAlkZXBlbmRzIG9uIEFSTSAmJiBDTEtE
RVZfTE9PS1VQCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2xvY2tzb3VyY2UvTWFrZWZpbGUgYi9k
cml2ZXJzL2Nsb2Nrc291cmNlL01ha2VmaWxlCj4gaW5kZXggMDBjYWYzN2U1MmY5Li5kOTQyNmY2
OWVjNjkgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9jbG9ja3NvdXJjZS9NYWtlZmlsZQo+ICsrKyBi
L2RyaXZlcnMvY2xvY2tzb3VyY2UvTWFrZWZpbGUKPiBAQCAtNjksNiArNjksNyBAQCBvYmotJChD
T05GSUdfSU5URUdSQVRPUl9BUF9USU1FUikJKz0gdGltZXItaW50ZWdyYXRvci1hcC5vCj4gIG9i
ai0kKENPTkZJR19DTEtTUkNfVkVSU0FUSUxFKQkJKz0gdmVyc2F0aWxlLm8KPiAgb2JqLSQoQ09O
RklHX0NMS1NSQ19NSVBTX0dJQykJCSs9IG1pcHMtZ2ljLXRpbWVyLm8KPiAgb2JqLSQoQ09ORklH
X0NMS1NSQ19UQU5HT19YVEFMKQkJKz0gdGFuZ29feHRhbC5vCj4gK29iai0kKENPTkZJR19DTEtT
UkNfSU1YX0VQSVQpCQkrPSB0aW1lci1pbXgtZXBpdC5vCj4gIG9iai0kKENPTkZJR19DTEtTUkNf
SU1YX0dQVCkJCSs9IHRpbWVyLWlteC1ncHQubwo+ICBvYmotJChDT05GSUdfQ0xLU1JDX0lNWF9U
UE0pCQkrPSB0aW1lci1pbXgtdHBtLm8KPiAgb2JqLSQoQ09ORklHX0FTTTkyNjBfVElNRVIpCQkr
PSBhc205MjYwX3RpbWVyLm8KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbG9ja3NvdXJjZS90aW1l
ci1pbXgtZXBpdC5jIGIvZHJpdmVycy9jbG9ja3NvdXJjZS90aW1lci1pbXgtZXBpdC5jCj4gbmV3
IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLjg3MDI1ZDVmM2E5Nwo+IC0t
LSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2Nsb2Nrc291cmNlL3RpbWVyLWlteC1lcGl0LmMK
PiBAQCAtMCwwICsxLDI4MyBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIu
MAo+ICsvKgo+ICsgKiBpLk1YIEVQSVQgVGltZXIKPiArICoKPiArICogQ29weXJpZ2h0IChDKSAy
MDEwIFNhc2NoYSBIYXVlciA8cy5oYXVlckBwZW5ndXRyb25peC5kZT4KPiArICogQ29weXJpZ2h0
IChDKSAyMDE4IENvbGluIERpZGllciA8Y29saW4uZGlkaWVyQGRldmlhbGV0LmNvbT4KPiArICog
Q29weXJpZ2h0IChDKSAyMDE4IENsw6ltZW50IFDDqXJvbiA8Y2xlbWVudC5wZXJvbkBkZXZpYWxl
dC5jb20+Cj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgo+ICsjaW5jbHVkZSA8
bGludXgvY2xvY2tjaGlwcy5oPgo+ICsjaW5jbHVkZSA8bGludXgvZXJyLmg+CgpUaGUgaW5jbHVk
ZSBhYm92ZSBjYW4gYmUgZHJvcHBlZC4KCj4gKyNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4K
PiArI2luY2x1ZGUgPGxpbnV4L2lycS5oPgoKVGhlIGluY2x1ZGUgYWJvdmUgY2FuIGJlIGRyb3Bw
ZWQuCgo+ICsjaW5jbHVkZSA8bGludXgvb2ZfYWRkcmVzcy5oPgo+ICsjaW5jbHVkZSA8bGludXgv
b2ZfaXJxLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZi5oPgoKVGhlIGluY2x1ZGUgYWJvdmUgY2Fu
IGJlIGRyb3BwZWQuCgo+ICsjaW5jbHVkZSA8bGludXgvc2NoZWRfY2xvY2suaD4KPiArI2luY2x1
ZGUgPGxpbnV4L3NsYWIuaD4KPiArCj4gKyNkZWZpbmUgRVBJVENSCQkJCTB4MDAKPiArI2RlZmlu
ZSBFUElUU1IJCQkJMHgwNAo+ICsjZGVmaW5lIEVQSVRMUgkJCQkweDA4Cj4gKyNkZWZpbmUgRVBJ
VENNUFIJCQkweDBjCj4gKyNkZWZpbmUgRVBJVENOUgkJCQkweDEwCj4gKwo+ICsjZGVmaW5lIEVQ
SVRDUl9FTgkJCUJJVCgwKQo+ICsjZGVmaW5lIEVQSVRDUl9FTk1PRAkJCUJJVCgxKQo+ICsjZGVm
aW5lIEVQSVRDUl9PQ0lFTgkJCUJJVCgyKQo+ICsjZGVmaW5lIEVQSVRDUl9STEQJCQlCSVQoMykK
PiArI2RlZmluZSBFUElUQ1JfUFJFU0MoeCkJCQkoKCh4KSAmIDB4ZmZmKSA8PCA0KQo+ICsjZGVm
aW5lIEVQSVRDUl9TV1IJCQlCSVQoMTYpCj4gKyNkZWZpbmUgRVBJVENSX0lPVlcJCQlCSVQoMTcp
Cj4gKyNkZWZpbmUgRVBJVENSX0RCR0VOCQkJQklUKDE4KQo+ICsjZGVmaW5lIEVQSVRDUl9XQUlU
RU4JCQlCSVQoMTkpCj4gKyNkZWZpbmUgRVBJVENSX1JFUwkJCUJJVCgyMCkKPiArI2RlZmluZSBF
UElUQ1JfU1RPUEVOCQkJQklUKDIxKQo+ICsjZGVmaW5lIEVQSVRDUl9PTV9ESVNDT04JCSgwIDw8
IDIyKQo+ICsjZGVmaW5lIEVQSVRDUl9PTV9UT0dHTEUJCSgxIDw8IDIyKQo+ICsjZGVmaW5lIEVQ
SVRDUl9PTV9DTEVBUgkJCSgyIDw8IDIyKQo+ICsjZGVmaW5lIEVQSVRDUl9PTV9TRVQJCQkoMyA8
PCAyMikKPiArI2RlZmluZSBFUElUQ1JfQ0xLU1JDX09GRgkJKDAgPDwgMjQpCj4gKyNkZWZpbmUg
RVBJVENSX0NMS1NSQ19QRVJJUEhFUkFMCSgxIDw8IDI0KQo+ICsjZGVmaW5lIEVQSVRDUl9DTEtT
UkNfUkVGX0hJR0gJCSgyIDw8IDI0KQo+ICsjZGVmaW5lIEVQSVRDUl9DTEtTUkNfUkVGX0xPVwkJ
KDMgPDwgMjQpCj4gKwo+ICsjZGVmaW5lIEVQSVRTUl9PQ0lGCQkJQklUKDApCj4gKwo+ICtzdHJ1
Y3QgZXBpdF90aW1lciB7Cj4gKwl2b2lkIF9faW9tZW0gKmJhc2U7Cj4gKwlpbnQgaXJxOwo+ICsJ
c3RydWN0IGNsayAqY2xrX3BlcjsKPiArCXN0cnVjdCBjbG9ja19ldmVudF9kZXZpY2UgY2VkOwo+
ICsJc3RydWN0IGlycWFjdGlvbiBhY3Q7Cj4gK307Cj4gKwo+ICtzdGF0aWMgdm9pZCBfX2lvbWVt
ICpzY2hlZF9jbG9ja19yZWc7Cj4gKwo+ICtzdGF0aWMgaW5saW5lIHN0cnVjdCBlcGl0X3RpbWVy
ICp0b19lcGl0X3RpbWVyKHN0cnVjdCBjbG9ja19ldmVudF9kZXZpY2UgKmNlZCkKPiArewo+ICsJ
cmV0dXJuIGNvbnRhaW5lcl9vZihjZWQsIHN0cnVjdCBlcGl0X3RpbWVyLCBjZWQpOwo+ICt9Cj4g
Kwo+ICtzdGF0aWMgaW5saW5lIHZvaWQgZXBpdF9pcnFfZGlzYWJsZShzdHJ1Y3QgZXBpdF90aW1l
ciAqZXBpdHRtKQo+ICt7Cj4gKwl1MzIgdmFsOwo+ICsKPiArCXZhbCA9IHJlYWRsX3JlbGF4ZWQo
ZXBpdHRtLT5iYXNlICsgRVBJVENSKTsKPiArCXdyaXRlbF9yZWxheGVkKHZhbCAmIH5FUElUQ1Jf
T0NJRU4sIGVwaXR0bS0+YmFzZSArIEVQSVRDUik7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUg
dm9pZCBlcGl0X2lycV9lbmFibGUoc3RydWN0IGVwaXRfdGltZXIgKmVwaXR0bSkKPiArewo+ICsJ
dTMyIHZhbDsKPiArCj4gKwl2YWwgPSByZWFkbF9yZWxheGVkKGVwaXR0bS0+YmFzZSArIEVQSVRD
Uik7Cj4gKwl3cml0ZWxfcmVsYXhlZCh2YWwgfCBFUElUQ1JfT0NJRU4sIGVwaXR0bS0+YmFzZSAr
IEVQSVRDUik7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIGVwaXRfaXJxX2Fja25vd2xlZGdlKHN0
cnVjdCBlcGl0X3RpbWVyICplcGl0dG0pCj4gK3sKPiArCXdyaXRlbF9yZWxheGVkKEVQSVRTUl9P
Q0lGLCBlcGl0dG0tPmJhc2UgKyBFUElUU1IpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdTY0IG5vdHJh
Y2UgZXBpdF9yZWFkX3NjaGVkX2Nsb2NrKHZvaWQpCj4gK3sKPiArCXJldHVybiB+cmVhZGxfcmVs
YXhlZChzY2hlZF9jbG9ja19yZWcpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IF9faW5pdCBlcGl0
X2Nsb2Nrc291cmNlX2luaXQoc3RydWN0IGVwaXRfdGltZXIgKmVwaXR0bSkKPiArewo+ICsJdW5z
aWduZWQgaW50IGMgPSBjbGtfZ2V0X3JhdGUoZXBpdHRtLT5jbGtfcGVyKTsKPiArCj4gKwlzY2hl
ZF9jbG9ja19yZWcgPSBlcGl0dG0tPmJhc2UgKyBFUElUQ05SOwo+ICsJc2NoZWRfY2xvY2tfcmVn
aXN0ZXIoZXBpdF9yZWFkX3NjaGVkX2Nsb2NrLCAzMiwgYyk7Cj4gKwo+ICsJcmV0dXJuIGNsb2Nr
c291cmNlX21taW9faW5pdChlcGl0dG0tPmJhc2UgKyBFUElUQ05SLCAiZXBpdCIsIGMsIDIwMCwg
MzIsCj4gKwkJCWNsb2Nrc291cmNlX21taW9fcmVhZGxfZG93bik7Cj4gK30KPiArCgpJIHdvdWxk
IHN1Z2dlc3QgdG8gcGxhY2UgZXBpdF9jbG9ja3NvdXJjZV9pbml0KCkgZnVuY3Rpb24gcmlnaHQg
YmVmb3JlCmVwaXRfdGltZXJfaW5pdCgpLgoKPiArc3RhdGljIGludCBlcGl0X3NldF9uZXh0X2V2
ZW50KHVuc2lnbmVkIGxvbmcgY3ljbGVzLAo+ICsJCQkgICAgICAgc3RydWN0IGNsb2NrX2V2ZW50
X2RldmljZSAqY2VkKQo+ICt7Cj4gKwlzdHJ1Y3QgZXBpdF90aW1lciAqZXBpdHRtID0gdG9fZXBp
dF90aW1lcihjZWQpOwo+ICsJdW5zaWduZWQgbG9uZyB0Y21wOwo+ICsKPiArCXRjbXAgPSByZWFk
bF9yZWxheGVkKGVwaXR0bS0+YmFzZSArIEVQSVRDTlIpIC0gY3ljbGVzOwo+ICsJd3JpdGVsX3Jl
bGF4ZWQodGNtcCwgZXBpdHRtLT5iYXNlICsgRVBJVENNUFIpOwo+ICsKPiArCXJldHVybiAwOwo+
ICt9Cj4gKwo+ICsvKiBMZWZ0IGV2ZW50IHNvdXJjZXMgZGlzYWJsZWQsIG5vIG1vcmUgaW50ZXJy
dXB0cyBhcHBlYXIgKi8KPiArc3RhdGljIGludCBlcGl0X3NodXRkb3duKHN0cnVjdCBjbG9ja19l
dmVudF9kZXZpY2UgKmNlZCkKPiArewo+ICsJc3RydWN0IGVwaXRfdGltZXIgKmVwaXR0bSA9IHRv
X2VwaXRfdGltZXIoY2VkKTsKPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwo+ICsJLyoKPiAr
CSAqIFRoZSB0aW1lciBpbnRlcnJ1cHQgZ2VuZXJhdGlvbiBpcyBkaXNhYmxlZCBhdCBsZWFzdAo+
ICsJICogZm9yIGVub3VnaCB0aW1lIHRvIGNhbGwgZXBpdF9zZXRfbmV4dF9ldmVudCgpCj4gKwkg
Ki8KPiArCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKPiArCj4gKwkvKiBEaXNhYmxlIGludGVycnVw
dCBpbiBFUElUIG1vZHVsZSAqLwo+ICsJZXBpdF9pcnFfZGlzYWJsZShlcGl0dG0pOwo+ICsKPiAr
CS8qIENsZWFyIHBlbmRpbmcgaW50ZXJydXB0ICovCj4gKwllcGl0X2lycV9hY2tub3dsZWRnZShl
cGl0dG0pOwo+ICsKPiArCWxvY2FsX2lycV9yZXN0b3JlKGZsYWdzKTsKPiArCj4gKwlyZXR1cm4g
MDsKPiArfQo+ICsKPiArc3RhdGljIGludCBlcGl0X3NldF9vbmVzaG90KHN0cnVjdCBjbG9ja19l
dmVudF9kZXZpY2UgKmNlZCkKPiArewo+ICsJc3RydWN0IGVwaXRfdGltZXIgKmVwaXR0bSA9IHRv
X2VwaXRfdGltZXIoY2VkKTsKPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwo+ICsJLyoKPiAr
CSAqIFRoZSB0aW1lciBpbnRlcnJ1cHQgZ2VuZXJhdGlvbiBpcyBkaXNhYmxlZCBhdCBsZWFzdAo+
ICsJICogZm9yIGVub3VnaCB0aW1lIHRvIGNhbGwgZXBpdF9zZXRfbmV4dF9ldmVudCgpCj4gKwkg
Ki8KPiArCWxvY2FsX2lycV9zYXZlKGZsYWdzKTsKPiArCj4gKwkvKiBEaXNhYmxlIGludGVycnVw
dCBpbiBFUElUIG1vZHVsZSAqLwo+ICsJZXBpdF9pcnFfZGlzYWJsZShlcGl0dG0pOwo+ICsKPiAr
CS8qIENsZWFyIHBlbmRpbmcgaW50ZXJydXB0LCBvbmx5IHdoaWxlIHN3aXRjaGluZyBtb2RlICov
Cj4gKwlpZiAoIWNsb2NrZXZlbnRfc3RhdGVfb25lc2hvdChjZWQpKQo+ICsJCWVwaXRfaXJxX2Fj
a25vd2xlZGdlKGVwaXR0bSk7Cj4gKwo+ICsJLyoKPiArCSAqIERvIG5vdCBwdXQgb3ZlcmhlYWQg
b2YgaW50ZXJydXB0IGVuYWJsZS9kaXNhYmxlIGludG8KPiArCSAqIGVwaXRfc2V0X25leHRfZXZl
bnQoKSwgdGhlIGNvcmUgaGFzIGFib3V0IDQgbWludXRlcwo+ICsJICogdG8gY2FsbCBlcGl0X3Nl
dF9uZXh0X2V2ZW50KCkgb3Igc2h1dGRvd24gY2xvY2sgYWZ0ZXIKPiArCSAqIG1vZGUgc3dpdGNo
aW5nCj4gKwkgKi8KPiArCWVwaXRfaXJxX2VuYWJsZShlcGl0dG0pOwo+ICsJbG9jYWxfaXJxX3Jl
c3RvcmUoZmxhZ3MpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaXJxcmV0
dXJuX3QgZXBpdF90aW1lcl9pbnRlcnJ1cHQoaW50IGlycSwgdm9pZCAqZGV2X2lkKQo+ICt7Cj4g
KwlzdHJ1Y3QgY2xvY2tfZXZlbnRfZGV2aWNlICpjZWQgPSBkZXZfaWQ7Cj4gKwlzdHJ1Y3QgZXBp
dF90aW1lciAqZXBpdHRtID0gdG9fZXBpdF90aW1lcihjZWQpOwo+ICsKPiArCWVwaXRfaXJxX2Fj
a25vd2xlZGdlKGVwaXR0bSk7Cj4gKwo+ICsJY2VkLT5ldmVudF9oYW5kbGVyKGNlZCk7Cj4gKwo+
ICsJcmV0dXJuIElSUV9IQU5ETEVEOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IF9faW5pdCBlcGl0
X2Nsb2NrZXZlbnRfaW5pdChzdHJ1Y3QgZXBpdF90aW1lciAqZXBpdHRtKQo+ICt7Cj4gKwlzdHJ1
Y3QgY2xvY2tfZXZlbnRfZGV2aWNlICpjZWQgPSAmZXBpdHRtLT5jZWQ7Cj4gKwlzdHJ1Y3QgaXJx
YWN0aW9uICphY3QgPSAmZXBpdHRtLT5hY3Q7Cj4gKwo+ICsJY2VkLT5uYW1lID0gImVwaXQiOwo+
ICsJY2VkLT5mZWF0dXJlcyA9IENMT0NLX0VWVF9GRUFUX09ORVNIT1QgfCBDTE9DS19FVlRfRkVB
VF9EWU5JUlE7Cj4gKwljZWQtPnNldF9zdGF0ZV9zaHV0ZG93biA9IGVwaXRfc2h1dGRvd247Cj4g
KwljZWQtPnRpY2tfcmVzdW1lID0gZXBpdF9zaHV0ZG93bjsKPiArCWNlZC0+c2V0X3N0YXRlX29u
ZXNob3QgPSBlcGl0X3NldF9vbmVzaG90Owo+ICsJY2VkLT5zZXRfbmV4dF9ldmVudCA9IGVwaXRf
c2V0X25leHRfZXZlbnQ7Cj4gKwljZWQtPnJhdGluZyA9IDIwMDsKPiArCWNlZC0+Y3B1bWFzayA9
IGNwdW1hc2tfb2YoMCk7Cj4gKwljZWQtPmlycSA9IGVwaXR0bS0+aXJxOwo+ICsJY2xvY2tldmVu
dHNfY29uZmlnX2FuZF9yZWdpc3RlcihjZWQsIGNsa19nZXRfcmF0ZShlcGl0dG0tPmNsa19wZXIp
LAo+ICsJCTB4ZmYsIDB4ZmZmZmZmZmUpOwoKUGxlYXNlIGluZGVudCB0aGUgd3JhcHBlZCBsaW5l
LgoKPiArCj4gKwlhY3QtPm5hbWUgPSAiaS5NWCBFUElUIFRpbWVyIFRpY2siLAo+ICsJYWN0LT5m
bGFncyA9IElSUUZfVElNRVIgfCBJUlFGX0lSUVBPTEw7Cj4gKwlhY3QtPmhhbmRsZXIgPSBlcGl0
X3RpbWVyX2ludGVycnVwdDsKPiArCWFjdC0+ZGV2X2lkID0gY2VkOwo+ICsKPiArCS8qIE1ha2Ug
aXJxcyBoYXBwZW4gKi8KPiArCXJldHVybiBzZXR1cF9pcnEoZXBpdHRtLT5pcnEsIGFjdCk7Cj4g
K30KPiArCj4gK3N0YXRpYyBpbnQgX19pbml0IGVwaXRfdGltZXJfaW5pdChzdHJ1Y3QgZGV2aWNl
X25vZGUgKm5wKQo+ICt7Cj4gKwlzdHJ1Y3QgZXBpdF90aW1lciAqZXBpdHRtOwo+ICsJc3RydWN0
IGNsayAqY2xrX2lwZzsKPiArCWludCByZXQ7Cj4gKwo+ICsJZXBpdHRtID0ga3phbGxvYyhzaXpl
b2YoKmVwaXR0bSksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFlcGl0dG0pCj4gKwkJcmV0dXJuIC1F
Tk9NRU07Cj4gKwo+ICsJZXBpdHRtLT5iYXNlID0gb2ZfaW9tYXAobnAsIDApOwo+ICsJaWYgKCFl
cGl0dG0tPmJhc2UpIHsKPiArCQlyZXQgPSAtRU5YSU87Cj4gKwkJZ290byBvdXRfa2ZyZWU7Cj4g
Kwl9Cj4gKwo+ICsJZXBpdHRtLT5pcnEgPSBpcnFfb2ZfcGFyc2VfYW5kX21hcChucCwgMCk7Cj4g
KwlpZiAoIWVwaXR0bS0+aXJxKSB7Cj4gKwkJcmV0ID0gLUVJTlZBTDsKPiArCQlnb3RvIG91dF9p
b3VubWFwOwo+ICsJfQo+ICsKPiArCWNsa19pcGcgPSBvZl9jbGtfZ2V0X2J5X25hbWUobnAsICJp
cGciKTsKPiArCWlmIChJU19FUlIoY2xrX2lwZykpIHsKPiArCQlwcl9lcnIoImkuTVggRVBJVDog
dW5hYmxlIHRvIGdldCBjbGtfaXBnXG4iKTsKPiArCQlyZXQgPSBQVFJfRVJSKGNsa19pcGcpOwo+
ICsJCWdvdG8gb3V0X2lvdW5tYXA7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5h
YmxlKGNsa19pcGcpOwo+ICsJaWYgKHJldCkgewo+ICsJCXByX2VycigiaS5NWCBFUElUOiB1bmFi
bGUgdG8gcHJlcGFyZStlbmFibGUgY2xrX2lwZ1xuIik7Cj4gKwkJZ290byBvdXRfY2xrX2lwZ19k
aXNhYmxlOwo+ICsJfQo+ICsKPiArCWVwaXR0bS0+Y2xrX3BlciA9IG9mX2Nsa19nZXRfYnlfbmFt
ZShucCwgInBlciIpOwo+ICsJaWYgKElTX0VSUihlcGl0dG0tPmNsa19wZXIpKSB7Cj4gKwkJcHJf
ZXJyKCJpLk1YIEVQSVQ6IHVuYWJsZSB0byBnZXQgY2xrX3BlclxuIik7Cj4gKwkJcmV0ID0gUFRS
X0VSUihlcGl0dG0tPmNsa19wZXIpOwo+ICsJCWdvdG8gb3V0X2Nsa19pcGdfZGlzYWJsZTsKPiAr
CX0KPiArCj4gKwlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUoZXBpdHRtLT5jbGtfcGVyKTsKPiAr
CWlmIChyZXQpIHsKPiArCQlwcl9lcnIoImkuTVggRVBJVDogdW5hYmxlIHRvIHByZXBhcmUrZW5h
YmxlIGNsa19wZXJcbiIpOwo+ICsJCWdvdG8gb3V0X2Nsa19pcGdfZGlzYWJsZTsKPiArCX0KPiAr
Cj4gKwkvKiBJbml0aWFsaXNlIHRvIGEga25vd24gc3RhdGUgKGFsbCB0aW1lcnMgb2ZmLCBhbmQg
dGltaW5nIHJlc2V0KSAqLwo+ICsJd3JpdGVsX3JlbGF4ZWQoMHgwLCBlcGl0dG0tPmJhc2UgKyBF
UElUQ1IpOwo+ICsJd3JpdGVsX3JlbGF4ZWQoMHhmZmZmZmZmZiwgZXBpdHRtLT5iYXNlICsgRVBJ
VExSKTsKPiArCXdyaXRlbF9yZWxheGVkKEVQSVRDUl9FTiB8IEVQSVRDUl9DTEtTUkNfUkVGX0hJ
R0ggfCBFUElUQ1JfV0FJVEVOLAo+ICsJCSAgICAgICBlcGl0dG0tPmJhc2UgKyBFUElUQ1IpOwo+
ICsKPiArCXJldCA9IGVwaXRfY2xvY2tzb3VyY2VfaW5pdChlcGl0dG0pOwo+ICsJaWYocmV0KSB7
CgpBZGQgYSBzcGFjZSBiZWZvcmUgbGVmdCBwYXJlbnRoZXNpcy4KCj4gKwkJcHJfZXJyKCJpLk1Y
IEVQSVQ6IGZhaWxlZCB0byBpbml0IGNsb2Nrc291cmNlXG4iKTsKPiArCQlnb3RvIG91dF9jbGtf
cGVyX2Rpc2FibGU7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gZXBpdF9jbG9ja2V2ZW50X2luaXQoZXBp
dHRtKTsKPiArCWlmKHJldCkgewoKQWRkIGEgc3BhY2UgYmVmb3JlIGxlZnQgcGFyZW50aGVzaXMu
Cgo+ICsJCXByX2VycigiaS5NWCBFUElUOiBmYWlsZWQgdG8gaW5pdCBjbG9ja2V2ZW50XG4iKTsK
PiArCQlnb3RvIG91dF9jbGtfcGVyX2Rpc2FibGU7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4g
Kwo+ICtvdXRfY2xrX3Blcl9kaXNhYmxlOgo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGVwaXR0
bS0+Y2xrX3Blcik7Cj4gK291dF9jbGtfaXBnX2Rpc2FibGU6Cj4gKwljbGtfZGlzYWJsZV91bnBy
ZXBhcmUoY2xrX2lwZyk7Cj4gK291dF9pb3VubWFwOgo+ICsJaW91bm1hcChlcGl0dG0tPmJhc2Up
Owo+ICtvdXRfa2ZyZWU6Cj4gKwlrZnJlZShlcGl0dG0pOwo+ICsKPiArCXJldHVybiByZXQ7Cj4g
K30KPiArVElNRVJfT0ZfREVDTEFSRShteDZxX3RpbWVyLCAiZnNsLGlteDZxLWVwaXQiLCBlcGl0
X3RpbWVyX2luaXQpOwo+IAoKSGVyZSAiZnNsLGlteDMxLWVwaXQiIHdvdWxkIGJlIHdheSBiZXR0
ZXIgdGhhbiAiZnNsLGlteDZxLWVwaXQiLCBwbGVhc2UKZml4IGl0IGluIHRoZSBkb2N1bWVudGF0
aW9uIGFzIHdlbGwuCgotLQpXaXRoIGJlc3Qgd2lzaGVzLApWbGFkaW1pcgoKX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWls
aW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0
cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=

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

* [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-30  6:56     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  6:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Cl?ment,

please find some more review comments.

On 05/29/2018 08:04 PM, Cl?ment P?ron wrote:
> From: Colin Didier <colin.didier@devialet.com>
> 
> Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.
> 
> Signed-off-by: Colin Didier <colin.didier@devialet.com>
> Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> ---
>  drivers/clocksource/Kconfig          |  12 ++
>  drivers/clocksource/Makefile         |   1 +
>  drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
>  3 files changed, 296 insertions(+)
>  create mode 100644 drivers/clocksource/timer-imx-epit.c
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 8e8a09755d10..920a0874f3a4 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -576,6 +576,18 @@ config H8300_TPU
>  	  This enables the clocksource for the H8300 platform with the
>  	  H8S2678 cpu.
>  
> +config CLKSRC_IMX_EPIT
> +	bool "Clocksource using i.MX EPIT"
> +	depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC || COMPILE_TEST)

Here 'depends on ARM' can be removed, because ARCH_MXC implies it.

Also ARCH_MXC implies ARCH_MULTIPLATFORM, which implies USE_OF in turn,
so I would say that the following line is correct, sorry about a previous
comment asking to add an explicit OF dependency:

	depends on CLKDEV_LOOKUP && (ARCH_MXC || COMPILE_TEST)

However most of the clocksource drivers follow 'bool "..." if COMPILE_TEST'
pattern, and it might be preferable to maintainers.

> +	select TIMER_OF

The driver does not have this dependency.

> +	select CLKSRC_MMIO
> +	help
> +	  This enables EPIT support available on some i.MX platforms.
> +	  Normally you don't have a reason to do so as the EPIT has
> +	  the same features and uses the same clocks as the GPT.
> +	  Anyway, on some systems the GPT may be in use for other
> +	  purposes.
> +
>  config CLKSRC_IMX_GPT
>  	bool "Clocksource using i.MX GPT" if COMPILE_TEST
>  	depends on ARM && CLKDEV_LOOKUP
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 00caf37e52f9..d9426f69ec69 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= timer-integrator-ap.o
>  obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
>  obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
>  obj-$(CONFIG_CLKSRC_TANGO_XTAL)		+= tango_xtal.o
> +obj-$(CONFIG_CLKSRC_IMX_EPIT)		+= timer-imx-epit.o
>  obj-$(CONFIG_CLKSRC_IMX_GPT)		+= timer-imx-gpt.o
>  obj-$(CONFIG_CLKSRC_IMX_TPM)		+= timer-imx-tpm.o
>  obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
> diff --git a/drivers/clocksource/timer-imx-epit.c b/drivers/clocksource/timer-imx-epit.c
> new file mode 100644
> index 000000000000..87025d5f3a97
> --- /dev/null
> +++ b/drivers/clocksource/timer-imx-epit.c
> @@ -0,0 +1,283 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * i.MX EPIT Timer
> + *
> + * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
> + * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
> + * Copyright (C) 2018 Cl?ment P?ron <clement.peron@devialet.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/err.h>

The include above can be dropped.

> +#include <linux/interrupt.h>
> +#include <linux/irq.h>

The include above can be dropped.

> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of.h>

The include above can be dropped.

> +#include <linux/sched_clock.h>
> +#include <linux/slab.h>
> +
> +#define EPITCR				0x00
> +#define EPITSR				0x04
> +#define EPITLR				0x08
> +#define EPITCMPR			0x0c
> +#define EPITCNR				0x10
> +
> +#define EPITCR_EN			BIT(0)
> +#define EPITCR_ENMOD			BIT(1)
> +#define EPITCR_OCIEN			BIT(2)
> +#define EPITCR_RLD			BIT(3)
> +#define EPITCR_PRESC(x)			(((x) & 0xfff) << 4)
> +#define EPITCR_SWR			BIT(16)
> +#define EPITCR_IOVW			BIT(17)
> +#define EPITCR_DBGEN			BIT(18)
> +#define EPITCR_WAITEN			BIT(19)
> +#define EPITCR_RES			BIT(20)
> +#define EPITCR_STOPEN			BIT(21)
> +#define EPITCR_OM_DISCON		(0 << 22)
> +#define EPITCR_OM_TOGGLE		(1 << 22)
> +#define EPITCR_OM_CLEAR			(2 << 22)
> +#define EPITCR_OM_SET			(3 << 22)
> +#define EPITCR_CLKSRC_OFF		(0 << 24)
> +#define EPITCR_CLKSRC_PERIPHERAL	(1 << 24)
> +#define EPITCR_CLKSRC_REF_HIGH		(2 << 24)
> +#define EPITCR_CLKSRC_REF_LOW		(3 << 24)
> +
> +#define EPITSR_OCIF			BIT(0)
> +
> +struct epit_timer {
> +	void __iomem *base;
> +	int irq;
> +	struct clk *clk_per;
> +	struct clock_event_device ced;
> +	struct irqaction act;
> +};
> +
> +static void __iomem *sched_clock_reg;
> +
> +static inline struct epit_timer *to_epit_timer(struct clock_event_device *ced)
> +{
> +	return container_of(ced, struct epit_timer, ced);
> +}
> +
> +static inline void epit_irq_disable(struct epit_timer *epittm)
> +{
> +	u32 val;
> +
> +	val = readl_relaxed(epittm->base + EPITCR);
> +	writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
> +}
> +
> +static inline void epit_irq_enable(struct epit_timer *epittm)
> +{
> +	u32 val;
> +
> +	val = readl_relaxed(epittm->base + EPITCR);
> +	writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
> +}
> +
> +static void epit_irq_acknowledge(struct epit_timer *epittm)
> +{
> +	writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
> +}
> +
> +static u64 notrace epit_read_sched_clock(void)
> +{
> +	return ~readl_relaxed(sched_clock_reg);
> +}
> +
> +static int __init epit_clocksource_init(struct epit_timer *epittm)
> +{
> +	unsigned int c = clk_get_rate(epittm->clk_per);
> +
> +	sched_clock_reg = epittm->base + EPITCNR;
> +	sched_clock_register(epit_read_sched_clock, 32, c);
> +
> +	return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c, 200, 32,
> +			clocksource_mmio_readl_down);
> +}
> +

I would suggest to place epit_clocksource_init() function right before
epit_timer_init().

> +static int epit_set_next_event(unsigned long cycles,
> +			       struct clock_event_device *ced)
> +{
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +	unsigned long tcmp;
> +
> +	tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles;
> +	writel_relaxed(tcmp, epittm->base + EPITCMPR);
> +
> +	return 0;
> +}
> +
> +/* Left event sources disabled, no more interrupts appear */
> +static int epit_shutdown(struct clock_event_device *ced)
> +{
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +	unsigned long flags;
> +
> +	/*
> +	 * The timer interrupt generation is disabled at least
> +	 * for enough time to call epit_set_next_event()
> +	 */
> +	local_irq_save(flags);
> +
> +	/* Disable interrupt in EPIT module */
> +	epit_irq_disable(epittm);
> +
> +	/* Clear pending interrupt */
> +	epit_irq_acknowledge(epittm);
> +
> +	local_irq_restore(flags);
> +
> +	return 0;
> +}
> +
> +static int epit_set_oneshot(struct clock_event_device *ced)
> +{
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +	unsigned long flags;
> +
> +	/*
> +	 * The timer interrupt generation is disabled at least
> +	 * for enough time to call epit_set_next_event()
> +	 */
> +	local_irq_save(flags);
> +
> +	/* Disable interrupt in EPIT module */
> +	epit_irq_disable(epittm);
> +
> +	/* Clear pending interrupt, only while switching mode */
> +	if (!clockevent_state_oneshot(ced))
> +		epit_irq_acknowledge(epittm);
> +
> +	/*
> +	 * Do not put overhead of interrupt enable/disable into
> +	 * epit_set_next_event(), the core has about 4 minutes
> +	 * to call epit_set_next_event() or shutdown clock after
> +	 * mode switching
> +	 */
> +	epit_irq_enable(epittm);
> +	local_irq_restore(flags);
> +
> +	return 0;
> +}
> +
> +static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
> +{
> +	struct clock_event_device *ced = dev_id;
> +	struct epit_timer *epittm = to_epit_timer(ced);
> +
> +	epit_irq_acknowledge(epittm);
> +
> +	ced->event_handler(ced);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int __init epit_clockevent_init(struct epit_timer *epittm)
> +{
> +	struct clock_event_device *ced = &epittm->ced;
> +	struct irqaction *act = &epittm->act;
> +
> +	ced->name = "epit";
> +	ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
> +	ced->set_state_shutdown = epit_shutdown;
> +	ced->tick_resume = epit_shutdown;
> +	ced->set_state_oneshot = epit_set_oneshot;
> +	ced->set_next_event = epit_set_next_event;
> +	ced->rating = 200;
> +	ced->cpumask = cpumask_of(0);
> +	ced->irq = epittm->irq;
> +	clockevents_config_and_register(ced, clk_get_rate(epittm->clk_per),
> +		0xff, 0xfffffffe);

Please indent the wrapped line.

> +
> +	act->name = "i.MX EPIT Timer Tick",
> +	act->flags = IRQF_TIMER | IRQF_IRQPOLL;
> +	act->handler = epit_timer_interrupt;
> +	act->dev_id = ced;
> +
> +	/* Make irqs happen */
> +	return setup_irq(epittm->irq, act);
> +}
> +
> +static int __init epit_timer_init(struct device_node *np)
> +{
> +	struct epit_timer *epittm;
> +	struct clk *clk_ipg;
> +	int ret;
> +
> +	epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
> +	if (!epittm)
> +		return -ENOMEM;
> +
> +	epittm->base = of_iomap(np, 0);
> +	if (!epittm->base) {
> +		ret = -ENXIO;
> +		goto out_kfree;
> +	}
> +
> +	epittm->irq = irq_of_parse_and_map(np, 0);
> +	if (!epittm->irq) {
> +		ret = -EINVAL;
> +		goto out_iounmap;
> +	}
> +
> +	clk_ipg = of_clk_get_by_name(np, "ipg");
> +	if (IS_ERR(clk_ipg)) {
> +		pr_err("i.MX EPIT: unable to get clk_ipg\n");
> +		ret = PTR_ERR(clk_ipg);
> +		goto out_iounmap;
> +	}
> +
> +	ret = clk_prepare_enable(clk_ipg);
> +	if (ret) {
> +		pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> +		goto out_clk_ipg_disable;
> +	}
> +
> +	epittm->clk_per = of_clk_get_by_name(np, "per");
> +	if (IS_ERR(epittm->clk_per)) {
> +		pr_err("i.MX EPIT: unable to get clk_per\n");
> +		ret = PTR_ERR(epittm->clk_per);
> +		goto out_clk_ipg_disable;
> +	}
> +
> +	ret = clk_prepare_enable(epittm->clk_per);
> +	if (ret) {
> +		pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
> +		goto out_clk_ipg_disable;
> +	}
> +
> +	/* Initialise to a known state (all timers off, and timing reset) */
> +	writel_relaxed(0x0, epittm->base + EPITCR);
> +	writel_relaxed(0xffffffff, epittm->base + EPITLR);
> +	writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
> +		       epittm->base + EPITCR);
> +
> +	ret = epit_clocksource_init(epittm);
> +	if(ret) {

Add a space before left parenthesis.

> +		pr_err("i.MX EPIT: failed to init clocksource\n");
> +		goto out_clk_per_disable;
> +	}
> +
> +	ret = epit_clockevent_init(epittm);
> +	if(ret) {

Add a space before left parenthesis.

> +		pr_err("i.MX EPIT: failed to init clockevent\n");
> +		goto out_clk_per_disable;
> +	}
> +
> +	return 0;
> +
> +out_clk_per_disable:
> +	clk_disable_unprepare(epittm->clk_per);
> +out_clk_ipg_disable:
> +	clk_disable_unprepare(clk_ipg);
> +out_iounmap:
> +	iounmap(epittm->base);
> +out_kfree:
> +	kfree(epittm);
> +
> +	return ret;
> +}
> +TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
> 

Here "fsl,imx31-epit" would be way better than "fsl,imx6q-epit", please
fix it in the documentation as well.

--
With best wishes,
Vladimir

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

* Re: [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
  2018-05-29 17:04   ` Clément Péron
  (?)
@ 2018-05-30  7:27     ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  7:27 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, linux-arm-kernel,
	devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam

Hi Clément,

On 05/29/2018 08:04 PM, Clément Péron wrote:
> From: Clément Peron <clement.peron@devialet.com>
> 
> Add devicetree binding document for NXP's i.MX SoC specific
> EPIT timer driver.
> 
> Signed-off-by: Clément Peron <clement.peron@devialet.com>
> ---
>  .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
> new file mode 100644
> index 000000000000..a84a60c6ae35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt

The file should be renamed to a more generic name like 'imx,epit.txt'
or 'imx31,epit.txt'.

Also note that the folder is incorrectly selected, it must be
Documentation/devicetree/bindings/timer/

> @@ -0,0 +1,24 @@
> +Binding for the i.MX6 EPIT timer

Let's change it to 'Binding for the i.MX EPIT timer'.

> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties:
> +- compatible: should be "fsl,imx6q-epit"

Compatible should be "fsl,imx31-epit", i.MX31 SoC seems to be the first
one in the series, which has the timer module.

There should be added more compatibles specific to later SoC versions.

> +- reg: physical base address of the controller and length of memory mapped
> +  region.
> +- interrupts: Should contain EPIT controller interrupt
> +- clocks: list of clock specifiers, must contain an entry for each required
> +  entry in clock-names
> +- clock-names : should include entries "ipg", "per"
> +
> +Example:
> +	epit1: epit@20d0000 {
> +		compatible = "fsl,imx6q-epit";

For i.MX6Q example a list of compatibles should be updated like

	compatible = "fsl,imx6q-epit", "fsl,imx31-epit";

> +		reg = <0x020d0000 0x4000>;
> +		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&clks IMX6QDL_CLK_EPIT1>,
> +			<&clks IMX6QDL_CLK_IPG_PER>;
> +		clock-names = "ipg", "per";

It looks like "ipg" and "per" clocks are swapped, please double check it.

> +	};
> 

--
With best wishes,
Vladimir

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
@ 2018-05-30  7:27     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  7:27 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, linux-arm-kernel,
	devicetree, linux-clk
  Cc: Fabio Estevam, Sascha Hauer, Rob Herring, NXP Linux Team,
	Pengutronix Kernel Team, Clément Peron

Hi Clément,

On 05/29/2018 08:04 PM, Clément Péron wrote:
> From: Clément Peron <clement.peron@devialet.com>
> 
> Add devicetree binding document for NXP's i.MX SoC specific
> EPIT timer driver.
> 
> Signed-off-by: Clément Peron <clement.peron@devialet.com>
> ---
>  .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
> new file mode 100644
> index 000000000000..a84a60c6ae35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt

The file should be renamed to a more generic name like 'imx,epit.txt'
or 'imx31,epit.txt'.

Also note that the folder is incorrectly selected, it must be
Documentation/devicetree/bindings/timer/

> @@ -0,0 +1,24 @@
> +Binding for the i.MX6 EPIT timer

Let's change it to 'Binding for the i.MX EPIT timer'.

> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties:
> +- compatible: should be "fsl,imx6q-epit"

Compatible should be "fsl,imx31-epit", i.MX31 SoC seems to be the first
one in the series, which has the timer module.

There should be added more compatibles specific to later SoC versions.

> +- reg: physical base address of the controller and length of memory mapped
> +  region.
> +- interrupts: Should contain EPIT controller interrupt
> +- clocks: list of clock specifiers, must contain an entry for each required
> +  entry in clock-names
> +- clock-names : should include entries "ipg", "per"
> +
> +Example:
> +	epit1: epit@20d0000 {
> +		compatible = "fsl,imx6q-epit";

For i.MX6Q example a list of compatibles should be updated like

	compatible = "fsl,imx6q-epit", "fsl,imx31-epit";

> +		reg = <0x020d0000 0x4000>;
> +		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&clks IMX6QDL_CLK_EPIT1>,
> +			<&clks IMX6QDL_CLK_IPG_PER>;
> +		clock-names = "ipg", "per";

It looks like "ipg" and "per" clocks are swapped, please double check it.

> +	};
> 

--
With best wishes,
Vladimir

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

* [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
@ 2018-05-30  7:27     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  7:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Cl?ment,

On 05/29/2018 08:04 PM, Cl?ment P?ron wrote:
> From: Cl?ment Peron <clement.peron@devialet.com>
> 
> Add devicetree binding document for NXP's i.MX SoC specific
> EPIT timer driver.
> 
> Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> ---
>  .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
> new file mode 100644
> index 000000000000..a84a60c6ae35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt

The file should be renamed to a more generic name like 'imx,epit.txt'
or 'imx31,epit.txt'.

Also note that the folder is incorrectly selected, it must be
Documentation/devicetree/bindings/timer/

> @@ -0,0 +1,24 @@
> +Binding for the i.MX6 EPIT timer

Let's change it to 'Binding for the i.MX EPIT timer'.

> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties:
> +- compatible: should be "fsl,imx6q-epit"

Compatible should be "fsl,imx31-epit", i.MX31 SoC seems to be the first
one in the series, which has the timer module.

There should be added more compatibles specific to later SoC versions.

> +- reg: physical base address of the controller and length of memory mapped
> +  region.
> +- interrupts: Should contain EPIT controller interrupt
> +- clocks: list of clock specifiers, must contain an entry for each required
> +  entry in clock-names
> +- clock-names : should include entries "ipg", "per"
> +
> +Example:
> +	epit1: epit at 20d0000 {
> +		compatible = "fsl,imx6q-epit";

For i.MX6Q example a list of compatibles should be updated like

	compatible = "fsl,imx6q-epit", "fsl,imx31-epit";

> +		reg = <0x020d0000 0x4000>;
> +		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&clks IMX6QDL_CLK_EPIT1>,
> +			<&clks IMX6QDL_CLK_IPG_PER>;
> +		clock-names = "ipg", "per";

It looks like "ipg" and "per" clocks are swapped, please double check it.

> +	};
> 

--
With best wishes,
Vladimir

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

* Re: [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
  2018-05-30  7:27     ` Vladimir Zapolskiy
  (?)
@ 2018-05-30  7:38       ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  7:38 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, linux-arm-kernel,
	devicetree, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam

On 05/30/2018 10:27 AM, Vladimir Zapolskiy wrote:
> Hi Clément,
> 
> On 05/29/2018 08:04 PM, Clément Péron wrote:
>> From: Clément Peron <clement.peron@devialet.com>
>>
>> Add devicetree binding document for NXP's i.MX SoC specific
>> EPIT timer driver.
>>
>> Signed-off-by: Clément Peron <clement.peron@devialet.com>
>> ---
>>  .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
>>  1 file changed, 24 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
>> new file mode 100644
>> index 000000000000..a84a60c6ae35
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
> 
> The file should be renamed to a more generic name like 'imx,epit.txt'
> or 'imx31,epit.txt'.
> 
> Also note that the folder is incorrectly selected, it must be
> Documentation/devicetree/bindings/timer/
> 

And linux-clk mailing list for publishing seems to be improper one,
instead please add Daniel Lezcano <daniel.lezcano@linaro.org> and
Thomas Gleixner <tglx@linutronix.de> to the list of addressees,
and the proper mailing list address is linux-kernel@vger.kernel.org

--
With best wishes,
Vladimir

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
@ 2018-05-30  7:38       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  7:38 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, linux-arm-kernel,
	devicetree, linux-clk
  Cc: Fabio Estevam, Sascha Hauer, Rob Herring, NXP Linux Team,
	Pengutronix Kernel Team, Clément Peron

On 05/30/2018 10:27 AM, Vladimir Zapolskiy wrote:
> Hi Clément,
> 
> On 05/29/2018 08:04 PM, Clément Péron wrote:
>> From: Clément Peron <clement.peron@devialet.com>
>>
>> Add devicetree binding document for NXP's i.MX SoC specific
>> EPIT timer driver.
>>
>> Signed-off-by: Clément Peron <clement.peron@devialet.com>
>> ---
>>  .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
>>  1 file changed, 24 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
>> new file mode 100644
>> index 000000000000..a84a60c6ae35
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
> 
> The file should be renamed to a more generic name like 'imx,epit.txt'
> or 'imx31,epit.txt'.
> 
> Also note that the folder is incorrectly selected, it must be
> Documentation/devicetree/bindings/timer/
> 

And linux-clk mailing list for publishing seems to be improper one,
instead please add Daniel Lezcano <daniel.lezcano@linaro.org> and
Thomas Gleixner <tglx@linutronix.de> to the list of addressees,
and the proper mailing list address is linux-kernel@vger.kernel.org

--
With best wishes,
Vladimir

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

* [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding
@ 2018-05-30  7:38       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 36+ messages in thread
From: Vladimir Zapolskiy @ 2018-05-30  7:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/30/2018 10:27 AM, Vladimir Zapolskiy wrote:
> Hi Cl?ment,
> 
> On 05/29/2018 08:04 PM, Cl?ment P?ron wrote:
>> From: Cl?ment Peron <clement.peron@devialet.com>
>>
>> Add devicetree binding document for NXP's i.MX SoC specific
>> EPIT timer driver.
>>
>> Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
>> ---
>>  .../devicetree/bindings/clock/imx6q,epit.txt  | 24 +++++++++++++++++++
>>  1 file changed, 24 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/imx6q,epit.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/imx6q,epit.txt b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
>> new file mode 100644
>> index 000000000000..a84a60c6ae35
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/imx6q,epit.txt
> 
> The file should be renamed to a more generic name like 'imx,epit.txt'
> or 'imx31,epit.txt'.
> 
> Also note that the folder is incorrectly selected, it must be
> Documentation/devicetree/bindings/timer/
> 

And linux-clk mailing list for publishing seems to be improper one,
instead please add Daniel Lezcano <daniel.lezcano@linaro.org> and
Thomas Gleixner <tglx@linutronix.de> to the list of addressees,
and the proper mailing list address is linux-kernel at vger.kernel.org

--
With best wishes,
Vladimir

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

* Re: [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
  2018-05-30  6:56     ` Vladimir Zapolskiy
  (?)
@ 2018-05-30  9:53       ` Clément PERON
  -1 siblings, 0 replies; 36+ messages in thread
From: Clément PERON @ 2018-05-30  9:53 UTC (permalink / raw)
  To: vladimir_zapolskiy
  Cc: devicetree, robh, Colin Didier, s.hauer, Clément Péron,
	linux-imx, kernel, fabio.estevam, linux-clk, linux-arm-kernel

Hi Vladimir,

Le mer. 30 mai 2018 à 08:56, Vladimir Zapolskiy <
vladimir_zapolskiy@mentor.com> a écrit :

> Hi Clément,

> please find some more review comments.

> On 05/29/2018 08:04 PM, Clément Péron wrote:
> > From: Colin Didier <colin.didier@devialet.com>
> >
> > Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.
> >
> > Signed-off-by: Colin Didier <colin.didier@devialet.com>
> > Signed-off-by: Clément Peron <clement.peron@devialet.com>
> > ---
> >  drivers/clocksource/Kconfig          |  12 ++
> >  drivers/clocksource/Makefile         |   1 +
> >  drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
> >  3 files changed, 296 insertions(+)
> >  create mode 100644 drivers/clocksource/timer-imx-epit.c
> >
> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> > index 8e8a09755d10..920a0874f3a4 100644
> > --- a/drivers/clocksource/Kconfig
> > +++ b/drivers/clocksource/Kconfig
> > @@ -576,6 +576,18 @@ config H8300_TPU
> >         This enables the clocksource for the H8300 platform with the
> >         H8S2678 cpu.
> >
> > +config CLKSRC_IMX_EPIT
> > +     bool "Clocksource using i.MX EPIT"
> > +     depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC ||
COMPILE_TEST)

> Here 'depends on ARM' can be removed, because ARCH_MXC implies it.

> Also ARCH_MXC implies ARCH_MULTIPLATFORM, which implies USE_OF in turn,
> so I would say that the following line is correct, sorry about a previous
> comment asking to add an explicit OF dependency:

>          depends on CLKDEV_LOOKUP && (ARCH_MXC || COMPILE_TEST)

> However most of the clocksource drivers follow 'bool "..." if
COMPILE_TEST'
> pattern, and it might be preferable to maintainers.

Usually, the timer driver are selected in the arch Kconfig. But in this
case,
we want to keep the i.MX GPT except if the user explicitly select the i.MX
EPIT.
With the "if COMPILE_TEST" the user can't choose it.


> > +     select TIMER_OF

> The driver does not have this dependency.

> > +     select CLKSRC_MMIO
> > +     help
> > +       This enables EPIT support available on some i.MX platforms.
> > +       Normally you don't have a reason to do so as the EPIT has
> > +       the same features and uses the same clocks as the GPT.
> > +       Anyway, on some systems the GPT may be in use for other
> > +       purposes.
> > +
> >  config CLKSRC_IMX_GPT
> >       bool "Clocksource using i.MX GPT" if COMPILE_TEST
> >       depends on ARM && CLKDEV_LOOKUP
> > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> > index 00caf37e52f9..d9426f69ec69 100644
> > --- a/drivers/clocksource/Makefile
> > +++ b/drivers/clocksource/Makefile
> > @@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)   +=
timer-integrator-ap.o
> >  obj-$(CONFIG_CLKSRC_VERSATILE)               += versatile.o
> >  obj-$(CONFIG_CLKSRC_MIPS_GIC)                += mips-gic-timer.o
> >  obj-$(CONFIG_CLKSRC_TANGO_XTAL)              += tango_xtal.o
> > +obj-$(CONFIG_CLKSRC_IMX_EPIT)                += timer-imx-epit.o
> >  obj-$(CONFIG_CLKSRC_IMX_GPT)         += timer-imx-gpt.o
> >  obj-$(CONFIG_CLKSRC_IMX_TPM)         += timer-imx-tpm.o
> >  obj-$(CONFIG_ASM9260_TIMER)          += asm9260_timer.o
> > diff --git a/drivers/clocksource/timer-imx-epit.c
b/drivers/clocksource/timer-imx-epit.c
> > new file mode 100644
> > index 000000000000..87025d5f3a97
> > --- /dev/null
> > +++ b/drivers/clocksource/timer-imx-epit.c
> > @@ -0,0 +1,283 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * i.MX EPIT Timer
> > + *
> > + * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
> > + * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
> > + * Copyright (C) 2018 Clément Péron <clement.peron@devialet.com>
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clockchips.h>
> > +#include <linux/err.h>

> The include above can be dropped.

> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>

> The include above can be dropped.

> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of.h>

> The include above can be dropped.

> > +#include <linux/sched_clock.h>
> > +#include <linux/slab.h>
> > +
> > +#define EPITCR                               0x00
> > +#define EPITSR                               0x04
> > +#define EPITLR                               0x08
> > +#define EPITCMPR                     0x0c
> > +#define EPITCNR                              0x10
> > +
> > +#define EPITCR_EN                    BIT(0)
> > +#define EPITCR_ENMOD                 BIT(1)
> > +#define EPITCR_OCIEN                 BIT(2)
> > +#define EPITCR_RLD                   BIT(3)
> > +#define EPITCR_PRESC(x)                      (((x) & 0xfff) << 4)
> > +#define EPITCR_SWR                   BIT(16)
> > +#define EPITCR_IOVW                  BIT(17)
> > +#define EPITCR_DBGEN                 BIT(18)
> > +#define EPITCR_WAITEN                        BIT(19)
> > +#define EPITCR_RES                   BIT(20)
> > +#define EPITCR_STOPEN                        BIT(21)
> > +#define EPITCR_OM_DISCON             (0 << 22)
> > +#define EPITCR_OM_TOGGLE             (1 << 22)
> > +#define EPITCR_OM_CLEAR                      (2 << 22)
> > +#define EPITCR_OM_SET                        (3 << 22)
> > +#define EPITCR_CLKSRC_OFF            (0 << 24)
> > +#define EPITCR_CLKSRC_PERIPHERAL     (1 << 24)
> > +#define EPITCR_CLKSRC_REF_HIGH               (2 << 24)
> > +#define EPITCR_CLKSRC_REF_LOW                (3 << 24)
> > +
> > +#define EPITSR_OCIF                  BIT(0)
> > +
> > +struct epit_timer {
> > +     void __iomem *base;
> > +     int irq;
> > +     struct clk *clk_per;
> > +     struct clock_event_device ced;
> > +     struct irqaction act;
> > +};
> > +
> > +static void __iomem *sched_clock_reg;
> > +
> > +static inline struct epit_timer *to_epit_timer(struct
clock_event_device *ced)
> > +{
> > +     return container_of(ced, struct epit_timer, ced);
> > +}
> > +
> > +static inline void epit_irq_disable(struct epit_timer *epittm)
> > +{
> > +     u32 val;
> > +
> > +     val = readl_relaxed(epittm->base + EPITCR);
> > +     writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
> > +}
> > +
> > +static inline void epit_irq_enable(struct epit_timer *epittm)
> > +{
> > +     u32 val;
> > +
> > +     val = readl_relaxed(epittm->base + EPITCR);
> > +     writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
> > +}
> > +
> > +static void epit_irq_acknowledge(struct epit_timer *epittm)
> > +{
> > +     writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
> > +}
> > +
> > +static u64 notrace epit_read_sched_clock(void)
> > +{
> > +     return ~readl_relaxed(sched_clock_reg);
> > +}
> > +
> > +static int __init epit_clocksource_init(struct epit_timer *epittm)
> > +{
> > +     unsigned int c = clk_get_rate(epittm->clk_per);
> > +
> > +     sched_clock_reg = epittm->base + EPITCNR;
> > +     sched_clock_register(epit_read_sched_clock, 32, c);
> > +
> > +     return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c,
200, 32,
> > +                     clocksource_mmio_readl_down);
> > +}
> > +

> I would suggest to place epit_clocksource_init() function right before
> epit_timer_init().

> > +static int epit_set_next_event(unsigned long cycles,
> > +                            struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +     unsigned long tcmp;
> > +
> > +     tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles;
> > +     writel_relaxed(tcmp, epittm->base + EPITCMPR);
> > +
> > +     return 0;
> > +}
> > +
> > +/* Left event sources disabled, no more interrupts appear */
> > +static int epit_shutdown(struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +     unsigned long flags;
> > +
> > +     /*
> > +      * The timer interrupt generation is disabled at least
> > +      * for enough time to call epit_set_next_event()
> > +      */
> > +     local_irq_save(flags);
> > +
> > +     /* Disable interrupt in EPIT module */
> > +     epit_irq_disable(epittm);
> > +
> > +     /* Clear pending interrupt */
> > +     epit_irq_acknowledge(epittm);
> > +
> > +     local_irq_restore(flags);
> > +
> > +     return 0;
> > +}
> > +
> > +static int epit_set_oneshot(struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +     unsigned long flags;
> > +
> > +     /*
> > +      * The timer interrupt generation is disabled at least
> > +      * for enough time to call epit_set_next_event()
> > +      */
> > +     local_irq_save(flags);
> > +
> > +     /* Disable interrupt in EPIT module */
> > +     epit_irq_disable(epittm);
> > +
> > +     /* Clear pending interrupt, only while switching mode */
> > +     if (!clockevent_state_oneshot(ced))
> > +             epit_irq_acknowledge(epittm);
> > +
> > +     /*
> > +      * Do not put overhead of interrupt enable/disable into
> > +      * epit_set_next_event(), the core has about 4 minutes
> > +      * to call epit_set_next_event() or shutdown clock after
> > +      * mode switching
> > +      */
> > +     epit_irq_enable(epittm);
> > +     local_irq_restore(flags);
> > +
> > +     return 0;
> > +}
> > +
> > +static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
> > +{
> > +     struct clock_event_device *ced = dev_id;
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +
> > +     epit_irq_acknowledge(epittm);
> > +
> > +     ced->event_handler(ced);
> > +
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +static int __init epit_clockevent_init(struct epit_timer *epittm)
> > +{
> > +     struct clock_event_device *ced = &epittm->ced;
> > +     struct irqaction *act = &epittm->act;
> > +
> > +     ced->name = "epit";
> > +     ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
> > +     ced->set_state_shutdown = epit_shutdown;
> > +     ced->tick_resume = epit_shutdown;
> > +     ced->set_state_oneshot = epit_set_oneshot;
> > +     ced->set_next_event = epit_set_next_event;
> > +     ced->rating = 200;
> > +     ced->cpumask = cpumask_of(0);
> > +     ced->irq = epittm->irq;
> > +     clockevents_config_and_register(ced,
clk_get_rate(epittm->clk_per),
> > +             0xff, 0xfffffffe);

> Please indent the wrapped line.

> > +
> > +     act->name = "i.MX EPIT Timer Tick",
> > +     act->flags = IRQF_TIMER | IRQF_IRQPOLL;
> > +     act->handler = epit_timer_interrupt;
> > +     act->dev_id = ced;
> > +
> > +     /* Make irqs happen */
> > +     return setup_irq(epittm->irq, act);
> > +}
> > +
> > +static int __init epit_timer_init(struct device_node *np)
> > +{
> > +     struct epit_timer *epittm;
> > +     struct clk *clk_ipg;
> > +     int ret;
> > +
> > +     epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
> > +     if (!epittm)
> > +             return -ENOMEM;
> > +
> > +     epittm->base = of_iomap(np, 0);
> > +     if (!epittm->base) {
> > +             ret = -ENXIO;
> > +             goto out_kfree;
> > +     }
> > +
> > +     epittm->irq = irq_of_parse_and_map(np, 0);
> > +     if (!epittm->irq) {
> > +             ret = -EINVAL;
> > +             goto out_iounmap;
> > +     }
> > +
> > +     clk_ipg = of_clk_get_by_name(np, "ipg");
> > +     if (IS_ERR(clk_ipg)) {
> > +             pr_err("i.MX EPIT: unable to get clk_ipg\n");
> > +             ret = PTR_ERR(clk_ipg);
> > +             goto out_iounmap;
> > +     }
> > +
> > +     ret = clk_prepare_enable(clk_ipg);
> > +     if (ret) {
> > +             pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     epittm->clk_per = of_clk_get_by_name(np, "per");
> > +     if (IS_ERR(epittm->clk_per)) {
> > +             pr_err("i.MX EPIT: unable to get clk_per\n");
> > +             ret = PTR_ERR(epittm->clk_per);
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     ret = clk_prepare_enable(epittm->clk_per);
> > +     if (ret) {
> > +             pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     /* Initialise to a known state (all timers off, and timing reset)
*/
> > +     writel_relaxed(0x0, epittm->base + EPITCR);
> > +     writel_relaxed(0xffffffff, epittm->base + EPITLR);
> > +     writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
> > +                    epittm->base + EPITCR);
> > +
> > +     ret = epit_clocksource_init(epittm);
> > +     if(ret) {

> Add a space before left parenthesis.

> > +             pr_err("i.MX EPIT: failed to init clocksource\n");
> > +             goto out_clk_per_disable;
> > +     }
> > +
> > +     ret = epit_clockevent_init(epittm);
> > +     if(ret) {

> Add a space before left parenthesis.

> > +             pr_err("i.MX EPIT: failed to init clockevent\n");
> > +             goto out_clk_per_disable;
> > +     }
> > +
> > +     return 0;
> > +
> > +out_clk_per_disable:
> > +     clk_disable_unprepare(epittm->clk_per);
> > +out_clk_ipg_disable:
> > +     clk_disable_unprepare(clk_ipg);
> > +out_iounmap:
> > +     iounmap(epittm->base);
> > +out_kfree:
> > +     kfree(epittm);
> > +
> > +     return ret;
> > +}
> > +TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
> >

> Here "fsl,imx31-epit" would be way better than "fsl,imx6q-epit", please
> fix it in the documentation as well.

> --
> With best wishes,
> Vladimir


Thanks for your review,
Clement

-- 
https://www.devialet.com/buy-phantom <https://www.devialet.com/buy-phantom>



- Confidential -

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-30  9:53       ` Clément PERON
  0 siblings, 0 replies; 36+ messages in thread
From: Clément PERON @ 2018-05-30  9:53 UTC (permalink / raw)
  To: vladimir_zapolskiy
  Cc: Clément Péron, Colin Didier, linux-arm-kernel,
	devicetree, linux-clk, fabio.estevam, s.hauer, robh, linux-imx,
	kernel

Hi Vladimir,

Le mer. 30 mai 2018 =C3=A0 08:56, Vladimir Zapolskiy <
vladimir_zapolskiy@mentor.com> a =C3=A9crit :

> Hi Cl=C3=A9ment,

> please find some more review comments.

> On 05/29/2018 08:04 PM, Cl=C3=A9ment P=C3=A9ron wrote:
> > From: Colin Didier <colin.didier@devialet.com>
> >
> > Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.
> >
> > Signed-off-by: Colin Didier <colin.didier@devialet.com>
> > Signed-off-by: Cl=C3=A9ment Peron <clement.peron@devialet.com>
> > ---
> >  drivers/clocksource/Kconfig          |  12 ++
> >  drivers/clocksource/Makefile         |   1 +
> >  drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
> >  3 files changed, 296 insertions(+)
> >  create mode 100644 drivers/clocksource/timer-imx-epit.c
> >
> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> > index 8e8a09755d10..920a0874f3a4 100644
> > --- a/drivers/clocksource/Kconfig
> > +++ b/drivers/clocksource/Kconfig
> > @@ -576,6 +576,18 @@ config H8300_TPU
> >         This enables the clocksource for the H8300 platform with the
> >         H8S2678 cpu.
> >
> > +config CLKSRC_IMX_EPIT
> > +     bool "Clocksource using i.MX EPIT"
> > +     depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC ||
COMPILE_TEST)

> Here 'depends on ARM' can be removed, because ARCH_MXC implies it.

> Also ARCH_MXC implies ARCH_MULTIPLATFORM, which implies USE_OF in turn,
> so I would say that the following line is correct, sorry about a previous
> comment asking to add an explicit OF dependency:

>          depends on CLKDEV_LOOKUP && (ARCH_MXC || COMPILE_TEST)

> However most of the clocksource drivers follow 'bool "..." if
COMPILE_TEST'
> pattern, and it might be preferable to maintainers.

Usually, the timer driver are selected in the arch Kconfig. But in this
case,
we want to keep the i.MX GPT except if the user explicitly select the i.MX
EPIT.
With the "if COMPILE_TEST" the user can't choose it.


> > +     select TIMER_OF

> The driver does not have this dependency.

> > +     select CLKSRC_MMIO
> > +     help
> > +       This enables EPIT support available on some i.MX platforms.
> > +       Normally you don't have a reason to do so as the EPIT has
> > +       the same features and uses the same clocks as the GPT.
> > +       Anyway, on some systems the GPT may be in use for other
> > +       purposes.
> > +
> >  config CLKSRC_IMX_GPT
> >       bool "Clocksource using i.MX GPT" if COMPILE_TEST
> >       depends on ARM && CLKDEV_LOOKUP
> > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefil=
e
> > index 00caf37e52f9..d9426f69ec69 100644
> > --- a/drivers/clocksource/Makefile
> > +++ b/drivers/clocksource/Makefile
> > @@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)   +=3D
timer-integrator-ap.o
> >  obj-$(CONFIG_CLKSRC_VERSATILE)               +=3D versatile.o
> >  obj-$(CONFIG_CLKSRC_MIPS_GIC)                +=3D mips-gic-timer.o
> >  obj-$(CONFIG_CLKSRC_TANGO_XTAL)              +=3D tango_xtal.o
> > +obj-$(CONFIG_CLKSRC_IMX_EPIT)                +=3D timer-imx-epit.o
> >  obj-$(CONFIG_CLKSRC_IMX_GPT)         +=3D timer-imx-gpt.o
> >  obj-$(CONFIG_CLKSRC_IMX_TPM)         +=3D timer-imx-tpm.o
> >  obj-$(CONFIG_ASM9260_TIMER)          +=3D asm9260_timer.o
> > diff --git a/drivers/clocksource/timer-imx-epit.c
b/drivers/clocksource/timer-imx-epit.c
> > new file mode 100644
> > index 000000000000..87025d5f3a97
> > --- /dev/null
> > +++ b/drivers/clocksource/timer-imx-epit.c
> > @@ -0,0 +1,283 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * i.MX EPIT Timer
> > + *
> > + * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
> > + * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
> > + * Copyright (C) 2018 Cl=C3=A9ment P=C3=A9ron <clement.peron@devialet.=
com>
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clockchips.h>
> > +#include <linux/err.h>

> The include above can be dropped.

> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>

> The include above can be dropped.

> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of.h>

> The include above can be dropped.

> > +#include <linux/sched_clock.h>
> > +#include <linux/slab.h>
> > +
> > +#define EPITCR                               0x00
> > +#define EPITSR                               0x04
> > +#define EPITLR                               0x08
> > +#define EPITCMPR                     0x0c
> > +#define EPITCNR                              0x10
> > +
> > +#define EPITCR_EN                    BIT(0)
> > +#define EPITCR_ENMOD                 BIT(1)
> > +#define EPITCR_OCIEN                 BIT(2)
> > +#define EPITCR_RLD                   BIT(3)
> > +#define EPITCR_PRESC(x)                      (((x) & 0xfff) << 4)
> > +#define EPITCR_SWR                   BIT(16)
> > +#define EPITCR_IOVW                  BIT(17)
> > +#define EPITCR_DBGEN                 BIT(18)
> > +#define EPITCR_WAITEN                        BIT(19)
> > +#define EPITCR_RES                   BIT(20)
> > +#define EPITCR_STOPEN                        BIT(21)
> > +#define EPITCR_OM_DISCON             (0 << 22)
> > +#define EPITCR_OM_TOGGLE             (1 << 22)
> > +#define EPITCR_OM_CLEAR                      (2 << 22)
> > +#define EPITCR_OM_SET                        (3 << 22)
> > +#define EPITCR_CLKSRC_OFF            (0 << 24)
> > +#define EPITCR_CLKSRC_PERIPHERAL     (1 << 24)
> > +#define EPITCR_CLKSRC_REF_HIGH               (2 << 24)
> > +#define EPITCR_CLKSRC_REF_LOW                (3 << 24)
> > +
> > +#define EPITSR_OCIF                  BIT(0)
> > +
> > +struct epit_timer {
> > +     void __iomem *base;
> > +     int irq;
> > +     struct clk *clk_per;
> > +     struct clock_event_device ced;
> > +     struct irqaction act;
> > +};
> > +
> > +static void __iomem *sched_clock_reg;
> > +
> > +static inline struct epit_timer *to_epit_timer(struct
clock_event_device *ced)
> > +{
> > +     return container_of(ced, struct epit_timer, ced);
> > +}
> > +
> > +static inline void epit_irq_disable(struct epit_timer *epittm)
> > +{
> > +     u32 val;
> > +
> > +     val =3D readl_relaxed(epittm->base + EPITCR);
> > +     writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
> > +}
> > +
> > +static inline void epit_irq_enable(struct epit_timer *epittm)
> > +{
> > +     u32 val;
> > +
> > +     val =3D readl_relaxed(epittm->base + EPITCR);
> > +     writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
> > +}
> > +
> > +static void epit_irq_acknowledge(struct epit_timer *epittm)
> > +{
> > +     writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
> > +}
> > +
> > +static u64 notrace epit_read_sched_clock(void)
> > +{
> > +     return ~readl_relaxed(sched_clock_reg);
> > +}
> > +
> > +static int __init epit_clocksource_init(struct epit_timer *epittm)
> > +{
> > +     unsigned int c =3D clk_get_rate(epittm->clk_per);
> > +
> > +     sched_clock_reg =3D epittm->base + EPITCNR;
> > +     sched_clock_register(epit_read_sched_clock, 32, c);
> > +
> > +     return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c,
200, 32,
> > +                     clocksource_mmio_readl_down);
> > +}
> > +

> I would suggest to place epit_clocksource_init() function right before
> epit_timer_init().

> > +static int epit_set_next_event(unsigned long cycles,
> > +                            struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm =3D to_epit_timer(ced);
> > +     unsigned long tcmp;
> > +
> > +     tcmp =3D readl_relaxed(epittm->base + EPITCNR) - cycles;
> > +     writel_relaxed(tcmp, epittm->base + EPITCMPR);
> > +
> > +     return 0;
> > +}
> > +
> > +/* Left event sources disabled, no more interrupts appear */
> > +static int epit_shutdown(struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm =3D to_epit_timer(ced);
> > +     unsigned long flags;
> > +
> > +     /*
> > +      * The timer interrupt generation is disabled at least
> > +      * for enough time to call epit_set_next_event()
> > +      */
> > +     local_irq_save(flags);
> > +
> > +     /* Disable interrupt in EPIT module */
> > +     epit_irq_disable(epittm);
> > +
> > +     /* Clear pending interrupt */
> > +     epit_irq_acknowledge(epittm);
> > +
> > +     local_irq_restore(flags);
> > +
> > +     return 0;
> > +}
> > +
> > +static int epit_set_oneshot(struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm =3D to_epit_timer(ced);
> > +     unsigned long flags;
> > +
> > +     /*
> > +      * The timer interrupt generation is disabled at least
> > +      * for enough time to call epit_set_next_event()
> > +      */
> > +     local_irq_save(flags);
> > +
> > +     /* Disable interrupt in EPIT module */
> > +     epit_irq_disable(epittm);
> > +
> > +     /* Clear pending interrupt, only while switching mode */
> > +     if (!clockevent_state_oneshot(ced))
> > +             epit_irq_acknowledge(epittm);
> > +
> > +     /*
> > +      * Do not put overhead of interrupt enable/disable into
> > +      * epit_set_next_event(), the core has about 4 minutes
> > +      * to call epit_set_next_event() or shutdown clock after
> > +      * mode switching
> > +      */
> > +     epit_irq_enable(epittm);
> > +     local_irq_restore(flags);
> > +
> > +     return 0;
> > +}
> > +
> > +static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
> > +{
> > +     struct clock_event_device *ced =3D dev_id;
> > +     struct epit_timer *epittm =3D to_epit_timer(ced);
> > +
> > +     epit_irq_acknowledge(epittm);
> > +
> > +     ced->event_handler(ced);
> > +
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +static int __init epit_clockevent_init(struct epit_timer *epittm)
> > +{
> > +     struct clock_event_device *ced =3D &epittm->ced;
> > +     struct irqaction *act =3D &epittm->act;
> > +
> > +     ced->name =3D "epit";
> > +     ced->features =3D CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
> > +     ced->set_state_shutdown =3D epit_shutdown;
> > +     ced->tick_resume =3D epit_shutdown;
> > +     ced->set_state_oneshot =3D epit_set_oneshot;
> > +     ced->set_next_event =3D epit_set_next_event;
> > +     ced->rating =3D 200;
> > +     ced->cpumask =3D cpumask_of(0);
> > +     ced->irq =3D epittm->irq;
> > +     clockevents_config_and_register(ced,
clk_get_rate(epittm->clk_per),
> > +             0xff, 0xfffffffe);

> Please indent the wrapped line.

> > +
> > +     act->name =3D "i.MX EPIT Timer Tick",
> > +     act->flags =3D IRQF_TIMER | IRQF_IRQPOLL;
> > +     act->handler =3D epit_timer_interrupt;
> > +     act->dev_id =3D ced;
> > +
> > +     /* Make irqs happen */
> > +     return setup_irq(epittm->irq, act);
> > +}
> > +
> > +static int __init epit_timer_init(struct device_node *np)
> > +{
> > +     struct epit_timer *epittm;
> > +     struct clk *clk_ipg;
> > +     int ret;
> > +
> > +     epittm =3D kzalloc(sizeof(*epittm), GFP_KERNEL);
> > +     if (!epittm)
> > +             return -ENOMEM;
> > +
> > +     epittm->base =3D of_iomap(np, 0);
> > +     if (!epittm->base) {
> > +             ret =3D -ENXIO;
> > +             goto out_kfree;
> > +     }
> > +
> > +     epittm->irq =3D irq_of_parse_and_map(np, 0);
> > +     if (!epittm->irq) {
> > +             ret =3D -EINVAL;
> > +             goto out_iounmap;
> > +     }
> > +
> > +     clk_ipg =3D of_clk_get_by_name(np, "ipg");
> > +     if (IS_ERR(clk_ipg)) {
> > +             pr_err("i.MX EPIT: unable to get clk_ipg\n");
> > +             ret =3D PTR_ERR(clk_ipg);
> > +             goto out_iounmap;
> > +     }
> > +
> > +     ret =3D clk_prepare_enable(clk_ipg);
> > +     if (ret) {
> > +             pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     epittm->clk_per =3D of_clk_get_by_name(np, "per");
> > +     if (IS_ERR(epittm->clk_per)) {
> > +             pr_err("i.MX EPIT: unable to get clk_per\n");
> > +             ret =3D PTR_ERR(epittm->clk_per);
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     ret =3D clk_prepare_enable(epittm->clk_per);
> > +     if (ret) {
> > +             pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     /* Initialise to a known state (all timers off, and timing reset)
*/
> > +     writel_relaxed(0x0, epittm->base + EPITCR);
> > +     writel_relaxed(0xffffffff, epittm->base + EPITLR);
> > +     writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN=
,
> > +                    epittm->base + EPITCR);
> > +
> > +     ret =3D epit_clocksource_init(epittm);
> > +     if(ret) {

> Add a space before left parenthesis.

> > +             pr_err("i.MX EPIT: failed to init clocksource\n");
> > +             goto out_clk_per_disable;
> > +     }
> > +
> > +     ret =3D epit_clockevent_init(epittm);
> > +     if(ret) {

> Add a space before left parenthesis.

> > +             pr_err("i.MX EPIT: failed to init clockevent\n");
> > +             goto out_clk_per_disable;
> > +     }
> > +
> > +     return 0;
> > +
> > +out_clk_per_disable:
> > +     clk_disable_unprepare(epittm->clk_per);
> > +out_clk_ipg_disable:
> > +     clk_disable_unprepare(clk_ipg);
> > +out_iounmap:
> > +     iounmap(epittm->base);
> > +out_kfree:
> > +     kfree(epittm);
> > +
> > +     return ret;
> > +}
> > +TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
> >

> Here "fsl,imx31-epit" would be way better than "fsl,imx6q-epit", please
> fix it in the documentation as well.

> --
> With best wishes,
> Vladimir


Thanks for your review,
Clement

--=20
https://www.devialet.com/buy-phantom <https://www.devialet.com/buy-phantom>



- Confidential -

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

* [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer
@ 2018-05-30  9:53       ` Clément PERON
  0 siblings, 0 replies; 36+ messages in thread
From: Clément PERON @ 2018-05-30  9:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vladimir,

Le mer. 30 mai 2018 ? 08:56, Vladimir Zapolskiy <
vladimir_zapolskiy@mentor.com> a ?crit :

> Hi Cl?ment,

> please find some more review comments.

> On 05/29/2018 08:04 PM, Cl?ment P?ron wrote:
> > From: Colin Didier <colin.didier@devialet.com>
> >
> > Add driver for NXP's EPIT timer used in i.MX 6 family of SoC.
> >
> > Signed-off-by: Colin Didier <colin.didier@devialet.com>
> > Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> > ---
> >  drivers/clocksource/Kconfig          |  12 ++
> >  drivers/clocksource/Makefile         |   1 +
> >  drivers/clocksource/timer-imx-epit.c | 283 +++++++++++++++++++++++++++
> >  3 files changed, 296 insertions(+)
> >  create mode 100644 drivers/clocksource/timer-imx-epit.c
> >
> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> > index 8e8a09755d10..920a0874f3a4 100644
> > --- a/drivers/clocksource/Kconfig
> > +++ b/drivers/clocksource/Kconfig
> > @@ -576,6 +576,18 @@ config H8300_TPU
> >         This enables the clocksource for the H8300 platform with the
> >         H8S2678 cpu.
> >
> > +config CLKSRC_IMX_EPIT
> > +     bool "Clocksource using i.MX EPIT"
> > +     depends on ARM && CLKDEV_LOOKUP && OF && (ARCH_MXC ||
COMPILE_TEST)

> Here 'depends on ARM' can be removed, because ARCH_MXC implies it.

> Also ARCH_MXC implies ARCH_MULTIPLATFORM, which implies USE_OF in turn,
> so I would say that the following line is correct, sorry about a previous
> comment asking to add an explicit OF dependency:

>          depends on CLKDEV_LOOKUP && (ARCH_MXC || COMPILE_TEST)

> However most of the clocksource drivers follow 'bool "..." if
COMPILE_TEST'
> pattern, and it might be preferable to maintainers.

Usually, the timer driver are selected in the arch Kconfig. But in this
case,
we want to keep the i.MX GPT except if the user explicitly select the i.MX
EPIT.
With the "if COMPILE_TEST" the user can't choose it.


> > +     select TIMER_OF

> The driver does not have this dependency.

> > +     select CLKSRC_MMIO
> > +     help
> > +       This enables EPIT support available on some i.MX platforms.
> > +       Normally you don't have a reason to do so as the EPIT has
> > +       the same features and uses the same clocks as the GPT.
> > +       Anyway, on some systems the GPT may be in use for other
> > +       purposes.
> > +
> >  config CLKSRC_IMX_GPT
> >       bool "Clocksource using i.MX GPT" if COMPILE_TEST
> >       depends on ARM && CLKDEV_LOOKUP
> > diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> > index 00caf37e52f9..d9426f69ec69 100644
> > --- a/drivers/clocksource/Makefile
> > +++ b/drivers/clocksource/Makefile
> > @@ -69,6 +69,7 @@ obj-$(CONFIG_INTEGRATOR_AP_TIMER)   +=
timer-integrator-ap.o
> >  obj-$(CONFIG_CLKSRC_VERSATILE)               += versatile.o
> >  obj-$(CONFIG_CLKSRC_MIPS_GIC)                += mips-gic-timer.o
> >  obj-$(CONFIG_CLKSRC_TANGO_XTAL)              += tango_xtal.o
> > +obj-$(CONFIG_CLKSRC_IMX_EPIT)                += timer-imx-epit.o
> >  obj-$(CONFIG_CLKSRC_IMX_GPT)         += timer-imx-gpt.o
> >  obj-$(CONFIG_CLKSRC_IMX_TPM)         += timer-imx-tpm.o
> >  obj-$(CONFIG_ASM9260_TIMER)          += asm9260_timer.o
> > diff --git a/drivers/clocksource/timer-imx-epit.c
b/drivers/clocksource/timer-imx-epit.c
> > new file mode 100644
> > index 000000000000..87025d5f3a97
> > --- /dev/null
> > +++ b/drivers/clocksource/timer-imx-epit.c
> > @@ -0,0 +1,283 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * i.MX EPIT Timer
> > + *
> > + * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
> > + * Copyright (C) 2018 Colin Didier <colin.didier@devialet.com>
> > + * Copyright (C) 2018 Cl?ment P?ron <clement.peron@devialet.com>
> > + */
> > +
> > +#include <linux/clk.h>
> > +#include <linux/clockchips.h>
> > +#include <linux/err.h>

> The include above can be dropped.

> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>

> The include above can be dropped.

> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of.h>

> The include above can be dropped.

> > +#include <linux/sched_clock.h>
> > +#include <linux/slab.h>
> > +
> > +#define EPITCR                               0x00
> > +#define EPITSR                               0x04
> > +#define EPITLR                               0x08
> > +#define EPITCMPR                     0x0c
> > +#define EPITCNR                              0x10
> > +
> > +#define EPITCR_EN                    BIT(0)
> > +#define EPITCR_ENMOD                 BIT(1)
> > +#define EPITCR_OCIEN                 BIT(2)
> > +#define EPITCR_RLD                   BIT(3)
> > +#define EPITCR_PRESC(x)                      (((x) & 0xfff) << 4)
> > +#define EPITCR_SWR                   BIT(16)
> > +#define EPITCR_IOVW                  BIT(17)
> > +#define EPITCR_DBGEN                 BIT(18)
> > +#define EPITCR_WAITEN                        BIT(19)
> > +#define EPITCR_RES                   BIT(20)
> > +#define EPITCR_STOPEN                        BIT(21)
> > +#define EPITCR_OM_DISCON             (0 << 22)
> > +#define EPITCR_OM_TOGGLE             (1 << 22)
> > +#define EPITCR_OM_CLEAR                      (2 << 22)
> > +#define EPITCR_OM_SET                        (3 << 22)
> > +#define EPITCR_CLKSRC_OFF            (0 << 24)
> > +#define EPITCR_CLKSRC_PERIPHERAL     (1 << 24)
> > +#define EPITCR_CLKSRC_REF_HIGH               (2 << 24)
> > +#define EPITCR_CLKSRC_REF_LOW                (3 << 24)
> > +
> > +#define EPITSR_OCIF                  BIT(0)
> > +
> > +struct epit_timer {
> > +     void __iomem *base;
> > +     int irq;
> > +     struct clk *clk_per;
> > +     struct clock_event_device ced;
> > +     struct irqaction act;
> > +};
> > +
> > +static void __iomem *sched_clock_reg;
> > +
> > +static inline struct epit_timer *to_epit_timer(struct
clock_event_device *ced)
> > +{
> > +     return container_of(ced, struct epit_timer, ced);
> > +}
> > +
> > +static inline void epit_irq_disable(struct epit_timer *epittm)
> > +{
> > +     u32 val;
> > +
> > +     val = readl_relaxed(epittm->base + EPITCR);
> > +     writel_relaxed(val & ~EPITCR_OCIEN, epittm->base + EPITCR);
> > +}
> > +
> > +static inline void epit_irq_enable(struct epit_timer *epittm)
> > +{
> > +     u32 val;
> > +
> > +     val = readl_relaxed(epittm->base + EPITCR);
> > +     writel_relaxed(val | EPITCR_OCIEN, epittm->base + EPITCR);
> > +}
> > +
> > +static void epit_irq_acknowledge(struct epit_timer *epittm)
> > +{
> > +     writel_relaxed(EPITSR_OCIF, epittm->base + EPITSR);
> > +}
> > +
> > +static u64 notrace epit_read_sched_clock(void)
> > +{
> > +     return ~readl_relaxed(sched_clock_reg);
> > +}
> > +
> > +static int __init epit_clocksource_init(struct epit_timer *epittm)
> > +{
> > +     unsigned int c = clk_get_rate(epittm->clk_per);
> > +
> > +     sched_clock_reg = epittm->base + EPITCNR;
> > +     sched_clock_register(epit_read_sched_clock, 32, c);
> > +
> > +     return clocksource_mmio_init(epittm->base + EPITCNR, "epit", c,
200, 32,
> > +                     clocksource_mmio_readl_down);
> > +}
> > +

> I would suggest to place epit_clocksource_init() function right before
> epit_timer_init().

> > +static int epit_set_next_event(unsigned long cycles,
> > +                            struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +     unsigned long tcmp;
> > +
> > +     tcmp = readl_relaxed(epittm->base + EPITCNR) - cycles;
> > +     writel_relaxed(tcmp, epittm->base + EPITCMPR);
> > +
> > +     return 0;
> > +}
> > +
> > +/* Left event sources disabled, no more interrupts appear */
> > +static int epit_shutdown(struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +     unsigned long flags;
> > +
> > +     /*
> > +      * The timer interrupt generation is disabled at least
> > +      * for enough time to call epit_set_next_event()
> > +      */
> > +     local_irq_save(flags);
> > +
> > +     /* Disable interrupt in EPIT module */
> > +     epit_irq_disable(epittm);
> > +
> > +     /* Clear pending interrupt */
> > +     epit_irq_acknowledge(epittm);
> > +
> > +     local_irq_restore(flags);
> > +
> > +     return 0;
> > +}
> > +
> > +static int epit_set_oneshot(struct clock_event_device *ced)
> > +{
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +     unsigned long flags;
> > +
> > +     /*
> > +      * The timer interrupt generation is disabled at least
> > +      * for enough time to call epit_set_next_event()
> > +      */
> > +     local_irq_save(flags);
> > +
> > +     /* Disable interrupt in EPIT module */
> > +     epit_irq_disable(epittm);
> > +
> > +     /* Clear pending interrupt, only while switching mode */
> > +     if (!clockevent_state_oneshot(ced))
> > +             epit_irq_acknowledge(epittm);
> > +
> > +     /*
> > +      * Do not put overhead of interrupt enable/disable into
> > +      * epit_set_next_event(), the core has about 4 minutes
> > +      * to call epit_set_next_event() or shutdown clock after
> > +      * mode switching
> > +      */
> > +     epit_irq_enable(epittm);
> > +     local_irq_restore(flags);
> > +
> > +     return 0;
> > +}
> > +
> > +static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
> > +{
> > +     struct clock_event_device *ced = dev_id;
> > +     struct epit_timer *epittm = to_epit_timer(ced);
> > +
> > +     epit_irq_acknowledge(epittm);
> > +
> > +     ced->event_handler(ced);
> > +
> > +     return IRQ_HANDLED;
> > +}
> > +
> > +static int __init epit_clockevent_init(struct epit_timer *epittm)
> > +{
> > +     struct clock_event_device *ced = &epittm->ced;
> > +     struct irqaction *act = &epittm->act;
> > +
> > +     ced->name = "epit";
> > +     ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
> > +     ced->set_state_shutdown = epit_shutdown;
> > +     ced->tick_resume = epit_shutdown;
> > +     ced->set_state_oneshot = epit_set_oneshot;
> > +     ced->set_next_event = epit_set_next_event;
> > +     ced->rating = 200;
> > +     ced->cpumask = cpumask_of(0);
> > +     ced->irq = epittm->irq;
> > +     clockevents_config_and_register(ced,
clk_get_rate(epittm->clk_per),
> > +             0xff, 0xfffffffe);

> Please indent the wrapped line.

> > +
> > +     act->name = "i.MX EPIT Timer Tick",
> > +     act->flags = IRQF_TIMER | IRQF_IRQPOLL;
> > +     act->handler = epit_timer_interrupt;
> > +     act->dev_id = ced;
> > +
> > +     /* Make irqs happen */
> > +     return setup_irq(epittm->irq, act);
> > +}
> > +
> > +static int __init epit_timer_init(struct device_node *np)
> > +{
> > +     struct epit_timer *epittm;
> > +     struct clk *clk_ipg;
> > +     int ret;
> > +
> > +     epittm = kzalloc(sizeof(*epittm), GFP_KERNEL);
> > +     if (!epittm)
> > +             return -ENOMEM;
> > +
> > +     epittm->base = of_iomap(np, 0);
> > +     if (!epittm->base) {
> > +             ret = -ENXIO;
> > +             goto out_kfree;
> > +     }
> > +
> > +     epittm->irq = irq_of_parse_and_map(np, 0);
> > +     if (!epittm->irq) {
> > +             ret = -EINVAL;
> > +             goto out_iounmap;
> > +     }
> > +
> > +     clk_ipg = of_clk_get_by_name(np, "ipg");
> > +     if (IS_ERR(clk_ipg)) {
> > +             pr_err("i.MX EPIT: unable to get clk_ipg\n");
> > +             ret = PTR_ERR(clk_ipg);
> > +             goto out_iounmap;
> > +     }
> > +
> > +     ret = clk_prepare_enable(clk_ipg);
> > +     if (ret) {
> > +             pr_err("i.MX EPIT: unable to prepare+enable clk_ipg\n");
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     epittm->clk_per = of_clk_get_by_name(np, "per");
> > +     if (IS_ERR(epittm->clk_per)) {
> > +             pr_err("i.MX EPIT: unable to get clk_per\n");
> > +             ret = PTR_ERR(epittm->clk_per);
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     ret = clk_prepare_enable(epittm->clk_per);
> > +     if (ret) {
> > +             pr_err("i.MX EPIT: unable to prepare+enable clk_per\n");
> > +             goto out_clk_ipg_disable;
> > +     }
> > +
> > +     /* Initialise to a known state (all timers off, and timing reset)
*/
> > +     writel_relaxed(0x0, epittm->base + EPITCR);
> > +     writel_relaxed(0xffffffff, epittm->base + EPITLR);
> > +     writel_relaxed(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
> > +                    epittm->base + EPITCR);
> > +
> > +     ret = epit_clocksource_init(epittm);
> > +     if(ret) {

> Add a space before left parenthesis.

> > +             pr_err("i.MX EPIT: failed to init clocksource\n");
> > +             goto out_clk_per_disable;
> > +     }
> > +
> > +     ret = epit_clockevent_init(epittm);
> > +     if(ret) {

> Add a space before left parenthesis.

> > +             pr_err("i.MX EPIT: failed to init clockevent\n");
> > +             goto out_clk_per_disable;
> > +     }
> > +
> > +     return 0;
> > +
> > +out_clk_per_disable:
> > +     clk_disable_unprepare(epittm->clk_per);
> > +out_clk_ipg_disable:
> > +     clk_disable_unprepare(clk_ipg);
> > +out_iounmap:
> > +     iounmap(epittm->base);
> > +out_kfree:
> > +     kfree(epittm);
> > +
> > +     return ret;
> > +}
> > +TIMER_OF_DECLARE(mx6q_timer, "fsl,imx6q-epit", epit_timer_init);
> >

> Here "fsl,imx31-epit" would be way better than "fsl,imx6q-epit", please
> fix it in the documentation as well.

> --
> With best wishes,
> Vladimir


Thanks for your review,
Clement

-- 
https://www.devialet.com/buy-phantom <https://www.devialet.com/buy-phantom>



- Confidential -

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

* Re: [PATCH v3 2/5] clk: imx6: add EPIT clock support
  2018-05-29 17:04   ` Clément Péron
  (?)
@ 2018-06-02  2:19     ` Stephen Boyd
  -1 siblings, 0 replies; 36+ messages in thread
From: Stephen Boyd @ 2018-06-02  2:19 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, devicetree,
	linux-arm-kernel, linux-clk
  Cc: Rob Herring, Sascha Hauer, Clément Peron, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Vladimir Zapolskiy

Quoting Clément Péron (2018-05-29 10:04:33)
> From: Colin Didier <colin.didier@devialet.com>
> 
> Add EPIT clock support to the i.MX6Q clocking infrastructure.
> 
> Signed-off-by: Colin Didier <colin.didier@devialet.com>
> Signed-off-by: Clément Peron <clement.peron@devialet.com>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> ---

Applied to clk-next


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 2/5] clk: imx6: add EPIT clock support
@ 2018-06-02  2:19     ` Stephen Boyd
  0 siblings, 0 replies; 36+ messages in thread
From: Stephen Boyd @ 2018-06-02  2:19 UTC (permalink / raw)
  To: Clément Péron, Colin Didier, devicetree,
	linux-arm-kernel, linux-clk
  Cc: Fabio Estevam, Vladimir Zapolskiy, Sascha Hauer, Rob Herring,
	NXP Linux Team, Pengutronix Kernel Team, Clément Peron

Quoting Cl=C3=A9ment P=C3=A9ron (2018-05-29 10:04:33)
> From: Colin Didier <colin.didier@devialet.com>
> =

> Add EPIT clock support to the i.MX6Q clocking infrastructure.
> =

> Signed-off-by: Colin Didier <colin.didier@devialet.com>
> Signed-off-by: Cl=C3=A9ment Peron <clement.peron@devialet.com>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> ---

Applied to clk-next


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

* [PATCH v3 2/5] clk: imx6: add EPIT clock support
@ 2018-06-02  2:19     ` Stephen Boyd
  0 siblings, 0 replies; 36+ messages in thread
From: Stephen Boyd @ 2018-06-02  2:19 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Cl?ment P?ron (2018-05-29 10:04:33)
> From: Colin Didier <colin.didier@devialet.com>
> 
> Add EPIT clock support to the i.MX6Q clocking infrastructure.
> 
> Signed-off-by: Colin Didier <colin.didier@devialet.com>
> Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> ---

Applied to clk-next

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

end of thread, other threads:[~2018-06-02  2:19 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-29 17:04 [PATCH v3 0/5] Reintroduce i.MX EPIT Timer Clément Péron
2018-05-29 17:04 ` Clément Péron
2018-05-29 17:04 ` Clément Péron
2018-05-29 17:04 ` [PATCH v3 1/5] ARM: imx: remove inexistant EPIT timer init Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-29 17:04 ` [PATCH v3 2/5] clk: imx6: add EPIT clock support Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-06-02  2:19   ` Stephen Boyd
2018-06-02  2:19     ` Stephen Boyd
2018-06-02  2:19     ` Stephen Boyd
2018-05-29 17:04 ` [PATCH v3 3/5] Documentation: DT: add i.MX EPIT timer binding Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-30  7:27   ` Vladimir Zapolskiy
2018-05-30  7:27     ` Vladimir Zapolskiy
2018-05-30  7:27     ` Vladimir Zapolskiy
2018-05-30  7:38     ` Vladimir Zapolskiy
2018-05-30  7:38       ` Vladimir Zapolskiy
2018-05-30  7:38       ` Vladimir Zapolskiy
2018-05-29 17:04 ` [PATCH v3 4/5] clocksource: add driver for i.MX EPIT timer Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-29 18:16   ` Fabio Estevam
2018-05-29 18:16     ` Fabio Estevam
2018-05-29 18:16     ` Fabio Estevam
2018-05-30  6:56   ` Vladimir Zapolskiy
2018-05-30  6:56     ` Vladimir Zapolskiy
2018-05-30  6:56     ` Vladimir Zapolskiy
2018-05-30  9:53     ` Clément PERON
2018-05-30  9:53       ` Clément PERON
2018-05-30  9:53       ` Clément PERON
2018-05-29 17:04 ` [PATCH v3 5/5] ARM: dts: imx6qdl: add missing compatible and clock properties for EPIT Clément Péron
2018-05-29 17:04   ` Clément Péron
2018-05-29 17:04   ` Clément Péron

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.