Commit 1a4120bc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'timer' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull arm-soc timer updates from Arnd Bergmann:
 "This contains two branches dealing with timers, one for the picoxcell
  platform that is now using DT with the platform-independent
  dw_apb_timer driver.  The other change is for the omap-specific
  dmtimer driver."

* tag 'timer' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
  clocksource: dw_apb_timer: Add common DTS glue for dw_apb_timer
  ARM: OMAP2+: Simplify dmtimer clock aliases
  ARM: OMAP2+: Move dmtimer clock set function to dmtimer driver
  ARM: OMAP1: Fix dmtimer support
  ARM: OMAP: Add flag to indicate if a timer needs a manual reset
  ARM: OMAP: Remove timer function pointer for context loss counter
  ARM: OMAP: Remove loses_context variable from timer platform data
  ARM: OMAP2+: Fix external clock support for dmtimers
  ARM: OMAP2+: HWMOD: Correct timer device attributes
  ARM: OMAP: Add DMTIMER capability variable to represent timer features
  ARM: OMAP2+: Add dmtimer platform function to reserve systimers
  ARM: OMAP2+: Remove unused max number of timers definition
  ARM: OMAP: Remove unnecessary clk structure
parents 2fa37947 35bf8cc7
* Designware APB timer
Required properties:
- compatible: "snps,dw-apb-timer-sp" or "snps,dw-apb-timer-osc"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: IRQ line for the timer.
- clock-frequency: The frequency in HZ of the timer.
- clock-freq: For backwards compatibility with picoxcell
Example:
timer1: timer@ffc09000 {
compatible = "snps,dw-apb-timer-sp";
interrupts = <0 168 4>;
clock-frequency = <200000000>;
reg = <0xffc09000 0x1000>;
};
timer2: timer@ffd00000 {
compatible = "snps,dw-apb-timer-osc";
interrupts = <0 169 4>;
clock-frequency = <200000000>;
reg = <0xffd00000 0x1000>;
};
...@@ -663,6 +663,7 @@ config ARCH_PICOXCELL ...@@ -663,6 +663,7 @@ config ARCH_PICOXCELL
select ARM_VIC select ARM_VIC
select CPU_V6K select CPU_V6K
select DW_APB_TIMER select DW_APB_TIMER
select DW_APB_TIMER_OF
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select GENERIC_GPIO select GENERIC_GPIO
select HAVE_TCM select HAVE_TCM
......
...@@ -140,7 +140,8 @@ static int __init omap1_dm_timer_init(void) ...@@ -140,7 +140,8 @@ static int __init omap1_dm_timer_init(void)
} }
pdata->set_timer_src = omap1_dm_timer_set_src; pdata->set_timer_src = omap1_dm_timer_set_src;
pdata->needs_manual_reset = 1; pdata->timer_capability = OMAP_TIMER_ALWON |
OMAP_TIMER_NEEDS_RESET;
ret = platform_device_add_data(pdev, pdata, sizeof(*pdata)); ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
if (ret) { if (ret) {
......
...@@ -1897,42 +1897,9 @@ static struct omap_clk omap2420_clks[] = { ...@@ -1897,42 +1897,9 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "pka_ick", &pka_ick, CK_242X), CLK(NULL, "pka_ick", &pka_ick, CK_242X),
CLK(NULL, "usb_fck", &usb_fck, CK_242X), CLK(NULL, "usb_fck", &usb_fck, CK_242X),
CLK("musb-hdrc", "fck", &osc_ck, CK_242X), CLK("musb-hdrc", "fck", &osc_ck, CK_242X),
CLK("omap_timer.1", "32k_ck", &func_32k_ck, CK_243X), CLK(NULL, "timer_32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.2", "32k_ck", &func_32k_ck, CK_243X), CLK(NULL, "timer_sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.3", "32k_ck", &func_32k_ck, CK_243X), CLK(NULL, "timer_ext_ck", &alt_ck, CK_243X),
CLK("omap_timer.4", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.5", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.6", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.7", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.8", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.9", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.10", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.11", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.12", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.1", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.2", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.3", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.4", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.5", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.6", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.7", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.8", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.9", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.10", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.11", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.12", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.1", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.2", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.3", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.4", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.5", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.6", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.7", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.8", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.9", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.10", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.11", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.12", "alt_ck", &alt_ck, CK_243X),
}; };
/* /*
......
...@@ -1990,42 +1990,9 @@ static struct omap_clk omap2430_clks[] = { ...@@ -1990,42 +1990,9 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X), CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X),
CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X), CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X),
CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X), CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X),
CLK("omap_timer.1", "32k_ck", &func_32k_ck, CK_243X), CLK(NULL, "timer_32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.2", "32k_ck", &func_32k_ck, CK_243X), CLK(NULL, "timer_sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.3", "32k_ck", &func_32k_ck, CK_243X), CLK(NULL, "timer_ext_ck", &alt_ck, CK_243X),
CLK("omap_timer.4", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.5", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.6", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.7", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.8", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.9", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.10", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.11", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.12", "32k_ck", &func_32k_ck, CK_243X),
CLK("omap_timer.1", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.2", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.3", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.4", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.5", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.6", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.7", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.8", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.9", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.10", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.11", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.12", "sys_ck", &sys_ck, CK_243X),
CLK("omap_timer.1", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.2", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.3", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.4", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.5", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.6", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.7", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.8", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.9", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.10", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.11", "alt_ck", &alt_ck, CK_243X),
CLK("omap_timer.12", "alt_ck", &alt_ck, CK_243X),
}; };
/* /*
......
...@@ -3476,30 +3476,8 @@ static struct omap_clk omap3xxx_clks[] = { ...@@ -3476,30 +3476,8 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "hsotgusb_fck", &hsotgusb_fck_am35xx, CK_AM35XX), CLK(NULL, "hsotgusb_fck", &hsotgusb_fck_am35xx, CK_AM35XX),
CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX), CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX),
CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX), CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX),
CLK("omap_timer.1", "32k_ck", &omap_32k_fck, CK_3XXX), CLK(NULL, "timer_32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.2", "32k_ck", &omap_32k_fck, CK_3XXX), CLK(NULL, "timer_sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.3", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.4", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.5", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.6", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.7", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.8", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.9", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.10", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.11", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.12", "32k_ck", &omap_32k_fck, CK_3XXX),
CLK("omap_timer.1", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.2", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.3", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.4", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.5", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.6", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.7", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.8", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.9", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.10", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.11", "sys_ck", &sys_ck, CK_3XXX),
CLK("omap_timer.12", "sys_ck", &sys_ck, CK_3XXX),
}; };
......
...@@ -3385,28 +3385,18 @@ static struct omap_clk omap44xx_clks[] = { ...@@ -3385,28 +3385,18 @@ static struct omap_clk omap44xx_clks[] = {
CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X), CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X),
CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X), CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X),
CLK("omap_wdt", "ick", &dummy_ck, CK_443X), CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X), CLK(NULL, "timer_32k_ck", &sys_32k_ck, CK_443X),
CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.1", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.3", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.2", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.4", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.3", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.5", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.4", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.6", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.9", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.7", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.10", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.8", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.11", "timer_sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.9", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.5", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.10", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.6", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.11", "32k_ck", &sys_32k_ck, CK_443X), CLK("omap_timer.7", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.1", "sys_ck", &sys_clkin_ck, CK_443X), CLK("omap_timer.8", "timer_sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.2", "sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.3", "sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.4", "sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.9", "sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.10", "sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.11", "sys_ck", &sys_clkin_ck, CK_443X),
CLK("omap_timer.5", "sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.6", "sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.7", "sys_ck", &syc_clk_div_ck, CK_443X),
CLK("omap_timer.8", "sys_ck", &syc_clk_div_ck, CK_443X),
}; };
int __init omap4xxx_clk_init(void) int __init omap4xxx_clk_init(void)
......
...@@ -68,7 +68,6 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = { ...@@ -68,7 +68,6 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
struct omap_hwmod_class omap2xxx_timer_hwmod_class = { struct omap_hwmod_class omap2xxx_timer_hwmod_class = {
.name = "timer", .name = "timer",
.sysc = &omap2xxx_timer_sysc, .sysc = &omap2xxx_timer_sysc,
.rev = OMAP_TIMER_IP_VERSION_1,
}; };
/* /*
...@@ -257,7 +256,6 @@ struct omap_hwmod omap2xxx_timer2_hwmod = { ...@@ -257,7 +256,6 @@ struct omap_hwmod omap2xxx_timer2_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class, .class = &omap2xxx_timer_hwmod_class,
}; };
...@@ -276,7 +274,6 @@ struct omap_hwmod omap2xxx_timer3_hwmod = { ...@@ -276,7 +274,6 @@ struct omap_hwmod omap2xxx_timer3_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT, .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class, .class = &omap2xxx_timer_hwmod_class,
}; };
...@@ -295,7 +292,6 @@ struct omap_hwmod omap2xxx_timer4_hwmod = { ...@@ -295,7 +292,6 @@ struct omap_hwmod omap2xxx_timer4_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT, .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class, .class = &omap2xxx_timer_hwmod_class,
}; };
...@@ -314,7 +310,6 @@ struct omap_hwmod omap2xxx_timer5_hwmod = { ...@@ -314,7 +310,6 @@ struct omap_hwmod omap2xxx_timer5_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class, .class = &omap2xxx_timer_hwmod_class,
}; };
...@@ -333,7 +328,6 @@ struct omap_hwmod omap2xxx_timer6_hwmod = { ...@@ -333,7 +328,6 @@ struct omap_hwmod omap2xxx_timer6_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class, .class = &omap2xxx_timer_hwmod_class,
}; };
...@@ -352,7 +346,6 @@ struct omap_hwmod omap2xxx_timer7_hwmod = { ...@@ -352,7 +346,6 @@ struct omap_hwmod omap2xxx_timer7_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class, .class = &omap2xxx_timer_hwmod_class,
}; };
...@@ -371,7 +364,6 @@ struct omap_hwmod omap2xxx_timer8_hwmod = { ...@@ -371,7 +364,6 @@ struct omap_hwmod omap2xxx_timer8_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap2xxx_timer_hwmod_class, .class = &omap2xxx_timer_hwmod_class,
}; };
......
...@@ -129,7 +129,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = { ...@@ -129,7 +129,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = {
static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = { static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = {
.name = "timer", .name = "timer",
.sysc = &omap3xxx_timer_1ms_sysc, .sysc = &omap3xxx_timer_1ms_sysc,
.rev = OMAP_TIMER_IP_VERSION_1,
}; };
static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
...@@ -145,12 +144,11 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { ...@@ -145,12 +144,11 @@ static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { static struct omap_hwmod_class omap3xxx_timer_hwmod_class = {
.name = "timer", .name = "timer",
.sysc = &omap3xxx_timer_sysc, .sysc = &omap3xxx_timer_sysc,
.rev = OMAP_TIMER_IP_VERSION_1,
}; };
/* secure timers dev attribute */ /* secure timers dev attribute */
static struct omap_timer_capability_dev_attr capability_secure_dev_attr = { static struct omap_timer_capability_dev_attr capability_secure_dev_attr = {
.timer_capability = OMAP_TIMER_SECURE, .timer_capability = OMAP_TIMER_ALWON | OMAP_TIMER_SECURE,
}; };
/* always-on timers dev attribute */ /* always-on timers dev attribute */
...@@ -195,7 +193,6 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = { ...@@ -195,7 +193,6 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT, .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap3xxx_timer_1ms_hwmod_class, .class = &omap3xxx_timer_1ms_hwmod_class,
}; };
...@@ -213,7 +210,6 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = { ...@@ -213,7 +210,6 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT, .idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap3xxx_timer_hwmod_class, .class = &omap3xxx_timer_hwmod_class,
}; };
...@@ -231,7 +227,6 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = { ...@@ -231,7 +227,6 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT, .idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap3xxx_timer_hwmod_class, .class = &omap3xxx_timer_hwmod_class,
}; };
...@@ -249,7 +244,6 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = { ...@@ -249,7 +244,6 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT, .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap3xxx_timer_hwmod_class, .class = &omap3xxx_timer_hwmod_class,
}; };
...@@ -267,7 +261,6 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = { ...@@ -267,7 +261,6 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT, .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap3xxx_timer_hwmod_class, .class = &omap3xxx_timer_hwmod_class,
}; };
...@@ -285,7 +278,6 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = { ...@@ -285,7 +278,6 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT, .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
.class = &omap3xxx_timer_hwmod_class, .class = &omap3xxx_timer_hwmod_class,
}; };
......
...@@ -2944,7 +2944,6 @@ static struct omap_hwmod omap44xx_timer2_hwmod = { ...@@ -2944,7 +2944,6 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
.modulemode = MODULEMODE_SWCTRL, .modulemode = MODULEMODE_SWCTRL,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
}; };
/* timer3 */ /* timer3 */
...@@ -2966,7 +2965,6 @@ static struct omap_hwmod omap44xx_timer3_hwmod = { ...@@ -2966,7 +2965,6 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {
.modulemode = MODULEMODE_SWCTRL, .modulemode = MODULEMODE_SWCTRL,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
}; };
/* timer4 */ /* timer4 */
...@@ -2988,7 +2986,6 @@ static struct omap_hwmod omap44xx_timer4_hwmod = { ...@@ -2988,7 +2986,6 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {
.modulemode = MODULEMODE_SWCTRL, .modulemode = MODULEMODE_SWCTRL,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
}; };
/* timer5 */ /* timer5 */
...@@ -3010,7 +3007,6 @@ static struct omap_hwmod omap44xx_timer5_hwmod = { ...@@ -3010,7 +3007,6 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
.modulemode = MODULEMODE_SWCTRL, .modulemode = MODULEMODE_SWCTRL,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
}; };
/* timer6 */ /* timer6 */
...@@ -3033,7 +3029,6 @@ static struct omap_hwmod omap44xx_timer6_hwmod = { ...@@ -3033,7 +3029,6 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
.modulemode = MODULEMODE_SWCTRL, .modulemode = MODULEMODE_SWCTRL,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
}; };
/* timer7 */ /* timer7 */
...@@ -3055,7 +3050,6 @@ static struct omap_hwmod omap44xx_timer7_hwmod = { ...@@ -3055,7 +3050,6 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
.modulemode = MODULEMODE_SWCTRL, .modulemode = MODULEMODE_SWCTRL,
}, },
}, },
.dev_attr = &capability_alwon_dev_attr,
}; };
/* timer8 */ /* timer8 */
......
...@@ -69,11 +69,6 @@ ...@@ -69,11 +69,6 @@
#define OMAP3_SECURE_TIMER 1 #define OMAP3_SECURE_TIMER 1
#endif #endif
/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
#define MAX_GPTIMER_ID 12
static u32 sys_timer_reserved;
/* Clockevent code */ /* Clockevent code */
static struct omap_dm_timer clkev; static struct omap_dm_timer clkev;
...@@ -180,7 +175,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -180,7 +175,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
omap_hwmod_enable(oh); omap_hwmod_enable(oh);
sys_timer_reserved |= (1 << (gptimer_id - 1)); if (omap_dm_timer_reserve_systimer(gptimer_id))
return -ENODEV;
if (gptimer_id != 12) { if (gptimer_id != 12) {
struct clk *src; struct clk *src;
...@@ -398,66 +394,6 @@ static void __init omap4_timer_init(void) ...@@ -398,66 +394,6 @@ static void __init omap4_timer_init(void)
OMAP_SYS_TIMER(4) OMAP_SYS_TIMER(4)
#endif #endif
/**
* omap2_dm_timer_set_src - change the timer input clock source
* @pdev: timer platform device pointer
* @source: array index of parent clock source
*/
static int omap2_dm_timer_set_src(struct platform_device *pdev, int source)
{
int ret;
struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
struct clk *fclk, *parent;
char *parent_name = NULL;
fclk = clk_get(&pdev->dev, "fck");
if (IS_ERR_OR_NULL(fclk)) {
dev_err(&pdev->dev, "%s: %d: clk_get() FAILED\n",
__func__, __LINE__);
return -EINVAL;
}
switch (source) {
case OMAP_TIMER_SRC_SYS_CLK:
parent_name = "sys_ck";
break;
case OMAP_TIMER_SRC_32_KHZ:
parent_name = "32k_ck";
break;
case OMAP_TIMER_SRC_EXT_CLK:
if (pdata->timer_ip_version == OMAP_TIMER_IP_VERSION_1) {
parent_name = "alt_ck";
break;
}
dev_err(&pdev->dev, "%s: %d: invalid clk src.\n",
__func__, __LINE__);
clk_put(fclk);
return -EINVAL;
}
parent = clk_get(&pdev->dev, parent_name);
if (IS_ERR_OR_NULL(parent)) {
dev_err(&pdev->dev, "%s: %d: clk_get() %s FAILED\n",
__func__, __LINE__, parent_name);
clk_put(fclk);
return -EINVAL;
}
ret = clk_set_parent(fclk, parent);
if (IS_ERR_VALUE(ret)) {
dev_err(&pdev->dev, "%s: clk_set_parent() to %s FAILED\n",
__func__, parent_name);
ret = -EINVAL;
}
clk_put(parent);
clk_put(fclk);
return ret;
}
/** /**
* omap_timer_init - build and register timer device with an * omap_timer_init - build and register timer device with an
* associated timer hwmod * associated timer hwmod
...@@ -478,7 +414,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) ...@@ -478,7 +414,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
struct dmtimer_platform_data *pdata; struct dmtimer_platform_data *pdata;
struct platform_device *pdev; struct platform_device *pdev;
struct omap_timer_capability_dev_attr *timer_dev_attr; struct omap_timer_capability_dev_attr *timer_dev_attr;
struct powerdomain *pwrdm;
pr_debug("%s: %s\n", __func__, oh->name); pr_debug("%s: %s\n", __func__, oh->name);
...@@ -506,18 +441,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) ...@@ -506,18 +441,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
*/ */
sscanf(oh->name, "timer%2d", &id); sscanf(oh->name, "timer%2d", &id);
pdata->set_timer_src = omap2_dm_timer_set_src; if (timer_dev_attr)
pdata->timer_ip_version = oh->class->rev; pdata->timer_capability = timer_dev_attr->timer_capability;
/* Mark clocksource and clockevent timers as reserved */
if ((sys_timer_reserved >> (id - 1)) & 0x1)
pdata->reserved = 1;
pwrdm = omap_hwmod_get_pwrdm(oh);
pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
#ifdef CONFIG_PM
pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
#endif
pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
NULL, 0, 0); NULL, 0, 0);
......
obj-y := common.o obj-y := common.o
obj-y += time.o
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/dw_apb_timer.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/hardware/vic.h> #include <asm/hardware/vic.h>
...@@ -97,7 +98,7 @@ DT_MACHINE_START(PICOXCELL, "Picochip picoXcell") ...@@ -97,7 +98,7 @@ DT_MACHINE_START(PICOXCELL, "Picochip picoXcell")
.nr_irqs = NR_IRQS_LEGACY, .nr_irqs = NR_IRQS_LEGACY,
.init_irq = picoxcell_init_irq, .init_irq = picoxcell_init_irq,
.handle_irq = vic_handle_irq, .handle_irq = vic_handle_irq,
.timer = &picoxcell_timer, .timer = &dw_apb_timer,
.init_machine = picoxcell_init_machine, .init_machine = picoxcell_init_machine,
.dt_compat = picoxcell_dt_match, .dt_compat = picoxcell_dt_match,
.restart = picoxcell_wdt_restart, .restart = picoxcell_wdt_restart,
......
...@@ -12,6 +12,6 @@ ...@@ -12,6 +12,6 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
extern struct sys_timer picoxcell_timer; extern struct sys_timer dw_apb_timer;
#endif /* __PICOXCELL_COMMON_H__ */ #endif /* __PICOXCELL_COMMON_H__ */
...@@ -42,9 +42,11 @@ ...@@ -42,9 +42,11 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <plat/dmtimer.h> #include <plat/dmtimer.h>
#include <plat/omap-pm.h>
#include <mach/hardware.h> #include <mach/hardware.h>
static u32 omap_reserved_systimers;
static LIST_HEAD(omap_timer_list); static LIST_HEAD(omap_timer_list);
static DEFINE_SPINLOCK(dm_timer_lock); static DEFINE_SPINLOCK(dm_timer_lock);
...@@ -133,17 +135,22 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) ...@@ -133,17 +135,22 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
int omap_dm_timer_prepare(struct omap_dm_timer *timer) int omap_dm_timer_prepare(struct omap_dm_timer *timer)
{ {
struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
int ret; int ret;
/*
* FIXME: OMAP1 devices do not use the clock framework for dmtimers so
* do not call clk_get() for these devices.
*/
if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
timer->fclk = clk_get(&timer->pdev->dev, "fck"); timer->fclk = clk_get(&timer->pdev->dev, "fck");
if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) { if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
timer->fclk = NULL; timer->fclk = NULL;
dev_err(&timer->pdev->dev, ": No fclk handle.\n"); dev_err(&timer->pdev->dev, ": No fclk handle.\n");
return -EINVAL; return -EINVAL;
} }
}
if (pdata->needs_manual_reset) if (timer->capability & OMAP_TIMER_NEEDS_RESET)
omap_dm_timer_reset(timer); omap_dm_timer_reset(timer);
ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
...@@ -152,6 +159,21 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer) ...@@ -152,6 +159,21 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
return ret; return ret;
} }
static inline u32 omap_dm_timer_reserved_systimer(int id)
{
return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
}
int omap_dm_timer_reserve_systimer(int id)
{
if (omap_dm_timer_reserved_systimer(id))
return -ENODEV;
omap_reserved_systimers |= (1 << (id - 1));
return 0;
}
struct omap_dm_timer *omap_dm_timer_request(void) struct omap_dm_timer *omap_dm_timer_request(void)
{ {
struct omap_dm_timer *timer = NULL, *t; struct omap_dm_timer *timer = NULL, *t;
...@@ -325,10 +347,9 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) ...@@ -325,10 +347,9 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
omap_dm_timer_enable(timer); omap_dm_timer_enable(timer);
if (timer->loses_context) { if (!(timer->capability & OMAP_TIMER_ALWON)) {
u32 ctx_loss_cnt_after = if (omap_pm_get_dev_context_loss_count(&timer->pdev->dev) !=
timer->get_context_loss_count(&timer->pdev->dev); timer->ctx_loss_count)
if (ctx_loss_cnt_after != timer->ctx_loss_count)
omap_timer_restore_context(timer); omap_timer_restore_context(timer);
} }
...@@ -347,20 +368,18 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start); ...@@ -347,20 +368,18 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start);
int omap_dm_timer_stop(struct omap_dm_timer *timer) int omap_dm_timer_stop(struct omap_dm_timer *timer)
{ {
unsigned long rate = 0; unsigned long rate = 0;
struct dmtimer_platform_data *pdata;
if (unlikely(!timer)) if (unlikely(!timer))
return -EINVAL; return -EINVAL;
pdata = timer->pdev->dev.platform_data; if (!(timer->capability & OMAP_TIMER_NEEDS_RESET))
if (!pdata->needs_manual_reset)
rate = clk_get_rate(timer->fclk); rate = clk_get_rate(timer->fclk);
__omap_dm_timer_stop(timer, timer->posted, rate); __omap_dm_timer_stop(timer, timer->posted, rate);
if (timer->loses_context && timer->get_context_loss_count) if (!(timer->capability & OMAP_TIMER_ALWON))
timer->ctx_loss_count = timer->ctx_loss_count =
timer->get_context_loss_count(&timer->pdev->dev); omap_pm_get_dev_context_loss_count(&timer->pdev->dev);
/* /*
* Since the register values are computed and written within * Since the register values are computed and written within
...@@ -378,6 +397,8 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop); ...@@ -378,6 +397,8 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
{ {
int ret; int ret;
char *parent_name = NULL;
struct clk *fclk, *parent;
struct dmtimer_platform_data *pdata; struct dmtimer_platform_data *pdata;
if (unlikely(!timer)) if (unlikely(!timer))
...@@ -388,7 +409,49 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) ...@@ -388,7 +409,49 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
if (source < 0 || source >= 3) if (source < 0 || source >= 3)
return -EINVAL; return -EINVAL;
ret = pdata->set_timer_src(timer->pdev, source); /*
* FIXME: Used for OMAP1 devices only because they do not currently
* use the clock framework to set the parent clock. To be removed
* once OMAP1 migrated to using clock framework for dmtimers
*/
if (pdata->set_timer_src)
return pdata->set_timer_src(timer->pdev, source);
fclk = clk_get(&timer->pdev->dev, "fck");
if (IS_ERR_OR_NULL(fclk)) {
pr_err("%s: fck not found\n", __func__);
return -EINVAL;
}
switch (source) {
case OMAP_TIMER_SRC_SYS_CLK:
parent_name = "timer_sys_ck";
break;
case OMAP_TIMER_SRC_32_KHZ:
parent_name = "timer_32k_ck";
break;
case OMAP_TIMER_SRC_EXT_CLK:
parent_name = "timer_ext_ck";
break;
}
parent = clk_get(&timer->pdev->dev, parent_name);
if (IS_ERR_OR_NULL(parent)) {
pr_err("%s: %s not found\n", __func__, parent_name);
ret = -EINVAL;
goto out;
}
ret = clk_set_parent(fclk, parent);
if (IS_ERR_VALUE(ret))
pr_err("%s: failed to set %s as parent\n", __func__,
parent_name);
clk_put(parent);
out:
clk_put(fclk);
return ret; return ret;
} }
...@@ -431,10 +494,9 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, ...@@ -431,10 +494,9 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
omap_dm_timer_enable(timer); omap_dm_timer_enable(timer);
if (timer->loses_context) { if (!(timer->capability & OMAP_TIMER_ALWON)) {
u32 ctx_loss_cnt_after = if (omap_pm_get_dev_context_loss_count(&timer->pdev->dev) !=
timer->get_context_loss_count(&timer->pdev->dev); timer->ctx_loss_count)
if (ctx_loss_cnt_after != timer->ctx_loss_count)
omap_timer_restore_context(timer); omap_timer_restore_context(timer);
} }
...@@ -674,13 +736,12 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) ...@@ -674,13 +736,12 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
timer->id = pdev->id; timer->id = pdev->id;
timer->irq = irq->start; timer->irq = irq->start;
timer->reserved = pdata->reserved; timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
timer->pdev = pdev; timer->pdev = pdev;
timer->loses_context = pdata->loses_context; timer->capability = pdata->timer_capability;
timer->get_context_loss_count = pdata->get_context_loss_count;
/* Skip pm_runtime_enable for OMAP1 */ /* Skip pm_runtime_enable for OMAP1 */
if (!pdata->needs_manual_reset) { if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
pm_runtime_irq_safe(&pdev->dev); pm_runtime_irq_safe(&pdev->dev);
} }
......
...@@ -55,23 +55,17 @@ ...@@ -55,23 +55,17 @@
#define OMAP_TIMER_TRIGGER_OVERFLOW 0x01 #define OMAP_TIMER_TRIGGER_OVERFLOW 0x01
#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02 #define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
/*
* IP revision identifier so that Highlander IP
* in OMAP4 can be distinguished.
*/
#define OMAP_TIMER_IP_VERSION_1 0x1
/* timer capabilities used in hwmod database */ /* timer capabilities used in hwmod database */
#define OMAP_TIMER_SECURE 0x80000000 #define OMAP_TIMER_SECURE 0x80000000
#define OMAP_TIMER_ALWON 0x40000000 #define OMAP_TIMER_ALWON 0x40000000
#define OMAP_TIMER_HAS_PWM 0x20000000 #define OMAP_TIMER_HAS_PWM 0x20000000
#define OMAP_TIMER_NEEDS_RESET 0x10000000
struct omap_timer_capability_dev_attr { struct omap_timer_capability_dev_attr {
u32 timer_capability; u32 timer_capability;
}; };
struct omap_dm_timer; struct omap_dm_timer;
struct clk;
struct timer_regs { struct timer_regs {
u32 tidr; u32 tidr;
...@@ -96,16 +90,12 @@ struct timer_regs { ...@@ -96,16 +90,12 @@ struct timer_regs {
}; };
struct dmtimer_platform_data { struct dmtimer_platform_data {
/* set_timer_src - Only used for OMAP1 devices */
int (*set_timer_src)(struct platform_device *pdev, int source); int (*set_timer_src)(struct platform_device *pdev, int source);
int timer_ip_version; u32 timer_capability;
u32 needs_manual_reset:1;
bool reserved;
bool loses_context;
int (*get_context_loss_count)(struct device *dev);
}; };
int omap_dm_timer_reserve_systimer(int id);
struct omap_dm_timer *omap_dm_timer_request(void); struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
int omap_dm_timer_free(struct omap_dm_timer *timer); int omap_dm_timer_free(struct omap_dm_timer *timer);
...@@ -272,13 +262,11 @@ struct omap_dm_timer { ...@@ -272,13 +262,11 @@ struct omap_dm_timer {
unsigned reserved:1; unsigned reserved:1;
unsigned posted:1; unsigned posted:1;
struct timer_regs context; struct timer_regs context;
bool loses_context;
int ctx_loss_count; int ctx_loss_count;
int revision; int revision;
u32 capability;
struct platform_device *pdev; struct platform_device *pdev;
struct list_head node; struct list_head node;
int (*get_context_loss_count)(struct device *dev);
}; };
int omap_dm_timer_prepare(struct omap_dm_timer *timer); int omap_dm_timer_prepare(struct omap_dm_timer *timer);
......
...@@ -16,6 +16,9 @@ config CLKSRC_MMIO ...@@ -16,6 +16,9 @@ config CLKSRC_MMIO
config DW_APB_TIMER config DW_APB_TIMER
bool bool
config DW_APB_TIMER_OF
bool
config CLKSRC_DBX500_PRCMU config CLKSRC_DBX500_PRCMU
bool "Clocksource PRCMU Timer" bool "Clocksource PRCMU Timer"
depends on UX500_SOC_DB8500 depends on UX500_SOC_DB8500
......
...@@ -10,4 +10,5 @@ obj-$(CONFIG_EM_TIMER_STI) += em_sti.o ...@@ -10,4 +10,5 @@ obj-$(CONFIG_EM_TIMER_STI) += em_sti.o
obj-$(CONFIG_CLKBLD_I8253) += i8253.o obj-$(CONFIG_CLKBLD_I8253) += i8253.o
obj-$(CONFIG_CLKSRC_MMIO) += mmio.o obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
\ No newline at end of file
/* /*
* Copyright (C) 2012 Altera Corporation
* Copyright (c) 2011 Picochip Ltd., Jamie Iles * Copyright (c) 2011 Picochip Ltd., Jamie Iles
* *
* Modified from mach-picoxcell/time.c
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
* All enquiries to support@picochip.com * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/dw_apb_timer.h> #include <linux/dw_apb_timer.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -15,8 +24,6 @@ ...@@ -15,8 +24,6 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/sched_clock.h> #include <asm/sched_clock.h>
#include "common.h"
static void timer_get_base_and_rate(struct device_node *np, static void timer_get_base_and_rate(struct device_node *np,
void __iomem **base, u32 *rate) void __iomem **base, u32 *rate)
{ {
...@@ -25,11 +32,12 @@ static void timer_get_base_and_rate(struct device_node *np, ...@@ -25,11 +32,12 @@ static void timer_get_base_and_rate(struct device_node *np,
if (!*base) if (!*base)
panic("Unable to map regs for %s", np->name); panic("Unable to map regs for %s", np->name);
if (of_property_read_u32(np, "clock-freq", rate)) if (of_property_read_u32(np, "clock-freq", rate) &&
panic("No clock-freq property for %s", np->name); of_property_read_u32(np, "clock-frequency", rate))
panic("No clock-frequency property for %s", np->name);
} }
static void picoxcell_add_clockevent(struct device_node *event_timer) static void add_clockevent(struct device_node *event_timer)
{ {
void __iomem *iobase; void __iomem *iobase;
struct dw_apb_clock_event_device *ced; struct dw_apb_clock_event_device *ced;
...@@ -49,7 +57,7 @@ static void picoxcell_add_clockevent(struct device_node *event_timer) ...@@ -49,7 +57,7 @@ static void picoxcell_add_clockevent(struct device_node *event_timer)
dw_apb_clockevent_register(ced); dw_apb_clockevent_register(ced);
} }
static void picoxcell_add_clocksource(struct device_node *source_timer) static void add_clocksource(struct device_node *source_timer)
{ {
void __iomem *iobase; void __iomem *iobase;
struct dw_apb_clocksource *cs; struct dw_apb_clocksource *cs;
...@@ -67,55 +75,57 @@ static void picoxcell_add_clocksource(struct device_node *source_timer) ...@@ -67,55 +75,57 @@ static void picoxcell_add_clocksource(struct device_node *source_timer)
static void __iomem *sched_io_base; static void __iomem *sched_io_base;
static u32 picoxcell_read_sched_clock(void) static u32 read_sched_clock(void)
{ {
return __raw_readl(sched_io_base); return __raw_readl(sched_io_base);
} }
static const struct of_device_id picoxcell_rtc_ids[] __initconst = { static const struct of_device_id sptimer_ids[] __initconst = {
{ .compatible = "picochip,pc3x2-rtc" }, { .compatible = "picochip,pc3x2-rtc" },
{ .compatible = "snps,dw-apb-timer-sp" },
{ /* Sentinel */ }, { /* Sentinel */ },
}; };
static void picoxcell_init_sched_clock(void) static void init_sched_clock(void)
{ {
struct device_node *sched_timer; struct device_node *sched_timer;
u32 rate; u32 rate;
sched_timer = of_find_matching_node(NULL, picoxcell_rtc_ids); sched_timer = of_find_matching_node(NULL, sptimer_ids);
if (!sched_timer) if (!sched_timer)
panic("No RTC for sched clock to use"); panic("No RTC for sched clock to use");
timer_get_base_and_rate(sched_timer, &sched_io_base, &rate); timer_get_base_and_rate(sched_timer, &sched_io_base, &rate);
of_node_put(sched_timer); of_node_put(sched_timer);
setup_sched_clock(picoxcell_read_sched_clock, 32, rate); setup_sched_clock(read_sched_clock, 32, rate);
} }
static const struct of_device_id picoxcell_timer_ids[] __initconst = { static const struct of_device_id osctimer_ids[] __initconst = {
{ .compatible = "picochip,pc3x2-timer" }, { .compatible = "picochip,pc3x2-timer" },
{ .compatible = "snps,dw-apb-timer-osc" },
{}, {},
}; };
static void __init picoxcell_timer_init(void) static void __init timer_init(void)
{ {
struct device_node *event_timer, *source_timer; struct device_node *event_timer, *source_timer;
event_timer = of_find_matching_node(NULL, picoxcell_timer_ids); event_timer = of_find_matching_node(NULL, osctimer_ids);
if (!event_timer) if (!event_timer)
panic("No timer for clockevent"); panic("No timer for clockevent");
picoxcell_add_clockevent(event_timer); add_clockevent(event_timer);
source_timer = of_find_matching_node(event_timer, picoxcell_timer_ids); source_timer = of_find_matching_node(event_timer, osctimer_ids);
if (!source_timer) if (!source_timer)
panic("No timer for clocksource"); panic("No timer for clocksource");
picoxcell_add_clocksource(source_timer); add_clocksource(source_timer);
of_node_put(source_timer); of_node_put(source_timer);
picoxcell_init_sched_clock(); init_sched_clock();
} }
struct sys_timer picoxcell_timer = { struct sys_timer dw_apb_timer = {
.init = picoxcell_timer_init, .init = timer_init,
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment