linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource
@ 2015-05-15  8:11 shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 1/9] ARM: imx: move timer resources into a structure shawnguo at kernel.org
                   ` (8 more replies)
  0 siblings, 9 replies; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

The series cleans up i.MX timer driver regarding those cpu_is_xxx()
usage by introducing gpt device type, and then moves the driver into
drivers/clocksource.

Shawn Guo (9):
  ARM: imx: move timer resources into a structure
  ARM: imx: define an enum for gpt timer device type
  ARM: imx: initialize gpt device type for DT boot
  ARM: imx: setup tctl register in device specific function
  ARM: imx: set up set_next_event hook in imx_timer_data_init()
  ARM: imx: define gpt register offset per device type
  ARM: imx: provide gpt device specific irq functions
  ARM: imx: remove platform headers from timer driver
  ARM: imx: move timer driver into drivers/clocksource

 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     |   3 +-
 drivers/clk/imx/clk.h           |   7 -
 drivers/clocksource/Makefile    |   1 +
 drivers/clocksource/timer-imx.c | 493 ++++++++++++++++++++++++++++++++++++++++
 include/soc/imx/timer.h         |  26 +++
 11 files changed, 531 insertions(+), 401 deletions(-)
 delete mode 100644 arch/arm/mach-imx/time.c
 create mode 100644 drivers/clocksource/timer-imx.c
 create mode 100644 include/soc/imx/timer.h

-- 
1.9.1

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

* [PATCH 1/9] ARM: imx: move timer resources into a structure
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15 16:36   ` Shenwei Wang
  2015-05-18 10:43   ` Daniel Lezcano
  2015-05-15  8:11 ` [PATCH 2/9] ARM: imx: define an enum for gpt timer device type shawnguo at kernel.org
                   ` (7 subsequent siblings)
  8 siblings, 2 replies; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Instead of passing around as argument, let's move timer resources like
irq and clocks together with base address into a data structure, and
reference the resources from the struct variable directly to simplify
the function call interface.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++-----------------------
 1 file changed, 61 insertions(+), 58 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index ab5ee1c445f3..8ad7cb2a7f08 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -84,27 +84,34 @@
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
-static void __iomem *timer_base;
+struct imx_timer {
+	void __iomem *base;
+	int irq;
+	struct clk *clk_per;
+	struct clk *clk_ipg;
+};
+
+static struct imx_timer imxtm;
 
 static inline void gpt_irq_disable(void)
 {
 	unsigned int tmp;
 
 	if (timer_is_v2())
-		__raw_writel(0, timer_base + V2_IR);
+		__raw_writel(0, imxtm.base + V2_IR);
 	else {
-		tmp = __raw_readl(timer_base + MXC_TCTL);
-		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
+		tmp = __raw_readl(imxtm.base + MXC_TCTL);
+		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, imxtm.base + MXC_TCTL);
 	}
 }
 
 static inline void gpt_irq_enable(void)
 {
 	if (timer_is_v2())
-		__raw_writel(1<<0, timer_base + V2_IR);
+		__raw_writel(1<<0, imxtm.base + V2_IR);
 	else {
-		__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
-			timer_base + MXC_TCTL);
+		__raw_writel(__raw_readl(imxtm.base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
+			imxtm.base + MXC_TCTL);
 	}
 }
 
@@ -112,12 +119,12 @@ static void gpt_irq_acknowledge(void)
 {
 	if (timer_is_v1()) {
 		if (cpu_is_mx1())
-			__raw_writel(0, timer_base + MX1_2_TSTAT);
+			__raw_writel(0, imxtm.base + MX1_2_TSTAT);
 		else
 			__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
-				timer_base + MX1_2_TSTAT);
+				imxtm.base + MX1_2_TSTAT);
 	} else if (timer_is_v2())
-		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
+		__raw_writel(V2_TSTAT_OF1, imxtm.base + V2_TSTAT);
 }
 
 static void __iomem *sched_clock_reg;
@@ -134,10 +141,10 @@ 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(void)
 {
-	unsigned int c = clk_get_rate(timer_clk);
-	void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
+	unsigned int c = clk_get_rate(imxtm.clk_per);
+	void __iomem *reg = imxtm.base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
 
 	imx_delay_timer.read_current_timer = &imx_read_current_timer;
 	imx_delay_timer.freq = c;
@@ -157,11 +164,11 @@ static int mx1_2_set_next_event(unsigned long evt,
 {
 	unsigned long tcmp;
 
-	tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt;
+	tcmp = __raw_readl(imxtm.base + MX1_2_TCN) + evt;
 
-	__raw_writel(tcmp, timer_base + MX1_2_TCMP);
+	__raw_writel(tcmp, imxtm.base + MX1_2_TCMP);
 
-	return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ?
+	return (int)(tcmp - __raw_readl(imxtm.base + MX1_2_TCN)) < 0 ?
 				-ETIME : 0;
 }
 
@@ -170,12 +177,12 @@ static int v2_set_next_event(unsigned long evt,
 {
 	unsigned long tcmp;
 
-	tcmp = __raw_readl(timer_base + V2_TCN) + evt;
+	tcmp = __raw_readl(imxtm.base + V2_TCN) + evt;
 
-	__raw_writel(tcmp, timer_base + V2_TCMP);
+	__raw_writel(tcmp, imxtm.base + V2_TCMP);
 
 	return evt < 0x7fffffff &&
-		(int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
+		(int)(tcmp - __raw_readl(imxtm.base + V2_TCN)) < 0 ?
 				-ETIME : 0;
 }
 
@@ -206,11 +213,11 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	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);
+			__raw_writel(__raw_readl(imxtm.base + V2_TCN) - 3,
+					imxtm.base + V2_TCMP);
 		else
-			__raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
-					timer_base + MX1_2_TCMP);
+			__raw_writel(__raw_readl(imxtm.base + MX1_2_TCN) - 3,
+					imxtm.base + MX1_2_TCMP);
 
 		/* Clear pending interrupt */
 		gpt_irq_acknowledge();
@@ -259,9 +266,9 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 	uint32_t tstat;
 
 	if (timer_is_v2())
-		tstat = __raw_readl(timer_base + V2_TSTAT);
+		tstat = __raw_readl(imxtm.base + V2_TSTAT);
 	else
-		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
+		tstat = __raw_readl(imxtm.base + MX1_2_TSTAT);
 
 	gpt_irq_acknowledge();
 
@@ -284,49 +291,48 @@ 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(void)
 {
 	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,
-					clk_get_rate(timer_clk),
+					clk_get_rate(imxtm.clk_per),
 					0xff, 0xfffffffe);
 
 	return 0;
 }
 
-static void __init _mxc_timer_init(int irq,
-				   struct clk *clk_per, struct clk *clk_ipg)
+static void __init _mxc_timer_init(void)
 {
 	uint32_t tctl_val;
 
-	if (IS_ERR(clk_per)) {
+	if (IS_ERR(imxtm.clk_per)) {
 		pr_err("i.MX timer: unable to get clk\n");
 		return;
 	}
 
-	if (!IS_ERR(clk_ipg))
-		clk_prepare_enable(clk_ipg);
+	if (!IS_ERR(imxtm.clk_ipg))
+		clk_prepare_enable(imxtm.clk_ipg);
 
-	clk_prepare_enable(clk_per);
+	clk_prepare_enable(imxtm.clk_per);
 
 	/*
 	 * Initialise to a known state (all timers off, and timing reset)
 	 */
 
-	__raw_writel(0, timer_base + MXC_TCTL);
-	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
+	__raw_writel(0, imxtm.base + MXC_TCTL);
+	__raw_writel(0, imxtm.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) {
+		if (clk_get_rate(imxtm.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);
+					imxtm.base + MXC_TPRER);
 				tctl_val |= V2_TCTL_24MEN;
 			}
 		} else {
@@ -336,47 +342,44 @@ static void __init _mxc_timer_init(int irq,
 		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
 	}
 
-	__raw_writel(tctl_val, timer_base + MXC_TCTL);
+	__raw_writel(tctl_val, imxtm.base + MXC_TCTL);
 
 	/* init and register the timer to the framework */
-	mxc_clocksource_init(clk_per);
-	mxc_clockevent_init(clk_per);
+	mxc_clocksource_init();
+	mxc_clockevent_init();
 
 	/* Make irqs happen */
-	setup_irq(irq, &mxc_timer_irq);
+	setup_irq(imxtm.irq, &mxc_timer_irq);
 }
 
 void __init mxc_timer_init(unsigned long pbase, int irq)
 {
-	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
-	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
+	imxtm.clk_per = clk_get_sys("imx-gpt.0", "per");
+	imxtm.clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
 
-	timer_base = ioremap(pbase, SZ_4K);
-	BUG_ON(!timer_base);
+	imxtm.base = ioremap(pbase, SZ_4K);
+	BUG_ON(!imxtm.base);
 
-	_mxc_timer_init(irq, clk_per, clk_ipg);
+	_mxc_timer_init();
 }
 
 static void __init mxc_timer_init_dt(struct device_node *np)
 {
-	struct clk *clk_per, *clk_ipg;
-	int irq;
-
-	if (timer_base)
+	if (imxtm.base)
 		return;
 
-	timer_base = of_iomap(np, 0);
-	WARN_ON(!timer_base);
-	irq = irq_of_parse_and_map(np, 0);
+	imxtm.base = of_iomap(np, 0);
+	WARN_ON(!imxtm.base);
+	imxtm.irq = irq_of_parse_and_map(np, 0);
 
-	clk_ipg = of_clk_get_by_name(np, "ipg");
+	imxtm.clk_ipg = of_clk_get_by_name(np, "ipg");
 
 	/* Try osc_per first, and fall back to per otherwise */
-	clk_per = of_clk_get_by_name(np, "osc_per");
-	if (IS_ERR(clk_per))
-		clk_per = of_clk_get_by_name(np, "per");
+	imxtm.clk_per = of_clk_get_by_name(np, "osc_per");
+	if (IS_ERR(imxtm.clk_per))
+		imxtm.clk_per = of_clk_get_by_name(np, "per");
 
-	_mxc_timer_init(irq, clk_per, clk_ipg);
+	_mxc_timer_init();
 }
 CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
 CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
-- 
1.9.1

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

* [PATCH 2/9] ARM: imx: define an enum for gpt timer device type
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 1/9] ARM: imx: move timer resources into a structure shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15 16:30   ` Shenwei Wang
  2015-05-15  8:11 ` [PATCH 3/9] ARM: imx: initialize gpt device type for DT boot shawnguo at kernel.org
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Define an enum for gpt timer device type in include/soc/imx/timer.h to
tell the gpt block differences among SoCs.  Update non-DT users (clock
drivers) to pass the device type.

As we now have include/soc/imx/timer.h, the declaration of
mxc_timer_init() is moved into there as the best fit.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/time.c    |  6 +++++-
 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 |  3 ++-
 drivers/clk/imx/clk.h       |  7 -------
 include/soc/imx/timer.h     | 26 ++++++++++++++++++++++++++
 8 files changed, 41 insertions(+), 13 deletions(-)
 create mode 100644 include/soc/imx/timer.h

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 8ad7cb2a7f08..5241a173fd60 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 <soc/imx/timer.h>
 
 #include <asm/mach/time.h>
 
@@ -85,6 +86,7 @@ static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
 struct imx_timer {
+	enum imx_gpt_type type;
 	void __iomem *base;
 	int irq;
 	struct clk *clk_per;
@@ -352,7 +354,7 @@ static void __init _mxc_timer_init(void)
 	setup_irq(imxtm.irq, &mxc_timer_irq);
 }
 
-void __init mxc_timer_init(unsigned long pbase, int irq)
+void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type)
 {
 	imxtm.clk_per = clk_get_sys("imx-gpt.0", "per");
 	imxtm.clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
@@ -360,6 +362,8 @@ void __init mxc_timer_init(unsigned long pbase, int irq)
 	imxtm.base = ioremap(pbase, SZ_4K);
 	BUG_ON(!imxtm.base);
 
+	imxtm.type = type;
+
 	_mxc_timer_init();
 }
 
diff --git a/drivers/clk/imx/clk-imx1.c b/drivers/clk/imx/clk-imx1.c
index c9812dbacac2..c2647fa19f28 100644
--- a/drivers/clk/imx/clk-imx1.c
+++ b/drivers/clk/imx/clk-imx1.c
@@ -23,6 +23,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <dt-bindings/clock/imx1-clock.h>
+#include <soc/imx/timer.h>
 #include <asm/irq.h>
 
 #include "clk.h"
@@ -102,7 +103,7 @@ 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);
+	mxc_timer_init(MX1_TIM1_BASE_ADDR, MX1_TIM1_INT, GPT_TYPE_IMX1);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx21.c b/drivers/clk/imx/clk-imx21.c
index 0ca842cf4ca7..dba987e3b89f 100644
--- a/drivers/clk/imx/clk-imx21.c
+++ b/drivers/clk/imx/clk-imx21.c
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <dt-bindings/clock/imx21-clock.h>
+#include <soc/imx/timer.h>
 #include <asm/irq.h>
 
 #include "clk.h"
@@ -156,7 +157,7 @@ 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);
+	mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, GPT_TYPE_IMX21);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
index df2dfc081c71..d9d50d54ef2a 100644
--- a/drivers/clk/imx/clk-imx27.c
+++ b/drivers/clk/imx/clk-imx27.c
@@ -6,6 +6,7 @@
 #include <linux/of_address.h>
 #include <dt-bindings/clock/imx27-clock.h>
 #include <soc/imx/revision.h>
+#include <soc/imx/timer.h>
 #include <asm/irq.h>
 
 #include "clk.h"
@@ -233,7 +234,7 @@ 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);
+	mxc_timer_init(MX27_GPT1_BASE_ADDR, MX27_INT_GPT1, GPT_TYPE_IMX21);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
index a55290c1c264..fe66c40b7be2 100644
--- a/drivers/clk/imx/clk-imx31.c
+++ b/drivers/clk/imx/clk-imx31.c
@@ -22,6 +22,7 @@
 #include <linux/err.h>
 #include <linux/of.h>
 #include <soc/imx/revision.h>
+#include <soc/imx/timer.h>
 #include <asm/irq.h>
 
 #include "clk.h"
@@ -198,7 +199,7 @@ 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);
+	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
index f2f3b8164f7b..69138ba3dec7 100644
--- a/drivers/clk/imx/clk-imx35.c
+++ b/drivers/clk/imx/clk-imx35.c
@@ -14,6 +14,7 @@
 #include <linux/of.h>
 #include <linux/err.h>
 #include <soc/imx/revision.h>
+#include <soc/imx/timer.h>
 #include <asm/irq.h>
 
 #include "clk.h"
@@ -293,7 +294,7 @@ int __init mx35_clocks_init(void)
 
 	imx_print_silicon_rev("i.MX35", mx35_revision());
 
-	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT);
+	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31);
 
 	return 0;
 }
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 6bae5374dc83..b5297e457a8e 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -6,13 +6,6 @@
 
 extern spinlock_t imx_ccm_lock;
 
-/*
- * This is a stop-gap solution for clock drivers like imx1/imx21 which call
- * 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 imx_check_clocks(struct clk *clks[], unsigned int count);
 
 extern void imx_cscmr1_fixup(u32 *val);
diff --git a/include/soc/imx/timer.h b/include/soc/imx/timer.h
new file mode 100644
index 000000000000..bbbafd65f464
--- /dev/null
+++ b/include/soc/imx/timer.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2015 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SOC_IMX_TIMER_H__
+#define __SOC_IMX_TIMER_H__
+
+enum imx_gpt_type {
+	GPT_TYPE_IMX1,		/* i.MX1 */
+	GPT_TYPE_IMX21,		/* i.MX21/27 */
+	GPT_TYPE_IMX31,		/* i.MX31/35/25/37/51/6Q */
+	GPT_TYPE_IMX6DL,	/* i.MX6DL/SX/SL */
+};
+
+/*
+ * This is a stop-gap solution for clock drivers like imx1/imx21 which call
+ * 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, enum imx_gpt_type type);
+
+#endif  /* __SOC_IMX_TIMER_H__ */
-- 
1.9.1

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

* [PATCH 3/9] ARM: imx: initialize gpt device type for DT boot
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 1/9] ARM: imx: move timer resources into a structure shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 2/9] ARM: imx: define an enum for gpt timer device type shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 4/9] ARM: imx: setup tctl register in device specific function shawnguo at kernel.org
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Use different initialization function in CLOCKSOURCE_OF_DECLARE() to
initialize gpt device type for DT boot.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/time.c | 44 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 36 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 5241a173fd60..ed01813cfc76 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -385,11 +385,39 @@ static void __init mxc_timer_init_dt(struct device_node *np)
 
 	_mxc_timer_init();
 }
-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);
-CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", mxc_timer_init_dt);
-CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", mxc_timer_init_dt);
+
+static void __init imx1_timer_init_dt(struct device_node *np)
+{
+	imxtm.type = GPT_TYPE_IMX1;
+	mxc_timer_init_dt(np);
+}
+
+static void __init imx21_timer_init_dt(struct device_node *np)
+{
+	imxtm.type = GPT_TYPE_IMX21;
+	mxc_timer_init_dt(np);
+}
+
+static void __init imx31_timer_init_dt(struct device_node *np)
+{
+	imxtm.type = GPT_TYPE_IMX31;
+	mxc_timer_init_dt(np);
+}
+
+static void __init imx6dl_timer_init_dt(struct device_node *np)
+{
+	imxtm.type = GPT_TYPE_IMX6DL;
+	mxc_timer_init_dt(np);
+}
+
+CLOCKSOURCE_OF_DECLARE(imx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx21_timer, "fsl,imx21-gpt", imx21_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx31_timer, "fsl,imx31-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx25_timer, "fsl,imx25-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx50_timer, "fsl,imx50-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx51_timer, "fsl,imx51-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx53_timer, "fsl,imx53-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6q_timer, "fsl,imx6q-gpt", imx31_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6dl_timer, "fsl,imx6dl-gpt", imx6dl_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6sl_timer, "fsl,imx6sl-gpt", imx6dl_timer_init_dt);
+CLOCKSOURCE_OF_DECLARE(imx6sx_timer, "fsl,imx6sx-gpt", imx6dl_timer_init_dt);
-- 
1.9.1

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

* [PATCH 4/9] ARM: imx: setup tctl register in device specific function
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
                   ` (2 preceding siblings ...)
  2015-05-15  8:11 ` [PATCH 3/9] ARM: imx: initialize gpt device type for DT boot shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15  8:35   ` Arnd Bergmann
  2015-05-15  8:11 ` [PATCH 5/9] ARM: imx: set up set_next_event hook in imx_timer_data_init() shawnguo at kernel.org
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

It creates device speicific function hook gpt_setup_tctl to set up gpt
TCTL register.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/time.c | 81 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 62 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index ed01813cfc76..c86e25922eb4 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -91,6 +91,7 @@ struct imx_timer {
 	int irq;
 	struct clk *clk_per;
 	struct clk *clk_ipg;
+	void (*gpt_setup_tctl)(void);
 };
 
 static struct imx_timer imxtm;
@@ -306,9 +307,68 @@ static int __init mxc_clockevent_init(void)
 	return 0;
 }
 
+static void imx1_gpt_setup_tctl(void)
+{
+	u32 tctl_val;
+
+	tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
+	__raw_writel(tctl_val, imxtm.base + MXC_TCTL);
+}
+#define imx21_gpt_setup_tctl imx1_gpt_setup_tctl
+
+static void imx31_gpt_setup_tctl(void)
+{
+	u32 tctl_val;
+
+	tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+	if (clk_get_rate(imxtm.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, imxtm.base + MXC_TCTL);
+}
+
+static void imx6dl_gpt_setup_tctl(void)
+{
+	u32 tctl_val;
+
+	tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
+	if (clk_get_rate(imxtm.clk_per) == V2_TIMER_RATE_OSC_DIV8) {
+		tctl_val |= V2_TCTL_CLK_OSC_DIV8;
+		/* 24 / 8 = 3 MHz */
+		__raw_writel(7 << V2_TPRER_PRE24M, imxtm.base + MXC_TPRER);
+		tctl_val |= V2_TCTL_24MEN;
+	} else {
+		tctl_val |= V2_TCTL_CLK_PER;
+	}
+
+	__raw_writel(tctl_val, imxtm.base + MXC_TCTL);
+}
+
+static void __init imx_timer_data_init(void)
+{
+	switch (imxtm.type) {
+	case GPT_TYPE_IMX1:
+		imxtm.gpt_setup_tctl = imx1_gpt_setup_tctl;
+		break;
+	case GPT_TYPE_IMX21:
+		imxtm.gpt_setup_tctl = imx21_gpt_setup_tctl;
+		break;
+	case GPT_TYPE_IMX31:
+		imxtm.gpt_setup_tctl = imx31_gpt_setup_tctl;
+		break;
+	case GPT_TYPE_IMX6DL:
+		imxtm.gpt_setup_tctl = imx6dl_gpt_setup_tctl;
+		break;
+	default:
+		BUG();
+	}
+}
+
 static void __init _mxc_timer_init(void)
 {
-	uint32_t tctl_val;
+	imx_timer_data_init();
 
 	if (IS_ERR(imxtm.clk_per)) {
 		pr_err("i.MX timer: unable to get clk\n");
@@ -327,24 +387,7 @@ static void __init _mxc_timer_init(void)
 	__raw_writel(0, imxtm.base + MXC_TCTL);
 	__raw_writel(0, imxtm.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(imxtm.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,
-					imxtm.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;
-	}
-
-	__raw_writel(tctl_val, imxtm.base + MXC_TCTL);
+	imxtm.gpt_setup_tctl();
 
 	/* init and register the timer to the framework */
 	mxc_clocksource_init();
-- 
1.9.1

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

* [PATCH 5/9] ARM: imx: set up set_next_event hook in imx_timer_data_init()
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
                   ` (3 preceding siblings ...)
  2015-05-15  8:11 ` [PATCH 4/9] ARM: imx: setup tctl register in device specific function shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 6/9] ARM: imx: define gpt register offset per device type shawnguo at kernel.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

Function imx_timer_data_init() was there for setting up device specific
data, so let's move the setup of set_next_event hook into there.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/time.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index c86e25922eb4..d79a00e24084 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -290,15 +290,11 @@ 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(void)
 {
-	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,
 					clk_get_rate(imxtm.clk_per),
@@ -351,15 +347,19 @@ static void __init imx_timer_data_init(void)
 	switch (imxtm.type) {
 	case GPT_TYPE_IMX1:
 		imxtm.gpt_setup_tctl = imx1_gpt_setup_tctl;
+		clockevent_mxc.set_next_event = mx1_2_set_next_event;
 		break;
 	case GPT_TYPE_IMX21:
 		imxtm.gpt_setup_tctl = imx21_gpt_setup_tctl;
+		clockevent_mxc.set_next_event = mx1_2_set_next_event;
 		break;
 	case GPT_TYPE_IMX31:
 		imxtm.gpt_setup_tctl = imx31_gpt_setup_tctl;
+		clockevent_mxc.set_next_event = v2_set_next_event;
 		break;
 	case GPT_TYPE_IMX6DL:
 		imxtm.gpt_setup_tctl = imx6dl_gpt_setup_tctl;
+		clockevent_mxc.set_next_event = v2_set_next_event;
 		break;
 	default:
 		BUG();
-- 
1.9.1

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

* [PATCH 6/9] ARM: imx: define gpt register offset per device type
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
                   ` (4 preceding siblings ...)
  2015-05-15  8:11 ` [PATCH 5/9] ARM: imx: set up set_next_event hook in imx_timer_data_init() shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15  8:34   ` Arnd Bergmann
  2015-05-15  8:11 ` [PATCH 7/9] ARM: imx: provide gpt device specific irq functions shawnguo at kernel.org
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

It initializes offset of gpt registers TSTAT, TCN and TCMP per device
type, so that the access to these registers can be unified.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/time.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index d79a00e24084..5908e78d9552 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -91,6 +91,9 @@ struct imx_timer {
 	int irq;
 	struct clk *clk_per;
 	struct clk *clk_ipg;
+	int reg_tstat;
+	int reg_tcn;
+	int reg_tcmp;
 	void (*gpt_setup_tctl)(void);
 };
 
@@ -147,7 +150,7 @@ static unsigned long imx_read_current_timer(void)
 static int __init mxc_clocksource_init(void)
 {
 	unsigned int c = clk_get_rate(imxtm.clk_per);
-	void __iomem *reg = imxtm.base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
+	void __iomem *reg = imxtm.base + imxtm.reg_tcn;
 
 	imx_delay_timer.read_current_timer = &imx_read_current_timer;
 	imx_delay_timer.freq = c;
@@ -214,13 +217,8 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	gpt_irq_disable();
 
 	if (mode != clockevent_mode) {
-		/* Set event time into far-far future */
-		if (timer_is_v2())
-			__raw_writel(__raw_readl(imxtm.base + V2_TCN) - 3,
-					imxtm.base + V2_TCMP);
-		else
-			__raw_writel(__raw_readl(imxtm.base + MX1_2_TCN) - 3,
-					imxtm.base + MX1_2_TCMP);
+		__raw_writel(__raw_readl(imxtm.base + imxtm.reg_tcn) - 3,
+					imxtm.base + imxtm.reg_tcmp);
 
 		/* Clear pending interrupt */
 		gpt_irq_acknowledge();
@@ -268,10 +266,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 	struct clock_event_device *evt = &clockevent_mxc;
 	uint32_t tstat;
 
-	if (timer_is_v2())
-		tstat = __raw_readl(imxtm.base + V2_TSTAT);
-	else
-		tstat = __raw_readl(imxtm.base + MX1_2_TSTAT);
+	tstat = __raw_readl(imxtm.base + imxtm.reg_tstat);
 
 	gpt_irq_acknowledge();
 
@@ -346,18 +341,30 @@ static void __init imx_timer_data_init(void)
 {
 	switch (imxtm.type) {
 	case GPT_TYPE_IMX1:
+		imxtm.reg_tstat = MX1_2_TSTAT;
+		imxtm.reg_tcn = MX1_2_TCN;
+		imxtm.reg_tcmp = MX1_2_TCMP;
 		imxtm.gpt_setup_tctl = imx1_gpt_setup_tctl;
 		clockevent_mxc.set_next_event = mx1_2_set_next_event;
 		break;
 	case GPT_TYPE_IMX21:
+		imxtm.reg_tstat = MX1_2_TSTAT;
+		imxtm.reg_tcn = MX1_2_TCN;
+		imxtm.reg_tcmp = MX1_2_TCMP;
 		imxtm.gpt_setup_tctl = imx21_gpt_setup_tctl;
 		clockevent_mxc.set_next_event = mx1_2_set_next_event;
 		break;
 	case GPT_TYPE_IMX31:
+		imxtm.reg_tstat = V2_TSTAT;
+		imxtm.reg_tcn = V2_TCN;
+		imxtm.reg_tcmp = V2_TCMP;
 		imxtm.gpt_setup_tctl = imx31_gpt_setup_tctl;
 		clockevent_mxc.set_next_event = v2_set_next_event;
 		break;
 	case GPT_TYPE_IMX6DL:
+		imxtm.reg_tstat = V2_TSTAT;
+		imxtm.reg_tcn = V2_TCN;
+		imxtm.reg_tcmp = V2_TCMP;
 		imxtm.gpt_setup_tctl = imx6dl_gpt_setup_tctl;
 		clockevent_mxc.set_next_event = v2_set_next_event;
 		break;
-- 
1.9.1

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

* [PATCH 7/9] ARM: imx: provide gpt device specific irq functions
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
                   ` (5 preceding siblings ...)
  2015-05-15  8:11 ` [PATCH 6/9] ARM: imx: define gpt register offset per device type shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 8/9] ARM: imx: remove platform headers from timer driver shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 9/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
  8 siblings, 0 replies; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

It splits irq enable/disable/acknowledge operations into device specific
functions to get proper hook called in the correct context.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/time.c | 76 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 51 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 5908e78d9552..174c553a3bb7 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -95,44 +95,58 @@ struct imx_timer {
 	int reg_tcn;
 	int reg_tcmp;
 	void (*gpt_setup_tctl)(void);
+	void (*gpt_irq_enable)(void);
+	void (*gpt_irq_disable)(void);
+	void (*gpt_irq_acknowledge)(void);
 };
 
 static struct imx_timer imxtm;
 
-static inline void gpt_irq_disable(void)
+static void imx1_gpt_irq_disable(void)
 {
 	unsigned int tmp;
 
-	if (timer_is_v2())
-		__raw_writel(0, imxtm.base + V2_IR);
-	else {
-		tmp = __raw_readl(imxtm.base + MXC_TCTL);
-		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, imxtm.base + MXC_TCTL);
-	}
+	tmp = __raw_readl(imxtm.base + MXC_TCTL);
+	__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, imxtm.base + MXC_TCTL);
+}
+#define imx21_gpt_irq_disable imx1_gpt_irq_disable
+
+static void imx31_gpt_irq_disable(void)
+{
+	__raw_writel(0, imxtm.base + V2_IR);
 }
+#define imx6dl_gpt_irq_disable imx31_gpt_irq_disable
 
-static inline void gpt_irq_enable(void)
+static void imx1_gpt_irq_enable(void)
 {
-	if (timer_is_v2())
-		__raw_writel(1<<0, imxtm.base + V2_IR);
-	else {
-		__raw_writel(__raw_readl(imxtm.base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
+	__raw_writel(__raw_readl(imxtm.base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
 			imxtm.base + MXC_TCTL);
-	}
+}
+#define imx21_gpt_irq_enable imx1_gpt_irq_enable
+
+static void imx31_gpt_irq_enable(void)
+{
+	__raw_writel(1<<0, imxtm.base + V2_IR);
+}
+#define imx6dl_gpt_irq_enable imx31_gpt_irq_enable
+
+static void imx1_gpt_irq_acknowledge(void)
+{
+	__raw_writel(0, imxtm.base + MX1_2_TSTAT);
 }
 
-static void gpt_irq_acknowledge(void)
+static void imx21_gpt_irq_acknowledge(void)
 {
-	if (timer_is_v1()) {
-		if (cpu_is_mx1())
-			__raw_writel(0, imxtm.base + MX1_2_TSTAT);
-		else
-			__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
+	__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
 				imxtm.base + MX1_2_TSTAT);
-	} else if (timer_is_v2())
-		__raw_writel(V2_TSTAT_OF1, imxtm.base + V2_TSTAT);
 }
 
+static void imx31_gpt_irq_acknowledge(void)
+{
+	__raw_writel(V2_TSTAT_OF1, imxtm.base + V2_TSTAT);
+}
+#define imx6dl_gpt_irq_acknowledge imx31_gpt_irq_acknowledge
+
 static void __iomem *sched_clock_reg;
 
 static u64 notrace mxc_read_sched_clock(void)
@@ -214,14 +228,14 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	local_irq_save(flags);
 
 	/* Disable interrupt in GPT module */
-	gpt_irq_disable();
+	imxtm.gpt_irq_disable();
 
 	if (mode != clockevent_mode) {
 		__raw_writel(__raw_readl(imxtm.base + imxtm.reg_tcn) - 3,
 					imxtm.base + imxtm.reg_tcmp);
 
 		/* Clear pending interrupt */
-		gpt_irq_acknowledge();
+		imxtm.gpt_irq_acknowledge();
 	}
 
 #ifdef DEBUG
@@ -247,7 +261,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	 * mode switching
 	 */
 		local_irq_save(flags);
-		gpt_irq_enable();
+		imxtm.gpt_irq_enable();
 		local_irq_restore(flags);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
@@ -268,7 +282,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 
 	tstat = __raw_readl(imxtm.base + imxtm.reg_tstat);
 
-	gpt_irq_acknowledge();
+	imxtm.gpt_irq_acknowledge();
 
 	evt->event_handler(evt);
 
@@ -345,6 +359,9 @@ static void __init imx_timer_data_init(void)
 		imxtm.reg_tcn = MX1_2_TCN;
 		imxtm.reg_tcmp = MX1_2_TCMP;
 		imxtm.gpt_setup_tctl = imx1_gpt_setup_tctl;
+		imxtm.gpt_irq_enable = imx1_gpt_irq_enable;
+		imxtm.gpt_irq_disable = imx1_gpt_irq_disable;
+		imxtm.gpt_irq_acknowledge = imx1_gpt_irq_acknowledge;
 		clockevent_mxc.set_next_event = mx1_2_set_next_event;
 		break;
 	case GPT_TYPE_IMX21:
@@ -352,6 +369,9 @@ static void __init imx_timer_data_init(void)
 		imxtm.reg_tcn = MX1_2_TCN;
 		imxtm.reg_tcmp = MX1_2_TCMP;
 		imxtm.gpt_setup_tctl = imx21_gpt_setup_tctl;
+		imxtm.gpt_irq_enable = imx21_gpt_irq_enable;
+		imxtm.gpt_irq_disable = imx21_gpt_irq_disable;
+		imxtm.gpt_irq_acknowledge = imx21_gpt_irq_acknowledge;
 		clockevent_mxc.set_next_event = mx1_2_set_next_event;
 		break;
 	case GPT_TYPE_IMX31:
@@ -359,6 +379,9 @@ static void __init imx_timer_data_init(void)
 		imxtm.reg_tcn = V2_TCN;
 		imxtm.reg_tcmp = V2_TCMP;
 		imxtm.gpt_setup_tctl = imx31_gpt_setup_tctl;
+		imxtm.gpt_irq_enable = imx31_gpt_irq_enable;
+		imxtm.gpt_irq_disable = imx31_gpt_irq_disable;
+		imxtm.gpt_irq_acknowledge = imx31_gpt_irq_acknowledge;
 		clockevent_mxc.set_next_event = v2_set_next_event;
 		break;
 	case GPT_TYPE_IMX6DL:
@@ -366,6 +389,9 @@ static void __init imx_timer_data_init(void)
 		imxtm.reg_tcn = V2_TCN;
 		imxtm.reg_tcmp = V2_TCMP;
 		imxtm.gpt_setup_tctl = imx6dl_gpt_setup_tctl;
+		imxtm.gpt_irq_enable = imx6dl_gpt_irq_enable;
+		imxtm.gpt_irq_disable = imx6dl_gpt_irq_disable;
+		imxtm.gpt_irq_acknowledge = imx6dl_gpt_irq_acknowledge;
 		clockevent_mxc.set_next_event = v2_set_next_event;
 		break;
 	default:
-- 
1.9.1

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

* [PATCH 8/9] ARM: imx: remove platform headers from timer driver
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
                   ` (6 preceding siblings ...)
  2015-05-15  8:11 ` [PATCH 7/9] ARM: imx: provide gpt device specific irq functions shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  2015-05-15  8:11 ` [PATCH 9/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
  8 siblings, 0 replies; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

With the cleanup done before, the platform specific headers now can be
removed.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 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 174c553a3bb7..ecf043f6c6fd 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -35,9 +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.
  *  - MX1/MXL
@@ -79,9 +76,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())
-
 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] 19+ messages in thread

* [PATCH 9/9] ARM: imx: move timer driver into drivers/clocksource
  2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
                   ` (7 preceding siblings ...)
  2015-05-15  8:11 ` [PATCH 8/9] ARM: imx: remove platform headers from timer driver shawnguo at kernel.org
@ 2015-05-15  8:11 ` shawnguo at kernel.org
  8 siblings, 0 replies; 19+ messages in thread
From: shawnguo at kernel.org @ 2015-05-15  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Shawn Guo <shawn.guo@linaro.org>

After the cleanup on imx timer driver, now it's ready to be moved into
drivers/clocksource/.  Let's do it.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/Makefile                                  | 2 +-
 drivers/clocksource/Makefile                                | 1 +
 arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx.c | 0
 3 files changed, 2 insertions(+), 1 deletion(-)
 rename arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx.c (100%)

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 40df12af5036..0ac47955f3e1 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 5b85f6adb258..5c5a89479631 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-imx.o
diff --git a/arch/arm/mach-imx/time.c b/drivers/clocksource/timer-imx.c
similarity index 100%
rename from arch/arm/mach-imx/time.c
rename to drivers/clocksource/timer-imx.c
-- 
1.9.1

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

* [PATCH 6/9] ARM: imx: define gpt register offset per device type
  2015-05-15  8:11 ` [PATCH 6/9] ARM: imx: define gpt register offset per device type shawnguo at kernel.org
