All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs.
@ 2015-04-30 14:44 Shenwei Wang
  2015-04-30 14:44 ` [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init Shenwei Wang
                   ` (18 more replies)
  0 siblings, 19 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

There are 4 versions of the timer hardware on Freescale MXC hardware.
--Version 0: MX1/MXL
--Version 1: MX21, MX27.
--Version 2: MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0)
--Version 3: MX6DL, MX6SX, MX6Q(Rev1.1+)

This patch has removed the SoC related codes, and implemented the driver directly upon
the hardware timer IP version. The new timer driver has redesigned the
internal APIs, and limited the use of global variables as well.

As the new driver has become independent of the SoCs, it has
been moved from the directory arch/arm/mach-imx into the
directory drivers/clocksources.


Shenwei Wang (18):
  ARM: imx: Add a parameter to mxc_timer_init
  ARM: imx: Add the definitions for imx_timer and its versions
  ARM: imx: Add an array of timer IP block versions
  ARM: imx: Added one more parameter for mxc_clockevent_init
  ARM: imx: Added one more parameter for mxc_clocksource_init
  ARM: imx: New timer driver APIs based on IP block
  ARM: imx: Initialize the imx_timer structure
  ARM: imx: Reimplemented the _mxc_timer_init based on IP version
  ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt
  ARM: imx: Removed the SoC relating codes in mxc_set_mode
  ARM: imx: Enabled the unused parameter
  ARM: imx: Remove one global variable in mxc_clocksource_init
  ARM: imx: Removed the unused functions and variables
  ARM: imx: Removed the global variable "timer_base"
  ARM: imx: Remove the SoC relating codes in mxc_clockevent_init
  ARM: imx: Move the  variable clockevent_mode into mxc_set_mode
  ARM: imx: Codes clean up
  ARM: imx: Move time.c into drivers/clocksources

 arch/arm/mach-imx/Makefile      |   2 +-
 arch/arm/mach-imx/time.c        | 388 ---------------------------
 drivers/clk/imx/clk-imx1.c      |   3 +-
 drivers/clk/imx/clk-imx21.c     |   3 +-
 drivers/clk/imx/clk-imx27.c     |   3 +-
 drivers/clk/imx/clk-imx31.c     |   3 +-
 drivers/clk/imx/clk-imx35.c     |   5 +-
 drivers/clk/imx/clk.h           |   2 +-
 drivers/clocksource/Makefile    |   1 +
 drivers/clocksource/timer-gpt.c | 572 ++++++++++++++++++++++++++++++++++++++++
 10 files changed, 586 insertions(+), 396 deletions(-)
 delete mode 100644 arch/arm/mach-imx/time.c
 create mode 100644 drivers/clocksource/timer-gpt.c

--
1.9.1

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

* [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-05-14  8:02   ` Shawn Guo
  2015-04-30 14:44 ` [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its versions Shenwei Wang
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

A parameter of integer type is added to the function mxc_timer_init,
so that a user could have a way to tell the timer driver the version
of the timer IP block.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c    | 2 +-
 drivers/clk/imx/clk-imx1.c  | 3 ++-
 drivers/clk/imx/clk-imx21.c | 3 ++-
 drivers/clk/imx/clk-imx27.c | 3 ++-
 drivers/clk/imx/clk-imx31.c | 3 ++-
 drivers/clk/imx/clk-imx35.c | 5 +++--
 drivers/clk/imx/clk.h       | 2 +-
 7 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index b1698e1..eef6b66 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -346,7 +346,7 @@ static void __init _mxc_timer_init(int irq,
 	setup_irq(irq, &mxc_timer_irq);
 }
 
-void __init mxc_timer_init(unsigned long pbase, int irq)
+void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
 {
 	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
 	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c
index c9812db..49534d8 100644
--- a/drivers/clk/imx/clk-imx1.c
+++ b/drivers/clk/imx/clk-imx1.c
@@ -102,7 +102,8 @@ int __init mx1_clocks_init(unsigned long fref)
 	clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0");
 	clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0");
 
-	mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT);
+	/*Timer version in MX1 is V0*/
+	mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, 0);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
index 0ca842c..08aa048 100644
--- a/drivers/clk/imx/clk-imx21.c
+++ b/drivers/clk/imx/clk-imx21.c
@@ -156,7 +156,8 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
 	clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
 	clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
 
-	mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1);
+	/*Timer version in MX21 is v1*/
+	mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, 1);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
index df2dfc0..f00a7c0 100644
--- a/drivers/clk/imx/clk-imx27.c
+++ b/drivers/clk/imx/clk-imx27.c
@@ -233,7 +233,8 @@ int __init mx27_clocks_init(unsigned long fref)
 	clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0");
 	clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0");
 
-	mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1);
+	/*Timer version in MX27 is v1*/
+	mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, 1);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
index a55290c..7c4a025 100644
--- a/drivers/clk/imx/clk-imx31.c
+++ b/drivers/clk/imx/clk-imx31.c
@@ -198,7 +198,8 @@ int __init mx31_clocks_init(unsigned long fref)
 	mx31_revision();
 	clk_disable_unprepare(clk[iim_gate]);
 
-	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT);
+	/*Timer version in MX31 is v2*/
+	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, 2);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
index 133fda1..a796c1e 100644
--- a/drivers/clk/imx/clk-imx35.c
+++ b/drivers/clk/imx/clk-imx35.c
@@ -145,7 +145,7 @@ int __init mx35_clocks_init(void)
 	clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
 
 	clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel));
-	clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */ 
+	clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
 	clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
 
 	clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
@@ -296,7 +296,8 @@ int __init mx35_clocks_init(void)
 #ifdef CONFIG_MXC_USE_EPIT
 	epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
 #else
-	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT);
+	/*Timer version in MX35 is v2*/
+	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, 2);
 #endif
 
 	return 0;
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 6bae537..06da84a 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -11,7 +11,7 @@ extern spinlock_t imx_ccm_lock;
  * mxc_timer_init() to initialize timer for non-DT boot.  It can be removed
  * when these legacy non-DT support is converted or dropped.
  */
-void mxc_timer_init(unsigned long pbase, int irq);
+void mxc_timer_init(unsigned long pbase, int irq, int);
 
 void imx_check_clocks(struct clk *clks[], unsigned int count);
 
-- 
1.9.1

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

* [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its versions
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
  2015-04-30 14:44 ` [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-05-15  1:18   ` Shawn Guo
  2015-04-30 14:44 ` [PATCH 03/18] ARM: imx: Add an array of timer IP block versions Shenwei Wang
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

A struct was added to describe the imx hardware timers.
Added four macros to define the imx timer version.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index eef6b66..5df3c53 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -81,6 +81,21 @@
 #define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
 #define timer_is_v2()	(!timer_is_v1())
 
+#define IMX_TIMER_V0         (0)
+#define IMX_TIMER_V1         (1)
+#define IMX_TIMER_V2         (2)
+#define IMX_TIMER_V3         (3)
+
+struct imx_timer {
+	void __iomem *timer_base;
+	int version;
+	struct clock_event_device evt;
+	struct irqaction act;
+	void (*gpt_irq_enable)(struct imx_timer *);
+	void (*gpt_irq_disable)(struct imx_timer *);
+	void (*gpt_irq_acknowledge)(struct imx_timer *);
+};
+
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
-- 
1.9.1

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

* [PATCH 03/18] ARM: imx: Add an array of timer IP block versions
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
  2015-04-30 14:44 ` [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init Shenwei Wang
  2015-04-30 14:44 ` [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its versions Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-05-15  1:33   ` Shawn Guo
  2015-04-30 14:44 ` [PATCH 04/18] ARM: imx: Added one more parameter for mxc_clockevent_init Shenwei Wang
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Added an array to record the relationship between the
compatible string and the version of timer IP block.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 5df3c53..f44c2aa 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -372,6 +372,23 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
 	_mxc_timer_init(irq, clk_per, clk_ipg);
 }
 
+struct imx_timer_ip_combo {
+	const char      *compat;
+	int             version;
+};
+
+static const struct imx_timer_ip_combo imx_timer_tables[] = {
+	{"fsl,imx1-gpt",        IMX_TIMER_V0},
+	{"fsl,imx25-gpt",       IMX_TIMER_V2},
+	{"fsl,imx25-gpt",       IMX_TIMER_V2},
+	{"fsl,imx50-gpt",       IMX_TIMER_V2},
+	{"fsl,imx51-gpt",       IMX_TIMER_V2},
+	{"fsl,imx53-gpt",       IMX_TIMER_V2},
+	{"fsl,imx6q-gpt",       IMX_TIMER_V2},
+	{"fsl,imx6sl-gpt",      IMX_TIMER_V3},
+	{"fsl,imx6sx-gpt",      IMX_TIMER_V3},
+};
+
 static void __init mxc_timer_init_dt(struct device_node *np)
 {
 	struct clk *clk_per, *clk_ipg;
-- 
1.9.1

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

* [PATCH 04/18] ARM: imx: Added one more parameter for mxc_clockevent_init
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (2 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 03/18] ARM: imx: Add an array of timer IP block versions Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 05/18] ARM: imx: Added one more parameter for mxc_clocksource_init Shenwei Wang
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

One more parameter was added for the function of
mxc_clockevent_init, so that we could remove the
global variables later.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index f44c2aa..f7403ab 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -299,7 +299,8 @@ static struct clock_event_device clockevent_mxc = {
 	.rating		= 200,
 };
 
-static int __init mxc_clockevent_init(struct clk *timer_clk)
+static int __init mxc_clockevent_init(struct clk *timer_clk,
+		struct imx_timer *tm)
 {
 	if (timer_is_v2())
 		clockevent_mxc.set_next_event = v2_set_next_event;
@@ -355,7 +356,7 @@ static void __init _mxc_timer_init(int irq,
 
 	/* init and register the timer to the framework */
 	mxc_clocksource_init(clk_per);
-	mxc_clockevent_init(clk_per);
+	mxc_clockevent_init(clk_per, 0);
 
 	/* Make irqs happen */
 	setup_irq(irq, &mxc_timer_irq);
-- 
1.9.1

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

* [PATCH 05/18] ARM: imx: Added one more parameter for mxc_clocksource_init
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (3 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 04/18] ARM: imx: Added one more parameter for mxc_clockevent_init Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 06/18] ARM: imx: New timer driver APIs based on IP block Shenwei Wang
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

One more parameter was added for the function of
mxc_clocksource_init, so that we could remove the
global variables later.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index f7403ab..4db233f 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -149,7 +149,8 @@ static unsigned long imx_read_current_timer(void)
 	return __raw_readl(sched_clock_reg);
 }
 
-static int __init mxc_clocksource_init(struct clk *timer_clk)
+static int __init mxc_clocksource_init(struct clk *timer_clk,
+				void __iomem *addr)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 	void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
@@ -355,7 +356,7 @@ static void __init _mxc_timer_init(int irq,
 	__raw_writel(tctl_val, timer_base + MXC_TCTL);
 
 	/* init and register the timer to the framework */
-	mxc_clocksource_init(clk_per);
+	mxc_clocksource_init(clk_per, 0);
 	mxc_clockevent_init(clk_per, 0);
 
 	/* Make irqs happen */
-- 
1.9.1

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

* [PATCH 06/18] ARM: imx: New timer driver APIs based on IP block
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (4 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 05/18] ARM: imx: Added one more parameter for mxc_clocksource_init Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-05-15  1:44   ` Shawn Guo
  2015-04-30 14:44 ` [PATCH 07/18] ARM: imx: Initialize the imx_timer structure Shenwei Wang
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Implemented the necessory imx timer driver APIs directly
based on the version of IP block. These APIs are only relating
to the version of the timer block, and are independent of
the SoC.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 4db233f..811d50a 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -101,6 +101,54 @@ static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
 static void __iomem *timer_base;
 
+static void gpt_irq_disable_v0_v1(struct imx_timer *tm)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readl(tm->timer_base + MXC_TCTL);
+	__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, tm->timer_base + MXC_TCTL);
+
+}
+
+static void gpt_irq_disable_v2_v3(struct imx_timer *tm)
+{
+	__raw_writel(0, tm->timer_base + V2_IR);
+
+}
+
+static void gpt_irq_enable_v0_v1(struct imx_timer *tm)
+{
+	__raw_writel(__raw_readl(tm->timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
+			tm->timer_base + MXC_TCTL);
+}
+
+static void gpt_irq_enable_v2_v3(struct imx_timer *tm)
+{
+	__raw_writel(1, tm->timer_base + V2_IR);
+}
+
+static void gpt_irq_acknowledge_v0(struct imx_timer *tm)
+{
+	__raw_readl(tm->timer_base + MX1_2_TSTAT);
+
+	__raw_writel(0, tm->timer_base + MX1_2_TSTAT);
+}
+
+static void gpt_irq_acknowledge_v1(struct imx_timer *tm)
+{
+	__raw_readl(tm->timer_base + MX1_2_TSTAT);
+
+	__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
+			tm->timer_base + MX1_2_TSTAT);
+}
+
+static void gpt_irq_acknowledge_v2_v3(struct imx_timer *tm)
+{
+	__raw_readl(tm->timer_base + V2_TSTAT);
+
+	__raw_writel(V2_TSTAT_OF1, tm->timer_base + V2_TSTAT);
+}
+
 static inline void gpt_irq_disable(void)
 {
 	unsigned int tmp;
@@ -314,6 +362,129 @@ static int __init mxc_clockevent_init(struct clk *timer_clk,
 	return 0;
 }
 
+static void __init _mxc_timer_init_v0_v1(int irq, struct clk *clk_per,
+		struct clk *clk_ipg, struct imx_timer *tm)
+{
+	uint32_t tctl_val;
+
+	if (IS_ERR(clk_per)) {
+		pr_err("i.MX timer: unable to get clk\n");
+		return;
+	}
+
+	if (!IS_ERR(clk_ipg))
+		clk_prepare_enable(clk_ipg);
+
+	clk_prepare_enable(clk_per);
+
+	/*
+	 * Initialise to a known state (all timers off, and timing reset)
+	 */
+
+	__raw_writel(0, tm->timer_base + MXC_TCTL);
+	__raw_writel(0, tm->timer_base + MXC_TPRER); /* see datasheet note */
+
+	tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
+
+	__raw_writel(tctl_val, tm->timer_base + MXC_TCTL);
+
+	/* init and register the timer to the framework */
+	mxc_clocksource_init(clk_per, tm->timer_base + MX1_2_TCN);
+
+	tm->evt.set_next_event = mx1_2_set_next_event;
+	mxc_clockevent_init(clk_per, tm);
+
+	/* Make irqs happen */
+	setup_irq(irq, &tm->act);
+}
+
+static void __init _mxc_timer_init_v2(int irq, struct clk *clk_per,
+		struct clk *clk_ipg, struct imx_timer *tm)
+{
+	uint32_t tctl_val;
+
+	if (IS_ERR(clk_per)) {
+		pr_err("i.MX timer: unable to get clk\n");
+		return;
+	}
+
+	if (!IS_ERR(clk_ipg))
+		clk_prepare_enable(clk_ipg);
+
+	clk_prepare_enable(clk_per);
+
+	/*
+	 * Initialise to a known state (all timers off, and timing reset)
+	 */
+
+	__raw_writel(0, tm->timer_base + MXC_TCTL);
+	__raw_writel(0, tm->timer_base + MXC_TPRER); /* see datasheet note */
+
+	tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+
+	if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8)
+		tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+	else
+		tctl_val |= V2_TCTL_CLK_PER;
+
+	__raw_writel(tctl_val, tm->timer_base + MXC_TCTL);
+
+	/* init and register the timer to the framework */
+	mxc_clocksource_init(clk_per, tm->timer_base + V2_TCN);
+
+	tm->evt.set_next_event = v2_set_next_event;
+	mxc_clockevent_init(clk_per, tm);
+
+	/* Make irqs happen */
+	setup_irq(irq, &tm->act);
+}
+
+static void __init _mxc_timer_init_v3(int irq, struct clk *clk_per,
+		struct clk *clk_ipg, struct imx_timer *tm)
+{
+	uint32_t tctl_val;
+
+	if (IS_ERR(clk_per)) {
+		pr_err("i.MX timer: unable to get clk\n");
+		return;
+	}
+
+	if (!IS_ERR(clk_ipg))
+		clk_prepare_enable(clk_ipg);
+
+	clk_prepare_enable(clk_per);
+
+	/*
+	 * Initialise to a known state (all timers off, and timing reset)
+	 */
+
+	__raw_writel(0, tm->timer_base + MXC_TCTL);
+	__raw_writel(0, tm->timer_base + MXC_TPRER); /* see datasheet note */
+
+	tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+
+	if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
+		tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+		/* 24 / 8 = 3 MHz */
+		__raw_writel(7 << V2_TPRER_PRE24M,
+					tm->timer_base + MXC_TPRER);
+		tctl_val |= V2_TCTL_24MEN;
+	} else {
+		tctl_val |= V2_TCTL_CLK_PER;
+	}
+
+	__raw_writel(tctl_val, tm->timer_base + MXC_TCTL);
+
+	/* init and register the timer to the framework */
+	mxc_clocksource_init(clk_per, tm->timer_base + V2_TCN);
+
+	tm->evt.set_next_event = v2_set_next_event;
+	mxc_clockevent_init(clk_per, tm);
+
+	/* Make irqs happen */
+	setup_irq(irq, &tm->act);
+}
+
 static void __init _mxc_timer_init(int irq,
 				   struct clk *clk_per, struct clk *clk_ipg)
 {
-- 
1.9.1

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

* [PATCH 07/18] ARM: imx: Initialize the imx_timer structure
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (5 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 06/18] ARM: imx: New timer driver APIs based on IP block Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-05-15  2:05   ` Shawn Guo
  2015-04-30 14:44 ` [PATCH 08/18] ARM: imx: Reimplemented the _mxc_timer_init based on IP version Shenwei Wang
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Initialized the imx_timer struct  in the following two functions:
mxc_timer_init
mxc_timer_init_dt

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 811d50a..451f761 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -31,6 +31,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/slab.h>
 
 #include <asm/mach/time.h>
 
@@ -536,12 +537,29 @@ static void __init _mxc_timer_init(int irq,
 
 void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
 {
+	struct imx_timer *timer;
 	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
 	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
 
 	timer_base = ioremap(pbase, SZ_4K);
 	BUG_ON(!timer_base);
 
+	timer = kzalloc(sizeof(struct imx_timer), GFP_KERNEL);
+	if (!timer)
+		panic("Can't allocate timer struct\n");
+
+	timer->timer_base = timer_base;
+	timer->version = ver;
+	timer->evt.name = "mxc_timer1";
+	timer->evt.rating = 200;
+	timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
+	timer->evt.set_mode = mxc_set_mode;
+	timer->evt.set_next_event = v2_set_next_event;
+	timer->act.name = "i.MX Timer Tick";
+	timer->act.flags = IRQF_TIMER | IRQF_IRQPOLL;
+	timer->act.dev_id = timer;
+	timer->act.handler = mxc_timer_interrupt;
+
 	_mxc_timer_init(irq, clk_per, clk_ipg);
 }
 
@@ -565,11 +583,34 @@ static const struct imx_timer_ip_combo imx_timer_tables[] = {
 static void __init mxc_timer_init_dt(struct device_node *np)
 {
 	struct clk *clk_per, *clk_ipg;
-	int irq;
+	int irq, i, ret, ver;
+	struct imx_timer *timer;
 
 	if (timer_base)
 		return;
 
+	for (i =  0; i < sizeof(imx_timer_tables) /
+			sizeof(struct imx_timer_ip_combo); i++) {
+		ret = of_device_is_compatible(np, imx_timer_tables[i].compat);
+		if (ret) {
+			ver = imx_timer_tables[i].version;
+			pr_err("<%s> compatible=%s timer_version=%d\r\n",
+				__func__, imx_timer_tables[i].compat, ver);
+			break;
+		}
+	}
+
+	if (!ret) {
+		pr_err("<%s> timer device node is not supported\r\n", __func__);
+		return;
+	}
+
+	timer = kzalloc(sizeof(struct imx_timer), GFP_KERNEL);
+	if (!timer)
+		panic("Can't allocate timer struct\n");
+
+	timer->timer_base = of_iomap(np, 0);
+
 	timer_base = of_iomap(np, 0);
 	WARN_ON(!timer_base);
 	irq = irq_of_parse_and_map(np, 0);
@@ -581,8 +622,20 @@ static void __init mxc_timer_init_dt(struct device_node *np)
 	if (IS_ERR(clk_per))
 		clk_per = of_clk_get_by_name(np, "per");
 
+	timer->version = ver;
+	timer->evt.name = np->name;
+	timer->evt.rating = 200;
+	timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
+	timer->evt.set_mode = mxc_set_mode;
+	timer->evt.set_next_event = v2_set_next_event;
+	timer->act.name = np->name;
+	timer->act.flags = IRQF_TIMER | IRQF_IRQPOLL;
+	timer->act.dev_id = timer;
+	timer->act.handler = mxc_timer_interrupt;
+
 	_mxc_timer_init(irq, clk_per, clk_ipg);
 }
+
 CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
 CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
 CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt);
-- 
1.9.1

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

* [PATCH 08/18] ARM: imx: Reimplemented the _mxc_timer_init based on IP version
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (6 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 07/18] ARM: imx: Initialize the imx_timer structure Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 09/18] ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt Shenwei Wang
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Reimplemented the function of _mxc_timer_init just based on the
version of timer IP block.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 75 +++++++++++++++++++++---------------------------
 1 file changed, 33 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 451f761..cf07401 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -486,53 +486,44 @@ static void __init _mxc_timer_init_v3(int irq, struct clk *clk_per,
 	setup_irq(irq, &tm->act);
 }
 
-static void __init _mxc_timer_init(int irq,
-				   struct clk *clk_per, struct clk *clk_ipg)
+static void __init _mxc_timer_init(int irq, struct clk *clk_per,
+		struct clk *clk_ipg, struct imx_timer *tm)
 {
-	uint32_t tctl_val;
-
-	if (IS_ERR(clk_per)) {
-		pr_err("i.MX timer: unable to get clk\n");
-		return;
-	}
 
-	if (!IS_ERR(clk_ipg))
-		clk_prepare_enable(clk_ipg);
-
-	clk_prepare_enable(clk_per);
+	switch (tm->version) {
+	case IMX_TIMER_V0:
+		tm->gpt_irq_enable = gpt_irq_enable_v0_v1;
+		tm->gpt_irq_disable = gpt_irq_disable_v0_v1;
+		tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v0;
+		_mxc_timer_init_v0_v1(irq, clk_per, clk_ipg, tm);
+		break;
 
-	/*
-	 * Initialise to a known state (all timers off, and timing reset)
-	 */
+	case IMX_TIMER_V1:
+		tm->gpt_irq_enable = gpt_irq_enable_v0_v1;
+		tm->gpt_irq_disable = gpt_irq_disable_v0_v1;
+		tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v1;
+		_mxc_timer_init_v0_v1(irq, clk_per, clk_ipg, tm);
+		break;
 
-	__raw_writel(0, timer_base + MXC_TCTL);
-	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
-
-	if (timer_is_v2()) {
-		tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
-		if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
-			tctl_val |= V2_TCTL_CLK_OSC_DIV8;
-			if (cpu_is_imx6dl() || cpu_is_imx6sx()) {
-				/* 24 / 8 = 3 MHz */
-				__raw_writel(7 << V2_TPRER_PRE24M,
-					timer_base + MXC_TPRER);
-				tctl_val |= V2_TCTL_24MEN;
-			}
-		} else {
-			tctl_val |= V2_TCTL_CLK_PER;
-		}
-	} else {
-		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
-	}
+	case IMX_TIMER_V2:
+		tm->gpt_irq_enable = gpt_irq_enable_v2_v3;
+		tm->gpt_irq_disable = gpt_irq_disable_v2_v3;
+		tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v2_v3;
+		_mxc_timer_init_v2(irq, clk_per, clk_ipg, tm);
+		break;
 
-	__raw_writel(tctl_val, timer_base + MXC_TCTL);
+	case IMX_TIMER_V3:
+		tm->gpt_irq_enable = gpt_irq_enable_v2_v3;
+		tm->gpt_irq_disable = gpt_irq_disable_v2_v3;
+		tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v2_v3;
+		_mxc_timer_init_v3(irq, clk_per, clk_ipg, tm);
+		break;
 
-	/* init and register the timer to the framework */
-	mxc_clocksource_init(clk_per, 0);
-	mxc_clockevent_init(clk_per, 0);
+	default:
+		pr_err("<%s> timer device node is not supported\r\n", __func__);
+		break;
 
-	/* Make irqs happen */
-	setup_irq(irq, &mxc_timer_irq);
+	}
 }
 
 void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
@@ -560,7 +551,7 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
 	timer->act.dev_id = timer;
 	timer->act.handler = mxc_timer_interrupt;
 
-	_mxc_timer_init(irq, clk_per, clk_ipg);
+	_mxc_timer_init(irq, clk_per, clk_ipg, timer);
 }
 
 struct imx_timer_ip_combo {
@@ -633,7 +624,7 @@ static void __init mxc_timer_init_dt(struct device_node *np)
 	timer->act.dev_id = timer;
 	timer->act.handler = mxc_timer_interrupt;
 
-	_mxc_timer_init(irq, clk_per, clk_ipg);
+	_mxc_timer_init(irq, clk_per, clk_ipg, timer);
 }
 
 CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
-- 
1.9.1

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

* [PATCH 09/18] ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (7 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 08/18] ARM: imx: Reimplemented the _mxc_timer_init based on IP version Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 10/18] ARM: imx: Removed the SoC relating codes in mxc_set_mode Shenwei Wang
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Removed the SoC relating codes in the function of
mxc_timer_interrupt.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index cf07401..e41bad9 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -320,17 +320,16 @@ static void mxc_set_mode(enum clock_event_mode mode,
  */
 static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = &clockevent_mxc;
-	uint32_t tstat;
+	struct imx_timer *tm = dev_id;
+	void (*event_handler)(struct clock_event_device *);
 
-	if (timer_is_v2())
-		tstat = __raw_readl(timer_base + V2_TSTAT);
-	else
-		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
+	BUG_ON(!tm);
 
-	gpt_irq_acknowledge();
+	tm->gpt_irq_acknowledge(tm);
 
-	evt->event_handler(evt);
+	event_handler = ACCESS_ONCE(tm->evt.event_handler);
+	if (event_handler)
+		event_handler(&tm->evt);
 
 	return IRQ_HANDLED;
 }
-- 
1.9.1

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

* [PATCH 10/18] ARM: imx: Removed the SoC relating codes in mxc_set_mode
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (8 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 09/18] ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 11/18] ARM: imx: Enabled the unused parameter Shenwei Wang
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Enabled the use of parameter *evt, and removed the SoC relating
codes in mxc_set_mode.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index e41bad9..ddbb3e7 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -258,6 +258,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
 				struct clock_event_device *evt)
 {
 	unsigned long flags;
+	struct imx_timer *tm = container_of(evt, struct imx_timer, evt);
 
 	/*
 	 * The timer interrupt generation is disabled at least
@@ -266,19 +267,14 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	local_irq_save(flags);
 
 	/* Disable interrupt in GPT module */
-	gpt_irq_disable();
+	tm->gpt_irq_disable(tm);
 
 	if (mode != clockevent_mode) {
 		/* Set event time into far-far future */
-		if (timer_is_v2())
-			__raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
-					timer_base + V2_TCMP);
-		else
-			__raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
-					timer_base + MX1_2_TCMP);
+		evt->set_next_event(-3, evt);
 
 		/* Clear pending interrupt */
-		gpt_irq_acknowledge();
+		tm->gpt_irq_acknowledge(tm);
 	}
 
 #ifdef DEBUG
@@ -304,7 +300,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	 * mode switching
 	 */
 		local_irq_save(flags);
-		gpt_irq_enable();
+		tm->gpt_irq_enable(tm);
 		local_irq_restore(flags);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
-- 
1.9.1

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

* [PATCH 11/18] ARM: imx: Enabled the unused parameter
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (9 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 10/18] ARM: imx: Removed the SoC relating codes in mxc_set_mode Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 12/18] ARM: imx: Remove one global variable in mxc_clocksource_init Shenwei Wang
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Enabled the unused parameter in the following two functions:
mx1_2_set_next_event
v2_set_next_event
and removed the use of the global variable of "timer_base".

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index ddbb3e7..b20ee80 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -218,29 +218,31 @@ static int __init mxc_clocksource_init(struct clk *timer_clk,
 /* clock event */
 
 static int mx1_2_set_next_event(unsigned long evt,
-			      struct clock_event_device *unused)
+			      struct clock_event_device *evt_dev)
 {
 	unsigned long tcmp;
+	struct imx_timer *tm = container_of(evt_dev, struct imx_timer, evt);
 
-	tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt;
+	tcmp = __raw_readl(tm->timer_base + MX1_2_TCN) + evt;
 
-	__raw_writel(tcmp, timer_base + MX1_2_TCMP);
+	__raw_writel(tcmp, tm->timer_base + MX1_2_TCMP);
 
-	return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ?
+	return (int)(tcmp - __raw_readl(tm->timer_base + MX1_2_TCN)) < 0 ?
 				-ETIME : 0;
 }
 
 static int v2_set_next_event(unsigned long evt,
-			      struct clock_event_device *unused)
+			      struct clock_event_device *evt_dev)
 {
 	unsigned long tcmp;
+	struct imx_timer *tm = container_of(evt_dev, struct imx_timer, evt);
 
-	tcmp = __raw_readl(timer_base + V2_TCN) + evt;
+	tcmp = __raw_readl(tm->timer_base + V2_TCN) + evt;
 
-	__raw_writel(tcmp, timer_base + V2_TCMP);
+	__raw_writel(tcmp, tm->timer_base + V2_TCMP);
 
 	return evt < 0x7fffffff &&
-		(int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
+		(int)(tcmp - __raw_readl(tm->timer_base + V2_TCN)) < 0 ?
 				-ETIME : 0;
 }
 
-- 
1.9.1

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

* [PATCH 12/18] ARM: imx: Remove one global variable in mxc_clocksource_init
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (10 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 11/18] ARM: imx: Enabled the unused parameter Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 13/18] ARM: imx: Removed the unused functions and variables Shenwei Wang
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Removed the use of global variable "timer_base" in the function of
mxc_clocksource_init, and get the register address from the
input parameter.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index b20ee80..4a6c625 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -202,16 +202,17 @@ static int __init mxc_clocksource_init(struct clk *timer_clk,
 				void __iomem *addr)
 {
 	unsigned int c = clk_get_rate(timer_clk);
-	void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
+
+	BUG_ON(!addr);
 
 	imx_delay_timer.read_current_timer = &imx_read_current_timer;
 	imx_delay_timer.freq = c;
 	register_current_timer_delay(&imx_delay_timer);
 
-	sched_clock_reg = reg;
+	sched_clock_reg = addr;
 
 	sched_clock_register(mxc_read_sched_clock, 32, c);
-	return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
+	return clocksource_mmio_init(addr, "mxc_timer1", c, 200, 32,
 			clocksource_mmio_readl_up);
 }
 
-- 
1.9.1

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

* [PATCH 13/18] ARM: imx: Removed the unused functions and variables
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (11 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 12/18] ARM: imx: Remove one global variable in mxc_clocksource_init Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 14/18] ARM: imx: Removed the global variable "timer_base" Shenwei Wang
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Removed the following unused functions which were related to SoC.
gpt_irq_disable(void)
gpt_irq_enable(void)
gpt_irq_acknowledge(void)

The following two global variables were removed:
irqaction mxc_timer_irq
clock_event_device clockevent_mxc

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 48 ------------------------------------------------
 1 file changed, 48 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 4a6c625..9a89bcf 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -150,40 +150,6 @@ static void gpt_irq_acknowledge_v2_v3(struct imx_timer *tm)
 	__raw_writel(V2_TSTAT_OF1, tm->timer_base + V2_TSTAT);
 }
 
-static inline void gpt_irq_disable(void)
-{
-	unsigned int tmp;
-
-	if (timer_is_v2())
-		__raw_writel(0, timer_base + V2_IR);
-	else {
-		tmp = __raw_readl(timer_base + MXC_TCTL);
-		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
-	}
-}
-
-static inline void gpt_irq_enable(void)
-{
-	if (timer_is_v2())
-		__raw_writel(1<<0, timer_base + V2_IR);
-	else {
-		__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
-			timer_base + MXC_TCTL);
-	}
-}
-
-static void gpt_irq_acknowledge(void)
-{
-	if (timer_is_v1()) {
-		if (cpu_is_mx1())
-			__raw_writel(0, timer_base + MX1_2_TSTAT);
-		else
-			__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
-				timer_base + MX1_2_TSTAT);
-	} else if (timer_is_v2())
-		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
-}
-
 static void __iomem *sched_clock_reg;
 
 static u64 notrace mxc_read_sched_clock(void)
@@ -333,20 +299,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static struct irqaction mxc_timer_irq = {
-	.name		= "i.MX Timer Tick",
-	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= mxc_timer_interrupt,
-};
-
-static struct clock_event_device clockevent_mxc = {
-	.name		= "mxc_timer1",
-	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= mxc_set_mode,
-	.set_next_event	= mx1_2_set_next_event,
-	.rating		= 200,
-};
-
 static int __init mxc_clockevent_init(struct clk *timer_clk,
 		struct imx_timer *tm)
 {
-- 
1.9.1

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

* [PATCH 14/18] ARM: imx: Removed the global variable "timer_base"
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (12 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 13/18] ARM: imx: Removed the unused functions and variables Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 15/18] ARM: imx: Remove the SoC relating codes in mxc_clockevent_init Shenwei Wang
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Removed the global variable "timer_base" by the
use of the input parameter.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 9a89bcf..29105ca 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -100,8 +100,6 @@ struct imx_timer {
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
-static void __iomem *timer_base;
-
 static void gpt_irq_disable_v0_v1(struct imx_timer *tm)
 {
 	unsigned int tmp;
@@ -482,14 +480,11 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
 	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
 	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
 
-	timer_base = ioremap(pbase, SZ_4K);
-	BUG_ON(!timer_base);
-
 	timer = kzalloc(sizeof(struct imx_timer), GFP_KERNEL);
 	if (!timer)
 		panic("Can't allocate timer struct\n");
 
-	timer->timer_base = timer_base;
+	timer->timer_base = (void __iomem *)pbase;
 	timer->version = ver;
 	timer->evt.name = "mxc_timer1";
 	timer->evt.rating = 200;
@@ -527,7 +522,7 @@ static void __init mxc_timer_init_dt(struct device_node *np)
 	int irq, i, ret, ver;
 	struct imx_timer *timer;
 
-	if (timer_base)
+	if (sched_clock_reg)
 		return;
 
 	for (i =  0; i < sizeof(imx_timer_tables) /
@@ -551,9 +546,8 @@ static void __init mxc_timer_init_dt(struct device_node *np)
 		panic("Can't allocate timer struct\n");
 
 	timer->timer_base = of_iomap(np, 0);
+	WARN_ON(!timer->timer_base || !ret);
 
-	timer_base = of_iomap(np, 0);
-	WARN_ON(!timer_base);
 	irq = irq_of_parse_and_map(np, 0);
 
 	clk_ipg = of_clk_get_by_name(np, "ipg");
-- 
1.9.1

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

* [PATCH 15/18] ARM: imx: Remove the SoC relating codes in mxc_clockevent_init
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (13 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 14/18] ARM: imx: Removed the global variable "timer_base" Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 16/18] ARM: imx: Move the variable clockevent_mode into mxc_set_mode Shenwei Wang
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Removed the SoC relating codes in the function of
mxc_clockevent_init.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 29105ca..836d255 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -300,11 +300,8 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 static int __init mxc_clockevent_init(struct clk *timer_clk,
 		struct imx_timer *tm)
 {
-	if (timer_is_v2())
-		clockevent_mxc.set_next_event = v2_set_next_event;
-
-	clockevent_mxc.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&clockevent_mxc,
+	tm->evt.cpumask = cpumask_of(0);
+	clockevents_config_and_register(&tm->evt,
 					clk_get_rate(timer_clk),
 					0xff, 0xfffffffe);
 
-- 
1.9.1

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

* [PATCH 16/18] ARM: imx: Move the variable clockevent_mode into mxc_set_mode
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (14 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 15/18] ARM: imx: Remove the SoC relating codes in mxc_clockevent_init Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 17/18] ARM: imx: Codes clean up Shenwei Wang
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

The global variable "clockevent_mode" was moved into the
function of mxc_set_mode.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 836d255..da4dc29 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -98,7 +98,6 @@ struct imx_timer {
 };
 
 static struct clock_event_device clockevent_mxc;
-static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
 static void gpt_irq_disable_v0_v1(struct imx_timer *tm)
 {
@@ -226,6 +225,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
 {
 	unsigned long flags;
 	struct imx_timer *tm = container_of(evt, struct imx_timer, evt);
+	static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
 	/*
 	 * The timer interrupt generation is disabled at least
-- 
1.9.1

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

* [PATCH 17/18] ARM: imx: Codes clean up
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (15 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 16/18] ARM: imx: Move the variable clockevent_mode into mxc_set_mode Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-04-30 14:44 ` [PATCH 18/18] ARM: imx: Move time.c into drivers/clocksources Shenwei Wang
  2015-05-15  7:54 ` [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shawn Guo
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Removed the unused SoC relating codes.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/time.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index da4dc29..f8dd53d 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -35,8 +35,6 @@
 
 #include <asm/mach/time.h>
 
-#include "common.h"
-#include "hardware.h"
 
 /*
  * There are 4 versions of the timer hardware on Freescale MXC hardware.
@@ -79,8 +77,6 @@
 
 #define V2_TIMER_RATE_OSC_DIV8	3000000
 
-#define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
-#define timer_is_v2()	(!timer_is_v1())
 
 #define IMX_TIMER_V0         (0)
 #define IMX_TIMER_V1         (1)
@@ -97,8 +93,6 @@ struct imx_timer {
 	void (*gpt_irq_acknowledge)(struct imx_timer *);
 };
 
-static struct clock_event_device clockevent_mxc;
-
 static void gpt_irq_disable_v0_v1(struct imx_timer *tm)
 {
 	unsigned int tmp;
-- 
1.9.1

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

* [PATCH 18/18] ARM: imx: Move time.c into drivers/clocksources
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (16 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 17/18] ARM: imx: Codes clean up Shenwei Wang
@ 2015-04-30 14:44 ` Shenwei Wang
  2015-05-15  7:54 ` [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shawn Guo
  18 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-04-30 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

The time.c was moved from arch/arm/mach-imx to
drivers/clocksources, and its name was changed
to timer-gpt.c.

Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
---
 arch/arm/mach-imx/Makefile                                  | 2 +-
 drivers/clocksource/Makefile                                | 1 +
 arch/arm/mach-imx/time.c => drivers/clocksource/timer-gpt.c | 0
 3 files changed, 2 insertions(+), 1 deletion(-)
 rename arch/arm/mach-imx/time.c => drivers/clocksource/timer-gpt.c (100%)

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 0622ced..08dc2f1 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,4 +1,4 @@
-obj-y := time.o cpu.o system.o irq-common.o
+obj-y := cpu.o system.o irq-common.o
 
 obj-$(CONFIG_SOC_IMX1) += mm-imx1.o
 obj-$(CONFIG_SOC_IMX21) += mm-imx21.o
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 5b85f6a..28bb2e6 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -52,3 +52,4 @@ obj-$(CONFIG_ARCH_INTEGRATOR_AP)	+= timer-integrator-ap.o
 obj-$(CONFIG_CLKSRC_VERSATILE)		+= versatile.o
 obj-$(CONFIG_CLKSRC_MIPS_GIC)		+= mips-gic-timer.o
 obj-$(CONFIG_ASM9260_TIMER)		+= asm9260_timer.o
+obj-$(CONFIG_ARCH_MXC)			+= timer-gpt.o
diff --git a/arch/arm/mach-imx/time.c b/drivers/clocksource/timer-gpt.c
similarity index 100%
rename from arch/arm/mach-imx/time.c
rename to drivers/clocksource/timer-gpt.c
-- 
1.9.1

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

* [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init
  2015-04-30 14:44 ` [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init Shenwei Wang
@ 2015-05-14  8:02   ` Shawn Guo
  2015-05-14 13:48     ` Shenwei Wang
  0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2015-05-14  8:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 30, 2015 at 09:44:16AM -0500, Shenwei Wang wrote:
> A parameter of integer type is added to the function mxc_timer_init,
> so that a user could have a way to tell the timer driver the version
> of the timer IP block.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> ---
>  arch/arm/mach-imx/time.c    | 2 +-
>  drivers/clk/imx/clk-imx1.c  | 3 ++-
>  drivers/clk/imx/clk-imx21.c | 3 ++-
>  drivers/clk/imx/clk-imx27.c | 3 ++-
>  drivers/clk/imx/clk-imx31.c | 3 ++-
>  drivers/clk/imx/clk-imx35.c | 5 +++--
>  drivers/clk/imx/clk.h       | 2 +-
>  7 files changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
> index b1698e1..eef6b66 100644
> --- a/arch/arm/mach-imx/time.c
> +++ b/arch/arm/mach-imx/time.c
> @@ -346,7 +346,7 @@ static void __init _mxc_timer_init(int irq,
>  	setup_irq(irq, &mxc_timer_irq);
>  }
>  
> -void __init mxc_timer_init(unsigned long pbase, int irq)
> +void __init mxc_timer_init(unsigned long pbase, int irq, int ver)

I prefer to have an enum type for it.

enum gpt_device_type {
	GPT_TYPE_IMX1,		/* MX1/MXL */
	GPT_TYPE_IMX21,		/* MX21, MX27 */
	GPT_TYPE_IMX31,		/* MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0) */
	GPT_TYPE_IMX6DL,	/* MX6DL, MX6SX, MX6Q(Rev1.1+) */
};

>  {
>  	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
>  	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
> diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c
> index c9812db..49534d8 100644
> --- a/drivers/clk/imx/clk-imx1.c
> +++ b/drivers/clk/imx/clk-imx1.c
> @@ -102,7 +102,8 @@ int __init mx1_clocks_init(unsigned long fref)
>  	clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0");
>  	clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0");
>  
> -	mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT);
> +	/*Timer version in MX1 is V0*/

There should be a space before and after '*'.

> +	mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, 0);
>  
>  	return 0;
>  }
> diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
> index 0ca842c..08aa048 100644
> --- a/drivers/clk/imx/clk-imx21.c
> +++ b/drivers/clk/imx/clk-imx21.c
> @@ -156,7 +156,8 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
>  	clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
>  	clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
>  
> -	mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1);
> +	/*Timer version in MX21 is v1*/
> +	mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, 1);
>  
>  	return 0;
>  }
> diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
> index df2dfc0..f00a7c0 100644
> --- a/drivers/clk/imx/clk-imx27.c
> +++ b/drivers/clk/imx/clk-imx27.c
> @@ -233,7 +233,8 @@ int __init mx27_clocks_init(unsigned long fref)
>  	clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0");
>  	clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0");
>  
> -	mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1);
> +	/*Timer version in MX27 is v1*/
> +	mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, 1);
>  
>  	return 0;
>  }
> diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
> index a55290c..7c4a025 100644
> --- a/drivers/clk/imx/clk-imx31.c
> +++ b/drivers/clk/imx/clk-imx31.c
> @@ -198,7 +198,8 @@ int __init mx31_clocks_init(unsigned long fref)
>  	mx31_revision();
>  	clk_disable_unprepare(clk[iim_gate]);
>  
> -	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT);
> +	/*Timer version in MX31 is v2*/
> +	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, 2);
>  
>  	return 0;
>  }
> diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
> index 133fda1..a796c1e 100644
> --- a/drivers/clk/imx/clk-imx35.c
> +++ b/drivers/clk/imx/clk-imx35.c
> @@ -145,7 +145,7 @@ int __init mx35_clocks_init(void)
>  	clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6);
>  
>  	clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel));
> -	clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */ 
> +	clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */

