diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-04 12:31:18 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-04 12:31:18 -0700 | 
| commit | 6fa52ed33bea997374a88dbacbba5bf8c7ac4fef (patch) | |
| tree | a0904b78d66c9b99d6acf944cf58bcaa0cffc511 /arch/arm/mach-omap2/timer.c | |
| parent | 1db772216f48978d5146b858586f6178433aad38 (diff) | |
| parent | bc8fd900c4d460b4e4bf785bb48bfced0ac9941b (diff) | |
| download | olio-linux-3.10-6fa52ed33bea997374a88dbacbba5bf8c7ac4fef.tar.xz olio-linux-3.10-6fa52ed33bea997374a88dbacbba5bf8c7ac4fef.zip  | |
Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver changes from Olof Johansson:
 "This is a rather large set of patches for device drivers that for one
  reason or another the subsystem maintainer preferred to get merged
  through the arm-soc tree.  There are both new drivers as well as
  existing drivers that are getting converted from platform-specific
  code into standalone drivers using the appropriate subsystem specific
  interfaces.
  In particular, we can now have pinctrl, clk, clksource and irqchip
  drivers in one file per driver, without the need to call into platform
  specific interface, or to get called from platform specific code, as
  long as all information about the hardware is provided through a
  device tree.
  Most of the drivers we touch this time are for clocksource.  Since now
  most of them are part of drivers/clocksource, I expect that we won't
  have to touch these again from arm-soc and can let the clocksource
  maintainers take care of these in the future.
  Another larger part of this series is specific to the exynos platform,
  which is seeing some significant effort in upstreaming and
  modernization of its device drivers this time around, which
  unfortunately is also the cause for the churn and a lot of the merge
  conflicts.
  There is one new subsystem that gets merged as part of this series:
  the reset controller interface, which is a very simple interface for
  taking devices on the SoC out of reset or back into reset.  Patches to
  use this interface on i.MX follow later in this merge window, and we
  are going to have other platforms (at least tegra and sirf) get
  converted in 3.11.  This will let us get rid of platform specific
  callbacks in a number of platform independent device drivers."
* tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (256 commits)
  irqchip: s3c24xx: add missing __init annotations
  ARM: dts: Disable the RTC by default on exynos5
  clk: exynos5250: Fix parent clock for sclk_mmc{0,1,2,3}
  ARM: exynos: restore mach/regs-clock.h for exynos5
  clocksource: exynos_mct: fix build error on non-DT
  pinctrl: vt8500: wmt: Fix checking return value of pinctrl_register()
  irqchip: vt8500: Convert arch-vt8500 to new irqchip infrastructure
  reset: NULL deref on allocation failure
  reset: Add reset controller API
  dt: describe base reset signal binding
  ARM: EXYNOS: Add arm-pmu DT binding for exynos421x
  ARM: EXYNOS: Add arm-pmu DT binding for exynos5250
  ARM: EXYNOS: Enable PMUs for exynos4
  irqchip: exynos-combiner: Correct combined IRQs for exynos4
  irqchip: exynos-combiner: Add set_irq_affinity function for combiner_irq
  ARM: EXYNOS: fix compilation error introduced due to common clock migration
  clk: exynos5250: Fix divider values for sclk_mmc{0,1,2,3}
  clk: exynos4: export clocks required for fimc-is
  clk: samsung: Fix compilation error
  clk: tegra: fix enum tegra114_clk to match binding
  ...
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
| -rw-r--r-- | arch/arm/mach-omap2/timer.c | 126 | 
1 files changed, 62 insertions, 64 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 63e6384fa72..f12aa6c15da 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -57,16 +57,6 @@  #include "common.h"  #include "powerdomain.h" -/* Parent clocks, eventually these will come from the clock framework */ - -#define OMAP2_MPU_SOURCE	"sys_ck" -#define OMAP3_MPU_SOURCE	OMAP2_MPU_SOURCE -#define OMAP4_MPU_SOURCE	"sys_clkin_ck" -#define OMAP5_MPU_SOURCE	"sys_clkin" -#define OMAP2_32K_SOURCE	"func_32k_ck" -#define OMAP3_32K_SOURCE	"omap_32k_fck" -#define OMAP4_32K_SOURCE	"sys_32k_ck" -  #define REALTIME_COUNTER_BASE				0x48243200  #define INCREMENTER_NUMERATOR_OFFSET			0x10  #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET		0x14 @@ -130,7 +120,6 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,  }  static struct clock_event_device clockevent_gpt = { -	.name		= "gp_timer",  	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,  	.rating		= 300,  	.set_next_event	= omap2_gp_timer_set_next_event, @@ -171,6 +160,12 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match,  		if (property && !of_get_property(np, property, NULL))  			continue; +		if (!property && (of_get_property(np, "ti,timer-alwon", NULL) || +				  of_get_property(np, "ti,timer-dsp", NULL) || +				  of_get_property(np, "ti,timer-pwm", NULL) || +				  of_get_property(np, "ti,timer-secure", NULL))) +			continue; +  		of_add_property(np, &device_disabled);  		return np;  	} @@ -215,16 +210,17 @@ static u32 __init omap_dm_timer_get_errata(void)  }  static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, -						int gptimer_id, -						const char *fck_source, -						const char *property, -						int posted) +					 const char *fck_source, +					 const char *property, +					 const char **timer_name, +					 int posted)  {  	char name[10]; /* 10 = sizeof("gptXX_Xck0") */  	const char *oh_name;  	struct device_node *np;  	struct omap_hwmod *oh;  	struct resource irq, mem; +	struct clk *src;  	int r = 0;  	if (of_have_populated_dt()) { @@ -244,10 +240,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,  		of_node_put(np);  	} else { -		if (omap_dm_timer_reserve_systimer(gptimer_id)) +		if (omap_dm_timer_reserve_systimer(timer->id))  			return -ENODEV; -		sprintf(name, "timer%d", gptimer_id); +		sprintf(name, "timer%d", timer->id);  		oh_name = name;  	} @@ -255,6 +251,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,  	if (!oh)  		return -ENODEV; +	*timer_name = oh->name; +  	if (!of_have_populated_dt()) {  		r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,  						   &irq); @@ -277,24 +275,24 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,  	/* After the dmtimer is using hwmod these clocks won't be needed */  	timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));  	if (IS_ERR(timer->fclk)) -		return -ENODEV; +		return PTR_ERR(timer->fclk); -	/* FIXME: Need to remove hard-coded test on timer ID */ -	if (gptimer_id != 12) { -		struct clk *src; +	src = clk_get(NULL, fck_source); +	if (IS_ERR(src)) +		return PTR_ERR(src); -		src = clk_get(NULL, fck_source); -		if (IS_ERR(src)) { -			r = -EINVAL; -		} else { -			r = clk_set_parent(timer->fclk, src); -			if (r < 0) -				pr_warn("%s: %s cannot set source\n", -					__func__, oh->name); +	if (clk_get_parent(timer->fclk) != src) { +		r = clk_set_parent(timer->fclk, src); +		if (r < 0) { +			pr_warn("%s: %s cannot set source\n", __func__, +				oh->name);  			clk_put(src); +			return r;  		}  	} +	clk_put(src); +  	omap_hwmod_setup_one(oh_name);  	omap_hwmod_enable(oh);  	__omap_dm_timer_init_regs(timer); @@ -318,6 +316,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,  {  	int res; +	clkev.id = gptimer_id;  	clkev.errata = omap_dm_timer_get_errata();  	/* @@ -327,8 +326,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,  	 */  	__omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); -	res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property, -				     OMAP_TIMER_POSTED); +	res = omap_dm_timer_init_one(&clkev, fck_source, property, +				     &clockevent_gpt.name, OMAP_TIMER_POSTED);  	BUG_ON(res);  	omap2_gp_timer_irq.dev_id = &clkev; @@ -342,8 +341,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,  					3, /* Timer internal resynch latency */  					0xffffffff); -	pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", -		gptimer_id, clkev.rate); +	pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, +		clkev.rate);  }  /* Clocksource code */ @@ -360,7 +359,6 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs)  }  static struct clocksource clocksource_gpt = { -	.name		= "gp_timer",  	.rating		= 300,  	.read		= clocksource_read_cycles,  	.mask		= CLOCKSOURCE_MASK(32), @@ -443,13 +441,16 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)  }  static void __init omap2_gptimer_clocksource_init(int gptimer_id, -						const char *fck_source) +						  const char *fck_source, +						  const char *property)  {  	int res; +	clksrc.id = gptimer_id;  	clksrc.errata = omap_dm_timer_get_errata(); -	res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL, +	res = omap_dm_timer_init_one(&clksrc, fck_source, property, +				     &clocksource_gpt.name,  				     OMAP_TIMER_NONPOSTED);  	BUG_ON(res); @@ -462,8 +463,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,  		pr_err("Could not register clocksource %s\n",  			clocksource_gpt.name);  	else -		pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", -			gptimer_id, clksrc.rate); +		pr_info("OMAP clocksource: %s at %lu Hz\n", +			clocksource_gpt.name, clksrc.rate);  }  #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER @@ -488,7 +489,7 @@ static void __init realtime_counter_init(void)  		pr_err("%s: ioremap failed\n", __func__);  		return;  	} -	sys_clk = clk_get(NULL, OMAP5_MPU_SOURCE); +	sys_clk = clk_get(NULL, "sys_clkin");  	if (IS_ERR(sys_clk)) {  		pr_err("%s: failed to get system clock handle\n", __func__);  		iounmap(base); @@ -545,53 +546,52 @@ static inline void __init realtime_counter_init(void)  #endif  #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop,	\ -			       clksrc_nr, clksrc_src)			\ +			       clksrc_nr, clksrc_src, clksrc_prop)	\  void __init omap##name##_gptimer_timer_init(void)			\  {									\ -	if (omap_clk_init)						\ -		omap_clk_init();					\  	omap_dmtimer_init();						\  	omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop);	\ -	omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);	\ +	omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src,		\ +					clksrc_prop);			\  }  #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop,	\ -				clksrc_nr, clksrc_src)			\ +				clksrc_nr, clksrc_src, clksrc_prop)	\  void __init omap##name##_sync32k_timer_init(void)		\  {									\ -	if (omap_clk_init)						\ -		omap_clk_init();					\  	omap_dmtimer_init();						\  	omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop);	\  	/* Enable the use of clocksource="gp_timer" kernel parameter */	\  	if (use_gptimer_clksrc)						\ -		omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ +		omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src,	\ +						clksrc_prop);		\  	else								\  		omap2_sync32k_clocksource_init();			\  }  #ifdef CONFIG_ARCH_OMAP2 -OMAP_SYS_32K_TIMER_INIT(2, 1, OMAP2_32K_SOURCE, "ti,timer-alwon", -			2, OMAP2_MPU_SOURCE); +OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon", +			2, "timer_sys_ck", NULL);  #endif /* CONFIG_ARCH_OMAP2 */  #ifdef CONFIG_ARCH_OMAP3 -OMAP_SYS_32K_TIMER_INIT(3, 1, OMAP3_32K_SOURCE, "ti,timer-alwon", -			2, OMAP3_MPU_SOURCE); -OMAP_SYS_32K_TIMER_INIT(3_secure, 12, OMAP3_32K_SOURCE, "ti,timer-secure", -			2, OMAP3_MPU_SOURCE); -OMAP_SYS_GP_TIMER_INIT(3_gp, 1, OMAP3_MPU_SOURCE, "ti,timer-alwon", -		       2, OMAP3_MPU_SOURCE); +OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon", +			2, "timer_sys_ck", NULL); +OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", +			2, "timer_sys_ck", NULL);  #endif /* CONFIG_ARCH_OMAP3 */ -#ifdef CONFIG_SOC_AM33XX -OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", -		       2, OMAP4_MPU_SOURCE); -#endif /* CONFIG_SOC_AM33XX */ +#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) +OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL, +		       1, "timer_sys_ck", "ti,timer-alwon"); +#endif + +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) +static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", +			       2, "sys_clkin_ck", NULL); +#endif  #ifdef CONFIG_ARCH_OMAP4 -OMAP_SYS_32K_TIMER_INIT(4, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", -			2, OMAP4_MPU_SOURCE);  #ifdef CONFIG_LOCAL_TIMERS  static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29);  void __init omap4_local_timer_init(void) @@ -620,13 +620,11 @@ void __init omap4_local_timer_init(void)  #endif /* CONFIG_ARCH_OMAP4 */  #ifdef CONFIG_SOC_OMAP5 -OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", -			2, OMAP5_MPU_SOURCE);  void __init omap5_realtime_timer_init(void)  {  	int err; -	omap5_sync32k_timer_init(); +	omap4_sync32k_timer_init();  	realtime_counter_init();  	err = arch_timer_of_register();  |