All of lore.kernel.org
 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 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.