Unrelated change?

Shawn

>  	clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
>  
>  	clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel));
> @@ -296,7 +296,8 @@ int __init mx35_clocks_init(void)
>  #ifdef CONFIG_MXC_USE_EPIT
>  	epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
>  #else
> -	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT);
> +	/*Timer version in MX35 is v2*/
> +	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, 2);
>  #endif
>  
>  	return 0;
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
> index 6bae537..06da84a 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -11,7 +11,7 @@ extern spinlock_t imx_ccm_lock;
>   * mxc_timer_init() to initialize timer for non-DT boot.  It can be removed
>   * when these legacy non-DT support is converted or dropped.
>   */
> -void mxc_timer_init(unsigned long pbase, int irq);
> +void mxc_timer_init(unsigned long pbase, int irq, int);
>  
>  void imx_check_clocks(struct clk *clks[], unsigned int count);
>  
> -- 
> 1.9.1
> 
> 

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

* [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init
  2015-05-14  8:02   ` Shawn Guo
@ 2015-05-14 13:48     ` Shenwei Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-05-14 13:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn Guo,

> -----Original Message-----
> From: Shawn Guo [mailto:shawn.guo at linaro.org]
> Sent: 2015?5?14? 3:02
> To: Wang Shenwei-B38339
> Cc: linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init
> 
> > b1698e1..eef6b66 100644
> > --- a/arch/arm/mach-imx/time.c
> > +++ b/arch/arm/mach-imx/time.c
> > @@ -346,7 +346,7 @@ static void __init _mxc_timer_init(int irq,
> >  	setup_irq(irq, &mxc_timer_irq);
> >  }
> >
> > -void __init mxc_timer_init(unsigned long pbase, int irq)
> > +void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
> 
> I prefer to have an enum type for it.
> 
> enum gpt_device_type {
> 	GPT_TYPE_IMX1,		/* MX1/MXL */
> 	GPT_TYPE_IMX21,		/* MX21, MX27 */
> 	GPT_TYPE_IMX31,		/* MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0)
> */
> 	GPT_TYPE_IMX6DL,	/* MX6DL, MX6SX, MX6Q(Rev1.1+) */
> };
> 
I just wanted to make the changes as simple as possible. Since the mxc_timer_init function 
is for legacy implementation only, I don't want to introduce any more changes in the 
legacy codes like imx1 and imx21. If an enum is defined here, it will have to be included
somewhere in legacy codes. So I prefer to keep the current implementation. I think this
part of codes will at last be removed as long as we redesigned all legacy codes based on 
device tree implementation.


> >  {
> >  	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
> >  	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); diff --git
> > a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c index
> > c9812db..49534d8 100644
> > --- a/drivers/clk/imx/clk-imx1.c
> > +++ b/drivers/clk/imx/clk-imx1.c
> > @@ -102,7 +102,8 @@ int __init mx1_clocks_init(unsigned long fref)
> >  	clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0");
> >  	clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0");
> >
> > -	mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT);
> > +	/*Timer version in MX1 is V0*/
> 
> There should be a space before and after '*'.

