ARM: imx: move timer driver into drivers/clocksource
Subsystems (6)
cover ARM: imx: move timer driver into drivers/clocksource
From: Shawn Guo <[email protected]>
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
Signature · 1 line
1.9.1
PATCH 1/9 ARM: imx: move timer resources into a structure
From: Shawn Guo <[email protected]>
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.
--- arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 58 deletions(-)
arch/arm/mach-imx/time.c +61 -58
@@ -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);
Signature · 1 line
1.9.1
PATCH 1/9 ARM: imx: move timer resources into a structure
Quoted 28 lines
-----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 structureFrom: Shawn Guo <[email protected]>
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 <[email protected]>--- arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 58 deletions(-)arch/arm/mach-imx/time.c index renamed from arch/arm/mach-imx/time.c +0
-0
ab5ee1c445f3..8ad7cb2a7f08100644arch/arm/mach-imx/time.c +0
-0@@ -84,27 +84,34 @@static struct clock_event_device clockevent_mxc;static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ;
arch/arm/mach-imx/time.c line 95
Quoted 10 lines
arch/arm/mach-imx/time.c +8
-1-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
Quoted 245 lines
arch/arm/mach-imx/time.c +22
-22static 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 */ arch/arm/mach-imx/time.c +31
-36gpt_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
PATCH 1/9 ARM: imx: move timer resources into a structure
Quoted 28 lines · Shenwei Wang
Quoted 28 lines
-----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 structureFrom: Shawn Guo <[email protected]>
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 <[email protected]>--- arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 58 deletions(-)arch/arm/mach-imx/time.c index renamed from arch/arm/mach-imx/time.c +0
-0
ab5ee1c445f3..8ad7cb2a7f08100644arch/arm/mach-imx/time.c +0
-0@@ -84,27 +84,34 @@static struct clock_event_device clockevent_mxc;static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ;
Quoted 12 lines
arch/arm/mach-imx/time.c line 95
Quoted 10 lines
arch/arm/mach-imx/time.c +8
-1-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
PATCH 1/9 ARM: imx: move timer resources into a structure
In reply to shawnguo at kernel.orgQuoted 8 lines · shawnguo at kernel.org
From: Shawn Guo <[email protected]>
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 <[email protected]>
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.
Quoted 267 lines
--- arch/arm/mach-imx/time.c | 119 ++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 58 deletions(-)arch/arm/mach-imx/time.c +61
-58@@ -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);
Signature · 5 lines
<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
PATCH 1/9 ARM: imx: move timer resources into a structure
Quoted 10 lines · Daniel Lezcano
Quoted 8 lines · shawnguo at kernel.org
From: Shawn Guo <[email protected]>
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 <[email protected]>
Quoted 8 lines
I would be nice to embed the
clockevent_mxcvariable in the structure as well and usecontainer_ofto 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.cas an example.
Okay, thanks for the example. I will add a patch to do that.
Shawn
PATCH 2/9 ARM: imx: define an enum for gpt timer device type
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
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.
--- 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
arch/arm/mach-imx/time.c +5 -1
@@ -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 (); }
drivers/clk/imx/clk-imx1.c +2 -1
@@ -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 ; }
drivers/clk/imx/clk-imx21.c +2 -1
@@ -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 ; }
drivers/clk/imx/clk-imx27.c +2 -1
@@ -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 ; }
drivers/clk/imx/clk-imx31.c +2 -1
@@ -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 ; }
drivers/clk/imx/clk-imx35.c +2 -1
@@ -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 ; }
drivers/clk/imx/clk.h +0 -7
@@ -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);
include/soc/imx/timer.h new file +26 -0
@@ -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__ */
Signature · 1 line
1.9.1
PATCH 2/9 ARM: imx: define an enum for gpt timer device type
Quoted 31 lines
-----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 typeFrom: Shawn Guo <[email protected]>
Define an enum for gpt timer device type in
include/soc/imx/timer.hto 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 ofmxc_timer_init()is moved into there as the best fit.Signed-off-by Shawn Guo <[email protected]>000000000000..bbbafd65f464
include/soc/imx/timer.h new file +8
-0@@ -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. +*/ +
include/soc/imx/timer.h line 18
Quoted 10 lines
include/soc/imx/timer.h new file +10
-0+#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
Quoted 13 lines
include/soc/imx/timer.h new file +11
-1+/* +* 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
PATCH 3/9 ARM: imx: initialize gpt device type for DT boot
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
Use different initialization function in CLOCKSOURCE_OF_DECLARE() to initialize gpt device type for DT boot.
--- arch/arm/mach-imx/time.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-)
arch/arm/mach-imx/time.c +36 -8
@@ -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);
Signature · 1 line
1.9.1
PATCH 4/9 ARM: imx: setup tctl register in device specific function
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
It creates device speicific function hook gpt_setup_tctl to set up gpt TCTL register.
--- arch/arm/mach-imx/time.c | 81 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 62 insertions(+), 19 deletions(-)
arch/arm/mach-imx/time.c +62 -19
@@ -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 ();
Signature · 1 line
1.9.1
PATCH 4/9 ARM: imx: setup tctl register in device specific function
arch/arm/mach-imx/time.c static int __init mxc_clockevent_init(void) · line 316
Quoted 10 lines · On Friday 15 May 2015 16:11:42 shawnguo at kernel.org wrote:
}
arch/arm/mach-imx/time.c +7
-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 ); +}
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
PATCH 4/9 ARM: imx: setup tctl register in device specific function
Quoted 15 lines · Arnd Bergmann
arch/arm/mach-imx/time.c static int __init mxc_clockevent_init(void) · line 316
Quoted 10 lines · On Friday 15 May 2015 16:11:42 shawnguo at kernel.org wrote:
}
arch/arm/mach-imx/time.c +7
-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 ); +}Could you add another upfront patch to convert all the __raw_readl/__raw_writel to readl_relaxed/writel_relaxed?
Quoted 3 lines
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
PATCH 5/9 ARM: imx: set up set_next_event hook in imx_timer_data_init()
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
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.
--- arch/arm/mach-imx/time.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/mach-imx/time.c +4 -4
@@ -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 ();
Signature · 1 line
1.9.1
PATCH 6/9 ARM: imx: define gpt register offset per device type
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
It initializes offset of gpt registers TSTAT, TCN and TCMP per device type, so that the access to these registers can be unified.
--- arch/arm/mach-imx/time.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
arch/arm/mach-imx/time.c +19 -12
@@ -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 ;
Signature · 1 line
1.9.1
PATCH 6/9 ARM: imx: define gpt register offset per device type
Quoted 21 lines · On Friday 15 May 2015 16:11:44 shawnguo at kernel.org wrote:
{ switch (imxtm.type) { case GPT_TYPE_IMX1:arch/arm/mach-imx/time.c +9
-0+ 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 ;
arch/arm/mach-imx/time.c static void __init imx_timer_data_init(void) · line 370
Quoted 10 lines
arch/arm/mach-imx/time.c +3
-0imxtm.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
PATCH 6/9 ARM: imx: define gpt register offset per device type
Quoted 33 lines · Arnd Bergmann
Quoted 21 lines · On Friday 15 May 2015 16:11:44 shawnguo at kernel.org wrote:
{ switch (imxtm.type) { case GPT_TYPE_IMX1:arch/arm/mach-imx/time.c +9
-0+ 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 ;arch/arm/mach-imx/time.c static void __init imx_timer_data_init(void) · line 370
Quoted 10 lines
arch/arm/mach-imx/time.c +3
-0imxtm.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 ;
Quoted 5 lines
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
PATCH 7/9 ARM: imx: provide gpt device specific irq functions
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
It splits irq enable/disable/acknowledge operations into device specific functions to get proper hook called in the correct context.
--- arch/arm/mach-imx/time.c | 76 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 25 deletions(-)
arch/arm/mach-imx/time.c +51 -25
@@ -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 :
Signature · 1 line
1.9.1
PATCH 8/9 ARM: imx: remove platform headers from timer driver
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
With the cleanup done before, the platform specific headers now can be removed.
--- arch/arm/mach-imx/time.c | 6 ------ 1 file changed, 6 deletions(-)
arch/arm/mach-imx/time.c +0 -6
@@ -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 ;
Signature · 1 line
1.9.1
PATCH 9/9 ARM: imx: move timer driver into drivers/clocksource
In reply to shawnguo at kernel.orgFrom: Shawn Guo <[email protected]>
After the cleanup on imx timer driver, now it's ready to be moved into drivers/clocksource/. Let's do it.
--- 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%)
arch/arm/mach-imx/Makefile +1 -1
@@ -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
drivers/clocksource/Makefile +1 -0
@@ -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
drivers/clocksource/timer-imx.c renamed from arch/arm/mach-imx/time.c +0 -0
Signature · 1 line
1.9.1