ARM: imx: move timer driver into drivers/clocksource
Subsystems (6)
v2 cover ARM: imx: move timer driver into drivers/clocksource
Changes since v1:
- Use relaxed IO accessor to replace __raw_xxx version
- Create imx_gpt_data structure to accommodate gpt device specific data
- Move clock event related variables into imx_timer structure
Daniel,
If the patch series looks good to you, can you please give your ACK on the last patch, so that I can send the whole series through IMX tree? Thanks.
Shawn
Shawn Guo (12):
ARM: imx: use relaxed IO accessor in timer driver
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 via imx_gpt_data
ARM: imx: move clock event variables into imx_timer
ARM: imx: define gpt register offset per device type
ARM: imx: get rid of variable timer_base
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 | 531 ++++++++++++++++++++++++++++++++++++++++ include/soc/imx/timer.h | 26 ++ 11 files changed, 569 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 v2 1/12 ARM: imx: use relaxed IO accessor in timer driver
Replace the __raw_readl/__raw_writel with readl_relaxed/writel_relaxed which is endian-safe, as a step of moving the driver code into folder drivers/clocksource.
--- arch/arm/mach-imx/time.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-)
arch/arm/mach-imx/time.c +24 -24
@@ -91,19 +91,19 @@ static inline void gpt_irq_disable(void)unsigned int tmp;if (timer_is_v2 ()) -__raw_writel (0 , timer_base +V2_IR ); +writel_relaxed (0 , timer_base +V2_IR );else { - tmp =__raw_readl (timer_base +MXC_TCTL ); -__raw_writel (tmp & ~MX1_2_TCTL_IRQEN , timer_base +MXC_TCTL ); + tmp =readl_relaxed (timer_base +MXC_TCTL ); +writel_relaxed (tmp & ~MX1_2_TCTL_IRQEN , timer_base +MXC_TCTL ); } }static inline void gpt_irq_enable (void ) {if (timer_is_v2 ()) -__raw_writel (1 <<0 , timer_base +V2_IR ); +writel_relaxed (1 <<0 , timer_base +V2_IR );else { -__raw_writel (__raw_readl (timer_base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , +writel_relaxed (readl_relaxed (timer_base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , timer_base +MXC_TCTL ); } }
@@ -112,26 +112,26 @@ static void gpt_irq_acknowledge(void) {if (timer_is_v1 ()) {if (cpu_is_mx1 ()) -__raw_writel (0 , timer_base +MX1_2_TSTAT ); +writel_relaxed (0 , timer_base +MX1_2_TSTAT );else -__raw_writel (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , +writel_relaxed (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , timer_base +MX1_2_TSTAT ); }else if (timer_is_v2 ()) -__raw_writel (V2_TSTAT_OF1 , timer_base +V2_TSTAT ); +writel_relaxed (V2_TSTAT_OF1 , timer_base +V2_TSTAT ); }static void __iomem *sched_clock_reg; static u64 notrace mxc_read_sched_clock(void) { -return sched_clock_reg ?__raw_readl (sched_clock_reg) :0 ; +return sched_clock_reg ?readl_relaxed (sched_clock_reg) :0 ; }static struct delay_timer imx_delay_timer;static unsigned long imx_read_current_timer (void ) { -return __raw_readl (sched_clock_reg); +return readl_relaxed (sched_clock_reg); }static int __init mxc_clocksource_init (struct clk *timer_clk)
@@ -157,11 +157,11 @@ static int mx1_2_set_next_event(unsigned long evt, {unsigned long tcmp; - tcmp =__raw_readl (timer_base +MX1_2_TCN ) + evt; + tcmp =readl_relaxed (timer_base +MX1_2_TCN ) + evt; -__raw_writel (tcmp, timer_base +MX1_2_TCMP ); +writel_relaxed (tcmp, timer_base +MX1_2_TCMP ); -return (int )(tcmp -__raw_readl (timer_base +MX1_2_TCN )) <0 ? +return (int )(tcmp -readl_relaxed (timer_base +MX1_2_TCN )) <0 ? -ETIME :0 ; }
@@ -170,12 +170,12 @@ static int v2_set_next_event(unsigned long evt, {unsigned long tcmp; - tcmp =__raw_readl (timer_base +V2_TCN ) + evt; + tcmp =readl_relaxed (timer_base +V2_TCN ) + evt; -__raw_writel (tcmp, timer_base +V2_TCMP ); +writel_relaxed (tcmp, timer_base +V2_TCMP );return evt <0x7fffffff && - (int )(tcmp -__raw_readl (timer_base +V2_TCN )) <0 ? + (int )(tcmp -readl_relaxed (timer_base +V2_TCN )) <0 ? -ETIME :0 ; }
@@ -206,10 +206,10 @@ 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 , +writel_relaxed (readl_relaxed (timer_base +V2_TCN ) -3 , timer_base +V2_TCMP );else -__raw_writel (__raw_readl (timer_base +MX1_2_TCN ) -3 , +writel_relaxed (readl_relaxed (timer_base +MX1_2_TCN ) -3 , timer_base +MX1_2_TCMP );/* Clear pending interrupt */
@@ -259,9 +259,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 =readl_relaxed (timer_base +V2_TSTAT );else - tstat =__raw_readl (timer_base +MX1_2_TSTAT ); + tstat =readl_relaxed (timer_base +MX1_2_TSTAT );gpt_irq_acknowledge ();
@@ -316,8 +316,8 @@ static void __init _mxc_timer_init(int irq,* 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 */ +writel_relaxed (0 , timer_base +MXC_TCTL ); +writel_relaxed (0 , timer_base +MXC_TPRER );/* see datasheet note */ if (timer_is_v2 ()) { tctl_val =V2_TCTL_FRR |V2_TCTL_WAITEN |MXC_TCTL_TEN ;
@@ -325,7 +325,7 @@ static void __init _mxc_timer_init(int irq, tctl_val |=V2_TCTL_CLK_OSC_DIV8 ;if (cpu_is_imx6dl () ||cpu_is_imx6sx ()) {/* 24 / 8 = 3 MHz */ -__raw_writel (7 <<V2_TPRER_PRE24M , +writel_relaxed (7 <<V2_TPRER_PRE24M , timer_base +MXC_TPRER ); tctl_val |=V2_TCTL_24MEN ; }
@@ -336,7 +336,7 @@ 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 ); +writel_relaxed (tctl_val, timer_base +MXC_TCTL );/* init and register the timer to the framework */ mxc_clocksource_init (clk_per);
Signature · 1 line
1.9.1
PATCH v2 2/12 ARM: imx: move timer resources into a structure
In reply to Shawn GuoInstead of passing around as individual argument, let's move timer resources like irq and clocks together with base address into a data structure, and pass pointer of the structure as argument to simplify the function call interface.
--- arch/arm/mach-imx/time.c | 91 +++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 35 deletions(-)
arch/arm/mach-imx/time.c +56 -35
@@ -28,6 +28,7 @@#include <linux/delay.h> #include <linux/err.h> #include <linux/sched_clock.h> +#include <linux/slab.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h>
@@ -84,6 +85,13 @@static struct clock_event_device clockevent_mxc;static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ; +struct imx_timer { +void __iomem *base; +int irq; +struct clk *clk_per; +struct clk *clk_ipg; +}; +static void __iomem *timer_base;static inline void gpt_irq_disable (void )
@@ -134,10 +142,10 @@ static unsigned long imx_read_current_timer(void)return readl_relaxed (sched_clock_reg); } -static int __init mxc_clocksource_init (struct clk *timer_clk) +static int __init mxc_clocksource_init (struct imx_timer *imxtm) { -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;
@@ -284,49 +292,51 @@ static struct clock_event_device clockevent_mxc = { .rating = 200, }; -static int __init mxc_clockevent_init (struct clk *timer_clk) +static int __init mxc_clockevent_init (struct imx_timer *imxtm) {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 (struct imx_timer *imxtm) {uint32_t tctl_val; -if (IS_ERR (clk_per)) { +/* Temporary */ + timer_base = imxtm->base; + +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) */ -writel_relaxed (0 , timer_base +MXC_TCTL ); -writel_relaxed (0 , timer_base +MXC_TPRER );/* see datasheet note */ +writel_relaxed (0 , imxtm->base +MXC_TCTL ); +writel_relaxed (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 */ writel_relaxed (7 <<V2_TPRER_PRE24M , - timer_base +MXC_TPRER ); + imxtm->base +MXC_TPRER ); tctl_val |=V2_TCTL_24MEN ; } }else {
@@ -336,47 +346,58 @@ static void __init _mxc_timer_init(int irq, tctl_val =MX1_2_TCTL_FRR |MX1_2_TCTL_CLK_PCLK1 |MXC_TCTL_TEN ; } -writel_relaxed (tctl_val, timer_base +MXC_TCTL ); +writel_relaxed (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 (imxtm); +mxc_clockevent_init (imxtm);/* 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" ); +struct imx_timer *imxtm; + + imxtm =kzalloc (sizeof (*imxtm),GFP_KERNEL ); +BUG_ON (!imxtm); - timer_base =ioremap (pbase,SZ_4K ); -BUG_ON (!timer_base); + imxtm->clk_per =clk_get_sys ("imx-gpt.0" ,"per" ); + imxtm->clk_ipg =clk_get_sys ("imx-gpt.0" ,"ipg" ); -_mxc_timer_init (irq, clk_per, clk_ipg); + imxtm->base =ioremap (pbase,SZ_4K ); +BUG_ON (!imxtm->base); + +_mxc_timer_init (imxtm); }static void __init mxc_timer_init_dt (struct device_node *np) { -struct clk *clk_per, *clk_ipg; -int irq; +struct imx_timer *imxtm; +static int initialized; -if (timer_base) +/* Support one instance only */ +if (initialized)return ; - timer_base =of_iomap (np,0 ); -WARN_ON (!timer_base); - irq =irq_of_parse_and_map (np,0 ); + imxtm =kzalloc (sizeof (*imxtm),GFP_KERNEL ); +BUG_ON (!imxtm); - clk_ipg =of_clk_get_by_name (np,"ipg" ); + imxtm->base =of_iomap (np,0 ); +WARN_ON (!imxtm->base); + imxtm->irq =irq_of_parse_and_map (np,0 ); + + 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 (imxtm); -_mxc_timer_init (irq, clk_per, clk_ipg); + initialized =1 ; }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 v2 3/12 ARM: imx: define an enum for gpt timer device type
In reply to Shawn GuoDefine 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
@@ -32,6 +32,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>
@@ -86,6 +87,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;
@@ -356,7 +358,7 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm)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) {struct imx_timer *imxtm;
@@ -369,6 +371,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 (imxtm); }
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 v2 4/12 ARM: imx: initialize gpt device type for DT boot
In reply to Shawn GuoUse 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, 35 insertions(+), 9 deletions(-)
arch/arm/mach-imx/time.c +35 -9
@@ -376,7 +376,7 @@ void __init mxc_timer_init(unsigned long pbase, int irq, enum imx_gpt_type type)_mxc_timer_init (imxtm); } -static void __init mxc_timer_init_dt (struct device_node *np) +static void __init mxc_timer_init_dt (struct device_node *np,enum imx_gpt_type type) {struct imx_timer *imxtm;static int initialized;
@@ -399,15 +399,41 @@ static void __init mxc_timer_init_dt(struct device_node *np)if (IS_ERR (imxtm->clk_per)) imxtm->clk_per =of_clk_get_by_name (np,"per" ); + imxtm->type = type; +_mxc_timer_init (imxtm); initialized =1 ; } -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) +{ +mxc_timer_init_dt (np,GPT_TYPE_IMX1 ); +} + +static void __init imx21_timer_init_dt (struct device_node *np) +{ +mxc_timer_init_dt (np,GPT_TYPE_IMX21 ); +} + +static void __init imx31_timer_init_dt (struct device_node *np) +{ +mxc_timer_init_dt (np,GPT_TYPE_IMX31 ); +} + +static void __init imx6dl_timer_init_dt (struct device_node *np) +{ +mxc_timer_init_dt (np,GPT_TYPE_IMX6DL ); +} + +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 v2 5/12 ARM: imx: setup tctl register in device specific function
In reply to Shawn GuoIt creates a gpt device speicific data structure and adds function hook gpt_setup_tctl in there to set up gpt TCTL register.
--- arch/arm/mach-imx/time.c | 98 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 20 deletions(-)
arch/arm/mach-imx/time.c +78 -20
@@ -92,6 +92,11 @@ struct imx_timer {int irq;struct clk *clk_per;struct clk *clk_ipg; +const struct imx_gpt_data *gpt; +}; + +struct imx_gpt_data { +void (*gpt_setup_tctl)(struct imx_timer *imxtm); };static void __iomem *timer_base;
@@ -307,13 +312,83 @@ static int __init mxc_clockevent_init(struct imx_timer *imxtm)return 0 ; } -static void __init _mxc_timer_init (struct imx_timer *imxtm) +static void imx1_gpt_setup_tctl (struct imx_timer *imxtm) +{ +u32 tctl_val; + + tctl_val =MX1_2_TCTL_FRR |MX1_2_TCTL_CLK_PCLK1 |MXC_TCTL_TEN ; +writel_relaxed (tctl_val, imxtm->base +MXC_TCTL ); +} +#define imx21_gpt_setup_tctl imx1_gpt_setup_tctl + +static void imx31_gpt_setup_tctl (struct imx_timer *imxtm) +{ +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 ; + +writel_relaxed (tctl_val, imxtm->base +MXC_TCTL ); +} + +static void imx6dl_gpt_setup_tctl (struct imx_timer *imxtm) { -uint32_t tctl_val; +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 */ +writel_relaxed (7 <<V2_TPRER_PRE24M , imxtm->base +MXC_TPRER ); + tctl_val |=V2_TCTL_24MEN ; + }else { + tctl_val |=V2_TCTL_CLK_PER ; + } + +writel_relaxed (tctl_val, imxtm->base +MXC_TCTL ); +} +static const struct imx_gpt_data imx1_gpt_data = { + .gpt_setup_tctl = imx1_gpt_setup_tctl, +}; + +static const struct imx_gpt_data imx21_gpt_data = { + .gpt_setup_tctl = imx21_gpt_setup_tctl, +}; + +static const struct imx_gpt_data imx31_gpt_data = { + .gpt_setup_tctl = imx31_gpt_setup_tctl, +}; + +static const struct imx_gpt_data imx6dl_gpt_data = { + .gpt_setup_tctl = imx6dl_gpt_setup_tctl, +}; + +static void __init _mxc_timer_init (struct imx_timer *imxtm) +{/* Temporary */ timer_base = imxtm->base; +switch (imxtm->type) { +case GPT_TYPE_IMX1 : + imxtm->gpt = &imx1_gpt_data; +break ; +case GPT_TYPE_IMX21 : + imxtm->gpt = &imx21_gpt_data; +break ; +case GPT_TYPE_IMX31 : + imxtm->gpt = &imx31_gpt_data; +break ; +case GPT_TYPE_IMX6DL : + imxtm->gpt = &imx6dl_gpt_data; +break ; +default : +BUG (); + } +if (IS_ERR (imxtm->clk_per)) {pr_err ("i.MX timer: unable to get clk\n" );return ;
@@ -331,24 +406,7 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm)writel_relaxed (0 , imxtm->base +MXC_TCTL );writel_relaxed (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 */ -writel_relaxed (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 ; - } - -writel_relaxed (tctl_val, imxtm->base +MXC_TCTL ); + imxtm->gpt->gpt_setup_tctl (imxtm);/* init and register the timer to the framework */ mxc_clocksource_init (imxtm);
Signature · 1 line
1.9.1
PATCH v2 5/12 ARM: imx: setup tctl register in device specific function
Hi Shawn,
Quoted 4 lines · Shawn Guo
It creates a gpt device speicific data structure and adds function hook
gpt_setup_tctlin there to set up gpt TCTL register.Signed-off-by Shawn Guo <[email protected]>
Starting with next-20150529, imx6dl-wandboard (both dual and solo) started having boot failures[1]. Today I bisected it down to this commit. It didn't revert cleanly, so I didn't verify that this patch alone is the root cause, but reproducing the boot failure should be pretty easy on wandboard with recent linux-next.
Kevin
[1] http://kernelci.org/boot/all/job/next/kernel/next-20150529/
PATCH v2 5/12 ARM: imx: setup tctl register in device specific function
Hi Kevin,
Quoted 6 lines · Kevin Hilman
Hi Shawn,
Quoted 3 lines · Shawn Guo
It creates a gpt device speicific data structure and adds function hook
gpt_setup_tctlin there to set up gpt TCTL register.
Quoted 7 lines
Quoted 1 line
Signed-off-by Shawn Guo <[email protected]>Starting with next-20150529, imx6dl-wandboard (both dual and solo) started having boot failures[1]. Today I bisected it down to this commit. It didn't revert cleanly, so I didn't verify that this patch alone is the root cause, but reproducing the boot failure should be pretty easy on wandboard with recent linux-next.
The imx clocksource driver was marked as BROKEN on linux-next, because it causes a build error on powerpc allyesconfig build [1]. I'm working on a fix for it.
Can you please try to remove the BROKEN mark in your test to see if it fixes your problem?
Sorry for the breakage.
Shawn
[1] http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg901156.html
PATCH v2 5/12 ARM: imx: setup tctl register in device specific function
Quoted 17 lines · Shawn Guo
Hi Kevin,
Quoted 6 lines · Kevin Hilman
Hi Shawn,
Quoted 3 lines · Shawn Guo
It creates a gpt device speicific data structure and adds function hook
gpt_setup_tctlin there to set up gpt TCTL register.Quoted 7 lines
Quoted 1 line
Signed-off-by Shawn Guo <[email protected]>Starting with next-20150529, imx6dl-wandboard (both dual and solo) started having boot failures[1]. Today I bisected it down to this commit. It didn't revert cleanly, so I didn't verify that this patch alone is the root cause, but reproducing the boot failure should be pretty easy on wandboard with recent linux-next.
Quoted 6 lines
The imx clocksource driver was marked as BROKEN on linux-next, because it causes a build error on powerpc allyesconfig build [1]. I'm working on a fix for it.
Can you please try to remove the BROKEN mark in your test to see if it fixes your problem?
I'm just using multi_v7_defconfig, and BROKEN is not set, but that driver is still built because it's explicitly selected by ARCH_MXC:
$ git describe next-20150601 $ rm build/.config $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- O=build multi_v7_defconfig make[1]: Entering directory `/work/kernel/next/build' GEN ./Makefile arch/arm/configs/multi_v7_defconfig:603:warning: override: reassigning to symbol COMMON_CLK_QCOM warning: (ARCH_MXC) selects CLKSRC_IMX_GPT which has unmet direct dependencies (OF && BROKEN) warning: (ARCH_MXC) selects CLKSRC_IMX_GPT which has unmet direct dependencies (OF && BROKEN) # # configuration written to .config # make[1]: Leaving directory `/work/kernel/next/build' $ grep CLKSRC_IMX_GPT build/.config CONFIG_CLKSRC_IMX_GPT=y $
Kevin
PATCH v2 5/12 ARM: imx: setup tctl register in device specific function
Quoted 14 lines · Kevin Hilman
I'm just using
multi_v7_defconfig, and BROKEN is not set, but that driver is still built because it's explicitly selected byARCH_MXC:$ git describe next-20150601 $ rm build/.config $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- O=build multi_v7_defconfig make[1]: Entering directory `/work/kernel/next/build' GEN ./Makefile arch/arm/configs/multi_v7_defconfig:603:warning: override: reassigning to symbol COMMON_CLK_QCOM warning: (ARCH_MXC) selects CLKSRC_IMX_GPT which has unmet direct dependencies (OF && BROKEN) warning: (ARCH_MXC) selects CLKSRC_IMX_GPT which has unmet direct
Quoted 8 lines
dependencies (OF && BROKEN) # # configuration written to .config # make[1]: Leaving directory `/work/kernel/next/build' $ grep CLKSRC_IMX_GPT build/.config CONFIG_CLKSRC_IMX_GPT=y $
Yes, you're right. It's broken on i.MX6DL/S indeed. The cause is that i.MX6DL/S DTBs are using the same GPT compatible string as i.MX6Q. It effectively makes kernel select an incorrect GPT device type on i.MX6DL/S. We will need to update i.MX6DL/S device tree to use a correct compatible string. But to keep the existing DTBs continue working, we need the following change. As I'm asked by Arnd to rebase my branch, I would like fold the changes into the original patch to save the git bisect issue.
Thanks for the bug report, and sorry for the breakage.
Shawn
-----8<------------------
drivers/clocksource/timer-imx-gpt.c +12 -1
@@ -508,7 +508,18 @@ static void __init imx21_timer_init_dt(struct device_node *np)static void __init imx31_timer_init_dt (struct device_node *np) { -mxc_timer_init_dt (np,GPT_TYPE_IMX31 ); +enum imx_gpt_type type =GPT_TYPE_IMX31 ; + +/* +* We were using the same compatible string for i.MX6Q/D and i.MX6DL/S +* GPT device, while they actually have different programming model. +* This is a workaround to keep the existing i.MX6DL/S DTBs continue +* working with the new kernel. +*/ +if (of_machine_is_compatible ("fsl,imx6dl" )) + type =GPT_TYPE_IMX6DL ; + +mxc_timer_init_dt (np, type); }static void __init imx6dl_timer_init_dt (struct device_node *np)
PATCH v2 5/12 ARM: imx: setup tctl register in device specific function
Quoted 24 lines · Shawn Guo
Quoted 14 lines · Kevin Hilman
I'm just using
multi_v7_defconfig, and BROKEN is not set, but that driver is still built because it's explicitly selected byARCH_MXC:$ git describe next-20150601 $ rm build/.config $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- O=build multi_v7_defconfig make[1]: Entering directory `/work/kernel/next/build' GEN ./Makefile arch/arm/configs/multi_v7_defconfig:603:warning: override: reassigning to symbol COMMON_CLK_QCOM warning: (ARCH_MXC) selects CLKSRC_IMX_GPT which has unmet direct dependencies (OF && BROKEN) warning: (ARCH_MXC) selects CLKSRC_IMX_GPT which has unmet directQuoted 8 lines
dependencies (OF && BROKEN) # # configuration written to .config # make[1]: Leaving directory `/work/kernel/next/build' $ grep CLKSRC_IMX_GPT build/.config CONFIG_CLKSRC_IMX_GPT=y $
Quoted 8 lines
Yes, you're right. It's broken on i.MX6DL/S indeed. The cause is that i.MX6DL/S DTBs are using the same GPT compatible string as i.MX6Q. It effectively makes kernel select an incorrect GPT device type on i.MX6DL/S. We will need to update i.MX6DL/S device tree to use a correct compatible string. But to keep the existing DTBs continue working, we need the following change. As I'm asked by Arnd to rebase my branch, I would like fold the changes into the original patch to save the git bisect issue.
I tried your patch on top of next-20150529 (where I originally found the issue) and it gets my wandboard dual and solo booting again.
Kevin
PATCH v2 5/12 ARM: imx: setup tctl register in device specific function
Quoted 4 lines · Kevin Hilman
I tried your patch on top of next-20150529 (where I originally found the issue) and it gets my wandboard dual and solo booting again.
Tested-by Kevin Hilman <[email protected]>
Thanks for confirming, Kevin.
Shawn
PATCH v2 6/12 ARM: imx: set up .set_next_event hook via imx_gpt_data
In reply to Shawn GuoSet up .set_next_event hook via imx_gpt_data, so that we can save the use of timer_is_v2().
--- arch/arm/mach-imx/time.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
arch/arm/mach-imx/time.c +7 -3
@@ -97,6 +97,8 @@ struct imx_timer {struct imx_gpt_data {void (*gpt_setup_tctl)(struct imx_timer *imxtm); +int (*set_next_event)(unsigned long evt, +struct clock_event_device *ced); };static void __iomem *timer_base;
@@ -301,9 +303,7 @@ static struct clock_event_device clockevent_mxc = {static int __init mxc_clockevent_init (struct imx_timer *imxtm) { -if (timer_is_v2 ()) - clockevent_mxc.set_next_event = v2_set_next_event; - + clockevent_mxc.set_next_event = imxtm->gpt->set_next_event; clockevent_mxc.cpumask =cpumask_of (0 ); clockevents_config_and_register(&clockevent_mxc, clk_get_rate(imxtm->clk_per),
@@ -353,18 +353,22 @@ static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm)static const struct imx_gpt_data imx1_gpt_data = { .gpt_setup_tctl = imx1_gpt_setup_tctl, + .set_next_event = mx1_2_set_next_event, };static const struct imx_gpt_data imx21_gpt_data = { .gpt_setup_tctl = imx21_gpt_setup_tctl, + .set_next_event = mx1_2_set_next_event, };static const struct imx_gpt_data imx31_gpt_data = { .gpt_setup_tctl = imx31_gpt_setup_tctl, + .set_next_event = v2_set_next_event, };static const struct imx_gpt_data imx6dl_gpt_data = { .gpt_setup_tctl = imx6dl_gpt_setup_tctl, + .set_next_event = v2_set_next_event, };static void __init _mxc_timer_init (struct imx_timer *imxtm)
Signature · 1 line
1.9.1
PATCH v2 7/12 ARM: imx: move clock event variables into imx_timer
In reply to Shawn GuoSince we now have imx_timer structure, it makes more sense to move those clock event related variables into the structure, so that we can save some global variables.
--- arch/arm/mach-imx/time.c | 64 +++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 31 deletions(-)
arch/arm/mach-imx/time.c +33 -31
@@ -83,9 +83,6 @@#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 ; -struct imx_timer {enum imx_gpt_type type;void __iomem *base;
@@ -93,6 +90,9 @@ struct imx_timer {struct clk *clk_per;struct clk *clk_ipg;const struct imx_gpt_data *gpt; +struct clock_event_device ced; +enum clock_event_mode cem; +struct irqaction act; };struct imx_gpt_data {
@@ -103,6 +103,11 @@ struct imx_gpt_data {static void __iomem *timer_base; +static inline struct imx_timer *to_imx_timer (struct clock_event_device *ced) +{ + return container_of(ced, struct imx_timer, ced); +} +static inline void gpt_irq_disable (void ) {unsigned int tmp;
@@ -207,8 +212,9 @@ static const char *clock_event_mode_label[] = {#endif /* DEBUG */ static void mxc_set_mode (enum clock_event_mode mode, -struct clock_event_device *evt) +struct clock_event_device *ced) { +struct imx_timer *imxtm =to_imx_timer (ced);unsigned long flags;/*
@@ -220,7 +226,7 @@ static void mxc_set_mode(enum clock_event_mode mode,/* Disable interrupt in GPT module */ gpt_irq_disable (); -if (mode != clockevent_mode) { +if (mode != imxtm->cem) {/* Set event time into far-far future */ if (timer_is_v2 ()) writel_relaxed(readl_relaxed(timer_base + V2_TCN) - 3,
@@ -235,12 +241,12 @@ static void mxc_set_mode(enum clock_event_mode mode,#ifdef DEBUG printk (KERN_INFO "mxc_set_mode: changing mode from %s to %s\n" , - clock_event_mode_label[clockevent_mode], + clock_event_mode_label[imxtm->cem], clock_event_mode_label[mode]);#endif /* DEBUG */ /* Remember timer mode */ - clockevent_mode = mode; + imxtm->cem = mode;local_irq_restore (flags);switch (mode) {
@@ -272,7 +278,7 @@ static void mxc_set_mode(enum clock_event_mode mode,*/ static irqreturn_t mxc_timer_interrupt (int irq,void *dev_id) { -struct clock_event_device *evt = &clockevent_mxc; +struct clock_event_device *ced = dev_id;uint32_t tstat;if (timer_is_v2 ())
@@ -282,34 +288,33 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)gpt_irq_acknowledge (); - evt->event_handler (evt); + ced->event_handler (ced);return IRQ_HANDLED ; } -static struct irqaction mxc_timer_irq = { - .name ="i.MX Timer Tick" , - .flags =IRQF_TIMER |IRQF_IRQPOLL , - .handler = mxc_timer_interrupt, -}; - -static struct clock_event_device clockevent_mxc = { - .name ="mxc_timer1" , - .features =CLOCK_EVT_FEAT_ONESHOT , - .set_mode = mxc_set_mode, - .set_next_event = mx1_2_set_next_event, - .rating =200 , -}; -static int __init mxc_clockevent_init (struct imx_timer *imxtm) { - clockevent_mxc.set_next_event = imxtm->gpt->set_next_event; - clockevent_mxc.cpumask =cpumask_of (0 ); -clockevents_config_and_register (&clockevent_mxc, -clk_get_rate (imxtm->clk_per), +struct clock_event_device *ced = &imxtm->ced; +struct irqaction *act = &imxtm->act; + + imxtm->cem =CLOCK_EVT_MODE_UNUSED ; + + ced->name ="mxc_timer1" ; + ced->features =CLOCK_EVT_FEAT_ONESHOT ; + ced->set_mode = mxc_set_mode; + ced->set_next_event = imxtm->gpt->set_next_event; + ced->rating =200 ; + ced->cpumask =cpumask_of (0 ); +clockevents_config_and_register (ced,clk_get_rate (imxtm->clk_per),0xff ,0xfffffffe ); -return 0 ; + act->name ="i.MX Timer Tick" ; + act->flags =IRQF_TIMER |IRQF_IRQPOLL ; + act->handler = mxc_timer_interrupt; + act->dev_id = ced; + +return setup_irq (imxtm->irq, act); }static void imx1_gpt_setup_tctl (struct imx_timer *imxtm)
@@ -415,9 +420,6 @@ static void __init _mxc_timer_init(struct imx_timer *imxtm)/* init and register the timer to the framework */ mxc_clocksource_init (imxtm);mxc_clockevent_init (imxtm); - -/* Make irqs happen */ -setup_irq (imxtm->irq, &mxc_timer_irq); }void __init mxc_timer_init (unsigned long pbase,int irq,enum imx_gpt_type type)
Signature · 1 line
1.9.1
PATCH v2 8/12 ARM: imx: define gpt register offset per device type
In reply to Shawn GuoIt defines offset of gpt registers TSTAT, TCN and TCMP per device type in imx_gpt_data, so that these registers can be accessed in an way without timer_is_v2() checking.
--- arch/arm/mach-imx/time.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-)
arch/arm/mach-imx/time.c +20 -11
@@ -96,6 +96,9 @@ struct imx_timer { };struct imx_gpt_data { +int reg_tstat; +int reg_tcn; +int reg_tcmp;void (*gpt_setup_tctl)(struct imx_timer *imxtm);int (*set_next_event)(unsigned long evt,struct clock_event_device *ced);
@@ -159,7 +162,7 @@ static unsigned long imx_read_current_timer(void)static int __init mxc_clocksource_init (struct imx_timer *imxtm) {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->gpt->reg_tcn; imx_delay_timer.read_current_timer = &imx_read_current_timer; imx_delay_timer.freq = c;
@@ -227,13 +230,9 @@ static void mxc_set_mode(enum clock_event_mode mode,gpt_irq_disable ();if (mode != imxtm->cem) { +u32 tcn =readl_relaxed (imxtm->base + imxtm->gpt->reg_tcn);/* Set event time into far-far future */ -if (timer_is_v2 ()) -writel_relaxed (readl_relaxed (timer_base +V2_TCN ) -3 , - timer_base +V2_TCMP ); -else -writel_relaxed (readl_relaxed (timer_base +MX1_2_TCN ) -3 , - timer_base +MX1_2_TCMP ); +writel_relaxed (tcn -3 , imxtm->base + imxtm->gpt->reg_tcmp);/* Clear pending interrupt */ gpt_irq_acknowledge ();
@@ -279,12 +278,10 @@ static void mxc_set_mode(enum clock_event_mode mode,static irqreturn_t mxc_timer_interrupt (int irq,void *dev_id) {struct clock_event_device *ced = dev_id; +struct imx_timer *imxtm =to_imx_timer (ced);uint32_t tstat; -if (timer_is_v2 ()) - tstat =readl_relaxed (timer_base +V2_TSTAT ); -else - tstat =readl_relaxed (timer_base +MX1_2_TSTAT ); + tstat =readl_relaxed (imxtm->base + imxtm->gpt->reg_tstat);gpt_irq_acknowledge ();
@@ -357,21 +354,33 @@ static void imx6dl_gpt_setup_tctl(struct imx_timer *imxtm) }static const struct imx_gpt_data imx1_gpt_data = { + .reg_tstat =MX1_2_TSTAT , + .reg_tcn =MX1_2_TCN , + .reg_tcmp =MX1_2_TCMP , .gpt_setup_tctl = imx1_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, };static const struct imx_gpt_data imx21_gpt_data = { + .reg_tstat =MX1_2_TSTAT , + .reg_tcn =MX1_2_TCN , + .reg_tcmp =MX1_2_TCMP , .gpt_setup_tctl = imx21_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, };static const struct imx_gpt_data imx31_gpt_data = { + .reg_tstat =V2_TSTAT , + .reg_tcn =V2_TCN , + .reg_tcmp =V2_TCMP , .gpt_setup_tctl = imx31_gpt_setup_tctl, .set_next_event = v2_set_next_event, };static const struct imx_gpt_data imx6dl_gpt_data = { + .reg_tstat =V2_TSTAT , + .reg_tcn =V2_TCN , + .reg_tcmp =V2_TCMP , .gpt_setup_tctl = imx6dl_gpt_setup_tctl, .set_next_event = v2_set_next_event, };
Signature · 1 line
1.9.1
PATCH v2 9/12 ARM: imx: get rid of variable timer_base
In reply to Shawn GuoWe now have pointer to imx_timer structure available where timer base address is needed, so we can just kill global timer_base by using imxtm->base instead.
--- arch/arm/mach-imx/time.c | 55 +++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 29 deletions(-)
arch/arm/mach-imx/time.c +26 -29
@@ -104,45 +104,43 @@ struct imx_gpt_data { struct clock_event_device *ced); }; -static void __iomem *timer_base; -static inline struct imx_timer *to_imx_timer (struct clock_event_device *ced) { return container_of(ced, struct imx_timer, ced); } -static inline void gpt_irq_disable (void ) +static inline void gpt_irq_disable (struct imx_timer *imxtm) {unsigned int tmp;if (timer_is_v2 ()) -writel_relaxed (0 , timer_base +V2_IR ); +writel_relaxed (0 , imxtm->base +V2_IR );else { - tmp =readl_relaxed (timer_base +MXC_TCTL ); -writel_relaxed (tmp & ~MX1_2_TCTL_IRQEN , timer_base +MXC_TCTL ); + tmp =readl_relaxed (imxtm->base +MXC_TCTL ); +writel_relaxed (tmp & ~MX1_2_TCTL_IRQEN , imxtm->base +MXC_TCTL ); } } -static inline void gpt_irq_enable (void ) +static inline void gpt_irq_enable (struct imx_timer *imxtm) {if (timer_is_v2 ()) -writel_relaxed (1 <<0 , timer_base +V2_IR ); +writel_relaxed (1 <<0 , imxtm->base +V2_IR );else { -writel_relaxed (readl_relaxed (timer_base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , - timer_base +MXC_TCTL ); +writel_relaxed (readl_relaxed (imxtm->base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , + imxtm->base +MXC_TCTL ); } } -static void gpt_irq_acknowledge (void ) +static void gpt_irq_acknowledge (struct imx_timer *imxtm) {if (timer_is_v1 ()) {if (cpu_is_mx1 ()) -writel_relaxed (0 , timer_base +MX1_2_TSTAT ); +writel_relaxed (0 , imxtm->base +MX1_2_TSTAT );else writel_relaxed (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , - timer_base +MX1_2_TSTAT ); + imxtm->base +MX1_2_TSTAT ); }else if (timer_is_v2 ()) -writel_relaxed (V2_TSTAT_OF1 , timer_base +V2_TSTAT ); +writel_relaxed (V2_TSTAT_OF1 , imxtm->base +V2_TSTAT ); }static void __iomem *sched_clock_reg;
@@ -178,29 +176,31 @@ static int __init mxc_clocksource_init(struct imx_timer *imxtm)/* clock event */ static int mx1_2_set_next_event (unsigned long evt, -struct clock_event_device *unused) +struct clock_event_device *ced) { +struct imx_timer *imxtm =to_imx_timer (ced);unsigned long tcmp; - tcmp =readl_relaxed (timer_base +MX1_2_TCN ) + evt; + tcmp =readl_relaxed (imxtm->base +MX1_2_TCN ) + evt; -writel_relaxed (tcmp, timer_base +MX1_2_TCMP ); +writel_relaxed (tcmp, imxtm->base +MX1_2_TCMP ); -return (int )(tcmp -readl_relaxed (timer_base +MX1_2_TCN )) <0 ? +return (int )(tcmp -readl_relaxed (imxtm->base +MX1_2_TCN )) <0 ? -ETIME :0 ; }static int v2_set_next_event (unsigned long evt, -struct clock_event_device *unused) +struct clock_event_device *ced) { +struct imx_timer *imxtm =to_imx_timer (ced);unsigned long tcmp; - tcmp =readl_relaxed (timer_base +V2_TCN ) + evt; + tcmp =readl_relaxed (imxtm->base +V2_TCN ) + evt; -writel_relaxed (tcmp, timer_base +V2_TCMP ); +writel_relaxed (tcmp, imxtm->base +V2_TCMP );return evt <0x7fffffff && - (int )(tcmp -readl_relaxed (timer_base +V2_TCN )) <0 ? + (int )(tcmp -readl_relaxed (imxtm->base +V2_TCN )) <0 ? -ETIME :0 ; }
@@ -227,7 +227,7 @@ static void mxc_set_mode(enum clock_event_mode mode,local_irq_save (flags);/* Disable interrupt in GPT module */ -gpt_irq_disable (); +gpt_irq_disable (imxtm);if (mode != imxtm->cem) {u32 tcn =readl_relaxed (imxtm->base + imxtm->gpt->reg_tcn);
@@ -235,7 +235,7 @@ static void mxc_set_mode(enum clock_event_mode mode,writel_relaxed (tcn -3 , imxtm->base + imxtm->gpt->reg_tcmp);/* Clear pending interrupt */ -gpt_irq_acknowledge (); +gpt_irq_acknowledge (imxtm); }#ifdef DEBUG
@@ -261,7 +261,7 @@ static void mxc_set_mode(enum clock_event_mode mode,* mode switching */ local_irq_save (flags); -gpt_irq_enable (); +gpt_irq_enable (imxtm);local_irq_restore (flags);break ;case CLOCK_EVT_MODE_SHUTDOWN :
@@ -283,7 +283,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) tstat =readl_relaxed (imxtm->base + imxtm->gpt->reg_tstat); -gpt_irq_acknowledge (); +gpt_irq_acknowledge (imxtm); ced->event_handler (ced);
@@ -387,9 +387,6 @@ static const struct imx_gpt_data imx6dl_gpt_data = {static void __init _mxc_timer_init (struct imx_timer *imxtm) { -/* Temporary */ - timer_base = imxtm->base; -switch (imxtm->type) {case GPT_TYPE_IMX1 : imxtm->gpt = &imx1_gpt_data;
Signature · 1 line
1.9.1
PATCH v2 10/12 ARM: imx: provide gpt device specific irq functions
In reply to Shawn GuoIt splits irq enable/disable/acknowledge operations into device specific functions as the hooks in imx_gpt_data, so that we can save the use of timer_is_xxx() and cpu_is_xxx() checking in these irq functions.
--- arch/arm/mach-imx/time.c | 80 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 26 deletions(-)
arch/arm/mach-imx/time.c +54 -26
@@ -100,6 +100,9 @@ struct imx_gpt_data {int reg_tcn;int reg_tcmp;void (*gpt_setup_tctl)(struct imx_timer *imxtm); +void (*gpt_irq_enable)(struct imx_timer *imxtm); +void (*gpt_irq_disable)(struct imx_timer *imxtm); +void (*gpt_irq_acknowledge)(struct imx_timer *imxtm);int (*set_next_event)(unsigned long evt,struct clock_event_device *ced); };
@@ -109,40 +112,53 @@ static inline struct imx_timer *to_imx_timer(struct clock_event_device *ced) return container_of(ced, struct imx_timer, ced); } -static inline void gpt_irq_disable (struct imx_timer *imxtm) +static void imx1_gpt_irq_disable (struct imx_timer *imxtm) {unsigned int tmp; -if (timer_is_v2 ()) -writel_relaxed (0 , imxtm->base +V2_IR ); -else { - tmp =readl_relaxed (imxtm->base +MXC_TCTL ); -writel_relaxed (tmp & ~MX1_2_TCTL_IRQEN , imxtm->base +MXC_TCTL ); - } + tmp =readl_relaxed (imxtm->base +MXC_TCTL ); +writel_relaxed (tmp & ~MX1_2_TCTL_IRQEN , imxtm->base +MXC_TCTL ); } +#define imx21_gpt_irq_disable imx1_gpt_irq_disable -static inline void gpt_irq_enable (struct imx_timer *imxtm) +static void imx31_gpt_irq_disable (struct imx_timer *imxtm) { -if (timer_is_v2 ()) -writel_relaxed (1 <<0 , imxtm->base +V2_IR ); -else { -writel_relaxed (readl_relaxed (imxtm->base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , - imxtm->base +MXC_TCTL ); - } +writel_relaxed (0 , imxtm->base +V2_IR ); +} +#define imx6dl_gpt_irq_disable imx31_gpt_irq_disable + +static void imx1_gpt_irq_enable (struct imx_timer *imxtm) +{ +unsigned int tmp; + + tmp =readl_relaxed (imxtm->base +MXC_TCTL ); +writel_relaxed (tmp |MX1_2_TCTL_IRQEN , imxtm->base +MXC_TCTL ); +} +#define imx21_gpt_irq_enable imx1_gpt_irq_enable + +static void imx31_gpt_irq_enable (struct imx_timer *imxtm) +{ +writel_relaxed (1 <<0 , imxtm->base +V2_IR ); +} +#define imx6dl_gpt_irq_enable imx31_gpt_irq_enable + +static void imx1_gpt_irq_acknowledge (struct imx_timer *imxtm) +{ +writel_relaxed (0 , imxtm->base +MX1_2_TSTAT ); } -static void gpt_irq_acknowledge (struct imx_timer *imxtm) +static void imx21_gpt_irq_acknowledge (struct imx_timer *imxtm) { -if (timer_is_v1 ()) { -if (cpu_is_mx1 ()) -writel_relaxed (0 , imxtm->base +MX1_2_TSTAT ); -else -writel_relaxed (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , +writel_relaxed (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , imxtm->base +MX1_2_TSTAT ); - }else if (timer_is_v2 ()) -writel_relaxed (V2_TSTAT_OF1 , imxtm->base +V2_TSTAT ); } +static void imx31_gpt_irq_acknowledge (struct imx_timer *imxtm) +{ +writel_relaxed (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)
@@ -227,7 +243,7 @@ static void mxc_set_mode(enum clock_event_mode mode,local_irq_save (flags);/* Disable interrupt in GPT module */ -gpt_irq_disable (imxtm); + imxtm->gpt->gpt_irq_disable (imxtm);if (mode != imxtm->cem) {u32 tcn =readl_relaxed (imxtm->base + imxtm->gpt->reg_tcn);
@@ -235,7 +251,7 @@ static void mxc_set_mode(enum clock_event_mode mode,writel_relaxed (tcn -3 , imxtm->base + imxtm->gpt->reg_tcmp);/* Clear pending interrupt */ -gpt_irq_acknowledge (imxtm); + imxtm->gpt->gpt_irq_acknowledge (imxtm); }#ifdef DEBUG
@@ -261,7 +277,7 @@ static void mxc_set_mode(enum clock_event_mode mode,* mode switching */ local_irq_save (flags); -gpt_irq_enable (imxtm); + imxtm->gpt->gpt_irq_enable (imxtm);local_irq_restore (flags);break ;case CLOCK_EVT_MODE_SHUTDOWN :
@@ -283,7 +299,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) tstat =readl_relaxed (imxtm->base + imxtm->gpt->reg_tstat); -gpt_irq_acknowledge (imxtm); + imxtm->gpt->gpt_irq_acknowledge (imxtm); ced->event_handler (ced);
@@ -357,6 +373,9 @@ static const struct imx_gpt_data imx1_gpt_data = { .reg_tstat = MX1_2_TSTAT, .reg_tcn = MX1_2_TCN, .reg_tcmp = MX1_2_TCMP, + .gpt_irq_enable = imx1_gpt_irq_enable, + .gpt_irq_disable = imx1_gpt_irq_disable, + .gpt_irq_acknowledge = imx1_gpt_irq_acknowledge, .gpt_setup_tctl = imx1_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, };
@@ -365,6 +384,9 @@ static const struct imx_gpt_data imx21_gpt_data = { .reg_tstat = MX1_2_TSTAT, .reg_tcn = MX1_2_TCN, .reg_tcmp = MX1_2_TCMP, + .gpt_irq_enable = imx21_gpt_irq_enable, + .gpt_irq_disable = imx21_gpt_irq_disable, + .gpt_irq_acknowledge = imx21_gpt_irq_acknowledge, .gpt_setup_tctl = imx21_gpt_setup_tctl, .set_next_event = mx1_2_set_next_event, };
@@ -373,6 +395,9 @@ static const struct imx_gpt_data imx31_gpt_data = { .reg_tstat = V2_TSTAT, .reg_tcn = V2_TCN, .reg_tcmp = V2_TCMP, + .gpt_irq_enable = imx31_gpt_irq_enable, + .gpt_irq_disable = imx31_gpt_irq_disable, + .gpt_irq_acknowledge = imx31_gpt_irq_acknowledge, .gpt_setup_tctl = imx31_gpt_setup_tctl, .set_next_event = v2_set_next_event, };
@@ -381,6 +406,9 @@ static const struct imx_gpt_data imx6dl_gpt_data = { .reg_tstat = V2_TSTAT, .reg_tcn = V2_TCN, .reg_tcmp = V2_TCMP, + .gpt_irq_enable = imx6dl_gpt_irq_enable, + .gpt_irq_disable = imx6dl_gpt_irq_disable, + .gpt_irq_acknowledge = imx6dl_gpt_irq_acknowledge, .gpt_setup_tctl = imx6dl_gpt_setup_tctl, .set_next_event = v2_set_next_event, };
Signature · 1 line
1.9.1
PATCH v2 11/12 ARM: imx: remove platform headers from timer driver
In reply to Shawn GuoWith 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
@@ -36,9 +36,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
@@ -80,9 +77,6 @@#define V2_TIMER_RATE_OSC_DIV8 3000000 -#define timer_is_v1 () (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) -#define timer_is_v2 () (!timer_is_v1()) -struct imx_timer {enum imx_gpt_type type;void __iomem *base;
Signature · 1 line
1.9.1
PATCH v2 12/12 ARM: imx: move timer driver into drivers/clocksource
In reply to Shawn GuoAfter 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
PATCH v2 12/12 ARM: imx: move timer driver into drivers/clocksource
Hi Shawn Guo
Quoted 34 lines
-----Original Message-----
From: Shawn Guo [mailto:shawn.guo at linaro.org]
Sent: 2015?5?22? 10:30
To: linux-arm-kernel at lists.infradead.org
Cc: kernel at pengutronix.de; Daniel Lezcano; Wang Shenwei-B38339; Arnd Bergmann; Shawn Guo
Subject: [PATCH v2 12/12] ARM: imx: move timer driver intodrivers/clocksourceAfter 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 <[email protected]>--- 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 index renamed from arch/arm/mach-imx/Makefile +0
-0
799e65a530be..f70e18470799100644arch/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.odrivers/clocksource/Makefile index renamed from drivers/clocksource/Makefile +0
-0
5b85f6adb258..5c5a89479631100644drivers/clocksource/Makefile +0
-0@@ -52,3 +52,4 @@ obj-$(CONFIG_ARCH_INTEGRATOR_AP) +=
Quoted 5 lines
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
Because there are several types of timers on imx family socs, and this is the driver for the GPT block only, so it would be better to change the file name to timer-gpt.c
Regards,
Shenwei
Quoted 5 lines
drivers/clocksource/timer-imx.c renamed from arch/arm/mach-imx/time.c +0
-0
drivers/clocksource/timer-imx.c
--
1.9.1
PATCH v2 12/12 ARM: imx: move timer driver into drivers/clocksource
Quoted 9 lines · Shenwei Wang
Quoted 6 lines
(quoted diff) +0
-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.oBecause there are several types of timers on imx family socs, and this is the driver for the GPT block only, so it would be better to change the file name to
timer-gpt.c
Okay, I decided to name it timer-imx-gpt.c, so that when people try to find the timer driver for i.MX in drivers/clocksource folder, it will be easier.
Shawn
PATCH v3 12/12 ARM: imx: move timer driver into drivers/clocksource
In reply to Shawn GuoAfter the cleanup on imx timer driver, now it's ready to be moved into drivers/clocksource/. Let's do it.
---
Changes since v2:
- Rename the file to timer-imx-gpt.c
arch/arm/mach-imx/Makefile | 2 +- drivers/clocksource/Makefile | 1 + arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx-gpt.c | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx-gpt.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-gpt.o
drivers/clocksource/timer-imx-gpt.c renamed from arch/arm/mach-imx/time.c +0 -0
Signature · 1 line
1.9.1
PATCH v3 12/12 ARM: imx: move timer driver into drivers/clocksource
Quoted 4 lines · Shawn Guo
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 <[email protected]>
Hi Daniel,
What's your option on this? I plan to send this to arm-soc folks via i.MX tree for 4.2, but need your ACK on this one.
Shawn
Quoted 36 lines
---
Changes since v2:
- Rename the file totimer-imx-gpt.carch/arm/mach-imx/Makefile | 2 +- drivers/clocksource/Makefile | 1 + arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx-gpt.c | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx-gpt.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.odrivers/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-gpt.odrivers/clocksource/timer-imx-gpt.c renamed from arch/arm/mach-imx/time.c +0
-0Signature · 1 line
1.9.1
PATCH v3 12/12 ARM: imx: move timer driver into drivers/clocksource
In reply to Shawn GuoQuoted 4 lines · Shawn Guo
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 <[email protected]>
I don't see the Kconfig change.
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 v3 12/12 ARM: imx: move timer driver into drivers/clocksource
Quoted 7 lines · Daniel Lezcano
Quoted 4 lines · Shawn Guo
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 <[email protected]>I don't see the
Kconfigchange.
As timer-imx-gpt is the only supported timer for i.MX, we use architecture option CONFIG_ARCH_MXC to control it for now.
Shawn
PATCH v3 12/12 ARM: imx: move timer driver into drivers/clocksource
Quoted 11 lines · Shawn Guo
Quoted 7 lines · Daniel Lezcano
Quoted 4 lines · Shawn Guo
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 <[email protected]>I don't see the
Kconfigchange.As timer-imx-gpt is the only supported timer for i.MX, we use architecture option
CONFIG_ARCH_MXCto control it for now.
Hi Shawn,
please use the same as:
https://lkml.org/lkml/2015/5/22/855
and then add in the platform's Kconfig the timer option as:
https://lkml.org/lkml/2015/5/22/937
Thanks
-- Daniel
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 v3 12/12 ARM: imx: move timer driver into drivers/clocksource
Quoted 7 lines · Daniel Lezcano
please use the same as:
https://lkml.org/lkml/2015/5/22/855
and then add in the platform's
Kconfigthe timer option as:
Okay, here it is.
------8<--------------------------
Quoted 1 line
From
fac8436459ad63531b2c39d4f060fd9420f93efdMon Sep 17 00:00:00 2001
From: Shawn Guo <[email protected]>
Date: Fri, 15 May 2015 15:41:00 +0800
Subject: [PATCH] ARM: imx: move timer driver into drivers/clocksource
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/Kconfig | 2 +- arch/arm/mach-imx/Makefile | 2 +- drivers/clocksource/Kconfig | 6 ++++++ drivers/clocksource/Makefile | 1 + arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx-gpt.c | 0 5 files changed, 9 insertions(+), 2 deletions(-) rename arch/arm/mach-imx/time.c => drivers/clocksource/timer-imx-gpt.c (100%)
arch/arm/mach-imx/Kconfig +1 -1
@@ -2,7 +2,7 @@ menuconfig ARCH_MXC bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 select ARCH_REQUIRE_GPIOLIB select ARM_CPU_SUSPEND if PM - select CLKSRC_MMIO + select CLKSRC_IMX_GPT select GENERIC_IRQ_CHIP select PINCTRL select PM_OPP if PM
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/Kconfig +6 -0
@@ -258,4 +258,10 @@ config CLKSRC_PXA help This enables OST0 support available on PXA and SA-11x0 platforms. + +config CLKSRC_IMX_GPT + bool "Clocksource using i.MX GPT" if COMPILE_TEST + depends on OF + select CLKSRC_MMIO + endmenu
drivers/clocksource/Makefile +1 -0
@@ -51,4 +51,5 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o 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_CLKSRC_IMX_GPT) += timer-imx-gpt.o obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o
drivers/clocksource/timer-imx-gpt.c renamed from arch/arm/mach-imx/time.c +0 -0
Signature · 1 line
1.9.1
PATCH v3 12/12 ARM: imx: move timer driver into drivers/clocksource
Quoted 18 lines · Shawn Guo
Quoted 7 lines · Daniel Lezcano
please use the same as:
https://lkml.org/lkml/2015/5/22/855
and then add in the platform's
Kconfigthe timer option as:Okay, here it is.
------8<--------------------------
From
fac8436459ad63531b2c39d4f060fd9420f93efdMon Sep 17 00:00:00 2001
From: Shawn Guo <[email protected]>
Date: Fri, 15 May 2015 15:41:00 +0800
Subject: [PATCH] ARM: imx: move timer driver intodrivers/clocksource
Quoted 5 lines
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 <[email protected]>---
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