Yes, I will update the patch.
> 
> > +	mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, 0);
> >
> >  	return 0;
> >  }
> > diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
> > index 0ca842c..08aa048 100644
> > --- a/drivers/clk/imx/clk-imx21.c
> > +++ b/drivers/clk/imx/clk-imx21.c
> > @@ -156,7 +156,8 @@ int __init mx21_clocks_init(unsigned long lref, unsigned
> long href)
> >  	clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
> >  	clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
> >
> > -	mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1);
> > +	/*Timer version in MX21 is v1*/
> > +	mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, 1);
> >
> >  	return 0;
> >  }
> > diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
> > index df2dfc0..f00a7c0 100644
> > --- a/drivers/clk/imx/clk-imx27.c
> > +++ b/drivers/clk/imx/clk-imx27.c
> > @@ -233,7 +233,8 @@ int __init mx27_clocks_init(unsigned long fref)
> >  	clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb",
> "m2m-emmaprp.0");
> >  	clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg",
> > "m2m-emmaprp.0");
> >
> > -	mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1);
> > +	/*Timer version in MX27 is v1*/
> > +	mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, 1);
> >
> >  	return 0;
> >  }
> > diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
> > index a55290c..7c4a025 100644
> > --- a/drivers/clk/imx/clk-imx31.c
> > +++ b/drivers/clk/imx/clk-imx31.c
> > @@ -198,7 +198,8 @@ int __init mx31_clocks_init(unsigned long fref)
> >  	mx31_revision();
> >  	clk_disable_unprepare(clk[iim_gate]);
> >
> > -	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT);
> > +	/*Timer version in MX31 is v2*/
> > +	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, 2);
> >
> >  	return 0;
> >  }
> > diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
> > index 133fda1..a796c1e 100644
> > --- a/drivers/clk/imx/clk-imx35.c
> > +++ b/drivers/clk/imx/clk-imx35.c
> > @@ -145,7 +145,7 @@ int __init mx35_clocks_init(void)
> >  	clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base +
> > MX35_CCM_PDR3, 16, 6);
> >
> >  	clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1,
> std_sel, ARRAY_SIZE(std_sel));
> > -	clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base +
> MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
> > +	clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel",
> > +base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */
> 
> Unrelated change?
> 
Right, it is unrelated. It was changed by the editor automatically.

Thanks,
Shenwei

> Shawn
> 
> >  	clk[spdif_div_post] = imx_clk_divider("spdif_div_post",
> > "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6);
> >
> >  	clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1,
> > std_sel, ARRAY_SIZE(std_sel)); @@ -296,7 +296,8 @@ int __init
> > mx35_clocks_init(void)  #ifdef CONFIG_MXC_USE_EPIT
> >  	epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR),
> > MX35_INT_EPIT1);  #else
> > -	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT);
> > +	/*Timer version in MX35 is v2*/
> > +	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, 2);
> >  #endif
> >
> >  	return 0;
> > diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index
> > 6bae537..06da84a 100644
> > --- a/drivers/clk/imx/clk.h
> > +++ b/drivers/clk/imx/clk.h
> > @@ -11,7 +11,7 @@ extern spinlock_t imx_ccm_lock;
> >   * mxc_timer_init() to initialize timer for non-DT boot.  It can be removed
> >   * when these legacy non-DT support is converted or dropped.
> >   */
> > -void mxc_timer_init(unsigned long pbase, int irq);
> > +void mxc_timer_init(unsigned long pbase, int irq, int);
> >
> >  void imx_check_clocks(struct clk *clks[], unsigned int count);
> >
> > --
> > 1.9.1
> >
> >

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

* [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its versions
  2015-04-30 14:44 ` [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its versions Shenwei Wang
@ 2015-05-15  1:18   ` Shawn Guo
  2015-05-15 15:47     ` Shenwei Wang
  0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2015-05-15  1:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 30, 2015 at 09:44:17AM -0500, Shenwei Wang wrote:
> A struct was added to describe the imx hardware timers.
> Added four macros to define the imx timer version.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> ---
>  arch/arm/mach-imx/time.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
> index eef6b66..5df3c53 100644
> --- a/arch/arm/mach-imx/time.c
> +++ b/arch/arm/mach-imx/time.c
> @@ -81,6 +81,21 @@
>  #define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
>  #define timer_is_v2()	(!timer_is_v1())
>  
> +#define IMX_TIMER_V0         (0)
> +#define IMX_TIMER_V1         (1)
> +#define IMX_TIMER_V2         (2)
> +#define IMX_TIMER_V3         (3)

I prefer to use an enum type instead of macros. Also I do not like the
versions which are numbered by software arbitrarily.  Instead, I'd like
to use SoC name that firstly integrates the version to code the
type/version.

Shawn

> +
> +struct imx_timer {
> +	void __iomem *timer_base;
> +	int version;
> +	struct clock_event_device evt;
> +	struct irqaction act;
> +	void (*gpt_irq_enable)(struct imx_timer *);
> +	void (*gpt_irq_disable)(struct imx_timer *);
> +	void (*gpt_irq_acknowledge)(struct imx_timer *);
> +};
> +
>  static struct clock_event_device clockevent_mxc;
>  static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
>  
> -- 
> 1.9.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 03/18] ARM: imx: Add an array of timer IP block versions
  2015-04-30 14:44 ` [PATCH 03/18] ARM: imx: Add an array of timer IP block versions Shenwei Wang
@ 2015-05-15  1:33   ` Shawn Guo
  0 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2015-05-15  1:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 30, 2015 at 09:44:18AM -0500, Shenwei Wang wrote:
> Added an array to record the relationship between the
> compatible string and the version of timer IP block.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> ---
>  arch/arm/mach-imx/time.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
> index 5df3c53..f44c2aa 100644
> --- a/arch/arm/mach-imx/time.c
> +++ b/arch/arm/mach-imx/time.c
> @@ -372,6 +372,23 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
>  	_mxc_timer_init(irq, clk_per, clk_ipg);
>  }
>  
> +struct imx_timer_ip_combo {
> +	const char      *compat;
> +	int             version;
> +};
> +
> +static const struct imx_timer_ip_combo imx_timer_tables[] = {
> +	{"fsl,imx1-gpt",        IMX_TIMER_V0},
> +	{"fsl,imx25-gpt",       IMX_TIMER_V2},
> +	{"fsl,imx25-gpt",       IMX_TIMER_V2},
> +	{"fsl,imx50-gpt",       IMX_TIMER_V2},
> +	{"fsl,imx51-gpt",       IMX_TIMER_V2},
> +	{"fsl,imx53-gpt",       IMX_TIMER_V2},
> +	{"fsl,imx6q-gpt",       IMX_TIMER_V2},
> +	{"fsl,imx6sl-gpt",      IMX_TIMER_V3},
> +	{"fsl,imx6sx-gpt",      IMX_TIMER_V3},
> +};
> +

I do not like this and the for-loop in mxc_timer_init_dt() to find
version number per compatible string.  I'd rather to have different init
function for different compatible string.

CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", imx25_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", imx25_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", imx25_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", imx25_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", imx25_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", imx6sl_timer_init_dt);
CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", imx6sl_timer_init_dt);

Do not take that <soc>_timer_init_dt is a timer init function for <soc>,
but this an init time for <soc> type of timer.  In this case, we can
read it from above CLOCKSOURCE_OF_DECLAREs that imx25/50/51/53/6q are
all using imx25 type of gpt, and imx6sx is using the imx6sl type.

Shawn


>  static void __init mxc_timer_init_dt(struct device_node *np)
>  {
>  	struct clk *clk_per, *clk_ipg;
> -- 
> 1.9.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 06/18] ARM: imx: New timer driver APIs based on IP block
  2015-04-30 14:44 ` [PATCH 06/18] ARM: imx: New timer driver APIs based on IP block Shenwei Wang
@ 2015-05-15  1:44   ` Shawn Guo
  0 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2015-05-15  1:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 30, 2015 at 09:44:21AM -0500, Shenwei Wang wrote:
> Implemented the necessory imx timer driver APIs directly
> based on the version of IP block. These APIs are only relating
> to the version of the timer block, and are independent of
> the SoC.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> ---
>  arch/arm/mach-imx/time.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 171 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
> index 4db233f..811d50a 100644
> --- a/arch/arm/mach-imx/time.c
> +++ b/arch/arm/mach-imx/time.c
> @@ -101,6 +101,54 @@ static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
>  
>  static void __iomem *timer_base;
>  
> +static void gpt_irq_disable_v0_v1(struct imx_timer *tm)
> +{
> +	unsigned int tmp;
> +
> +	tmp = __raw_readl(tm->timer_base + MXC_TCTL);
> +	__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, tm->timer_base + MXC_TCTL);
> +
> +}
> +
> +static void gpt_irq_disable_v2_v3(struct imx_timer *tm)
> +{
> +	__raw_writel(0, tm->timer_base + V2_IR);
> +
> +}
> +
> +static void gpt_irq_enable_v0_v1(struct imx_timer *tm)
> +{
> +	__raw_writel(__raw_readl(tm->timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
> +			tm->timer_base + MXC_TCTL);
> +}
> +
> +static void gpt_irq_enable_v2_v3(struct imx_timer *tm)
> +{
> +	__raw_writel(1, tm->timer_base + V2_IR);
> +}
> +
> +static void gpt_irq_acknowledge_v0(struct imx_timer *tm)
> +{
> +	__raw_readl(tm->timer_base + MX1_2_TSTAT);
> +
> +	__raw_writel(0, tm->timer_base + MX1_2_TSTAT);
> +}
> +
> +static void gpt_irq_acknowledge_v1(struct imx_timer *tm)
> +{
> +	__raw_readl(tm->timer_base + MX1_2_TSTAT);
> +
> +	__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
> +			tm->timer_base + MX1_2_TSTAT);
> +}
> +
> +static void gpt_irq_acknowledge_v2_v3(struct imx_timer *tm)
> +{
> +	__raw_readl(tm->timer_base + V2_TSTAT);
> +
> +	__raw_writel(V2_TSTAT_OF1, tm->timer_base + V2_TSTAT);
> +}
> +
>  static inline void gpt_irq_disable(void)
>  {
>  	unsigned int tmp;
> @@ -314,6 +362,129 @@ static int __init mxc_clockevent_init(struct clk *timer_clk,
>  	return 0;
>  }
>  
> +static void __init _mxc_timer_init_v0_v1(int irq, struct clk *clk_per,
> +		struct clk *clk_ipg, struct imx_timer *tm)
> +{
> +	uint32_t tctl_val;
> +
> +	if (IS_ERR(clk_per)) {
> +		pr_err("i.MX timer: unable to get clk\n");
> +		return;
> +	}
> +
> +	if (!IS_ERR(clk_ipg))
> +		clk_prepare_enable(clk_ipg);
> +
> +	clk_prepare_enable(clk_per);
> +
> +	/*
> +	 * Initialise to a known state (all timers off, and timing reset)
> +	 */
> +
> +	__raw_writel(0, tm->timer_base + MXC_TCTL);
> +	__raw_writel(0, tm->timer_base + MXC_TPRER); /* see datasheet note */
> +
> +	tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
> +
> +	__raw_writel(tctl_val, tm->timer_base + MXC_TCTL);
> +
> +	/* init and register the timer to the framework */
> +	mxc_clocksource_init(clk_per, tm->timer_base + MX1_2_TCN);
> +
> +	tm->evt.set_next_event = mx1_2_set_next_event;
> +	mxc_clockevent_init(clk_per, tm);
> +
> +	/* Make irqs happen */
> +	setup_irq(irq, &tm->act);
> +}
> +
> +static void __init _mxc_timer_init_v2(int irq, struct clk *clk_per,
> +		struct clk *clk_ipg, struct imx_timer *tm)
> +{
> +	uint32_t tctl_val;
> +
> +	if (IS_ERR(clk_per)) {
> +		pr_err("i.MX timer: unable to get clk\n");
> +		return;
> +	}
> +
> +	if (!IS_ERR(clk_ipg))
> +		clk_prepare_enable(clk_ipg);
> +
> +	clk_prepare_enable(clk_per);
> +
> +	/*
> +	 * Initialise to a known state (all timers off, and timing reset)
> +	 */
> +
> +	__raw_writel(0, tm->timer_base + MXC_TCTL);
> +	__raw_writel(0, tm->timer_base + MXC_TPRER); /* see datasheet note */
> +
> +	tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
> +
> +	if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8)
> +		tctl_val |= V2_TCTL_CLK_OSC_DIV8;
> +	else
> +		tctl_val |= V2_TCTL_CLK_PER;
> +
> +	__raw_writel(tctl_val, tm->timer_base + MXC_TCTL);
> +
> +	/* init and register the timer to the framework */
> +	mxc_clocksource_init(clk_per, tm->timer_base + V2_TCN);
> +
> +	tm->evt.set_next_event = v2_set_next_event;
> +	mxc_clockevent_init(clk_per, tm);
> +
> +	/* Make irqs happen */
> +	setup_irq(irq, &tm->act);
> +}
> +
> +static void __init _mxc_timer_init_v3(int irq, struct clk *clk_per,
> +		struct clk *clk_ipg, struct imx_timer *tm)
> +{
> +	uint32_t tctl_val;
> +
> +	if (IS_ERR(clk_per)) {
> +		pr_err("i.MX timer: unable to get clk\n");
> +		return;
> +	}
> +
> +	if (!IS_ERR(clk_ipg))
> +		clk_prepare_enable(clk_ipg);
> +
> +	clk_prepare_enable(clk_per);
> +
> +	/*
> +	 * Initialise to a known state (all timers off, and timing reset)
> +	 */
> +
> +	__raw_writel(0, tm->timer_base + MXC_TCTL);
> +	__raw_writel(0, tm->timer_base + MXC_TPRER); /* see datasheet note */
> +
> +	tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
> +
> +	if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) {
> +		tctl_val |= V2_TCTL_CLK_OSC_DIV8;
> +		/* 24 / 8 = 3 MHz */
> +		__raw_writel(7 << V2_TPRER_PRE24M,
> +					tm->timer_base + MXC_TPRER);
> +		tctl_val |= V2_TCTL_24MEN;
> +	} else {
> +		tctl_val |= V2_TCTL_CLK_PER;
> +	}
> +
> +	__raw_writel(tctl_val, tm->timer_base + MXC_TCTL);
> +
> +	/* init and register the timer to the framework */
> +	mxc_clocksource_init(clk_per, tm->timer_base + V2_TCN);
> +
> +	tm->evt.set_next_event = v2_set_next_event;
> +	mxc_clockevent_init(clk_per, tm);
> +
> +	/* Make irqs happen */
> +	setup_irq(irq, &tm->act);
> +}
> +

Quite some bit of the code is duplicated among these three
_mxc_timer_init_v?() functions.  I'm not sure this makes the most sense.

Shawn

>  static void __init _mxc_timer_init(int irq,
>  				   struct clk *clk_per, struct clk *clk_ipg)
>  {
> -- 
> 1.9.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 07/18] ARM: imx: Initialize the imx_timer structure
  2015-04-30 14:44 ` [PATCH 07/18] ARM: imx: Initialize the imx_timer structure Shenwei Wang
@ 2015-05-15  2:05   ` Shawn Guo
  0 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2015-05-15  2:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 30, 2015 at 09:44:22AM -0500, Shenwei Wang wrote:
> Initialized the imx_timer struct  in the following two functions:
> mxc_timer_init
> mxc_timer_init_dt
> 
> Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> ---
>  arch/arm/mach-imx/time.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 54 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
> index 811d50a..451f761 100644
> --- a/arch/arm/mach-imx/time.c
> +++ b/arch/arm/mach-imx/time.c
> @@ -31,6 +31,7 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_irq.h>
> +#include <linux/slab.h>
>  
>  #include <asm/mach/time.h>
>  
> @@ -536,12 +537,29 @@ static void __init _mxc_timer_init(int irq,
>  
>  void __init mxc_timer_init(unsigned long pbase, int irq, int ver)
>  {
> +	struct imx_timer *timer;
>  	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
>  	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
>  
>  	timer_base = ioremap(pbase, SZ_4K);
>  	BUG_ON(!timer_base);
>  
> +	timer = kzalloc(sizeof(struct imx_timer), GFP_KERNEL);
> +	if (!timer)
> +		panic("Can't allocate timer struct\n");
> +
> +	timer->timer_base = timer_base;
> +	timer->version = ver;
> +	timer->evt.name = "mxc_timer1";
> +	timer->evt.rating = 200;
> +	timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
> +	timer->evt.set_mode = mxc_set_mode;
> +	timer->evt.set_next_event = v2_set_next_event;
> +	timer->act.name = "i.MX Timer Tick";
> +	timer->act.flags = IRQF_TIMER | IRQF_IRQPOLL;
> +	timer->act.dev_id = timer;
> +	timer->act.handler = mxc_timer_interrupt;
> +
>  	_mxc_timer_init(irq, clk_per, clk_ipg);
>  }
>  
> @@ -565,11 +583,34 @@ static const struct imx_timer_ip_combo imx_timer_tables[] = {
>  static void __init mxc_timer_init_dt(struct device_node *np)
>  {
>  	struct clk *clk_per, *clk_ipg;
> -	int irq;
> +	int irq, i, ret, ver;
> +	struct imx_timer *timer;
>  
>  	if (timer_base)
>  		return;
>  
> +	for (i =  0; i < sizeof(imx_timer_tables) /
> +			sizeof(struct imx_timer_ip_combo); i++) {
> +		ret = of_device_is_compatible(np, imx_timer_tables[i].compat);
> +		if (ret) {
> +			ver = imx_timer_tables[i].version;
> +			pr_err("<%s> compatible=%s timer_version=%d\r\n",
> +				__func__, imx_timer_tables[i].compat, ver);
> +			break;
> +		}
> +	}
> +
> +	if (!ret) {
> +		pr_err("<%s> timer device node is not supported\r\n", __func__);
> +		return;
> +	}
> +
> +	timer = kzalloc(sizeof(struct imx_timer), GFP_KERNEL);
> +	if (!timer)
> +		panic("Can't allocate timer struct\n");
> +
> +	timer->timer_base = of_iomap(np, 0);
> +
>  	timer_base = of_iomap(np, 0);
>  	WARN_ON(!timer_base);
>  	irq = irq_of_parse_and_map(np, 0);
> @@ -581,8 +622,20 @@ static void __init mxc_timer_init_dt(struct device_node *np)
>  	if (IS_ERR(clk_per))
>  		clk_per = of_clk_get_by_name(np, "per");
>  
> +	timer->version = ver;
> +	timer->evt.name = np->name;

These names shouldn't be treated differently between DT and non-DT.
Also I do not see obvious benefit to allocate the structure over static
definition.  Using static one can let us keep necessary consistency
between DT and non-DT.

Shawn

> +	timer->evt.rating = 200;
> +	timer->evt.features = CLOCK_EVT_FEAT_ONESHOT;
> +	timer->evt.set_mode = mxc_set_mode;
> +	timer->evt.set_next_event = v2_set_next_event;
> +	timer->act.name = np->name;
> +	timer->act.flags = IRQF_TIMER | IRQF_IRQPOLL;
> +	timer->act.dev_id = timer;
> +	timer->act.handler = mxc_timer_interrupt;
> +
>  	_mxc_timer_init(irq, clk_per, clk_ipg);
>  }
> +
>  CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
>  CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
>  CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt);
> -- 
> 1.9.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs.
  2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
                   ` (17 preceding siblings ...)
  2015-04-30 14:44 ` [PATCH 18/18] ARM: imx: Move time.c into drivers/clocksources Shenwei Wang
@ 2015-05-15  7:54 ` Shawn Guo
  2015-05-15 15:39   ` Shenwei Wang
  18 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2015-05-15  7:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 30, 2015 at 09:44:15AM -0500, Shenwei Wang wrote:
> There are 4 versions of the timer hardware on Freescale MXC hardware.
> --Version 0: MX1/MXL
> --Version 1: MX21, MX27.
> --Version 2: MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0)
> --Version 3: MX6DL, MX6SX, MX6Q(Rev1.1+)
> 
> This patch has removed the SoC related codes, and implemented the driver directly upon
> the hardware timer IP version. The new timer driver has redesigned the
> internal APIs, and limited the use of global variables as well.
> 
> As the new driver has become independent of the SoCs, it has
> been moved from the directory arch/arm/mach-imx into the
> directory drivers/clocksources.

Overall, I do not like how things get done here, the software version
numbering, the patch splitting, invasive changes than necessary.  So I
just worked out my version and will post for review shortly.

Shawn

> Shenwei Wang (18):
>   ARM: imx: Add a parameter to mxc_timer_init
>   ARM: imx: Add the definitions for imx_timer and its versions
>   ARM: imx: Add an array of timer IP block versions
>   ARM: imx: Added one more parameter for mxc_clockevent_init
>   ARM: imx: Added one more parameter for mxc_clocksource_init
>   ARM: imx: New timer driver APIs based on IP block
>   ARM: imx: Initialize the imx_timer structure
>   ARM: imx: Reimplemented the _mxc_timer_init based on IP version
>   ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt
>   ARM: imx: Removed the SoC relating codes in mxc_set_mode
>   ARM: imx: Enabled the unused parameter
>   ARM: imx: Remove one global variable in mxc_clocksource_init
>   ARM: imx: Removed the unused functions and variables
>   ARM: imx: Removed the global variable "timer_base"
>   ARM: imx: Remove the SoC relating codes in mxc_clockevent_init
>   ARM: imx: Move the  variable clockevent_mode into mxc_set_mode
>   ARM: imx: Codes clean up
>   ARM: imx: Move time.c into drivers/clocksources
> 
>  arch/arm/mach-imx/Makefile      |   2 +-
>  arch/arm/mach-imx/time.c        | 388 ---------------------------
>  drivers/clk/imx/clk-imx1.c      |   3 +-
>  drivers/clk/imx/clk-imx21.c     |   3 +-
>  drivers/clk/imx/clk-imx27.c     |   3 +-
>  drivers/clk/imx/clk-imx31.c     |   3 +-
>  drivers/clk/imx/clk-imx35.c     |   5 +-
>  drivers/clk/imx/clk.h           |   2 +-
>  drivers/clocksource/Makefile    |   1 +
>  drivers/clocksource/timer-gpt.c | 572 ++++++++++++++++++++++++++++++++++++++++
>  10 files changed, 586 insertions(+), 396 deletions(-)
>  delete mode 100644 arch/arm/mach-imx/time.c
>  create mode 100644 drivers/clocksource/timer-gpt.c
> 
> --
> 1.9.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs.
  2015-05-15  7:54 ` [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shawn Guo
@ 2015-05-15 15:39   ` Shenwei Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-05-15 15:39 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Shawn Guo [mailto:shawnguo at kernel.org]
> Sent: 2015?5?15? 2:54
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 00/18] ARM: imx: make the imx timer driver implementation
> independent of SoCs.
> 
> On Thu, Apr 30, 2015 at 09:44:15AM -0500, Shenwei Wang wrote:
> > There are 4 versions of the timer hardware on Freescale MXC hardware.
> > --Version 0: MX1/MXL
> > --Version 1: MX21, MX27.
> > --Version 2: MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0) --Version 3:
> > MX6DL, MX6SX, MX6Q(Rev1.1+)
> >
> > This patch has removed the SoC related codes, and implemented the
> > driver directly upon the hardware timer IP version. The new timer
> > driver has redesigned the internal APIs, and limited the use of global variables
> as well.
> >
> > As the new driver has become independent of the SoCs, it has been
> > moved from the directory arch/arm/mach-imx into the directory
> > drivers/clocksources.
> 
> Overall, I do not like how things get done here, the software version numbering,
> the patch splitting, invasive changes than necessary.  So I just worked out my
> version and will post for review shortly.
> 
Agreed that the patch was splitting because I wanted to let the reviewers know the
Procedures of the changes. The idea for the series of patches is to re-implement 
The gpt timer driver just based on the IP. I don't want to involve any SoC
Information inside the driver. A driver should have no knowledge of a SoC, but be simply
Implemented upon the IP block. 


> Shawn
> 
> > Shenwei Wang (18):
> >   ARM: imx: Add a parameter to mxc_timer_init
> >   ARM: imx: Add the definitions for imx_timer and its versions
> >   ARM: imx: Add an array of timer IP block versions
> >   ARM: imx: Added one more parameter for mxc_clockevent_init
> >   ARM: imx: Added one more parameter for mxc_clocksource_init
> >   ARM: imx: New timer driver APIs based on IP block
> >   ARM: imx: Initialize the imx_timer structure
> >   ARM: imx: Reimplemented the _mxc_timer_init based on IP version
> >   ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt
> >   ARM: imx: Removed the SoC relating codes in mxc_set_mode
> >   ARM: imx: Enabled the unused parameter
> >   ARM: imx: Remove one global variable in mxc_clocksource_init
> >   ARM: imx: Removed the unused functions and variables
> >   ARM: imx: Removed the global variable "timer_base"
> >   ARM: imx: Remove the SoC relating codes in mxc_clockevent_init
> >   ARM: imx: Move the  variable clockevent_mode into mxc_set_mode
> >   ARM: imx: Codes clean up
> >   ARM: imx: Move time.c into drivers/clocksources
> >
> >  arch/arm/mach-imx/Makefile      |   2 +-
> >  arch/arm/mach-imx/time.c        | 388 ---------------------------
> >  drivers/clk/imx/clk-imx1.c      |   3 +-
> >  drivers/clk/imx/clk-imx21.c     |   3 +-
> >  drivers/clk/imx/clk-imx27.c     |   3 +-
> >  drivers/clk/imx/clk-imx31.c     |   3 +-
> >  drivers/clk/imx/clk-imx35.c     |   5 +-
> >  drivers/clk/imx/clk.h           |   2 +-
> >  drivers/clocksource/Makefile    |   1 +
> >  drivers/clocksource/timer-gpt.c | 572
> > ++++++++++++++++++++++++++++++++++++++++
> >  10 files changed, 586 insertions(+), 396 deletions(-)  delete mode
> > 100644 arch/arm/mach-imx/time.c  create mode 100644
> > drivers/clocksource/timer-gpt.c
> >
> > --
> > 1.9.1
> >
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its versions
  2015-05-15  1:18   ` Shawn Guo
@ 2015-05-15 15:47     ` Shenwei Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Shenwei Wang @ 2015-05-15 15:47 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: Shawn Guo [mailto:shawnguo at kernel.org]
> Sent: 2015?5?14? 20:19
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its
> versions
> 
> On Thu, Apr 30, 2015 at 09:44:17AM -0500, Shenwei Wang wrote:
> > A struct was added to describe the imx hardware timers.
> > Added four macros to define the imx timer version.
> >
> > Signed-off-by: Shenwei Wang <shenwei.wang@freescale.com>
> > ---
> >  arch/arm/mach-imx/time.c | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> >
> > diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index
> > eef6b66..5df3c53 100644
> > --- a/arch/arm/mach-imx/time.c
> > +++ b/arch/arm/mach-imx/time.c
> > @@ -81,6 +81,21 @@
> >  #define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
> >  #define timer_is_v2()	(!timer_is_v1())
> >
> > +#define IMX_TIMER_V0         (0)
> > +#define IMX_TIMER_V1         (1)
> > +#define IMX_TIMER_V2         (2)
> > +#define IMX_TIMER_V3         (3)
> 
> I prefer to use an enum type instead of macros. Also I do not like the versions
> which are numbered by software arbitrarily.  Instead, I'd like to use SoC name
> that firstly integrates the version to code the type/version.
> 
Seems we have different implementation philosophy. I don't want to involve any
SoC information inside a driver for either an IP block or an external component.
The only exception here is the DT bindings, as the SoC name is commonly accepted
To be used in the compatible string.

Regards,
Shenwei


> Shawn
> 
> > +
> > +struct imx_timer {
> > +	void __iomem *timer_base;
> > +	int version;
> > +	struct clock_event_device evt;
> > +	struct irqaction act;
> > +	void (*gpt_irq_enable)(struct imx_timer *);
> > +	void (*gpt_irq_disable)(struct imx_timer *);
> > +	void (*gpt_irq_acknowledge)(struct imx_timer *); };
> > +
> >  static struct clock_event_device clockevent_mxc;  static enum
> > clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> >
> > --
> > 1.9.1
> >
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2015-05-15 15:47 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-30 14:44 [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shenwei Wang
2015-04-30 14:44 ` [PATCH 01/18] ARM: imx: Add a parameter to mxc_timer_init Shenwei Wang
2015-05-14  8:02   ` Shawn Guo
2015-05-14 13:48     ` Shenwei Wang
2015-04-30 14:44 ` [PATCH 02/18] ARM: imx: Add the definitions for imx_timer and its versions Shenwei Wang
2015-05-15  1:18   ` Shawn Guo
2015-05-15 15:47     ` Shenwei Wang
2015-04-30 14:44 ` [PATCH 03/18] ARM: imx: Add an array of timer IP block versions Shenwei Wang
2015-05-15  1:33   ` Shawn Guo
2015-04-30 14:44 ` [PATCH 04/18] ARM: imx: Added one more parameter for mxc_clockevent_init Shenwei Wang
2015-04-30 14:44 ` [PATCH 05/18] ARM: imx: Added one more parameter for mxc_clocksource_init Shenwei Wang
2015-04-30 14:44 ` [PATCH 06/18] ARM: imx: New timer driver APIs based on IP block Shenwei Wang
2015-05-15  1:44   ` Shawn Guo
2015-04-30 14:44 ` [PATCH 07/18] ARM: imx: Initialize the imx_timer structure Shenwei Wang
2015-05-15  2:05   ` Shawn Guo
2015-04-30 14:44 ` [PATCH 08/18] ARM: imx: Reimplemented the _mxc_timer_init based on IP version Shenwei Wang
2015-04-30 14:44 ` [PATCH 09/18] ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt Shenwei Wang
2015-04-30 14:44 ` [PATCH 10/18] ARM: imx: Removed the SoC relating codes in mxc_set_mode Shenwei Wang
2015-04-30 14:44 ` [PATCH 11/18] ARM: imx: Enabled the unused parameter Shenwei Wang
2015-04-30 14:44 ` [PATCH 12/18] ARM: imx: Remove one global variable in mxc_clocksource_init Shenwei Wang
2015-04-30 14:44 ` [PATCH 13/18] ARM: imx: Removed the unused functions and variables Shenwei Wang
2015-04-30 14:44 ` [PATCH 14/18] ARM: imx: Removed the global variable "timer_base" Shenwei Wang
2015-04-30 14:44 ` [PATCH 15/18] ARM: imx: Remove the SoC relating codes in mxc_clockevent_init Shenwei Wang
2015-04-30 14:44 ` [PATCH 16/18] ARM: imx: Move the variable clockevent_mode into mxc_set_mode Shenwei Wang
2015-04-30 14:44 ` [PATCH 17/18] ARM: imx: Codes clean up Shenwei Wang
2015-04-30 14:44 ` [PATCH 18/18] ARM: imx: Move time.c into drivers/clocksources Shenwei Wang
2015-05-15  7:54 ` [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs Shawn Guo
2015-05-15 15:39   ` Shenwei Wang

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.