ARM: imx: make the imx timer driver implementation independent of SoCs.
Subsystems (6)
cover ARM: imx: make the imx timer driver implementation independent of SoCs.
There are 4 versions of the timer hardware on Freescale MXC hardware. --Version 0: MX1/MXL
--Version 1: MX21, MX27.
--Version 2: MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0) --Version 3: MX6DL, MX6SX, MX6Q(Rev1.1+)
This patch has removed the SoC related codes, and implemented the driver directly upon the hardware timer IP version. The new timer driver has redesigned the internal APIs, and limited the use of global variables as well.
As the new driver has become independent of the SoCs, it has been moved from the directory arch/arm/mach-imx into the directory drivers/clocksources.
Shenwei Wang (18):
ARM: imx: Add a parameter to mxc_timer_init
ARM: imx: Add the definitions for imx_timer and its versions
ARM: imx: Add an array of timer IP block versions
ARM: imx: Added one more parameter for mxc_clockevent_init
ARM: imx: Added one more parameter for mxc_clocksource_init
ARM: imx: New timer driver APIs based on IP block
ARM: imx: Initialize the imx_timer structure
ARM: imx: Reimplemented the _mxc_timer_init based on IP version
ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt
ARM: imx: Removed the SoC relating codes in mxc_set_mode
ARM: imx: Enabled the unused parameter
ARM: imx: Remove one global variable in mxc_clocksource_init
ARM: imx: Removed the unused functions and variables
ARM: imx: Removed the global variable "timer_base"
ARM: imx: Remove the SoC relating codes in mxc_clockevent_init
ARM: imx: Move the variable clockevent_mode into mxc_set_mode
ARM: imx: Codes clean up
ARM: imx: Move time.c into drivers/clocksources
arch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/time.c | 388 --------------------------- drivers/clk/imx/clk-imx1.c | 3 +- drivers/clk/imx/clk-imx21.c | 3 +- drivers/clk/imx/clk-imx27.c | 3 +- drivers/clk/imx/clk-imx31.c | 3 +- drivers/clk/imx/clk-imx35.c | 5 +- drivers/clk/imx/clk.h | 2 +- drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-gpt.c | 572 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 586 insertions(+), 396 deletions(-) delete mode 100644 arch/arm/mach-imx/time.c create mode 100644 drivers/clocksource/timer-gpt.c
--
1.9.1
PATCH 1/18 ARM: imx: Add a parameter to mxc_timer_init
A parameter of integer type is added to the function mxc_timer_init, so that a user could have a way to tell the timer driver the version of the timer IP block.
--- arch/arm/mach-imx/time.c | 2 +- drivers/clk/imx/clk-imx1.c | 3 ++- drivers/clk/imx/clk-imx21.c | 3 ++- drivers/clk/imx/clk-imx27.c | 3 ++- drivers/clk/imx/clk-imx31.c | 3 ++- drivers/clk/imx/clk-imx35.c | 5 +++-- drivers/clk/imx/clk.h | 2 +- 7 files changed, 13 insertions(+), 8 deletions(-)
arch/arm/mach-imx/time.c +1 -1
@@ -346,7 +346,7 @@ static void __init _mxc_timer_init(int irq,setup_irq (irq, &mxc_timer_irq); } -void __init mxc_timer_init (unsigned long pbase,int irq) +void __init mxc_timer_init (unsigned long pbase,int irq,int ver) {struct clk *clk_per =clk_get_sys ("imx-gpt.0" ,"per" );struct clk *clk_ipg =clk_get_sys ("imx-gpt.0" ,"ipg" );
drivers/clk/imx/clk-imx1.c +2 -1
@@ -102,7 +102,8 @@ int __init mx1_clocks_init(unsigned long fref)clk_register_clkdev (clk[IMX1_CLK_DUMMY ],"ipg" ,"imx1-fb.0" );clk_register_clkdev (clk[IMX1_CLK_DUMMY ],"ahb" ,"imx1-fb.0" ); -mxc_timer_init (MX1_TIM1_BASE_ADDR ,MX1_TIM1_INT ); +/*Timer version in MX1 is V0*/ +mxc_timer_init (MX1_TIM1_BASE_ADDR ,MX1_TIM1_INT ,0 );return 0 ; }
drivers/clk/imx/clk-imx21.c +2 -1
@@ -156,7 +156,8 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)clk_register_clkdev (clk[IMX21_CLK_I2C_GATE ],NULL ,"imx21-i2c.0" );clk_register_clkdev (clk[IMX21_CLK_OWIRE_GATE ],NULL ,"mxc_w1.0" ); -mxc_timer_init (MX21_GPT1_BASE_ADDR ,MX21_INT_GPT1 ); +/*Timer version in MX21 is v1*/ +mxc_timer_init (MX21_GPT1_BASE_ADDR ,MX21_INT_GPT1 ,1 );return 0 ; }
drivers/clk/imx/clk-imx27.c +2 -1
@@ -233,7 +233,8 @@ int __init mx27_clocks_init(unsigned long fref)clk_register_clkdev (clk[IMX27_CLK_EMMA_AHB_GATE ],"ahb" ,"m2m-emmaprp.0" );clk_register_clkdev (clk[IMX27_CLK_EMMA_IPG_GATE ],"ipg" ,"m2m-emmaprp.0" ); -mxc_timer_init (MX27_GPT1_BASE_ADDR ,MX27_INT_GPT1 ); +/*Timer version in MX27 is v1*/ +mxc_timer_init (MX27_GPT1_BASE_ADDR ,MX27_INT_GPT1 ,1 );return 0 ; }
drivers/clk/imx/clk-imx31.c +2 -1
@@ -198,7 +198,8 @@ int __init mx31_clocks_init(unsigned long fref)mx31_revision ();clk_disable_unprepare (clk[iim_gate]); -mxc_timer_init (MX31_GPT1_BASE_ADDR ,MX31_INT_GPT ); +/*Timer version in MX31 is v2*/ +mxc_timer_init (MX31_GPT1_BASE_ADDR ,MX31_INT_GPT ,2 );return 0 ; }
drivers/clk/imx/clk-imx35.c +3 -2
@@ -145,7 +145,7 @@ int __init mx35_clocks_init(void) clk[esdhc3_div] =imx_clk_divider ("esdhc3_div" ,"esdhc_sel" , base +MX35_CCM_PDR3 ,16 ,6 ); clk[spdif_sel] =imx_clk_mux ("spdif_sel" , base +MX35_CCM_PDR3 ,22 ,1 , std_sel,ARRAY_SIZE (std_sel)); - clk[spdif_div_pre] =imx_clk_divider ("spdif_div_pre" ,"spdif_sel" , base +MX35_CCM_PDR3 ,29 ,3 );/* divide by 1 not allowed */ + clk[spdif_div_pre] =imx_clk_divider ("spdif_div_pre" ,"spdif_sel" , base +MX35_CCM_PDR3 ,29 ,3 );/* divide by 1 not allowed */ clk[spdif_div_post] =imx_clk_divider ("spdif_div_post" ,"spdif_div_pre" , base +MX35_CCM_PDR3 ,23 ,6 ); clk[ssi_sel] =imx_clk_mux ("ssi_sel" , base +MX35_CCM_PDR2 ,6 ,1 , std_sel,ARRAY_SIZE (std_sel));
@@ -296,7 +296,8 @@ int __init mx35_clocks_init(void)#ifdef CONFIG_MXC_USE_EPIT epit_timer_init (MX35_IO_ADDRESS (MX35_EPIT1_BASE_ADDR ),MX35_INT_EPIT1 );#else -mxc_timer_init (MX35_GPT1_BASE_ADDR ,MX35_INT_GPT ); +/*Timer version in MX35 is v2*/ +mxc_timer_init (MX35_GPT1_BASE_ADDR ,MX35_INT_GPT ,2 );#endif return 0 ;
drivers/clk/imx/clk.h +1 -1
@@ -11,7 +11,7 @@ extern spinlock_t imx_ccm_lock;* mxc_timer_init() to initialize timer for non-DT boot. It can be removed * when these legacy non-DT support is converted or dropped. */ -void mxc_timer_init (unsigned long pbase,int irq); +void mxc_timer_init (unsigned long pbase,int irq,int );void imx_check_clocks (struct clk *clks[],unsigned int count);
Signature · 1 line
1.9.1
PATCH 1/18 ARM: imx: Add a parameter to mxc_timer_init
Quoted 20 lines · Shenwei Wang
A parameter of integer type is added to the function
mxc_timer_init, so that a user could have a way to tell the timer driver the version of the timer IP block.Signed-off-by Shenwei Wang <[email protected]>--- arch/arm/mach-imx/time.c | 2 +- drivers/clk/imx/clk-imx1.c | 3 ++- drivers/clk/imx/clk-imx21.c | 3 ++- drivers/clk/imx/clk-imx27.c | 3 ++- drivers/clk/imx/clk-imx31.c | 3 ++- drivers/clk/imx/clk-imx35.c | 5 +++-- drivers/clk/imx/clk.h | 2 +- 7 files changed, 13 insertions(+), 8 deletions(-)arch/arm/mach-imx/time.c +0
-0
arch/arm/mach-imx/time.c static void __init _mxc_timer_init(int irq, · line 349
Quoted 5 lines
arch/arm/mach-imx/time.c +1
-1@@ -346,7 +346,7 @@ static void __init _mxc_timer_init(int irq,setup_irq (irq, &mxc_timer_irq); } -void __init mxc_timer_init (unsigned long pbase,int irq) +void __init mxc_timer_init (unsigned long pbase,int irq,int ver)
I prefer to have an enum type for it.
enum gpt_device_type {
GPT_TYPE_IMX1, /* MX1/MXL */
GPT_TYPE_IMX21, /* MX21, MX27 */
GPT_TYPE_IMX31, /* MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0) */
GPT_TYPE_IMX6DL, /* MX6DL, MX6SX, MX6Q(Rev1.1+) */
};drivers/clk/imx/clk-imx1.c int __init mx1_clocks_init(unsigned long fref) · line 105
Quoted 13 lines
arch/arm/mach-imx/time.c +0
-0{struct clk *clk_per =clk_get_sys ("imx-gpt.0" ,"per" );struct clk *clk_ipg =clk_get_sys ("imx-gpt.0" ,"ipg" );drivers/clk/imx/clk-imx1.c +1
-1@@ -102,7 +102,8 @@ int __init mx1_clocks_init(unsigned long fref)clk_register_clkdev (clk[IMX1_CLK_DUMMY ],"ipg" ,"imx1-fb.0" );clk_register_clkdev (clk[IMX1_CLK_DUMMY ],"ahb" ,"imx1-fb.0" ); -mxc_timer_init (MX1_TIM1_BASE_ADDR ,MX1_TIM1_INT ); +/*Timer version in MX1 is V0*/
There should be a space before and after '*'.
Quoted 51 lines
drivers/clk/imx/clk-imx1.c +1
-0+mxc_timer_init (MX1_TIM1_BASE_ADDR ,MX1_TIM1_INT ,0 );return 0 ; }drivers/clk/imx/clk-imx21.c +2
-1@@ -156,7 +156,8 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)clk_register_clkdev (clk[IMX21_CLK_I2C_GATE ],NULL ,"imx21-i2c.0" );clk_register_clkdev (clk[IMX21_CLK_OWIRE_GATE ],NULL ,"mxc_w1.0" ); -mxc_timer_init (MX21_GPT1_BASE_ADDR ,MX21_INT_GPT1 ); +/*Timer version in MX21 is v1*/ +mxc_timer_init (MX21_GPT1_BASE_ADDR ,MX21_INT_GPT1 ,1 );return 0 ; }drivers/clk/imx/clk-imx27.c +2
-1@@ -233,7 +233,8 @@ int __init mx27_clocks_init(unsigned long fref)clk_register_clkdev (clk[IMX27_CLK_EMMA_AHB_GATE ],"ahb" ,"m2m-emmaprp.0" );clk_register_clkdev (clk[IMX27_CLK_EMMA_IPG_GATE ],"ipg" ,"m2m-emmaprp.0" ); -mxc_timer_init (MX27_GPT1_BASE_ADDR ,MX27_INT_GPT1 ); +/*Timer version in MX27 is v1*/ +mxc_timer_init (MX27_GPT1_BASE_ADDR ,MX27_INT_GPT1 ,1 );return 0 ; }drivers/clk/imx/clk-imx31.c +2
-1@@ -198,7 +198,8 @@ int __init mx31_clocks_init(unsigned long fref)mx31_revision ();clk_disable_unprepare (clk[iim_gate]); -mxc_timer_init (MX31_GPT1_BASE_ADDR ,MX31_INT_GPT ); +/*Timer version in MX31 is v2*/ +mxc_timer_init (MX31_GPT1_BASE_ADDR ,MX31_INT_GPT ,2 );return 0 ; }drivers/clk/imx/clk-imx35.c +0
-0
drivers/clk/imx/clk-imx35.c int __init mx35_clocks_init(void) · line 148
Quoted 5 lines
drivers/clk/imx/clk-imx35.c +1
-1@@ -145,7 +145,7 @@ int __init mx35_clocks_init(void) clk[esdhc3_div] =imx_clk_divider ("esdhc3_div" ,"esdhc_sel" , base +MX35_CCM_PDR3 ,16 ,6 ); clk[spdif_sel] =imx_clk_mux ("spdif_sel" , base +MX35_CCM_PDR3 ,22 ,1 , std_sel,ARRAY_SIZE (std_sel)); - clk[spdif_div_pre] =imx_clk_divider ("spdif_div_pre" ,"spdif_sel" , base +MX35_CCM_PDR3 ,29 ,3 );/* divide by 1 not allowed */ + clk[spdif_div_pre] =imx_clk_divider ("spdif_div_pre" ,"spdif_sel" , base +MX35_CCM_PDR3 ,29 ,3 );/* divide by 1 not allowed */
Unrelated change?
Shawn
Quoted 30 lines
drivers/clk/imx/clk-imx35.c +2
-1clk[spdif_div_post] =imx_clk_divider ("spdif_div_post" ,"spdif_div_pre" , base +MX35_CCM_PDR3 ,23 ,6 ); clk[ssi_sel] =imx_clk_mux ("ssi_sel" , base +MX35_CCM_PDR2 ,6 ,1 , std_sel,ARRAY_SIZE (std_sel));@@ -296,7 +296,8 @@ int __init mx35_clocks_init(void)#ifdef CONFIG_MXC_USE_EPIT epit_timer_init (MX35_IO_ADDRESS (MX35_EPIT1_BASE_ADDR ),MX35_INT_EPIT1 );#else -mxc_timer_init (MX35_GPT1_BASE_ADDR ,MX35_INT_GPT ); +/*Timer version in MX35 is v2*/ +mxc_timer_init (MX35_GPT1_BASE_ADDR ,MX35_INT_GPT ,2 );#endif return 0 ;drivers/clk/imx/clk.h +1
-1@@ -11,7 +11,7 @@ extern spinlock_t imx_ccm_lock;* mxc_timer_init() to initialize timer for non-DT boot. It can be removed * when these legacy non-DT support is converted or dropped. */ -void mxc_timer_init (unsigned long pbase,int irq); +void mxc_timer_init (unsigned long pbase,int irq,int );void imx_check_clocks (struct clk *clks[],unsigned int count);Signature · 1 line
1.9.1
PATCH 1/18 ARM: imx: Add a parameter to mxc_timer_init
Hi Shawn Guo,
Quoted 19 lines
-----Original Message-----
From: Shawn Guo [mailto:shawn.guo at linaro.org]
Sent: 2015?5?14? 3:02
To: Wang Shenwei-B38339
Cc: linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH 01/18] ARM: imx: Add a parameter tomxc_timer_initarch/arm/mach-imx/time.c static void __init _mxc_timer_init(int irq, · line 349
Quoted 9 lines
b1698e1..eef6b66 100644
arch/arm/mach-imx/time.c +1
-1@@ -346,7 +346,7 @@ static void __init _mxc_timer_init(int irq,setup_irq (irq, &mxc_timer_irq); } -void __init mxc_timer_init (unsigned long pbase,int irq) +void __init mxc_timer_init (unsigned long pbase,int irq,int ver)I prefer to have an enum type for it.
Quoted 8 lines
enum gpt_device_type {
GPT_TYPE_IMX1, /* MX1/MXL */
GPT_TYPE_IMX21, /* MX21, MX27 */
GPT_TYPE_IMX31, /* MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0)
*/
GPT_TYPE_IMX6DL, /* MX6DL, MX6SX, MX6Q(Rev1.1+) */
};I just wanted to make the changes as simple as possible. Since the mxc_timer_init function is for legacy implementation only, I don't want to introduce any more changes in the legacy codes like imx1 and imx21. If an enum is defined here, it will have to be included somewhere in legacy codes. So I prefer to keep the current implementation. I think this part of codes will at last be removed as long as we redesigned all legacy codes based on device tree implementation.
Quoted 11 lines
Quoted 11 lines
arch/arm/mach-imx/time.c +0
-0{struct clk *clk_per =clk_get_sys ("imx-gpt.0" ,"per" ); struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); diff --git
a/drivers/clk/imx/clk-imx1.cb/drivers/clk/imx/clk-imx1.cindex c9812db..49534d8 100644drivers/clk/imx/clk-imx1.c +0
-0@@ -102,7 +102,8 @@ int __init mx1_clocks_init(unsigned long fref)clk_register_clkdev (clk[IMX1_CLK_DUMMY ],"ipg" ,"imx1-fb.0" );clk_register_clkdev (clk[IMX1_CLK_DUMMY ],"ahb" ,"imx1-fb.0" );
Quoted 4 lines
drivers/clk/imx/clk-imx1.c int __init mx1_clocks_init(unsigned long fref) · line 105
Quoted 2 lines
drivers/clk/imx/clk-imx1.c +1
-1-mxc_timer_init (MX1_TIM1_BASE_ADDR ,MX1_TIM1_INT ); +/*Timer version in MX1 is V0*/ There should be a space before and after '*'.
Yes, I will update the patch.
Quoted 58 lines
drivers/clk/imx/clk-imx21.c int __init mx21_clocks_init(unsigned long lref, unsigned
Quoted 10 lines
drivers/clk/imx/clk-imx1.c +1
-0+mxc_timer_init (MX1_TIM1_BASE_ADDR ,MX1_TIM1_INT ,0 );return 0 ; }drivers/clk/imx/clk-imx21.c +0
-0@@ -156,7 +156,8 @@ int __init mx21_clocks_init(unsigned long lref, unsignedlong href)
Quoted 14 lines
drivers/clk/imx/clk-imx21.c +2
-1clk_register_clkdev (clk[IMX21_CLK_I2C_GATE ],NULL ,"imx21-i2c.0" );clk_register_clkdev (clk[IMX21_CLK_OWIRE_GATE ],NULL ,"mxc_w1.0" ); -mxc_timer_init (MX21_GPT1_BASE_ADDR ,MX21_INT_GPT1 ); +/*Timer version in MX21 is v1*/ +mxc_timer_init (MX21_GPT1_BASE_ADDR ,MX21_INT_GPT1 ,1 );return 0 ; }drivers/clk/imx/clk-imx27.c +0
-0drivers/clk/imx/clk-imx27.c int __init mx27_clocks_init(unsigned long fref) · line 233
Quoted 1 line
drivers/clk/imx/clk-imx27.c +0
-0@@ -233,7 +233,8 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb","m2m-emmaprp.0");
Quoted 31 lines
drivers/clk/imx/clk-imx27.c +2
-1clk_register_clkdev (clk[IMX27_CLK_EMMA_IPG_GATE ],"ipg" ,"m2m-emmaprp.0" ); -mxc_timer_init (MX27_GPT1_BASE_ADDR ,MX27_INT_GPT1 ); +/*Timer version in MX27 is v1*/ +mxc_timer_init (MX27_GPT1_BASE_ADDR ,MX27_INT_GPT1 ,1 );return 0 ;}
drivers/clk/imx/clk-imx31.c +2
-1@@ -198,7 +198,8 @@ int __init mx31_clocks_init(unsigned long fref)mx31_revision ();clk_disable_unprepare (clk[iim_gate]); -mxc_timer_init (MX31_GPT1_BASE_ADDR ,MX31_INT_GPT ); +/*Timer version in MX31 is v2*/ +mxc_timer_init (MX31_GPT1_BASE_ADDR ,MX31_INT_GPT ,2 );return 0 ; }drivers/clk/imx/clk-imx35.c +0
-0@@ -145,7 +145,7 @@ int __init mx35_clocks_init(void) clk[esdhc3_div] =imx_clk_divider ("esdhc3_div" ,"esdhc_sel" , base +MX35_CCM_PDR3 ,16 ,6 );
Quoted 9 lines
drivers/clk/imx/clk-imx35.c int __init mx35_clocks_init(void) · line 148
Quoted 1 line
drivers/clk/imx/clk-imx35.c +0
-0clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1,
std_sel,ARRAY_SIZE(std_sel));drivers/clk/imx/clk-imx35.c int __init mx35_clocks_init(void) · line 149
Quoted 1 line
drivers/clk/imx/clk-imx35.c +0
-1- clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base +
MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */drivers/clk/imx/clk-imx35.c int __init mx35_clocks_init(void) · line 150
Quoted 2 lines
drivers/clk/imx/clk-imx35.c +2
-0+ clk[spdif_div_pre] =imx_clk_divider ("spdif_div_pre" ,"spdif_sel" , +base +MX35_CCM_PDR3 ,29 ,3 );/* divide by 1 not allowed */ Unrelated change?
Right, it is unrelated. It was changed by the editor automatically.
Thanks,
Shenwei
Quoted 33 lines
Shawn
Quoted 31 lines
drivers/clk/imx/clk-imx35.c +0
-0clk[spdif_div_post] = imx_clk_divider("spdif_div_post","
spdif_div_pre", base +MX35_CCM_PDR3, 23, 6);clk[ssi_sel] = imx_clk_mux("ssi_sel", base +
MX35_CCM_PDR2, 6, 1,std_sel,ARRAY_SIZE(std_sel)); @@ -296,7 +296,8 @@ int__initmx35_clocks_init(void)#ifdefCONFIG_MXC_USE_EPIT
epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR),MX35_INT_EPIT1); #elsedrivers/clk/imx/clk-imx35.c +2
-1-mxc_timer_init (MX35_GPT1_BASE_ADDR ,MX35_INT_GPT ); +/*Timer version in MX35 is v2*/ +mxc_timer_init (MX35_GPT1_BASE_ADDR ,MX35_INT_GPT ,2 );#endif return 0 ;drivers/clk/imx/clk.h index renamed from drivers/clk/imx/clk.h +0
-06bae537..06da84a 100644
drivers/clk/imx/clk.h +1
-2@@ -11,7 +11,7 @@ extern spinlock_t imx_ccm_lock;* mxc_timer_init() to initialize timer for non-DT boot. It can be removed * when these legacy non-DT support is converted or dropped. */ -void mxc_timer_init (unsigned long pbase,int irq); +void mxc_timer_init (unsigned long pbase,int irq,int );void imx_check_clocks (struct clk *clks[],unsigned int count); --1.9.1
PATCH 2/18 ARM: imx: Add the definitions for imx_timer and its versions
In reply to Shenwei WangA struct was added to describe the imx hardware timers. Added four macros to define the imx timer version.
--- arch/arm/mach-imx/time.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
arch/arm/mach-imx/time.c +15 -0
@@ -81,6 +81,21 @@#define timer_is_v1 () (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())#define timer_is_v2 () (!timer_is_v1()) +#define IMX_TIMER_V0 (0) +#define IMX_TIMER_V1 (1) +#define IMX_TIMER_V2 (2) +#define IMX_TIMER_V3 (3) + +struct imx_timer { +void __iomem *timer_base; +int version; +struct clock_event_device evt; +struct irqaction act; +void (*gpt_irq_enable)(struct imx_timer *); +void (*gpt_irq_disable)(struct imx_timer *); +void (*gpt_irq_acknowledge)(struct imx_timer *); +}; +static struct clock_event_device clockevent_mxc;static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ;
Signature · 1 line
1.9.1
PATCH 2/18 ARM: imx: Add the definitions for imx_timer and its versions
Quoted 13 lines · Shenwei Wang
A struct was added to describe the imx hardware timers. Added four macros to define the imx timer version.
Signed-off-by Shenwei Wang <[email protected]>--- arch/arm/mach-imx/time.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)arch/arm/mach-imx/time.c +0
-0
arch/arm/mach-imx/time.c line 87
Quoted 7 lines
arch/arm/mach-imx/time.c +4
-0@@ -81,6 +81,21 @@#define timer_is_v1 () (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())#define timer_is_v2 () (!timer_is_v1()) +#define IMX_TIMER_V0 (0) +#define IMX_TIMER_V1 (1) +#define IMX_TIMER_V2 (2) +#define IMX_TIMER_V3 (3)
I prefer to use an enum type instead of macros. Also I do not like the versions which are numbered by software arbitrarily. Instead, I'd like to use SoC name that firstly integrates the version to code the type/version.
Shawn
Quoted 23 lines
arch/arm/mach-imx/time.c +11
-0+ +struct imx_timer { +void __iomem *timer_base; +int version; +struct clock_event_device evt; +struct irqaction act; +void (*gpt_irq_enable)(struct imx_timer *); +void (*gpt_irq_disable)(struct imx_timer *); +void (*gpt_irq_acknowledge)(struct imx_timer *); +}; +static struct clock_event_device clockevent_mxc;static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ;Signature · 8 lines
1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 2/18 ARM: imx: Add the definitions for imx_timer and its versions
Quoted 27 lines
-----Original Message-----
From: Shawn Guo [mailto:shawnguo at kernel.org]
Sent: 2015?5?14? 20:19
To: Wang Shenwei-B38339
Cc: shawn.guo at linaro.org; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH 02/18] ARM: imx: Add the definitions forimx_timerand its versionsQuoted 16 lines · Shenwei Wang
A struct was added to describe the imx hardware timers. Added four macros to define the imx timer version.
Signed-off-by Shenwei Wang <[email protected]>--- arch/arm/mach-imx/time.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)arch/arm/mach-imx/time.c index renamed from arch/arm/mach-imx/time.c +0
-0eef6b66..5df3c53 100644
arch/arm/mach-imx/time.c +0
-0@@ -81,6 +81,21 @@#define timer_is_v1 () (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())#define timer_is_v2 () (!timer_is_v1())
Quoted 9 lines
arch/arm/mach-imx/time.c line 87
Quoted 4 lines
arch/arm/mach-imx/time.c +4
-0+#define IMX_TIMER_V0 (0) +#define IMX_TIMER_V1 (1) +#define IMX_TIMER_V2 (2) +#define IMX_TIMER_V3 (3)I prefer to use an enum type instead of macros. Also I do not like the versions which are numbered by software arbitrarily. Instead, I'd like to use SoC name that firstly integrates the version to code the type/version.
Seems we have different implementation philosophy. I don't want to involve any SoC information inside a driver for either an IP block or an external component. The only exception here is the DT bindings, as the SoC name is commonly accepted To be used in the compatible string.
Regards,
Shenwei
Quoted 24 lines
Shawn
Quoted 22 lines
arch/arm/mach-imx/time.c +10
-1+ +struct imx_timer { +void __iomem *timer_base; +int version; +struct clock_event_device evt; +struct irqaction act; +void (*gpt_irq_enable)(struct imx_timer *); +void (*gpt_irq_disable)(struct imx_timer *); +void (*gpt_irq_acknowledge)(struct imx_timer *); }; +static struct clock_event_device clockevent_mxc;static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ; --1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 3/18 ARM: imx: Add an array of timer IP block versions
In reply to Shenwei WangAdded an array to record the relationship between the compatible string and the version of timer IP block.
--- arch/arm/mach-imx/time.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/arm/mach-imx/time.c +17 -0
@@ -372,6 +372,23 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver)_mxc_timer_init (irq, clk_per, clk_ipg); } +struct imx_timer_ip_combo { +const char *compat; +int version; +}; + +static const struct imx_timer_ip_combo imx_timer_tables[] = { + {"fsl,imx1-gpt" ,IMX_TIMER_V0 }, + {"fsl,imx25-gpt" ,IMX_TIMER_V2 }, + {"fsl,imx25-gpt" ,IMX_TIMER_V2 }, + {"fsl,imx50-gpt" ,IMX_TIMER_V2 }, + {"fsl,imx51-gpt" ,IMX_TIMER_V2 }, + {"fsl,imx53-gpt" ,IMX_TIMER_V2 }, + {"fsl,imx6q-gpt" ,IMX_TIMER_V2 }, + {"fsl,imx6sl-gpt" ,IMX_TIMER_V3 }, + {"fsl,imx6sx-gpt" ,IMX_TIMER_V3 }, +}; +static void __init mxc_timer_init_dt (struct device_node *np) {struct clk *clk_per, *clk_ipg;
Signature · 1 line
1.9.1
PATCH 3/18 ARM: imx: Add an array of timer IP block versions
Quoted 23 lines · Shenwei Wang
Added an array to record the relationship between the compatible string and the version of timer IP block.
Signed-off-by Shenwei Wang <[email protected]>--- arch/arm/mach-imx/time.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)arch/arm/mach-imx/time.c +7
-0@@ -372,6 +372,23 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver)_mxc_timer_init (irq, clk_per, clk_ipg); } +struct imx_timer_ip_combo { +const char *compat; +int version; +}; + +static const struct imx_timer_ip_combo imx_timer_tables[] = { + {"fsl,imx1-gpt" ,IMX_TIMER_V0 },
arch/arm/mach-imx/time.c void __init mxc_timer_init(unsigned long pbase, int irq, int ver) · line 391
Quoted 10 lines
arch/arm/mach-imx/time.c +10
-0+ {"fsl,imx25-gpt", IMX_TIMER_V2}, + {"fsl,imx25-gpt", IMX_TIMER_V2}, + {"fsl,imx50-gpt", IMX_TIMER_V2}, + {"fsl,imx51-gpt", IMX_TIMER_V2}, + {"fsl,imx53-gpt", IMX_TIMER_V2}, + {"fsl,imx6q-gpt", IMX_TIMER_V2}, + {"fsl,imx6sl-gpt", IMX_TIMER_V3}, + {"fsl,imx6sx-gpt", IMX_TIMER_V3}, +}; +
I do not like this and the for-loop in mxc_timer_init_dt() to find version number per compatible string. I'd rather to have different init function for different compatible string.
CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", imx1_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", imx25_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", imx25_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", imx25_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", imx25_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", imx25_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", imx6sl_timer_init_dt); CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", imx6sl_timer_init_dt);
Do not take that <soc>_timer_init_dt is a timer init function for <soc>, but this an init time for <soc> type of timer. In this case, we can read it from above CLOCKSOURCE_OF_DECLAREs that imx25/50/51/53/6q are all using imx25 type of gpt, and imx6sx is using the imx6sl type.
Shawn
Quoted 12 lines
arch/arm/mach-imx/time.c +0
-0static void __init mxc_timer_init_dt (struct device_node *np) {struct clk *clk_per, *clk_ipg;Signature · 8 lines
1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 4/18 ARM: imx: Added one more parameter for mxc_clockevent_init
In reply to Shenwei WangOne more parameter was added for the function ofmxc_clockevent_init, so that we could remove the
global variables later.
--- arch/arm/mach-imx/time.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-imx/time.c +3 -2
@@ -299,7 +299,8 @@ static struct clock_event_device clockevent_mxc = { .rating = 200, }; -static int __init mxc_clockevent_init (struct clk *timer_clk) +static int __init mxc_clockevent_init (struct clk *timer_clk, +struct imx_timer *tm) {if (timer_is_v2 ()) clockevent_mxc.set_next_event = v2_set_next_event;
@@ -355,7 +356,7 @@ static void __init _mxc_timer_init(int irq,/* init and register the timer to the framework */ mxc_clocksource_init (clk_per); -mxc_clockevent_init (clk_per); +mxc_clockevent_init (clk_per,0 );/* Make irqs happen */ setup_irq (irq, &mxc_timer_irq);
Signature · 1 line
1.9.1
PATCH 5/18 ARM: imx: Added one more parameter for mxc_clocksource_init
In reply to Shenwei WangOne more parameter was added for the function ofmxc_clocksource_init, so that we could remove the
global variables later.
--- arch/arm/mach-imx/time.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm/mach-imx/time.c +3 -2
@@ -149,7 +149,8 @@ static unsigned long imx_read_current_timer(void)return __raw_readl (sched_clock_reg); } -static int __init mxc_clocksource_init (struct clk *timer_clk) +static int __init mxc_clocksource_init (struct clk *timer_clk, +void __iomem *addr) {unsigned int c =clk_get_rate (timer_clk);void __iomem *reg = timer_base + (timer_is_v2 () ?V2_TCN :MX1_2_TCN );
@@ -355,7 +356,7 @@ static void __init _mxc_timer_init(int irq,__raw_writel (tctl_val, timer_base +MXC_TCTL );/* init and register the timer to the framework */ -mxc_clocksource_init (clk_per); +mxc_clocksource_init (clk_per,0 );mxc_clockevent_init (clk_per,0 );/* Make irqs happen */
Signature · 1 line
1.9.1
PATCH 6/18 ARM: imx: New timer driver APIs based on IP block
In reply to Shenwei WangImplemented the necessory imx timer driver APIs directly based on the version of IP block. These APIs are only relating to the version of the timer block, and are independent of the SoC.
--- arch/arm/mach-imx/time.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+)
arch/arm/mach-imx/time.c +171 -0
@@ -101,6 +101,54 @@ static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;static void __iomem *timer_base; +static void gpt_irq_disable_v0_v1 (struct imx_timer *tm) +{ +unsigned int tmp; + + tmp =__raw_readl (tm->timer_base +MXC_TCTL ); +__raw_writel (tmp & ~MX1_2_TCTL_IRQEN , tm->timer_base +MXC_TCTL ); + +} + +static void gpt_irq_disable_v2_v3 (struct imx_timer *tm) +{ +__raw_writel (0 , tm->timer_base +V2_IR ); + +} + +static void gpt_irq_enable_v0_v1 (struct imx_timer *tm) +{ +__raw_writel (__raw_readl (tm->timer_base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , + tm->timer_base +MXC_TCTL ); +} + +static void gpt_irq_enable_v2_v3 (struct imx_timer *tm) +{ +__raw_writel (1 , tm->timer_base +V2_IR ); +} + +static void gpt_irq_acknowledge_v0 (struct imx_timer *tm) +{ +__raw_readl (tm->timer_base +MX1_2_TSTAT ); + +__raw_writel (0 , tm->timer_base +MX1_2_TSTAT ); +} + +static void gpt_irq_acknowledge_v1 (struct imx_timer *tm) +{ +__raw_readl (tm->timer_base +MX1_2_TSTAT ); + +__raw_writel (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , + tm->timer_base +MX1_2_TSTAT ); +} + +static void gpt_irq_acknowledge_v2_v3 (struct imx_timer *tm) +{ +__raw_readl (tm->timer_base +V2_TSTAT ); + +__raw_writel (V2_TSTAT_OF1 , tm->timer_base +V2_TSTAT ); +} +static inline void gpt_irq_disable (void ) {unsigned int tmp;
@@ -314,6 +362,129 @@ static int __init mxc_clockevent_init(struct clk *timer_clk,return 0 ; } +static void __init _mxc_timer_init_v0_v1 (int irq,struct clk *clk_per, +struct clk *clk_ipg,struct imx_timer *tm) +{ +uint32_t tctl_val; + +if (IS_ERR (clk_per)) { +pr_err ("i.MX timer: unable to get clk\n" ); +return ; + } + +if (!IS_ERR (clk_ipg)) +clk_prepare_enable (clk_ipg); + +clk_prepare_enable (clk_per); + +/* +* Initialise to a known state (all timers off, and timing reset) +*/ + +__raw_writel (0 , tm->timer_base +MXC_TCTL ); +__raw_writel (0 , tm->timer_base +MXC_TPRER );/* see datasheet note */ + + tctl_val =MX1_2_TCTL_FRR |MX1_2_TCTL_CLK_PCLK1 |MXC_TCTL_TEN ; + +__raw_writel (tctl_val, tm->timer_base +MXC_TCTL ); + +/* init and register the timer to the framework */ +mxc_clocksource_init (clk_per, tm->timer_base +MX1_2_TCN ); + + tm->evt.set_next_event = mx1_2_set_next_event; +mxc_clockevent_init (clk_per, tm); + +/* Make irqs happen */ +setup_irq (irq, &tm->act); +} + +static void __init _mxc_timer_init_v2 (int irq,struct clk *clk_per, +struct clk *clk_ipg,struct imx_timer *tm) +{ +uint32_t tctl_val; + +if (IS_ERR (clk_per)) { +pr_err ("i.MX timer: unable to get clk\n" ); +return ; + } + +if (!IS_ERR (clk_ipg)) +clk_prepare_enable (clk_ipg); + +clk_prepare_enable (clk_per); + +/* +* Initialise to a known state (all timers off, and timing reset) +*/ + +__raw_writel (0 , tm->timer_base +MXC_TCTL ); +__raw_writel (0 , tm->timer_base +MXC_TPRER );/* see datasheet note */ + + tctl_val =V2_TCTL_FRR |V2_TCTL_WAITEN |MXC_TCTL_TEN ; + +if (clk_get_rate (clk_per) ==V2_TIMER_RATE_OSC_DIV8 ) + tctl_val |=V2_TCTL_CLK_OSC_DIV8 ; +else + tctl_val |=V2_TCTL_CLK_PER ; + +__raw_writel (tctl_val, tm->timer_base +MXC_TCTL ); + +/* init and register the timer to the framework */ +mxc_clocksource_init (clk_per, tm->timer_base +V2_TCN ); + + tm->evt.set_next_event = v2_set_next_event; +mxc_clockevent_init (clk_per, tm); + +/* Make irqs happen */ +setup_irq (irq, &tm->act); +} + +static void __init _mxc_timer_init_v3 (int irq,struct clk *clk_per, +struct clk *clk_ipg,struct imx_timer *tm) +{ +uint32_t tctl_val; + +if (IS_ERR (clk_per)) { +pr_err ("i.MX timer: unable to get clk\n" ); +return ; + } + +if (!IS_ERR (clk_ipg)) +clk_prepare_enable (clk_ipg); + +clk_prepare_enable (clk_per); + +/* +* Initialise to a known state (all timers off, and timing reset) +*/ + +__raw_writel (0 , tm->timer_base +MXC_TCTL ); +__raw_writel (0 , tm->timer_base +MXC_TPRER );/* see datasheet note */ + + tctl_val =V2_TCTL_FRR |V2_TCTL_WAITEN |MXC_TCTL_TEN ; + +if (clk_get_rate (clk_per) ==V2_TIMER_RATE_OSC_DIV8 ) { + tctl_val |=V2_TCTL_CLK_OSC_DIV8 ; +/* 24 / 8 = 3 MHz */ +__raw_writel (7 <<V2_TPRER_PRE24M , + tm->timer_base +MXC_TPRER ); + tctl_val |=V2_TCTL_24MEN ; + }else { + tctl_val |=V2_TCTL_CLK_PER ; + } + +__raw_writel (tctl_val, tm->timer_base +MXC_TCTL ); + +/* init and register the timer to the framework */ +mxc_clocksource_init (clk_per, tm->timer_base +V2_TCN ); + + tm->evt.set_next_event = v2_set_next_event; +mxc_clockevent_init (clk_per, tm); + +/* Make irqs happen */ +setup_irq (irq, &tm->act); +} +static void __init _mxc_timer_init (int irq,struct clk *clk_per,struct clk *clk_ipg) {
Signature · 1 line
1.9.1
PATCH 6/18 ARM: imx: New timer driver APIs based on IP block
Quoted 186 lines · Shenwei Wang
Implemented the necessory imx timer driver APIs directly based on the version of IP block. These APIs are only relating to the version of the timer block, and are independent of the SoC.
Signed-off-by Shenwei Wang <[email protected]>--- arch/arm/mach-imx/time.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+)arch/arm/mach-imx/time.c +161
-0@@ -101,6 +101,54 @@ static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;static void __iomem *timer_base; +static void gpt_irq_disable_v0_v1 (struct imx_timer *tm) +{ +unsigned int tmp; + + tmp =__raw_readl (tm->timer_base +MXC_TCTL ); +__raw_writel (tmp & ~MX1_2_TCTL_IRQEN , tm->timer_base +MXC_TCTL ); + +} + +static void gpt_irq_disable_v2_v3 (struct imx_timer *tm) +{ +__raw_writel (0 , tm->timer_base +V2_IR ); + +} + +static void gpt_irq_enable_v0_v1 (struct imx_timer *tm) +{ +__raw_writel (__raw_readl (tm->timer_base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , + tm->timer_base +MXC_TCTL ); +} + +static void gpt_irq_enable_v2_v3 (struct imx_timer *tm) +{ +__raw_writel (1 , tm->timer_base +V2_IR ); +} + +static void gpt_irq_acknowledge_v0 (struct imx_timer *tm) +{ +__raw_readl (tm->timer_base +MX1_2_TSTAT ); + +__raw_writel (0 , tm->timer_base +MX1_2_TSTAT ); +} + +static void gpt_irq_acknowledge_v1 (struct imx_timer *tm) +{ +__raw_readl (tm->timer_base +MX1_2_TSTAT ); + +__raw_writel (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , + tm->timer_base +MX1_2_TSTAT ); +} + +static void gpt_irq_acknowledge_v2_v3 (struct imx_timer *tm) +{ +__raw_readl (tm->timer_base +V2_TSTAT ); + +__raw_writel (V2_TSTAT_OF1 , tm->timer_base +V2_TSTAT ); +} +static inline void gpt_irq_disable (void ) {unsigned int tmp;@@ -314,6 +362,129 @@ static int __init mxc_clockevent_init(struct clk *timer_clk,return 0 ; } +static void __init _mxc_timer_init_v0_v1 (int irq,struct clk *clk_per, +struct clk *clk_ipg,struct imx_timer *tm) +{ +uint32_t tctl_val; + +if (IS_ERR (clk_per)) { +pr_err ("i.MX timer: unable to get clk\n" ); +return ; + } + +if (!IS_ERR (clk_ipg)) +clk_prepare_enable (clk_ipg); + +clk_prepare_enable (clk_per); + +/* +* Initialise to a known state (all timers off, and timing reset) +*/ + +__raw_writel (0 , tm->timer_base +MXC_TCTL ); +__raw_writel (0 , tm->timer_base +MXC_TPRER );/* see datasheet note */ + + tctl_val =MX1_2_TCTL_FRR |MX1_2_TCTL_CLK_PCLK1 |MXC_TCTL_TEN ; + +__raw_writel (tctl_val, tm->timer_base +MXC_TCTL ); + +/* init and register the timer to the framework */ +mxc_clocksource_init (clk_per, tm->timer_base +MX1_2_TCN ); + + tm->evt.set_next_event = mx1_2_set_next_event; +mxc_clockevent_init (clk_per, tm); + +/* Make irqs happen */ +setup_irq (irq, &tm->act); +} + +static void __init _mxc_timer_init_v2 (int irq,struct clk *clk_per, +struct clk *clk_ipg,struct imx_timer *tm) +{ +uint32_t tctl_val; + +if (IS_ERR (clk_per)) { +pr_err ("i.MX timer: unable to get clk\n" ); +return ; + } + +if (!IS_ERR (clk_ipg)) +clk_prepare_enable (clk_ipg); + +clk_prepare_enable (clk_per); + +/* +* Initialise to a known state (all timers off, and timing reset) +*/ + +__raw_writel (0 , tm->timer_base +MXC_TCTL ); +__raw_writel (0 , tm->timer_base +MXC_TPRER );/* see datasheet note */ + + tctl_val =V2_TCTL_FRR |V2_TCTL_WAITEN |MXC_TCTL_TEN ; + +if (clk_get_rate (clk_per) ==V2_TIMER_RATE_OSC_DIV8 ) + tctl_val |=V2_TCTL_CLK_OSC_DIV8 ; +else + tctl_val |=V2_TCTL_CLK_PER ; + +__raw_writel (tctl_val, tm->timer_base +MXC_TCTL ); + +/* init and register the timer to the framework */ +mxc_clocksource_init (clk_per, tm->timer_base +V2_TCN ); + + tm->evt.set_next_event = v2_set_next_event; +mxc_clockevent_init (clk_per, tm); + +/* Make irqs happen */ +setup_irq (irq, &tm->act); +} + +static void __init _mxc_timer_init_v3 (int irq,struct clk *clk_per, +struct clk *clk_ipg,struct imx_timer *tm) +{ +uint32_t tctl_val; + +if (IS_ERR (clk_per)) { +pr_err ("i.MX timer: unable to get clk\n" ); +return ; + } + +if (!IS_ERR (clk_ipg)) +clk_prepare_enable (clk_ipg); + +clk_prepare_enable (clk_per); + +/* +* Initialise to a known state (all timers off, and timing reset) +*/ + +__raw_writel (0 , tm->timer_base +MXC_TCTL ); +__raw_writel (0 , tm->timer_base +MXC_TPRER );/* see datasheet note */ + + tctl_val =V2_TCTL_FRR |V2_TCTL_WAITEN |MXC_TCTL_TEN ; + +if (clk_get_rate (clk_per) ==V2_TIMER_RATE_OSC_DIV8 ) { + tctl_val |=V2_TCTL_CLK_OSC_DIV8 ; +/* 24 / 8 = 3 MHz */ +__raw_writel (7 <<V2_TPRER_PRE24M , + tm->timer_base +MXC_TPRER ); + tctl_val |=V2_TCTL_24MEN ; + }else { + tctl_val |=V2_TCTL_CLK_PER ; + } + +__raw_writel (tctl_val, tm->timer_base +MXC_TCTL ); +
arch/arm/mach-imx/time.c static int __init mxc_clockevent_init(struct clk *timer_clk, · line 487
Quoted 10 lines
arch/arm/mach-imx/time.c +10
-0+/* init and register the timer to the framework */ +mxc_clocksource_init (clk_per, tm->timer_base +V2_TCN ); + + tm->evt.set_next_event = v2_set_next_event; +mxc_clockevent_init (clk_per, tm); + +/* Make irqs happen */ +setup_irq (irq, &tm->act); +} +
Quite some bit of the code is duplicated among these three _mxc_timer_init_v?() functions. I'm not sure this makes the most sense.
Shawn
Quoted 12 lines
arch/arm/mach-imx/time.c +0
-0static void __init _mxc_timer_init (int irq,struct clk *clk_per,struct clk *clk_ipg) {Signature · 8 lines
1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 7/18 ARM: imx: Initialize the imx_timer structure
In reply to Shenwei WangInitialized the imx_timer struct in the following two functions:mxc_timer_initmxc_timer_init_dt
--- arch/arm/mach-imx/time.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-)
arch/arm/mach-imx/time.c +54 -1
@@ -31,6 +31,7 @@#include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> +#include <linux/slab.h> #include <asm/mach/time.h>
@@ -536,12 +537,29 @@ static void __init _mxc_timer_init(int irq,void __init mxc_timer_init (unsigned long pbase,int irq,int ver) { +struct imx_timer *timer;struct clk *clk_per =clk_get_sys ("imx-gpt.0" ,"per" );struct clk *clk_ipg =clk_get_sys ("imx-gpt.0" ,"ipg" ); timer_base =ioremap (pbase,SZ_4K );BUG_ON (!timer_base); + timer =kzalloc (sizeof (struct imx_timer ),GFP_KERNEL ); +if (!timer) +panic ("Can't allocate timer struct\n" ); + + timer->timer_base = timer_base; + timer->version = ver; + timer->evt.name ="mxc_timer1" ; + timer->evt.rating =200 ; + timer->evt.features =CLOCK_EVT_FEAT_ONESHOT ; + timer->evt.set_mode = mxc_set_mode; + timer->evt.set_next_event = v2_set_next_event; + timer->act.name ="i.MX Timer Tick" ; + timer->act.flags =IRQF_TIMER |IRQF_IRQPOLL ; + timer->act.dev_id = timer; + timer->act.handler = mxc_timer_interrupt; +_mxc_timer_init (irq, clk_per, clk_ipg); }
@@ -565,11 +583,34 @@ static const struct imx_timer_ip_combo imx_timer_tables[] = {static void __init mxc_timer_init_dt (struct device_node *np) {struct clk *clk_per, *clk_ipg; -int irq; +int irq, i, ret, ver; +struct imx_timer *timer;if (timer_base)return ; +for (i =0 ; i <sizeof (imx_timer_tables) / +sizeof (struct imx_timer_ip_combo ); i++) { + ret =of_device_is_compatible (np, imx_timer_tables[i].compat); +if (ret) { + ver = imx_timer_tables[i].version; +pr_err ("<%s> compatible=%s timer_version=%d\r\n" , + __func__, imx_timer_tables[i].compat, ver); +break ; + } + } + +if (!ret) { +pr_err ("<%s> timer device node is not supported\r\n" , __func__); +return ; + } + + timer =kzalloc (sizeof (struct imx_timer ),GFP_KERNEL ); +if (!timer) +panic ("Can't allocate timer struct\n" ); + + timer->timer_base =of_iomap (np,0 ); + timer_base =of_iomap (np,0 );WARN_ON (!timer_base); irq =irq_of_parse_and_map (np,0 );
@@ -581,8 +622,20 @@ static void __init mxc_timer_init_dt(struct device_node *np)if (IS_ERR (clk_per)) clk_per =of_clk_get_by_name (np,"per" ); + timer->version = ver; + timer->evt.name = np->name; + timer->evt.rating =200 ; + timer->evt.features =CLOCK_EVT_FEAT_ONESHOT ; + timer->evt.set_mode = mxc_set_mode; + timer->evt.set_next_event = v2_set_next_event; + timer->act.name = np->name; + timer->act.flags =IRQF_TIMER |IRQF_IRQPOLL ; + timer->act.dev_id = timer; + timer->act.handler = mxc_timer_interrupt; +_mxc_timer_init (irq, clk_per, clk_ipg); } +CLOCKSOURCE_OF_DECLARE (mx1_timer,"fsl,imx1-gpt" , mxc_timer_init_dt);CLOCKSOURCE_OF_DECLARE (mx25_timer,"fsl,imx25-gpt" , mxc_timer_init_dt);CLOCKSOURCE_OF_DECLARE (mx50_timer,"fsl,imx50-gpt" , mxc_timer_init_dt);
Signature · 1 line
1.9.1
PATCH 7/18 ARM: imx: Initialize the imx_timer structure
Quoted 88 lines · Shenwei Wang
Initialized the
imx_timerstruct in the following two functions:mxc_timer_initmxc_timer_init_dtSigned-off-by Shenwei Wang <[email protected]>--- arch/arm/mach-imx/time.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-)arch/arm/mach-imx/time.c +42
-1@@ -31,6 +31,7 @@#include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> +#include <linux/slab.h> #include <asm/mach/time.h> @@ -536,12 +537,29 @@ static void __init _mxc_timer_init(int irq,void __init mxc_timer_init (unsigned long pbase,int irq,int ver) { +struct imx_timer *timer;struct clk *clk_per =clk_get_sys ("imx-gpt.0" ,"per" );struct clk *clk_ipg =clk_get_sys ("imx-gpt.0" ,"ipg" ); timer_base =ioremap (pbase,SZ_4K );BUG_ON (!timer_base); + timer =kzalloc (sizeof (struct imx_timer ),GFP_KERNEL ); +if (!timer) +panic ("Can't allocate timer struct\n" ); + + timer->timer_base = timer_base; + timer->version = ver; + timer->evt.name ="mxc_timer1" ; + timer->evt.rating =200 ; + timer->evt.features =CLOCK_EVT_FEAT_ONESHOT ; + timer->evt.set_mode = mxc_set_mode; + timer->evt.set_next_event = v2_set_next_event; + timer->act.name ="i.MX Timer Tick" ; + timer->act.flags =IRQF_TIMER |IRQF_IRQPOLL ; + timer->act.dev_id = timer; + timer->act.handler = mxc_timer_interrupt; +_mxc_timer_init (irq, clk_per, clk_ipg); }@@ -565,11 +583,34 @@ static const struct imx_timer_ip_combo imx_timer_tables[] = {static void __init mxc_timer_init_dt (struct device_node *np) {struct clk *clk_per, *clk_ipg; -int irq; +int irq, i, ret, ver; +struct imx_timer *timer;if (timer_base)return ; +for (i =0 ; i <sizeof (imx_timer_tables) / +sizeof (struct imx_timer_ip_combo ); i++) { + ret =of_device_is_compatible (np, imx_timer_tables[i].compat); +if (ret) { + ver = imx_timer_tables[i].version; +pr_err ("<%s> compatible=%s timer_version=%d\r\n" , + __func__, imx_timer_tables[i].compat, ver); +break ; + } + } + +if (!ret) { +pr_err ("<%s> timer device node is not supported\r\n" , __func__); +return ; + } + + timer =kzalloc (sizeof (struct imx_timer ),GFP_KERNEL ); +if (!timer) +panic ("Can't allocate timer struct\n" ); + + timer->timer_base =of_iomap (np,0 ); + timer_base =of_iomap (np,0 );WARN_ON (!timer_base); irq =irq_of_parse_and_map (np,0 );
arch/arm/mach-imx/time.c static void __init mxc_timer_init_dt(struct device_node *np) · line 626
Quoted 5 lines
arch/arm/mach-imx/time.c +2
-0@@ -581,8 +622,20 @@ static void __init mxc_timer_init_dt(struct device_node *np)if (IS_ERR (clk_per)) clk_per =of_clk_get_by_name (np,"per" ); + timer->version = ver; + timer->evt.name = np->name;
These names shouldn't be treated differently between DT and non-DT. Also I do not see obvious benefit to allocate the structure over static definition. Using static one can let us keep necessary consistency between DT and non-DT.
Shawn
Quoted 24 lines
arch/arm/mach-imx/time.c +10
-0+ timer->evt.rating =200 ; + timer->evt.features =CLOCK_EVT_FEAT_ONESHOT ; + timer->evt.set_mode = mxc_set_mode; + timer->evt.set_next_event = v2_set_next_event; + timer->act.name = np->name; + timer->act.flags =IRQF_TIMER |IRQF_IRQPOLL ; + timer->act.dev_id = timer; + timer->act.handler = mxc_timer_interrupt; +_mxc_timer_init (irq, clk_per, clk_ipg); } +CLOCKSOURCE_OF_DECLARE (mx1_timer,"fsl,imx1-gpt" , mxc_timer_init_dt);CLOCKSOURCE_OF_DECLARE (mx25_timer,"fsl,imx25-gpt" , mxc_timer_init_dt);CLOCKSOURCE_OF_DECLARE (mx50_timer,"fsl,imx50-gpt" , mxc_timer_init_dt);Signature · 8 lines
1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 8/18 ARM: imx: Reimplemented the _mxc_timer_init based on IP version
In reply to Shenwei WangReimplemented the function of _mxc_timer_init just based on the version of timer IP block.
--- arch/arm/mach-imx/time.c | 75 +++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 42 deletions(-)
arch/arm/mach-imx/time.c +33 -42
@@ -486,53 +486,44 @@ static void __init _mxc_timer_init_v3(int irq, struct clk *clk_per,setup_irq (irq, &tm->act); } -static void __init _mxc_timer_init (int irq, -struct clk *clk_per,struct clk *clk_ipg) +static void __init _mxc_timer_init (int irq,struct clk *clk_per, +struct clk *clk_ipg,struct imx_timer *tm) { -uint32_t tctl_val; - -if (IS_ERR (clk_per)) { -pr_err ("i.MX timer: unable to get clk\n" ); -return ; - } -if (!IS_ERR (clk_ipg)) -clk_prepare_enable (clk_ipg); - -clk_prepare_enable (clk_per); +switch (tm->version) { +case IMX_TIMER_V0 : + tm->gpt_irq_enable = gpt_irq_enable_v0_v1; + tm->gpt_irq_disable = gpt_irq_disable_v0_v1; + tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v0; +_mxc_timer_init_v0_v1 (irq, clk_per, clk_ipg, tm); +break ; -/* -* Initialise to a known state (all timers off, and timing reset) -*/ +case IMX_TIMER_V1 : + tm->gpt_irq_enable = gpt_irq_enable_v0_v1; + tm->gpt_irq_disable = gpt_irq_disable_v0_v1; + tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v1; +_mxc_timer_init_v0_v1 (irq, clk_per, clk_ipg, tm); +break ; -__raw_writel (0 , timer_base +MXC_TCTL ); -__raw_writel (0 , timer_base +MXC_TPRER );/* see datasheet note */ - -if (timer_is_v2 ()) { - tctl_val =V2_TCTL_FRR |V2_TCTL_WAITEN |MXC_TCTL_TEN ; -if (clk_get_rate (clk_per) ==V2_TIMER_RATE_OSC_DIV8 ) { - tctl_val |=V2_TCTL_CLK_OSC_DIV8 ; -if (cpu_is_imx6dl () ||cpu_is_imx6sx ()) { -/* 24 / 8 = 3 MHz */ -__raw_writel (7 <<V2_TPRER_PRE24M , - timer_base +MXC_TPRER ); - tctl_val |=V2_TCTL_24MEN ; - } - }else { - tctl_val |=V2_TCTL_CLK_PER ; - } - }else { - tctl_val =MX1_2_TCTL_FRR |MX1_2_TCTL_CLK_PCLK1 |MXC_TCTL_TEN ; - } +case IMX_TIMER_V2 : + tm->gpt_irq_enable = gpt_irq_enable_v2_v3; + tm->gpt_irq_disable = gpt_irq_disable_v2_v3; + tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v2_v3; +_mxc_timer_init_v2 (irq, clk_per, clk_ipg, tm); +break ; -__raw_writel (tctl_val, timer_base +MXC_TCTL ); +case IMX_TIMER_V3 : + tm->gpt_irq_enable = gpt_irq_enable_v2_v3; + tm->gpt_irq_disable = gpt_irq_disable_v2_v3; + tm->gpt_irq_acknowledge = gpt_irq_acknowledge_v2_v3; +_mxc_timer_init_v3 (irq, clk_per, clk_ipg, tm); +break ; -/* init and register the timer to the framework */ -mxc_clocksource_init (clk_per,0 ); -mxc_clockevent_init (clk_per,0 ); +default : +pr_err ("<%s> timer device node is not supported\r\n" , __func__); +break ; -/* Make irqs happen */ -setup_irq (irq, &mxc_timer_irq); + } }void __init mxc_timer_init (unsigned long pbase,int irq,int ver)
@@ -560,7 +551,7 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver) timer->act.dev_id = timer; timer->act.handler = mxc_timer_interrupt; -_mxc_timer_init (irq, clk_per, clk_ipg); +_mxc_timer_init (irq, clk_per, clk_ipg, timer); }struct imx_timer_ip_combo {
@@ -633,7 +624,7 @@ static void __init mxc_timer_init_dt(struct device_node *np) timer->act.dev_id = timer; timer->act.handler = mxc_timer_interrupt; -_mxc_timer_init (irq, clk_per, clk_ipg); +_mxc_timer_init (irq, clk_per, clk_ipg, timer); }CLOCKSOURCE_OF_DECLARE (mx1_timer,"fsl,imx1-gpt" , mxc_timer_init_dt);
Signature · 1 line
1.9.1
PATCH 9/18 ARM: imx: Removed the SoC relating codes in mxc_timer_interrupt
In reply to Shenwei WangRemoved the SoC relating codes in the function ofmxc_timer_interrupt.
--- arch/arm/mach-imx/time.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
arch/arm/mach-imx/time.c +7 -8
@@ -320,17 +320,16 @@ static void mxc_set_mode(enum clock_event_mode mode,*/ static irqreturn_t mxc_timer_interrupt (int irq,void *dev_id) { -struct clock_event_device *evt = &clockevent_mxc; -uint32_t tstat; +struct imx_timer *tm = dev_id; +void (*event_handler)(struct clock_event_device *); -if (timer_is_v2 ()) - tstat =__raw_readl (timer_base +V2_TSTAT ); -else - tstat =__raw_readl (timer_base +MX1_2_TSTAT ); +BUG_ON (!tm); -gpt_irq_acknowledge (); + tm->gpt_irq_acknowledge (tm); - evt->event_handler (evt); + event_handler =ACCESS_ONCE (tm->evt.event_handler); +if (event_handler) +event_handler (&tm->evt);return IRQ_HANDLED ; }
Signature · 1 line
1.9.1
PATCH 10/18 ARM: imx: Removed the SoC relating codes in mxc_set_mode
In reply to Shenwei WangEnabled the use of parameter *evt, and removed the SoC relating codes in mxc_set_mode.
--- arch/arm/mach-imx/time.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
arch/arm/mach-imx/time.c +5 -9
@@ -258,6 +258,7 @@ static void mxc_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) {unsigned long flags; + struct imx_timer *tm = container_of(evt, struct imx_timer, evt);/* * The timer interrupt generation is disabled at least
@@ -266,19 +267,14 @@ static void mxc_set_mode(enum clock_event_mode mode,local_irq_save (flags);/* Disable interrupt in GPT module */ -gpt_irq_disable (); + tm->gpt_irq_disable (tm);if (mode != clockevent_mode) {/* Set event time into far-far future */ -if (timer_is_v2 ()) -__raw_writel (__raw_readl (timer_base +V2_TCN ) -3 , - timer_base +V2_TCMP ); -else -__raw_writel (__raw_readl (timer_base +MX1_2_TCN ) -3 , - timer_base +MX1_2_TCMP ); + evt->set_next_event (-3 , evt);/* Clear pending interrupt */ -gpt_irq_acknowledge (); + tm->gpt_irq_acknowledge (tm); }#ifdef DEBUG
@@ -304,7 +300,7 @@ static void mxc_set_mode(enum clock_event_mode mode,* mode switching */ local_irq_save (flags); -gpt_irq_enable (); + tm->gpt_irq_enable (tm);local_irq_restore (flags);break ;case CLOCK_EVT_MODE_SHUTDOWN :
Signature · 1 line
1.9.1
PATCH 11/18 ARM: imx: Enabled the unused parameter
In reply to Shenwei WangEnabled the unused parameter in the following two functions:mx1_2_set_next_eventv2_set_next_event
and removed the use of the global variable of "timer_base".
--- arch/arm/mach-imx/time.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
arch/arm/mach-imx/time.c +10 -8
@@ -218,29 +218,31 @@ static int __init mxc_clocksource_init(struct clk *timer_clk,/* clock event */ static int mx1_2_set_next_event (unsigned long evt, -struct clock_event_device *unused) +struct clock_event_device *evt_dev) {unsigned long tcmp; + struct imx_timer *tm = container_of(evt_dev, struct imx_timer, evt); - tcmp =__raw_readl (timer_base +MX1_2_TCN ) + evt; + tcmp =__raw_readl (tm->timer_base +MX1_2_TCN ) + evt; -__raw_writel (tcmp, timer_base +MX1_2_TCMP ); +__raw_writel (tcmp, tm->timer_base +MX1_2_TCMP ); -return (int )(tcmp -__raw_readl (timer_base +MX1_2_TCN )) <0 ? +return (int )(tcmp -__raw_readl (tm->timer_base +MX1_2_TCN )) <0 ? -ETIME :0 ; }static int v2_set_next_event (unsigned long evt, -struct clock_event_device *unused) +struct clock_event_device *evt_dev) {unsigned long tcmp; + struct imx_timer *tm = container_of(evt_dev, struct imx_timer, evt); - tcmp =__raw_readl (timer_base +V2_TCN ) + evt; + tcmp =__raw_readl (tm->timer_base +V2_TCN ) + evt; -__raw_writel (tcmp, timer_base +V2_TCMP ); +__raw_writel (tcmp, tm->timer_base +V2_TCMP );return evt <0x7fffffff && - (int )(tcmp -__raw_readl (timer_base +V2_TCN )) <0 ? + (int )(tcmp -__raw_readl (tm->timer_base +V2_TCN )) <0 ? -ETIME :0 ; }
Signature · 1 line
1.9.1
PATCH 12/18 ARM: imx: Remove one global variable in mxc_clocksource_init
In reply to Shenwei WangRemoved the use of global variable "timer_base" in the function of mxc_clocksource_init, and get the register address from the input parameter.
--- arch/arm/mach-imx/time.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
arch/arm/mach-imx/time.c +4 -3
@@ -202,16 +202,17 @@ static int __init mxc_clocksource_init(struct clk *timer_clk, void __iomem *addr) {unsigned int c =clk_get_rate (timer_clk); -void __iomem *reg = timer_base + (timer_is_v2 () ?V2_TCN :MX1_2_TCN ); + +BUG_ON (!addr); imx_delay_timer.read_current_timer = &imx_read_current_timer; imx_delay_timer.freq = c;register_current_timer_delay (&imx_delay_timer); - sched_clock_reg = reg; + sched_clock_reg = addr;sched_clock_register (mxc_read_sched_clock,32 , c); -return clocksource_mmio_init (reg,"mxc_timer1" , c,200 ,32 , +return clocksource_mmio_init (addr,"mxc_timer1" , c,200 ,32 , clocksource_mmio_readl_up); }
Signature · 1 line
1.9.1
PATCH 13/18 ARM: imx: Removed the unused functions and variables
In reply to Shenwei WangRemoved the following unused functions which were related to SoC. gpt_irq_disable(void)gpt_irq_enable(void)gpt_irq_acknowledge(void)
The following two global variables were removed:
irqaction mxc_timer_irqclock_event_device clockevent_mxc
--- arch/arm/mach-imx/time.c | 48 ------------------------------------------------ 1 file changed, 48 deletions(-)
arch/arm/mach-imx/time.c +0 -48
@@ -150,40 +150,6 @@ static void gpt_irq_acknowledge_v2_v3(struct imx_timer *tm)__raw_writel (V2_TSTAT_OF1 , tm->timer_base +V2_TSTAT ); } -static inline void gpt_irq_disable (void ) -{ -unsigned int tmp; - -if (timer_is_v2 ()) -__raw_writel (0 , timer_base +V2_IR ); -else { - tmp =__raw_readl (timer_base +MXC_TCTL ); -__raw_writel (tmp & ~MX1_2_TCTL_IRQEN , timer_base +MXC_TCTL ); - } -} - -static inline void gpt_irq_enable (void ) -{ -if (timer_is_v2 ()) -__raw_writel (1 <<0 , timer_base +V2_IR ); -else { -__raw_writel (__raw_readl (timer_base +MXC_TCTL ) |MX1_2_TCTL_IRQEN , - timer_base +MXC_TCTL ); - } -} - -static void gpt_irq_acknowledge (void ) -{ -if (timer_is_v1 ()) { -if (cpu_is_mx1 ()) -__raw_writel (0 , timer_base +MX1_2_TSTAT ); -else -__raw_writel (MX2_TSTAT_CAPT |MX2_TSTAT_COMP , - timer_base +MX1_2_TSTAT ); - }else if (timer_is_v2 ()) -__raw_writel (V2_TSTAT_OF1 , timer_base +V2_TSTAT ); -} -static void __iomem *sched_clock_reg; static u64 notrace mxc_read_sched_clock(void)
@@ -333,20 +299,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)return IRQ_HANDLED ; } -static struct irqaction mxc_timer_irq = { - .name ="i.MX Timer Tick" , - .flags =IRQF_TIMER |IRQF_IRQPOLL , - .handler = mxc_timer_interrupt, -}; - -static struct clock_event_device clockevent_mxc = { - .name ="mxc_timer1" , - .features =CLOCK_EVT_FEAT_ONESHOT , - .set_mode = mxc_set_mode, - .set_next_event = mx1_2_set_next_event, - .rating =200 , -}; -static int __init mxc_clockevent_init (struct clk *timer_clk,struct imx_timer *tm) {
Signature · 1 line
1.9.1
PATCH 14/18 ARM: imx: Removed the global variable "timer_base"
In reply to Shenwei WangRemoved the global variable "timer_base" by the
use of the input parameter.
--- arch/arm/mach-imx/time.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
arch/arm/mach-imx/time.c +3 -9
@@ -100,8 +100,6 @@ struct imx_timer {static struct clock_event_device clockevent_mxc;static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ; -static void __iomem *timer_base; -static void gpt_irq_disable_v0_v1 (struct imx_timer *tm) {unsigned int tmp;
@@ -482,14 +480,11 @@ void __init mxc_timer_init(unsigned long pbase, int irq, int ver)struct clk *clk_per =clk_get_sys ("imx-gpt.0" ,"per" );struct clk *clk_ipg =clk_get_sys ("imx-gpt.0" ,"ipg" ); - timer_base =ioremap (pbase,SZ_4K ); -BUG_ON (!timer_base); - timer =kzalloc (sizeof (struct imx_timer ),GFP_KERNEL );if (!timer)panic ("Can't allocate timer struct\n" ); - timer->timer_base = timer_base; + timer->timer_base = (void __iomem *)pbase; timer->version = ver; timer->evt.name ="mxc_timer1" ; timer->evt.rating =200 ;
@@ -527,7 +522,7 @@ static void __init mxc_timer_init_dt(struct device_node *np)int irq, i, ret, ver;struct imx_timer *timer; -if (timer_base) +if (sched_clock_reg)return ; for (i = 0; i < sizeof(imx_timer_tables) /
@@ -551,9 +546,8 @@ static void __init mxc_timer_init_dt(struct device_node *np)panic ("Can't allocate timer struct\n" ); timer->timer_base =of_iomap (np,0 ); +WARN_ON (!timer->timer_base || !ret); - timer_base =of_iomap (np,0 ); -WARN_ON (!timer_base); irq =irq_of_parse_and_map (np,0 ); clk_ipg =of_clk_get_by_name (np,"ipg" );
Signature · 1 line
1.9.1
PATCH 15/18 ARM: imx: Remove the SoC relating codes in mxc_clockevent_init
In reply to Shenwei WangRemoved the SoC relating codes in the function ofmxc_clockevent_init.
--- arch/arm/mach-imx/time.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
arch/arm/mach-imx/time.c +2 -5
@@ -300,11 +300,8 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)static int __init mxc_clockevent_init (struct clk *timer_clk,struct imx_timer *tm) { -if (timer_is_v2 ()) - clockevent_mxc.set_next_event = v2_set_next_event; - - clockevent_mxc.cpumask =cpumask_of (0 ); -clockevents_config_and_register (&clockevent_mxc, + tm->evt.cpumask =cpumask_of (0 ); +clockevents_config_and_register (&tm->evt,clk_get_rate (timer_clk),0xff ,0xfffffffe );
Signature · 1 line
1.9.1
PATCH 16/18 ARM: imx: Move the variable clockevent_mode into mxc_set_mode
In reply to Shenwei WangThe global variable "clockevent_mode" was moved into the function of mxc_set_mode.
--- arch/arm/mach-imx/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-imx/time.c +1 -1
@@ -98,7 +98,6 @@ struct imx_timer { };static struct clock_event_device clockevent_mxc; -static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ;static void gpt_irq_disable_v0_v1 (struct imx_timer *tm) {
@@ -226,6 +225,7 @@ static void mxc_set_mode(enum clock_event_mode mode, {unsigned long flags; struct imx_timer *tm = container_of(evt, struct imx_timer, evt); +static enum clock_event_mode clockevent_mode =CLOCK_EVT_MODE_UNUSED ;/* * The timer interrupt generation is disabled at least
Signature · 1 line
1.9.1
PATCH 17/18 ARM: imx: Codes clean up
In reply to Shenwei WangRemoved the unused SoC relating codes.
--- arch/arm/mach-imx/time.c | 6 ------ 1 file changed, 6 deletions(-)
arch/arm/mach-imx/time.c +0 -6
@@ -35,8 +35,6 @@#include <asm/mach/time.h> -#include "common.h" -#include "hardware.h" /* * There are 4 versions of the timer hardware on Freescale MXC hardware.
@@ -79,8 +77,6 @@#define V2_TIMER_RATE_OSC_DIV8 3000000 -#define timer_is_v1 () (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) -#define timer_is_v2 () (!timer_is_v1())#define IMX_TIMER_V0 (0)#define IMX_TIMER_V1 (1)
@@ -97,8 +93,6 @@ struct imx_timer {void (*gpt_irq_acknowledge)(struct imx_timer *); }; -static struct clock_event_device clockevent_mxc; -static void gpt_irq_disable_v0_v1 (struct imx_timer *tm) {unsigned int tmp;
Signature · 1 line
1.9.1
PATCH 18/18 ARM: imx: Move time.c into drivers/clocksources
In reply to Shenwei WangThe time.c was moved from arch/arm/mach-imx todrivers/clocksources, and its name was changed
to timer-gpt.c.
--- arch/arm/mach-imx/Makefile | 2 +- drivers/clocksource/Makefile | 1 + arch/arm/mach-imx/time.c => drivers/clocksource/timer-gpt.c | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename arch/arm/mach-imx/time.c => drivers/clocksource/timer-gpt.c (100%)
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-gpt.o
drivers/clocksource/timer-gpt.c renamed from arch/arm/mach-imx/time.c +0 -0
Signature · 1 line
1.9.1
cover ARM: imx: make the imx timer driver implementation independent of SoCs.
In reply to Shenwei WangQuoted 6 lines · Shenwei Wang
There are 4 versions of the timer hardware on Freescale MXC hardware. --Version 0: MX1/MXL
--Version 1: MX21, MX27.
--Version 2: MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0) --Version 3: MX6DL, MX6SX, MX6Q(Rev1.1+)
Quoted 7 lines
This patch has removed the SoC related codes, and implemented the driver directly upon the hardware timer IP version. The new timer driver has redesigned the internal APIs, and limited the use of global variables as well.
As the new driver has become independent of the SoCs, it has been moved from the directory
arch/arm/mach-imxinto the directorydrivers/clocksources.
Overall, I do not like how things get done here, the software version numbering, the patch splitting, invasive changes than necessary. So I just worked out my version and will post for review shortly.
Shawn
Quoted 43 lines
Shenwei Wang (18):
ARM: imx: Add a parameter tomxc_timer_init
ARM: imx: Add the definitions forimx_timerand its versions
ARM: imx: Add an array of timer IP block versions
ARM: imx: Added one more parameter formxc_clockevent_init
ARM: imx: Added one more parameter formxc_clocksource_init
ARM: imx: New timer driver APIs based on IP block
ARM: imx: Initialize theimx_timerstructure
ARM: imx: Reimplemented the_mxc_timer_initbased on IP version
ARM: imx: Removed the SoC relating codes inmxc_timer_interrupt
ARM: imx: Removed the SoC relating codes inmxc_set_mode
ARM: imx: Enabled the unused parameter
ARM: imx: Remove one global variable inmxc_clocksource_init
ARM: imx: Removed the unused functions and variables
ARM: imx: Removed the global variable "timer_base"
ARM: imx: Remove the SoC relating codes inmxc_clockevent_init
ARM: imx: Move the variableclockevent_modeintomxc_set_mode
ARM: imx: Codes clean up
ARM: imx: Movetime.cintodrivers/clocksourcesarch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/time.c | 388 --------------------------- drivers/clk/imx/clk-imx1.c | 3 +- drivers/clk/imx/clk-imx21.c | 3 +- drivers/clk/imx/clk-imx27.c | 3 +- drivers/clk/imx/clk-imx31.c | 3 +- drivers/clk/imx/clk-imx35.c | 5 +- drivers/clk/imx/clk.h | 2 +- drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-gpt.c | 572 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 586 insertions(+), 396 deletions(-) delete mode 100644 arch/arm/mach-imx/time.c create mode 100644 drivers/clocksource/timer-gpt.c--
1.9.1_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
cover ARM: imx: make the imx timer driver implementation independent of SoCs.
Quoted 22 lines
-----Original Message-----
From: Shawn Guo [mailto:shawnguo at kernel.org]
Sent: 2015?5?15? 2:54
To: Wang Shenwei-B38339
Cc: shawn.guo at linaro.org; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH 00/18] ARM: imx: make the imx timer driver implementation independent of SoCs.Quoted 9 lines · Shenwei Wang
There are 4 versions of the timer hardware on Freescale MXC hardware. --Version 0: MX1/MXL
--Version 1: MX21, MX27.
--Version 2: MX25, MX31, MX35, MX37, MX51, MX6Q(Rev1.0) --Version 3:
MX6DL, MX6SX, MX6Q(Rev1.1+)This patch has removed the SoC related codes, and implemented the driver directly upon the hardware timer IP version. The new timer driver has redesigned the internal APIs, and limited the use of global variables
as well.
Quoted 1 line
Quoted 8 lines
Quoted 3 lines
As the new driver has become independent of the SoCs, it has been moved from the directory
arch/arm/mach-imxinto the directorydrivers/clocksources.Overall, I do not like how things get done here, the software version numbering, the patch splitting, invasive changes than necessary. So I just worked out my version and will post for review shortly.
Agreed that the patch was splitting because I wanted to let the reviewers know the Procedures of the changes. The idea for the series of patches is to re-implement The gpt timer driver just based on the IP. I don't want to involve any SoC Information inside the driver. A driver should have no knowledge of a SoC, but be simply Implemented upon the IP block.
Quoted 46 lines
Shawn
Quoted 44 lines
Shenwei Wang (18):
ARM: imx: Add a parameter tomxc_timer_init
ARM: imx: Add the definitions forimx_timerand its versions
ARM: imx: Add an array of timer IP block versions
ARM: imx: Added one more parameter formxc_clockevent_init
ARM: imx: Added one more parameter formxc_clocksource_init
ARM: imx: New timer driver APIs based on IP block
ARM: imx: Initialize theimx_timerstructure
ARM: imx: Reimplemented the_mxc_timer_initbased on IP version
ARM: imx: Removed the SoC relating codes inmxc_timer_interrupt
ARM: imx: Removed the SoC relating codes inmxc_set_mode
ARM: imx: Enabled the unused parameter
ARM: imx: Remove one global variable inmxc_clocksource_init
ARM: imx: Removed the unused functions and variables
ARM: imx: Removed the global variable "timer_base"
ARM: imx: Remove the SoC relating codes inmxc_clockevent_init
ARM: imx: Move the variableclockevent_modeintomxc_set_mode
ARM: imx: Codes clean up
ARM: imx: Movetime.cintodrivers/clocksourcesarch/arm/mach-imx/Makefile | 2 +- arch/arm/mach-imx/time.c | 388 --------------------------- drivers/clk/imx/clk-imx1.c | 3 +- drivers/clk/imx/clk-imx21.c | 3 +- drivers/clk/imx/clk-imx27.c | 3 +- drivers/clk/imx/clk-imx31.c | 3 +- drivers/clk/imx/clk-imx35.c | 5 +- drivers/clk/imx/clk.h | 2 +- drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-gpt.c | 572 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 586 insertions(+), 396 deletions(-) delete mode100644
arch/arm/mach-imx/time.ccreate mode 100644drivers/clocksource/timer-gpt.c--
1.9.1_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel