summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 12:31:18 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 12:31:18 -0700
commit6fa52ed33bea997374a88dbacbba5bf8c7ac4fef (patch)
treea0904b78d66c9b99d6acf944cf58bcaa0cffc511 /arch/arm/mach-omap2/timer.c
parent1db772216f48978d5146b858586f6178433aad38 (diff)
parentbc8fd900c4d460b4e4bf785bb48bfced0ac9941b (diff)
downloadlinux-6fa52ed33bea997374a88dbacbba5bf8c7ac4fef.tar.gz
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.c128
1 files changed, 63 insertions, 65 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 63e6384fa72e..f12aa6c15da4 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)) {
- r = -EINVAL;
- } else {
- r = clk_set_parent(timer->fclk, src);
- if (r < 0)
- pr_warn("%s: %s cannot set source\n",
- __func__, oh->name);
+ src = clk_get(NULL, fck_source);
+ if (IS_ERR(src))
+ return PTR_ERR(src);
+
+ 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();