@ 2015-05-15  8:34   ` Arnd Bergmann
  2015-05-19  8:09     ` Shawn Guo
  0 siblings, 1 reply; 19+ messages in thread
From: Arnd Bergmann @ 2015-05-15  8:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 15 May 2015 16:11:44 shawnguo at kernel.org wrote:
>  {
>         switch (imxtm.type) {
>         case GPT_TYPE_IMX1:
> +               imxtm.reg_tstat = MX1_2_TSTAT;
> +               imxtm.reg_tcn = MX1_2_TCN;
> +               imxtm.reg_tcmp = MX1_2_TCMP;
>                 imxtm.gpt_setup_tctl = imx1_gpt_setup_tctl;
>                 clockevent_mxc.set_next_event = mx1_2_set_next_event;
>                 break;
>         case GPT_TYPE_IMX21:
> +               imxtm.reg_tstat = MX1_2_TSTAT;
> +               imxtm.reg_tcn = MX1_2_TCN;
> +               imxtm.reg_tcmp = MX1_2_TCMP;
>                 imxtm.gpt_setup_tctl = imx21_gpt_setup_tctl;
>                 clockevent_mxc.set_next_event = mx1_2_set_next_event;
>                 break;
>         case GPT_TYPE_IMX31:
> +               imxtm.reg_tstat = V2_TSTAT;
> +               imxtm.reg_tcn = V2_TCN;
> +               imxtm.reg_tcmp = V2_TCMP;
>                 imxtm.gpt_setup_tctl = imx31_gpt_setup_tctl;
>                 clockevent_mxc.set_next_event = v2_set_next_event;
>                 break;
>         case GPT_TYPE_IMX6DL:
> +               imxtm.reg_tstat = V2_TSTAT;
> +               imxtm.reg_tcn = V2_TCN;
> +               imxtm.reg_tcmp = V2_TCMP;
>                 imxtm.gpt_setup_tctl = imx6dl_gpt_setup_tctl;
>                 clockevent_mxc.set_next_event = v2_set_next_event;
>                 break;
> 

Hi Shawn,

I think this could be expressed in a nicer way by defining a structure
that contains all the settings you derive from the type here, and then
setting a pointer to that structure based on the compatible string.

	Arnd

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

* [PATCH 4/9] ARM: imx: setup tctl register in device specific function
  2015-05-15  8:11 ` [PATCH 4/9] ARM: imx: setup tctl register in device specific function shawnguo at kernel.org
@ 2015-05-15  8:35   ` Arnd Bergmann
  2015-05-19  8:08     ` Shawn Guo
  0 siblings, 1 reply; 19+ messages in thread
From: Arnd Bergmann @ 2015-05-15  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 15 May 2015 16:11:42 shawnguo at kernel.org wrote:
>  }
>  
> +static void imx1_gpt_setup_tctl(void)
> +{
> +       u32 tctl_val;
> +
> +       tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
> +       __raw_writel(tctl_val, imxtm.base + MXC_TCTL);
> +}
> 

Could you add another upfront patch to convert all the __raw_readl/__raw_writel
to readl_relaxed/writel_relaxed?

It would be nice if the driver was endian-safe by the time it gets moved to
drivers/clocksource, and you don't add any unsafe accesses for the changed
code.

	Arnd

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

* [PATCH 2/9] ARM: imx: define an enum for gpt timer device type
  2015-05-15  8:11 ` [PATCH 2/9] ARM: imx: define an enum for gpt timer device type shawnguo at kernel.org
@ 2015-05-15 16:30   ` Shenwei Wang
  0 siblings, 0 replies; 19+ messages in thread
From: Shenwei Wang @ 2015-05-15 16:30 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: shawnguo at kernel.org [mailto:shawnguo at kernel.org]
> Sent: 2015?5?15? 3:12
> To: linux-arm-kernel at lists.infradead.org
> Cc: kernel at pengutronix.de; Daniel Lezcano; Wang Shenwei-B38339; Shawn Guo
> Subject: [PATCH 2/9] ARM: imx: define an enum for gpt timer device type
> 
> From: Shawn Guo <shawn.guo@linaro.org>
> 
> Define an enum for gpt timer device type in include/soc/imx/timer.h to tell the
> gpt block differences among SoCs.  Update non-DT users (clock
> drivers) to pass the device type.
> 
> As we now have include/soc/imx/timer.h, the declaration of
> mxc_timer_init() is moved into there as the best fit.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> 000000000000..bbbafd65f464
> --- /dev/null
> +++ b/include/soc/imx/timer.h
> @@ -0,0 +1,26 @@
> +/*
> + * Copyright 2015 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __SOC_IMX_TIMER_H__
> +#define __SOC_IMX_TIMER_H__
> +
> +enum imx_gpt_type {
> +	GPT_TYPE_IMX1,		/* i.MX1 */
> +	GPT_TYPE_IMX21,		/* i.MX21/27 */
> +	GPT_TYPE_IMX31,		/* i.MX31/35/25/37/51/6Q */
> +	GPT_TYPE_IMX6DL,	/* i.MX6DL/SX/SL */
> +};
> +

Since there is only one type of GPT IP block with different versions, I think to use the word of "GPT_VER_xxx" would make sense.

Regards,
Shenwei

> +/*
> + * This is a stop-gap solution for clock drivers like imx1/imx21 which
> +call
> + * 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, enum imx_gpt_type
> +type);
> +
> +#endif  /* __SOC_IMX_TIMER_H__ */
> --
> 1.9.1

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

* [PATCH 1/9] ARM: imx: move timer resources into a structure
  2015-05-15  8:11 ` [PATCH 1/9] ARM: imx: move timer resources into a structure shawnguo at kernel.org
@ 2015-05-15 16:36   ` Shenwei Wang
  2015-05-19  7:57     ` Shawn Guo
  2015-05-18 10:43   ` Daniel Lezcano
  1 sibling, 1 reply; 19+ messages in thread
From: Shenwei Wang @ 2015-05-15 16:36 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: shawnguo at kernel.org [mailto:shawnguo at kernel.org]
> Sent: 2015?5?15? 3:12
> To: linux-arm-kernel at lists.infradead.org
> Cc: kernel at pengutronix.de; Daniel Lezcano; Wang Shenwei-B38339; Shawn Guo
> Subject: [PATCH 1/9] ARM: imx: move timer resources into a structure
> 
> From: Shawn Guo <shawn.guo@linaro.org>
> 
> Instead of passing around as argument, let's move timer resources like irq and
> clocks together with base address into a data structure, and reference the
> resources from the struct variable directly to simplify the function call interface.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
>  arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++-----------------------
>  1 file changed, 61 insertions(+), 58 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index
> ab5ee1c445f3..8ad7cb2a7f08 100644
> --- a/arch/arm/mach-imx/time.c
> +++ b/arch/arm/mach-imx/time.c
> @@ -84,27 +84,34 @@
>  static struct clock_event_device clockevent_mxc;  static enum
> clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> 
> -static void __iomem *timer_base;
> +struct imx_timer {
> +	void __iomem *base;
> +	int irq;
> +	struct clk *clk_per;
> +	struct clk *clk_ipg;
> +};
> +
> +static struct imx_timer imxtm;
> 
Since the changes still used a global variable to hold the information, it doesn't take advantage of what the clocksource framework provides, and make the driver unable to support multi-instances.

Regards,
Shenwei

>  static inline void gpt_irq_disable(void)  {
>  	unsigned int tmp;
> 
>  	if (timer_is_v2())
> -		__raw_writel(0, timer_base + V2_IR);
> +		__raw_writel(0, imxtm.base + V2_IR);
>  	else {
> -		tmp = __raw_readl(timer_base + MXC_TCTL);
> -		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
> +		tmp = __raw_readl(imxtm.base + MXC_TCTL);
> +		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, imxtm.base + MXC_TCTL);
>  	}
>  }
> 
>  static inline void gpt_irq_enable(void)  {
>  	if (timer_is_v2())
> -		__raw_writel(1<<0, timer_base + V2_IR);
> +		__raw_writel(1<<0, imxtm.base + V2_IR);
>  	else {
> -		__raw_writel(__raw_readl(timer_base + MXC_TCTL) |
> MX1_2_TCTL_IRQEN,
> -			timer_base + MXC_TCTL);
> +		__raw_writel(__raw_readl(imxtm.base + MXC_TCTL) |
> MX1_2_TCTL_IRQEN,
> +			imxtm.base + MXC_TCTL);
>  	}
>  }
> 
> @@ -112,12 +119,12 @@ static void gpt_irq_acknowledge(void)  {
>  	if (timer_is_v1()) {
>  		if (cpu_is_mx1())
> -			__raw_writel(0, timer_base + MX1_2_TSTAT);
> +			__raw_writel(0, imxtm.base + MX1_2_TSTAT);
>  		else
>  			__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
> -				timer_base + MX1_2_TSTAT);
> +				imxtm.base + MX1_2_TSTAT);
>  	} else if (timer_is_v2())
> -		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
> +		__raw_writel(V2_TSTAT_OF1, imxtm.base + V2_TSTAT);
>  }
> 
>  static void __iomem *sched_clock_reg;
> @@ -134,10 +141,10 @@ 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(void)
>  {
> -	unsigned int c = clk_get_rate(timer_clk);
> -	void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
> +	unsigned int c = clk_get_rate(imxtm.clk_per);
> +	void __iomem *reg = imxtm.base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
> 
>  	imx_delay_timer.read_current_timer = &imx_read_current_timer;
>  	imx_delay_timer.freq = c;
> @@ -157,11 +164,11 @@ static int mx1_2_set_next_event(unsigned long evt,
> {
>  	unsigned long tcmp;
> 
> -	tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt;
> +	tcmp = __raw_readl(imxtm.base + MX1_2_TCN) + evt;
> 
> -	__raw_writel(tcmp, timer_base + MX1_2_TCMP);
> +	__raw_writel(tcmp, imxtm.base + MX1_2_TCMP);
> 
> -	return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ?
> +	return (int)(tcmp - __raw_readl(imxtm.base + MX1_2_TCN)) < 0 ?
>  				-ETIME : 0;
>  }
> 
> @@ -170,12 +177,12 @@ static int v2_set_next_event(unsigned long evt,  {
>  	unsigned long tcmp;
> 
> -	tcmp = __raw_readl(timer_base + V2_TCN) + evt;
> +	tcmp = __raw_readl(imxtm.base + V2_TCN) + evt;
> 
> -	__raw_writel(tcmp, timer_base + V2_TCMP);
> +	__raw_writel(tcmp, imxtm.base + V2_TCMP);
> 
>  	return evt < 0x7fffffff &&
> -		(int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
> +		(int)(tcmp - __raw_readl(imxtm.base + V2_TCN)) < 0 ?
>  				-ETIME : 0;
>  }
> 
> @@ -206,11 +213,11 @@ static void mxc_set_mode(enum clock_event_mode
> mode,
>  	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);
> +			__raw_writel(__raw_readl(imxtm.base + V2_TCN) - 3,
> +					imxtm.base + V2_TCMP);
>  		else
> -			__raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
> -					timer_base + MX1_2_TCMP);
> +			__raw_writel(__raw_readl(imxtm.base + MX1_2_TCN) - 3,
> +					imxtm.base + MX1_2_TCMP);
> 
>  		/* Clear pending interrupt */
>  		gpt_irq_acknowledge();
> @@ -259,9 +266,9 @@ static irqreturn_t mxc_timer_interrupt(int irq, void
> *dev_id)
>  	uint32_t tstat;
> 
>  	if (timer_is_v2())
> -		tstat = __raw_readl(timer_base + V2_TSTAT);
> +		tstat = __raw_readl(imxtm.base + V2_TSTAT);
>  	else
> -		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
> +		tstat = __raw_readl(imxtm.base + MX1_2_TSTAT);
> 
>  	gpt_irq_acknowledge();
> 
> @@ -284,49 +291,48 @@ 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(void)
>  {
>  	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,
> -					clk_get_rate(timer_clk),
> +					clk_get_rate(imxtm.clk_per),
>  					0xff, 0xfffffffe);
> 
>  	return 0;
>  }
> 
> -static void __init _mxc_timer_init(int irq,
> -				   struct clk *clk_per, struct clk *clk_ipg)
> +static void __init _mxc_timer_init(void)
>  {
>  	uint32_t tctl_val;
> 
> -	if (IS_ERR(clk_per)) {
> +	if (IS_ERR(imxtm.clk_per)) {
>  		pr_err("i.MX timer: unable to get clk\n");
>  		return;
>  	}
> 
> -	if (!IS_ERR(clk_ipg))
> -		clk_prepare_enable(clk_ipg);
> +	if (!IS_ERR(imxtm.clk_ipg))
> +		clk_prepare_enable(imxtm.clk_ipg);
> 
> -	clk_prepare_enable(clk_per);
> +	clk_prepare_enable(imxtm.clk_per);
> 
>  	/*
>  	 * Initialise to a known state (all timers off, and timing reset)
>  	 */
> 
> -	__raw_writel(0, timer_base + MXC_TCTL);
> -	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
> +	__raw_writel(0, imxtm.base + MXC_TCTL);
> +	__raw_writel(0, imxtm.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) {
> +		if (clk_get_rate(imxtm.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);
> +					imxtm.base + MXC_TPRER);
>  				tctl_val |= V2_TCTL_24MEN;
>  			}
>  		} else {
> @@ -336,47 +342,44 @@ static void __init _mxc_timer_init(int irq,
>  		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 |
> MXC_TCTL_TEN;
>  	}
> 
> -	__raw_writel(tctl_val, timer_base + MXC_TCTL);
> +	__raw_writel(tctl_val, imxtm.base + MXC_TCTL);
> 
>  	/* init and register the timer to the framework */
> -	mxc_clocksource_init(clk_per);
> -	mxc_clockevent_init(clk_per);
> +	mxc_clocksource_init();
> +	mxc_clockevent_init();
> 
>  	/* Make irqs happen */
> -	setup_irq(irq, &mxc_timer_irq);
> +	setup_irq(imxtm.irq, &mxc_timer_irq);
>  }
> 
>  void __init mxc_timer_init(unsigned long pbase, int irq)  {
> -	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
> -	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
> +	imxtm.clk_per = clk_get_sys("imx-gpt.0", "per");
> +	imxtm.clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
> 
> -	timer_base = ioremap(pbase, SZ_4K);
> -	BUG_ON(!timer_base);
> +	imxtm.base = ioremap(pbase, SZ_4K);
> +	BUG_ON(!imxtm.base);
> 
> -	_mxc_timer_init(irq, clk_per, clk_ipg);
> +	_mxc_timer_init();
>  }
> 
>  static void __init mxc_timer_init_dt(struct device_node *np)  {
> -	struct clk *clk_per, *clk_ipg;
> -	int irq;
> -
> -	if (timer_base)
> +	if (imxtm.base)
>  		return;
> 
> -	timer_base = of_iomap(np, 0);
> -	WARN_ON(!timer_base);
> -	irq = irq_of_parse_and_map(np, 0);
> +	imxtm.base = of_iomap(np, 0);
> +	WARN_ON(!imxtm.base);
> +	imxtm.irq = irq_of_parse_and_map(np, 0);
> 
> -	clk_ipg = of_clk_get_by_name(np, "ipg");
> +	imxtm.clk_ipg = of_clk_get_by_name(np, "ipg");
> 
>  	/* Try osc_per first, and fall back to per otherwise */
> -	clk_per = of_clk_get_by_name(np, "osc_per");
> -	if (IS_ERR(clk_per))
> -		clk_per = of_clk_get_by_name(np, "per");
> +	imxtm.clk_per = of_clk_get_by_name(np, "osc_per");
> +	if (IS_ERR(imxtm.clk_per))
> +		imxtm.clk_per = of_clk_get_by_name(np, "per");
> 
> -	_mxc_timer_init(irq, clk_per, clk_ipg);
> +	_mxc_timer_init();
>  }
>  CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
> CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
> --
> 1.9.1

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

* [PATCH 1/9] ARM: imx: move timer resources into a structure
  2015-05-15  8:11 ` [PATCH 1/9] ARM: imx: move timer resources into a structure shawnguo at kernel.org
  2015-05-15 16:36   ` Shenwei Wang
@ 2015-05-18 10:43   ` Daniel Lezcano
  2015-05-19  7:58     ` Shawn Guo
  1 sibling, 1 reply; 19+ messages in thread
From: Daniel Lezcano @ 2015-05-18 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/15/2015 10:11 AM, shawnguo at kernel.org wrote:
> From: Shawn Guo <shawn.guo@linaro.org>
>
> Instead of passing around as argument, let's move timer resources like
> irq and clocks together with base address into a data structure, and
> reference the resources from the struct variable directly to simplify
> the function call interface.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>

I would be nice to embed the clockevent_mxc variable in the structure as 
well and use container_of to retrieve the structure from the struct 
clockevent.

The struct clockevent can be the unified parameter across the different 
functions.

Refer to drivers/clocksource/rockchip_timer.c as an example.

> ---
>   arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++-----------------------
>   1 file changed, 61 insertions(+), 58 deletions(-)
>
> diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
> index ab5ee1c445f3..8ad7cb2a7f08 100644
> --- a/arch/arm/mach-imx/time.c
> +++ b/arch/arm/mach-imx/time.c
> @@ -84,27 +84,34 @@
>   static struct clock_event_device clockevent_mxc;
>   static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
>
> -static void __iomem *timer_base;
> +struct imx_timer {
> +	void __iomem *base;
> +	int irq;
> +	struct clk *clk_per;
> +	struct clk *clk_ipg;
> +};
> +
> +static struct imx_timer imxtm;
>
>   static inline void gpt_irq_disable(void)
>   {
>   	unsigned int tmp;
>
>   	if (timer_is_v2())
> -		__raw_writel(0, timer_base + V2_IR);
> +		__raw_writel(0, imxtm.base + V2_IR);
>   	else {
> -		tmp = __raw_readl(timer_base + MXC_TCTL);
> -		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
> +		tmp = __raw_readl(imxtm.base + MXC_TCTL);
> +		__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, imxtm.base + MXC_TCTL);
>   	}
>   }
>
>   static inline void gpt_irq_enable(void)
>   {
>   	if (timer_is_v2())
> -		__raw_writel(1<<0, timer_base + V2_IR);
> +		__raw_writel(1<<0, imxtm.base + V2_IR);
>   	else {
> -		__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
> -			timer_base + MXC_TCTL);
> +		__raw_writel(__raw_readl(imxtm.base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
> +			imxtm.base + MXC_TCTL);
>   	}
>   }
>
> @@ -112,12 +119,12 @@ static void gpt_irq_acknowledge(void)
>   {
>   	if (timer_is_v1()) {
>   		if (cpu_is_mx1())
> -			__raw_writel(0, timer_base + MX1_2_TSTAT);
> +			__raw_writel(0, imxtm.base + MX1_2_TSTAT);
>   		else
>   			__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
> -				timer_base + MX1_2_TSTAT);
> +				imxtm.base + MX1_2_TSTAT);
>   	} else if (timer_is_v2())
> -		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
> +		__raw_writel(V2_TSTAT_OF1, imxtm.base + V2_TSTAT);
>   }
>
>   static void __iomem *sched_clock_reg;
> @@ -134,10 +141,10 @@ 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(void)
>   {
> -	unsigned int c = clk_get_rate(timer_clk);
> -	void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
> +	unsigned int c = clk_get_rate(imxtm.clk_per);
> +	void __iomem *reg = imxtm.base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
>
>   	imx_delay_timer.read_current_timer = &imx_read_current_timer;
>   	imx_delay_timer.freq = c;
> @@ -157,11 +164,11 @@ static int mx1_2_set_next_event(unsigned long evt,
>   {
>   	unsigned long tcmp;
>
> -	tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt;
> +	tcmp = __raw_readl(imxtm.base + MX1_2_TCN) + evt;
>
> -	__raw_writel(tcmp, timer_base + MX1_2_TCMP);
> +	__raw_writel(tcmp, imxtm.base + MX1_2_TCMP);
>
> -	return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ?
> +	return (int)(tcmp - __raw_readl(imxtm.base + MX1_2_TCN)) < 0 ?
>   				-ETIME : 0;
>   }
>
> @@ -170,12 +177,12 @@ static int v2_set_next_event(unsigned long evt,
>   {
>   	unsigned long tcmp;
>
> -	tcmp = __raw_readl(timer_base + V2_TCN) + evt;
> +	tcmp = __raw_readl(imxtm.base + V2_TCN) + evt;
>
> -	__raw_writel(tcmp, timer_base + V2_TCMP);
> +	__raw_writel(tcmp, imxtm.base + V2_TCMP);
>
>   	return evt < 0x7fffffff &&
> -		(int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
> +		(int)(tcmp - __raw_readl(imxtm.base + V2_TCN)) < 0 ?
>   				-ETIME : 0;
>   }
>
> @@ -206,11 +213,11 @@ static void mxc_set_mode(enum clock_event_mode mode,
>   	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);
> +			__raw_writel(__raw_readl(imxtm.base + V2_TCN) - 3,
> +					imxtm.base + V2_TCMP);
>   		else
> -			__raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
> -					timer_base + MX1_2_TCMP);
> +			__raw_writel(__raw_readl(imxtm.base + MX1_2_TCN) - 3,
> +					imxtm.base + MX1_2_TCMP);
>
>   		/* Clear pending interrupt */
>   		gpt_irq_acknowledge();
> @@ -259,9 +266,9 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
>   	uint32_t tstat;
>
>   	if (timer_is_v2())
> -		tstat = __raw_readl(timer_base + V2_TSTAT);
> +		tstat = __raw_readl(imxtm.base + V2_TSTAT);
>   	else
> -		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
> +		tstat = __raw_readl(imxtm.base + MX1_2_TSTAT);
>
>   	gpt_irq_acknowledge();
>
> @@ -284,49 +291,48 @@ 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(void)
>   {
>   	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,
> -					clk_get_rate(timer_clk),
> +					clk_get_rate(imxtm.clk_per),
>   					0xff, 0xfffffffe);
>
>   	return 0;
>   }
>
> -static void __init _mxc_timer_init(int irq,
> -				   struct clk *clk_per, struct clk *clk_ipg)
> +static void __init _mxc_timer_init(void)
>   {
>   	uint32_t tctl_val;
>
> -	if (IS_ERR(clk_per)) {
> +	if (IS_ERR(imxtm.clk_per)) {
>   		pr_err("i.MX timer: unable to get clk\n");
>   		return;
>   	}
>
> -	if (!IS_ERR(clk_ipg))
> -		clk_prepare_enable(clk_ipg);
> +	if (!IS_ERR(imxtm.clk_ipg))
> +		clk_prepare_enable(imxtm.clk_ipg);
>
> -	clk_prepare_enable(clk_per);
> +	clk_prepare_enable(imxtm.clk_per);
>
>   	/*
>   	 * Initialise to a known state (all timers off, and timing reset)
>   	 */
>
> -	__raw_writel(0, timer_base + MXC_TCTL);
> -	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
> +	__raw_writel(0, imxtm.base + MXC_TCTL);
> +	__raw_writel(0, imxtm.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) {
> +		if (clk_get_rate(imxtm.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);
> +					imxtm.base + MXC_TPRER);
>   				tctl_val |= V2_TCTL_24MEN;
>   			}
>   		} else {
> @@ -336,47 +342,44 @@ static void __init _mxc_timer_init(int irq,
>   		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
>   	}
>
> -	__raw_writel(tctl_val, timer_base + MXC_TCTL);
> +	__raw_writel(tctl_val, imxtm.base + MXC_TCTL);
>
>   	/* init and register the timer to the framework */
> -	mxc_clocksource_init(clk_per);
> -	mxc_clockevent_init(clk_per);
> +	mxc_clocksource_init();
> +	mxc_clockevent_init();
>
>   	/* Make irqs happen */
> -	setup_irq(irq, &mxc_timer_irq);
> +	setup_irq(imxtm.irq, &mxc_timer_irq);
>   }
>
>   void __init mxc_timer_init(unsigned long pbase, int irq)
>   {
> -	struct clk *clk_per = clk_get_sys("imx-gpt.0", "per");
> -	struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
> +	imxtm.clk_per = clk_get_sys("imx-gpt.0", "per");
> +	imxtm.clk_ipg = clk_get_sys("imx-gpt.0", "ipg");
>
> -	timer_base = ioremap(pbase, SZ_4K);
> -	BUG_ON(!timer_base);
> +	imxtm.base = ioremap(pbase, SZ_4K);
> +	BUG_ON(!imxtm.base);
>
> -	_mxc_timer_init(irq, clk_per, clk_ipg);
> +	_mxc_timer_init();
>   }
>
>   static void __init mxc_timer_init_dt(struct device_node *np)
>   {
> -	struct clk *clk_per, *clk_ipg;
> -	int irq;
> -
> -	if (timer_base)
> +	if (imxtm.base)
>   		return;
>
> -	timer_base = of_iomap(np, 0);
> -	WARN_ON(!timer_base);
> -	irq = irq_of_parse_and_map(np, 0);
> +	imxtm.base = of_iomap(np, 0);
> +	WARN_ON(!imxtm.base);
> +	imxtm.irq = irq_of_parse_and_map(np, 0);
>
> -	clk_ipg = of_clk_get_by_name(np, "ipg");
> +	imxtm.clk_ipg = of_clk_get_by_name(np, "ipg");
>
>   	/* Try osc_per first, and fall back to per otherwise */
> -	clk_per = of_clk_get_by_name(np, "osc_per");
> -	if (IS_ERR(clk_per))
> -		clk_per = of_clk_get_by_name(np, "per");
> +	imxtm.clk_per = of_clk_get_by_name(np, "osc_per");
> +	if (IS_ERR(imxtm.clk_per))
> +		imxtm.clk_per = of_clk_get_by_name(np, "per");
>
> -	_mxc_timer_init(irq, clk_per, clk_ipg);
> +	_mxc_timer_init();
>   }
>   CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt);
>   CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt);
>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

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

* [PATCH 1/9] ARM: imx: move timer resources into a structure
  2015-05-15 16:36   ` Shenwei Wang
@ 2015-05-19  7:57     ` Shawn Guo
  0 siblings, 0 replies; 19+ messages in thread
From: Shawn Guo @ 2015-05-19  7:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 15, 2015 at 04:36:18PM +0000, Shenwei Wang wrote:
> 
> 
> > -----Original Message-----
> > From: shawnguo at kernel.org [mailto:shawnguo at kernel.org]
> > Sent: 2015?5?15? 3:12
> > To: linux-arm-kernel at lists.infradead.org
> > Cc: kernel at pengutronix.de; Daniel Lezcano; Wang Shenwei-B38339; Shawn Guo
> > Subject: [PATCH 1/9] ARM: imx: move timer resources into a structure
> > 
> > From: Shawn Guo <shawn.guo@linaro.org>
> > 
> > Instead of passing around as argument, let's move timer resources like irq and
> > clocks together with base address into a data structure, and reference the
> > resources from the struct variable directly to simplify the function call interface.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> >  arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++-----------------------
> >  1 file changed, 61 insertions(+), 58 deletions(-)
> > 
> > diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index
> > ab5ee1c445f3..8ad7cb2a7f08 100644
> > --- a/arch/arm/mach-imx/time.c
> > +++ b/arch/arm/mach-imx/time.c
> > @@ -84,27 +84,34 @@
> >  static struct clock_event_device clockevent_mxc;  static enum
> > clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> > 
> > -static void __iomem *timer_base;
> > +struct imx_timer {
> > +	void __iomem *base;
> > +	int irq;
> > +	struct clk *clk_per;
> > +	struct clk *clk_ipg;
> > +};
> > +
> > +static struct imx_timer imxtm;
> > 
> Since the changes still used a global variable to hold the information, it doesn't take advantage of what the clocksource framework provides, and make the driver unable to support multi-instances.
> 

The goal of the series is to clean up cpu_is_xxx usages, and move the
driver into drivers/clocksource.  The multi-instances can be supported
later when we see a need for that.

Shawn

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

* [PATCH 1/9] ARM: imx: move timer resources into a structure
  2015-05-18 10:43   ` Daniel Lezcano
@ 2015-05-19  7:58     ` Shawn Guo
  0 siblings, 0 replies; 19+ messages in thread
From: Shawn Guo @ 2015-05-19  7:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 18, 2015 at 12:43:10PM +0200, Daniel Lezcano wrote:
> On 05/15/2015 10:11 AM, shawnguo at kernel.org wrote:
> >From: Shawn Guo <shawn.guo@linaro.org>
> >
> >Instead of passing around as argument, let's move timer resources like
> >irq and clocks together with base address into a data structure, and
> >reference the resources from the struct variable directly to simplify
> >the function call interface.
> >
> >Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> 
> I would be nice to embed the clockevent_mxc variable in the
> structure as well and use container_of to retrieve the structure
> from the struct clockevent.
> 
> The struct clockevent can be the unified parameter across the
> different functions.
> 
> Refer to drivers/clocksource/rockchip_timer.c as an example.

Okay, thanks for the example.  I will add a patch to do that.

Shawn

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

* [PATCH 4/9] ARM: imx: setup tctl register in device specific function
  2015-05-15  8:35   ` Arnd Bergmann
@ 2015-05-19  8:08     ` Shawn Guo
  0 siblings, 0 replies; 19+ messages in thread
From: Shawn Guo @ 2015-05-19  8:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 15, 2015 at 10:35:51AM +0200, Arnd Bergmann wrote:
> On Friday 15 May 2015 16:11:42 shawnguo at kernel.org wrote:
> >  }
> >  
> > +static void imx1_gpt_setup_tctl(void)
> > +{
> > +       u32 tctl_val;
> > +
> > +       tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
> > +       __raw_writel(tctl_val, imxtm.base + MXC_TCTL);
> > +}
> > 
> 
> Could you add another upfront patch to convert all the __raw_readl/__raw_writel
> to readl_relaxed/writel_relaxed?
> 
> It would be nice if the driver was endian-safe by the time it gets moved to
> drivers/clocksource, and you don't add any unsafe accesses for the changed
> code.

Make sense.  Will do.

Shawn

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

* [PATCH 6/9] ARM: imx: define gpt register offset per device type
  2015-05-15  8:34   ` Arnd Bergmann
@ 2015-05-19  8:09     ` Shawn Guo
  0 siblings, 0 replies; 19+ messages in thread
From: Shawn Guo @ 2015-05-19  8:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 15, 2015 at 10:34:03AM +0200, Arnd Bergmann wrote:
> On Friday 15 May 2015 16:11:44 shawnguo at kernel.org wrote:
> >  {
> >         switch (imxtm.type) {
> >         case GPT_TYPE_IMX1:
> > +               imxtm.reg_tstat = MX1_2_TSTAT;
> > +               imxtm.reg_tcn = MX1_2_TCN;
> > +               imxtm.reg_tcmp = MX1_2_TCMP;
> >                 imxtm.gpt_setup_tctl = imx1_gpt_setup_tctl;
> >                 clockevent_mxc.set_next_event = mx1_2_set_next_event;
> >                 break;
> >         case GPT_TYPE_IMX21:
> > +               imxtm.reg_tstat = MX1_2_TSTAT;
> > +               imxtm.reg_tcn = MX1_2_TCN;
> > +               imxtm.reg_tcmp = MX1_2_TCMP;
> >                 imxtm.gpt_setup_tctl = imx21_gpt_setup_tctl;
> >                 clockevent_mxc.set_next_event = mx1_2_set_next_event;
> >                 break;
> >         case GPT_TYPE_IMX31:
> > +               imxtm.reg_tstat = V2_TSTAT;
> > +               imxtm.reg_tcn = V2_TCN;
> > +               imxtm.reg_tcmp = V2_TCMP;
> >                 imxtm.gpt_setup_tctl = imx31_gpt_setup_tctl;
> >                 clockevent_mxc.set_next_event = v2_set_next_event;
> >                 break;
> >         case GPT_TYPE_IMX6DL:
> > +               imxtm.reg_tstat = V2_TSTAT;
> > +               imxtm.reg_tcn = V2_TCN;
> > +               imxtm.reg_tcmp = V2_TCMP;
> >                 imxtm.gpt_setup_tctl = imx6dl_gpt_setup_tctl;
> >                 clockevent_mxc.set_next_event = v2_set_next_event;
> >                 break;
> > 
> 
> Hi Shawn,
> 
> I think this could be expressed in a nicer way by defining a structure
> that contains all the settings you derive from the type here, and then
> setting a pointer to that structure based on the compatible string.

Yeah, good suggestion.  Will change.

Shawn

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

end of thread, other threads:[~2015-05-19  8:09 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-15  8:11 [PATCH 0/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org
2015-05-15  8:11 ` [PATCH 1/9] ARM: imx: move timer resources into a structure shawnguo at kernel.org
2015-05-15 16:36   ` Shenwei Wang
2015-05-19  7:57     ` Shawn Guo
2015-05-18 10:43   ` Daniel Lezcano
2015-05-19  7:58     ` Shawn Guo
2015-05-15  8:11 ` [PATCH 2/9] ARM: imx: define an enum for gpt timer device type shawnguo at kernel.org
2015-05-15 16:30   ` Shenwei Wang
2015-05-15  8:11 ` [PATCH 3/9] ARM: imx: initialize gpt device type for DT boot shawnguo at kernel.org
2015-05-15  8:11 ` [PATCH 4/9] ARM: imx: setup tctl register in device specific function shawnguo at kernel.org
2015-05-15  8:35   ` Arnd Bergmann
2015-05-19  8:08     ` Shawn Guo
2015-05-15  8:11 ` [PATCH 5/9] ARM: imx: set up set_next_event hook in imx_timer_data_init() shawnguo at kernel.org
2015-05-15  8:11 ` [PATCH 6/9] ARM: imx: define gpt register offset per device type shawnguo at kernel.org
2015-05-15  8:34   ` Arnd Bergmann
2015-05-19  8:09     ` Shawn Guo
2015-05-15  8:11 ` [PATCH 7/9] ARM: imx: provide gpt device specific irq functions shawnguo at kernel.org
2015-05-15  8:11 ` [PATCH 8/9] ARM: imx: remove platform headers from timer driver shawnguo at kernel.org
2015-05-15  8:11 ` [PATCH 9/9] ARM: imx: move timer driver into drivers/clocksource shawnguo at kernel.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).