dmtimer adaptation to platform_driver
Subsystems (6)
v14 cover dmtimer adaptation to platform_driver
Adaptation of dmtimer code to platform driver using omap_device and omap_hwmod abstraction. It also include pm-runtime and off-mode support.
Baseline: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Branch: Master
I have applied the patch series on top of Tony Lindgren's dmtimer patch series taken from git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
Branch:devel-timer
REPOST:
- Following comments from Todd Poynor <[email protected]> implemented
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg52677.html
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg52676.html
- Incorrect balancing of *_runtime_get/put_sync for wakeup domain timers in the off-mode patch corrected.
Test Info:
- OMAP4430SDP: Functional tests.
- OMAP3430SDP: Functional and Off-mode tests.
- OMAP2430SDP: Functional tests.
- OMAP2420SDP: Functional tests.
- OMAP1710SDP: Boot test.
v14:
(1) Baselined on top of Tony Lindgren's latest timer patch series.
(2) Context save/restore routines.
(3) Off-mode support
v13:
(1) Handling of early timer removed because this is being taken care by Tony's patch series.
(2) Timers reserved for clockevent/clocksource during early boot are registered and marked reserved.
(3) Platform specific timer code merged to mach-omap2/timer.c.
(4) Timer capabilities are added in the hwmod database to each of the omap timers.
(5) plat-omap/dmtimer.c plat-omap/include/plat/dmtimer.h are converted to a driver by moving them to drivers/misc/timer-omap.c and include/linux/timer-omap.h
v12:
(1) Remove registration and initialization of all timers during early boot. Initialize only the system timer which is set by the board file or default value assigned to it. This timer is not considered later during rest of the timers initialization.
(2) Use mutex instead of spinlock since there is no interrupt context.
(3) Remove hacky code to manage GPTIMER12 in mach-omap2/dmtimer.c. This is now changed to use dev_attr instead to identify if it is a secure timer. In the hwmod database, any secure timer entry can use this dev_attr so that driver avoids registering tha particular timer.
(4) Removed reset function from OMAP1 and kept it back to its original place in plat-omap/dmtimer.c, with modification of course. Instead of (is_omap16xx) flag a new variable (needs_manual_reset) added. This flag is set for OMAP1. So, call to reset function is made if this value is set implying that reset is called only for OMAP1.
(5) Timer enable and disable functions cleanup with checks for early boot condition removed. Added new interface wrapper function to configure system timer clock source.
(6) Move OMAP4 specific register offsets from mach-omap2 to driver code along with other register offset definitions.
(7) omap2_dm_timer_early_init() renamed to omap2_system_timer_init(), omap2_dm_timer_normal_init() renamed to omap2_dm_timer_init().
(8) Use dev_err() instead of pr_err() in low level read/write functions.
v11:
(1) Removed early timer initialization call from omap2_init_common_devices() in io.c. It is now called from omap2_gp_timer_init() in timer-gp.c as part of following call sequence:
start_kernel()->time_init()->timer->init()->omap2_gp_timer_init()
(2) Basedlined on top of Paul's patch series mentioned above.
v10:
(1) Update PM runtime for active early timers so that PM runtime userspace info is correct.
(2) Include code to configure timers to POSTED mode which got missed in the previous version.
(3) Remove pm runtime_enable from OMAP1 specific code since this is not applicable.
v9:
(1) In OMAP3 hwmod database, added entry for timer12 which was missing. Beagle board uses timer12 as its millisecond timer.
(2) In OMAP3 hwmod database, rectified in-correct prcm configurations for timer10 and timer11.
From:
.prcm = {
.module_bit = OMAP24XX_EN_GPT10_SHIFT,
.idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT,
},
To:
.prcm = {
.module_bit = OMAP3430_EN_GPT10_SHIFT,
.idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT,
},(3) In OMAP3 hwmod database, removed timer master port entry for all timers because it is not supported.
static struct omap_hwmod_ocp_if *omap3xxx_timer7_masters[] = {
&omap3xxx_l4_per__timer7,
};(4) In OMAP4 hwmod database, added SIDLE_SMART_WKUP flag for non-millisecond timers.
(5) In OMAP3 hwmod database, rectified sysconfig configuration for non-millisecond timers.
From: omap_hwmod_sysc_type2 To: omap_hwmod_sysc_type1. This was preventing system to go to RETENTION and OFF modes.
v8:
(1) Baselined on Tony's tree in omap-for-linus branch
(2) The last patch in v7 series has been removed because it is fixed by following patch:
commit: 78f26e872f77b6312273216de1a8f836c6f2e143
OMAP: hwmod: Set autoidle after smartidle during _sysc_enable
v7:
(1) In omap1_dm_timer_set_src(), the computation of shift value to respective dmtimer clock source was corrected:
From:
int n = (pdev->id) << 1;
To:
int n = (pdev->id - 1) << 1;
This change is needed because dmtimer is indexed from 1 now instead of 0.
(2) In omap1_dm_timer_init(void) memory resource end address chnaged:
From:
res[0].end = base + 0xff;
To:
res[0].end = base + 0x46;
This was causing request_mem_region() failure in driver probe().
(3) In the export APIs there are some calls which are not applicable to OMAP1. They have been made conditional now. They include following calls:
timer->fclk = clk_get(&timer->pdev->dev, "fck");omap_dm_timer_enable()omap_dm_timer_disable()
(4) Remove usage of cpu_is_omap16xx() and instead a flag has been added in struct dmtimer_platform_data {
...
u32 is_omap16xx:1;
}
This flag is set to 1 in mach-omap1/dmtimer.c and set to 0 in mach-omap2/dmtimer.c This flag is used in plat-omap/dmtimer.c wherever it needs to distiguish omap16xx.
(5) Remove #include <plat/omap_device.h> from mach-omap1/dmtimer.c
(6) Instead of using macros like INT_24XX_GPTIMERx, use the numbers directly in OMAP2420, OMAP2430 and OMAP3xxx hwmod database.
(7) pm_runtime_get_sync() and pm_runtime_put_sync() return value check modified from positive to negative value:
if (pm_runtime_get_sync(...) < 0) {
...
}
v6:
(1) Removed reset functions to mach-omap1/dmtimer.c.
Access to reset function from plat-omap/dmtimer.c is provided by means of function pointer.
(2) Remove multiple calls to omap_device_build() for registering timer devices during early and regular initialization. Regular device registration is now done by reading data from temporary list. This list is populated during early init where timer data is read from hwmod database and corresponding memory allocated.
(3) kfree(pdata) under error condition since platform_device_unregister does not free its pdata.
(4) Removed extra header inclusion in mach-omap2 and plat-omap
NOTE: omap_dm_timer.<id> field could not be removed because during regular boot there is no mechanism to match the current pdev with corresponding entry in the timer list which was partially initialized during early boot.
v5:
(1) In mach-omap2/dmtimer.c merged the merged two different init functions into a single one, viz: omap_timer_init(*oh, *user). Now this function is used both during early init and later. The distinction is between the two is made thriugh the *user field.
(2) Added timeout to low-level access routines in place of infinite while loop which waits on write-pend register bit.
(3) Modified devices names from "omap-timer.x" to "omap_timer.x"
(4) Modified module description from "OMAP DUAL MODE TIMER DRIVER" to:MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
(5) Use well-defined constants for new IP revision register constants instead of hard-coded values.
(6) Use consistent naming mechanism by using _dm_timer_ instead of _dmtimer_ wherever applicable.
(7) Removed id field from omap_dm_timer{} since the same can be obtained from pdev.
(8) clk_get() and clk_put() moved from probe() and remove() functions. Now clk_get() is called when timer is acquired in the omap_dm_timer_prepare() and clk_put() is called in omap_dm_timer_free().
(9) Incorporated general comments:
(i) Redundant Copyright information.
(ii) Typos in comments.
(iii) Modify subjects for hwmod database related patches.
(iv) Remove redundant comments from hwmod database as they would be lost during auto-generation in the future.
v4:
(1) clock aliases are renamed as "32k_ck", "sys_ck" and "alt_ck"
(2) incorporate missing clk_put() for corresponding clk_get()
(3) modified clk_get()/clk_put() to be called once once in platform driver.
(4) consistent header for new files
(5) check return value of omap_hwmod_for_each_by_class() in device init routines.
(6) remove is_abe_timer field in dmtimer_platform_data structure. this is no longer needed with new input clock source aliasing.
(7) proper splitting of patch series
(8) remove register map from hwmod database.
(9) remove clock source strings array from hwmod database and associated structure declaration from plat/dmtimer.h. this is no longer needed.
(10) remove dev_attr from hwmod database. this is no longer needed.
(11) use register offsets to identify OMAP 4 registers instead of register map.
(12) remove clock source name strings from hwmod database.
(13) introduce new mechanism for getting struct clk associated with clock source names. this is achieved by adding clock alisases for all supported clock sources.
(14) remove clock setup functions in mach-omap2 for populating struct clk associated with all input clock sources because this is no longer needed with above implementation.
(15) device names changed from dmtimer to omap-timer
(16) device index starts from 1 instead of 0
(17) remove .init_name from hwmod database. this is not needed.
(18) introduce separate functions for reading/writing interrupt registers instead of doing all operations within a single function.
v3:
(1) multi-line comment error correction
(2) provision to allow any of the available dmtimers as early timers instead of restricting them to millisecond timers only.
(3) in 'struct omap_dmtimer{}' is_initialized flag is redundant and so must be removed. if the element is found in the list it is already initialized.
(4) remove 'found' flag in omap_dm_timer_request() and omap_dm_timer_request_specific() functions.
this is not needed with alternate implementation.
(5) use .init_name to initialize device names so that it can be identified during early boot as well. This is to avoid duplicate functions for clock manipulations during early boot and later.
(6) remove redundant functions from mach-omap2 which are created just to call pm functions like: pm_runtime_get_sync(),pm_runtime_put_sync(),.. and instead call them directly from plat-omap function api's.
(7) timer clock source names made part of hwmod database. source_clock[] of type 'struct clk' is made part of platform data.
(8) clockactivity field initialized in hwmod database to preserve fclk during idle. code which manipulate OCP config removed since they are already taken care by hwmod framework.
(9) omap2_dm_timer_set_src() is optimized. Clock enable/disbale routines moved to plat-omap layer and simplfied to the level so as not to sacrifice intended functionality.
NOTE: During early boot clock management was requested to be placed upon client drivers responsibility. this has not been done keeping in mind that it would entail (i) multiple modifications of client drivers (ii) it would violate the purpose of having a framework (open to debate).
(10) dmtimer register maps moved to hwmod database
v2:
(1) removed dedicated functions for early timer clock access. instead, now we have common functions for early and normal timers.
(2) removed usage of clock source strings for reading corresponding struct clks. this is now achieved through clock aliases introduced for each input clock sources.
(3) IP revision to distinguish new IP standard and the rest and then initialize dmtimer interrupt and functional offsets.
(4) provision to initialize all dmtimers as early timers.
(5) remove dm_timer_setup() function because this is no longer needed.
(6) modify the device index to start from 1 instead of 0.
(7) device name changed from dmtimer to omap-timer
(8) extract device ids' from hwmod name and same used for device build.
(9) additional resource allocation checks and free
(10) early timer variable initialization
(11) initialize timer_ip_type and register offsets in platform data structure.
(12) some more comments/logs
Tarun Kanti DebBarma (11):
OMAP2+: dmtimer: add device names to flck nodes
OMAP4: hwmod data: add dmtimer version information OMAP2+: dmtimer: convert to platform devices
OMAP: dmtimer: platform driver
OMAP: dmtimer: switch-over to platform device driver
OMAP: dmtimer: pm_runtime support
OMAP: dmtimer: add timeout to low-level routines
OMAP: dmtimer: use mutex instead of spinlock
OMAP: dmtimer: mark clocksource and clockevent timers reserved
OMAP: dmtimer: add context save/restore routines
OMAP: dmtimer: Off mode support
Thara Gopinath (1):
OMAP1: dmtimer: conversion to platform devices
arch/arm/mach-omap1/Makefile | 2 +- arch/arm/mach-omap1/timer.c | 176 ++++++++ arch/arm/mach-omap2/clock2420_data.c | 52 ++- arch/arm/mach-omap2/clock2430_data.c | 48 ++ arch/arm/mach-omap2/clock3xxx_data.c | 36 ++ arch/arm/mach-omap2/clock44xx_data.c | 33 ++ arch/arm/mach-omap2/omap_hwmod_2420_data.c | 22 + arch/arm/mach-omap2/omap_hwmod_2430_data.c | 22 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 27 ++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 24 + arch/arm/mach-omap2/timer.c | 201 ++++++++- arch/arm/plat-omap/dmtimer.c | 674 ++++++++++++++++------------ arch/arm/plat-omap/include/plat/dmtimer.h | 173 ++++++-- 13 files changed, 1139 insertions(+), 351 deletions(-) create mode 100644 arch/arm/mach-omap1/timer.c
PATCH v14 1/12 OMAP2+: dmtimer: add device names to flck nodes
Add device name to OMAP2 dmtimer fclk nodes so that the fclk nodes can be retrieved by doing a clk_get with the corresponding device pointers or device names.
--- arch/arm/mach-omap2/clock2420_data.c | 52 ++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/clock2430_data.c | 48 +++++++++++++++++++++++++++++++ arch/arm/mach-omap2/clock3xxx_data.c | 36 +++++++++++++++++++++++ arch/arm/mach-omap2/clock44xx_data.c | 33 +++++++++++++++++++++ 4 files changed, 167 insertions(+), 2 deletions(-)
arch/arm/mach-omap2/clock2420_data.c +50 -2
@@ -1838,9 +1838,9 @@ static struct omap_clk omap2420_clks[] = {CLK (NULL ,"gpt9_ick" , &gpt9_ick,CK_242X ),CLK (NULL ,"gpt9_fck" , &gpt9_fck,CK_242X ),CLK (NULL ,"gpt10_ick" , &gpt10_ick,CK_242X ), -CLK (NULL ,"gpt10_fck" , &gpt10_fck,CK_242X ), +CLK (NULL ,"gpt_10fck" , &gpt10_fck,CK_242X ),CLK (NULL ,"gpt11_ick" , &gpt11_ick,CK_242X ), -CLK (NULL ,"gpt11_fck" , &gpt11_fck,CK_242X ), +CLK (NULL ,"gpt_11fck" , &gpt11_fck,CK_242X ),CLK (NULL ,"gpt12_ick" , &gpt12_ick,CK_242X ),CLK (NULL ,"gpt12_fck" , &gpt12_fck,CK_242X ), CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_242X),
@@ -1898,6 +1898,54 @@ static struct omap_clk omap2420_clks[] = {CLK (NULL ,"pka_ick" , &pka_ick,CK_242X ),CLK (NULL ,"usb_fck" , &usb_fck,CK_242X ),CLK ("musb-hdrc" ,"fck" , &osc_ck,CK_242X ), +CLK ("omap_timer.1" ,"fck" , &gpt1_fck,CK_242X ), +CLK ("omap_timer.2" ,"fck" , &gpt2_fck,CK_242X ), +CLK ("omap_timer.3" ,"fck" , &gpt3_fck,CK_242X ), +CLK ("omap_timer.4" ,"fck" , &gpt4_fck,CK_242X ), +CLK ("omap_timer.5" ,"fck" , &gpt5_fck,CK_242X ), +CLK ("omap_timer.6" ,"fck" , &gpt6_fck,CK_242X ), +CLK ("omap_timer.7" ,"fck" , &gpt7_fck,CK_242X ), +CLK ("omap_timer.8" ,"fck" , &gpt8_fck,CK_242X ), +CLK ("omap_timer.9" ,"fck" , &gpt9_fck,CK_242X ), +CLK ("omap_timer.10" ,"fck" , &gpt10_fck,CK_242X ), +CLK ("omap_timer.11" ,"fck" , &gpt11_fck,CK_242X ), +CLK ("omap_timer.12" ,"fck" , &gpt12_fck,CK_242X ), +CLK ("omap_timer.1" ,"32k_ck" , &func_32k_ck,CK_243X ), +CLK ("omap_timer.2" ,"32k_ck" , &func_32k_ck,CK_243X ), +CLK ("omap_timer.3" ,"32k_ck" , &func_32k_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), };/*
arch/arm/mach-omap2/clock2430_data.c +48 -0
54 lines not on this page · raw message
arch/arm/mach-omap2/clock3xxx_data.c +36 -0
@@ -3462,6 +3462,42 @@ static struct omap_clk omap3xxx_clks[] = {CLK ("musb-am35x" ,"fck" , &hsotgusb_fck_am35xx,CK_AM35XX ),CLK (NULL ,"hecc_ck" , &hecc_ck,CK_AM35XX ),CLK (NULL ,"uart4_ick" , &uart4_ick_am35xx,CK_AM35XX ), +CLK ("omap_timer.1" ,"fck" , &gpt1_fck,CK_3XXX ), +CLK ("omap_timer.2" ,"fck" , &gpt2_fck,CK_3XXX ), +CLK ("omap_timer.3" ,"fck" , &gpt3_fck,CK_3XXX ), +CLK ("omap_timer.4" ,"fck" , &gpt4_fck,CK_3XXX ), +CLK ("omap_timer.5" ,"fck" , &gpt5_fck,CK_3XXX ), +CLK ("omap_timer.6" ,"fck" , &gpt6_fck,CK_3XXX ), +CLK ("omap_timer.7" ,"fck" , &gpt7_fck,CK_3XXX ), +CLK ("omap_timer.8" ,"fck" , &gpt8_fck,CK_3XXX ), +CLK ("omap_timer.9" ,"fck" , &gpt9_fck,CK_3XXX ), +CLK ("omap_timer.10" ,"fck" , &gpt10_fck,CK_3XXX ), +CLK ("omap_timer.11" ,"fck" , &gpt11_fck,CK_3XXX ), +CLK ("omap_timer.12" ,"fck" , &gpt12_fck,CK_3XXX ), +CLK ("omap_timer.1" ,"32k_ck" , &omap_32k_fck,CK_3XXX ), +CLK ("omap_timer.2" ,"32k_ck" , &omap_32k_fck,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), };
arch/arm/mach-omap2/clock44xx_data.c +33 -0
@@ -3283,6 +3283,39 @@ static struct omap_clk omap44xx_clks[] = {CLK (NULL ,"auxclkreq3_ck" , &auxclkreq3_ck,CK_443X ),CLK (NULL ,"auxclkreq4_ck" , &auxclkreq4_ck,CK_443X ),CLK (NULL ,"auxclkreq5_ck" , &auxclkreq5_ck,CK_443X ), +CLK ("omap_timer.1" ,"fck" , &timer1_fck,CK_443X ), +CLK ("omap_timer.2" ,"fck" , &timer2_fck,CK_443X ), +CLK ("omap_timer.3" ,"fck" , &timer3_fck,CK_443X ), +CLK ("omap_timer.4" ,"fck" , &timer4_fck,CK_443X ), +CLK ("omap_timer.5" ,"fck" , &timer5_fck,CK_443X ), +CLK ("omap_timer.6" ,"fck" , &timer6_fck,CK_443X ), +CLK ("omap_timer.7" ,"fck" , &timer7_fck,CK_443X ), +CLK ("omap_timer.8" ,"fck" , &timer8_fck,CK_443X ), +CLK ("omap_timer.9" ,"fck" , &timer9_fck,CK_443X ), +CLK ("omap_timer.10" ,"fck" , &timer10_fck,CK_443X ), +CLK ("omap_timer.11" ,"fck" , &timer11_fck,CK_443X ), +CLK ("omap_timer.1" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.2" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.3" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.4" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.5" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.6" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.7" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.8" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.9" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.10" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.11" ,"32k_ck" , &sys_32k_ck,CK_443X ), +CLK ("omap_timer.1" ,"sys_ck" , &sys_clkin_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 )
Signature · 1 line
1.6.0.4
PATCH v14 1/12 OMAP2+: dmtimer: add device names to flck nodes
Quoted 8 lines · Tarun Kanti DebBarma
Add device name to OMAP2 dmtimer fclk nodes so that the fclk nodes can be retrieved by doing a
clk_getwith the corresponding device pointers or device names.Signed-off-by Tarun Kanti DebBarma<[email protected]Signed-off-by Thara Gopinath<[email protected]>Acked-by Cousson, Benoit<[email protected]>---
Looks good to me.
Regards
Santosh
PATCH v14 2/12 OMAP4: hwmod data: add dmtimer version information
In reply to Tarun Kanti DebBarmaOMAP4 has two groups of timers: version 1 timers are 1, 2, 10, while the rest of the timers, 3-9, 11 are version 2 timers. The version information is required by the driver so that they could be handled correctly by it.
--- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 3 +++ arch/arm/plat-omap/include/plat/dmtimer.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +3 -0
@@ -27,6 +27,7 @@#include <plat/mcspi.h> #include <plat/mcbsp.h> #include <plat/mmc.h> +#include <plat/dmtimer.h> #include "omap_hwmod_common_data.h"
@@ -3994,6 +3995,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = {static struct omap_hwmod_class omap44xx_timer_1ms_hwmod_class = { .name ="timer" , .sysc = &omap44xx_timer_1ms_sysc, + .rev =OMAP_TIMER_IP_VERSION_1 , };static struct omap_hwmod_class_sysconfig omap44xx_timer_sysc = {
@@ -4009,6 +4011,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_timer_sysc = {static struct omap_hwmod_class omap44xx_timer_hwmod_class = { .name ="timer" , .sysc = &omap44xx_timer_sysc, + .rev =OMAP_TIMER_IP_VERSION_2 , };/* timer1 */
arch/arm/plat-omap/include/plat/dmtimer.h +3 -1
@@ -57,7 +57,9 @@* IP revision identifier so that Highlander IP * in OMAP4 can be distinguished. */ -#define OMAP_TIMER_IP_VERSION_1 0x1 +#define OMAP_TIMER_IP_VERSION_1 0x1 +#define OMAP_TIMER_IP_VERSION_2 0x2 +struct omap_dm_timer ;struct clk ;
Signature · 1 line
1.6.0.4
PATCH v14 2/12 OMAP4: hwmod data: add dmtimer version information
Quoted 9 lines · Tarun Kanti DebBarma
OMAP4 has two groups of timers: version 1 timers are 1, 2, 10, while the rest of the timers, 3-9, 11 are version 2 timers. The version information is required by the driver so that they could be handled correctly by it.
Signed-off-by Tarun Kanti DebBarma<[email protected]>Acked-by Cousson, Benoit<[email protected]>Cc Cousson, Benoit<[email protected]>---
Since Benoit has already acked it, you can remove the CC.
Regards
Santosh
PATCH v14 3/12 OMAP1: dmtimer: conversion to platform devices
In reply to Tarun Kanti DebBarmaFrom: Thara Gopinath <[email protected]>
Convert OMAP1 dmtimers into a platform devices and then registers with device model framework so that it can be bound to corresponding driver.
--- arch/arm/mach-omap1/Makefile | 2 +- arch/arm/mach-omap1/timer.c | 174 +++++++++++++++++++++++++++++ arch/arm/plat-omap/dmtimer.c | 56 ++------- arch/arm/plat-omap/include/plat/dmtimer.h | 8 ++ 4 files changed, 195 insertions(+), 45 deletions(-) create mode 100644 arch/arm/mach-omap1/timer.c
arch/arm/mach-omap1/Makefile +1 -1
@@ -4,7 +4,7 @@ # Common support obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o -obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o +obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o timer.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
arch/arm/mach-omap1/timer.c new file +174 -0
174 lines not on this page · raw message
arch/arm/plat-omap/dmtimer.c +12 -44
94 lines not on this page · raw message
arch/arm/plat-omap/include/plat/dmtimer.h +8 -0
@@ -34,6 +34,7 @@#include <linux/clk.h> #include <linux/delay.h> +#include <linux/platform_device.h> #ifndef __ASM_ARCH_DMTIMER_H#define __ASM_ARCH_DMTIMER_H
@@ -63,6 +64,12 @@struct omap_dm_timer ;struct clk ; +struct dmtimer_platform_data { +int (*set_timer_src)(struct platform_device *pdev,int source); +int timer_ip_type; +u32 needs_manual_reset:1 ; +}; +struct omap_dm_timer *omap_dm_timer_request (void );struct omap_dm_timer *omap_dm_timer_request_specific (int timer_id);void omap_dm_timer_free (struct omap_dm_timer *timer);
@@ -219,6 +226,7 @@ struct omap_dm_timer { unsigned reserved:1; unsigned enabled:1; unsigned posted:1; +struct platform_device *pdev; };extern u32 sys_timer_reserved;
Signature · 1 line
1.6.0.4
PATCH v14 3/12 OMAP1: dmtimer: conversion to platform devices
Quoted 35 lines · Tarun Kanti DebBarma
From: Thara Gopinath<[email protected]>
Convert OMAP1 dmtimers into a platform devices and then registers with device model framework so that it can be bound to corresponding driver.
Signed-off-by Thara Gopinath<[email protected]>Signed-off-by Tarun Kanti DebBarma<[email protected]>Acked-by Cousson, Benoit<[email protected]>--- arch/arm/mach-omap1/Makefile | 2 +- arch/arm/mach-omap1/timer.c | 174 +++++++++++++++++++++++++++++ arch/arm/plat-omap/dmtimer.c | 56 ++------- arch/arm/plat-omap/include/plat/dmtimer.h | 8 ++ 4 files changed, 195 insertions(+), 45 deletions(-)create mode 100644
arch/arm/mach-omap1/timer.carch/arm/mach-omap1/Makefile +1
-1@@ -4,7 +4,7 @@ # Common support obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o -obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o +obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o timer.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.oarch/arm/mach-omap1/timer.c new file +0
-0
arch/arm/mach-omap1/timer.c line 9
Quoted 9 lines
arch/arm/mach-omap1/timer.c new file +9
-0@@ -0,0 +1,174 @@ +/** +* OMAP1 Dual-Mode Timers - platform device registration +* +* Contains first level initialization routines which internally +* generates timer device information and registers with linux +* device model. It also has low level function to chnage the timer +* input clock source. +* +* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
/s/2010 /2011
Quoted 33 lines
arch/arm/mach-omap1/timer.c new file +33
-0+* Tarun Kanti DebBarma<[email protected]> +* Thara Gopinath<[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* This program is distributed "as is" WITHOUT ANY WARRANTY of any +* kind, whether express or implied; without even the implied warranty +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/platform_device.h> + +#include <mach/irqs.h> + +#include <plat/dmtimer.h> + +#define OMAP1610_GPTIMER1_BASE 0xfffb1400 +#define OMAP1610_GPTIMER2_BASE 0xfffb1c00 +#define OMAP1610_GPTIMER3_BASE 0xfffb2400 +#define OMAP1610_GPTIMER4_BASE 0xfffb2c00 +#define OMAP1610_GPTIMER5_BASE 0xfffb3400 +#define OMAP1610_GPTIMER6_BASE 0xfffb3c00 +#define OMAP1610_GPTIMER7_BASE 0xfffb7400 +#define OMAP1610_GPTIMER8_BASE 0xfffbd400 + +#define OMAP1_DM_TIMER_COUNT 8
arch/arm/mach-omap1/timer.c line 52
Quoted 10 lines
arch/arm/mach-omap1/timer.c new file +10
-0+ +static int omap1_dm_timer_set_src (struct platform_device *pdev, +int source) +{ +int n = (pdev->id -1 )<<1 ; +u32 l; + + l =omap_readl (MOD_CONF_CTRL_1 )& ~(0x03 << n); + l |= source<< n; +omap_writel (l,MOD_CONF_CTRL_1 );
Stop using omap_readl/omap_writel. Use standard readl/writel
rest looks ok to me.
Regards
Santosh
PATCH v14 4/12 OMAP2+: dmtimer: convert to platform devices
In reply to Tarun Kanti DebBarmaAdd routines to converts dmtimers to platform devices. The device data is obtained from hwmod database of respective platform and is registered to device model after successful binding to driver.
In addition, capability attribute of each of the timers is added in hwmod database.
--- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 22 +++++ arch/arm/mach-omap2/omap_hwmod_2430_data.c | 22 +++++ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 27 ++++++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 21 +++++ arch/arm/mach-omap2/timer.c | 136 ++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/dmtimer.h | 10 ++- 6 files changed, 237 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap_hwmod_2420_data.c +22 -0
@@ -358,6 +358,16 @@ static struct omap_hwmod_class omap2420_timer_hwmod_class = { .rev = OMAP_TIMER_IP_VERSION_1, }; +/* always-on timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { + .timer_capability =OMAP_TIMER_ALWON , +}; + +/* pwm timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { + .timer_capability =OMAP_TIMER_HAS_PWM , +}; +/* timer1 */ static struct omap_hwmod omap2420_timer1_hwmod;static struct omap_hwmod_irq_info omap2420_timer1_mpu_irqs[] = {
@@ -402,6 +412,7 @@ static struct omap_hwmod omap2420_timer1_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer1_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer1_slaves), .class = &omap2420_timer_hwmod_class,
@@ -452,6 +463,7 @@ static struct omap_hwmod omap2420_timer2_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer2_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer2_slaves), .class = &omap2420_timer_hwmod_class,
@@ -502,6 +514,7 @@ static struct omap_hwmod omap2420_timer3_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer3_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer3_slaves), .class = &omap2420_timer_hwmod_class,
@@ -552,6 +565,7 @@ static struct omap_hwmod omap2420_timer4_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer4_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer4_slaves), .class = &omap2420_timer_hwmod_class,
@@ -602,6 +616,7 @@ static struct omap_hwmod omap2420_timer5_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer5_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer5_slaves), .class = &omap2420_timer_hwmod_class,
@@ -653,6 +668,7 @@ static struct omap_hwmod omap2420_timer6_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer6_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer6_slaves), .class = &omap2420_timer_hwmod_class,
@@ -703,6 +719,7 @@ static struct omap_hwmod omap2420_timer7_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer7_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer7_slaves), .class = &omap2420_timer_hwmod_class,
@@ -753,6 +770,7 @@ static struct omap_hwmod omap2420_timer8_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2420_timer8_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer8_slaves), .class = &omap2420_timer_hwmod_class,
@@ -803,6 +821,7 @@ static struct omap_hwmod omap2420_timer9_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2420_timer9_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer9_slaves), .class = &omap2420_timer_hwmod_class,
@@ -853,6 +872,7 @@ static struct omap_hwmod omap2420_timer10_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2420_timer10_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer10_slaves), .class = &omap2420_timer_hwmod_class,
@@ -903,6 +923,7 @@ static struct omap_hwmod omap2420_timer11_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2420_timer11_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer11_slaves), .class = &omap2420_timer_hwmod_class,
@@ -953,6 +974,7 @@ static struct omap_hwmod omap2420_timer12_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2420_timer12_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_timer12_slaves), .class = &omap2420_timer_hwmod_class,
arch/arm/mach-omap2/omap_hwmod_2430_data.c +22 -0
@@ -459,6 +459,16 @@ static struct omap_hwmod_class omap2430_timer_hwmod_class = { .rev = OMAP_TIMER_IP_VERSION_1, }; +/* always-on timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { + .timer_capability =OMAP_TIMER_ALWON , +}; + +/* pwm timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { + .timer_capability =OMAP_TIMER_HAS_PWM , +}; +/* timer1 */ static struct omap_hwmod omap2430_timer1_hwmod;static struct omap_hwmod_irq_info omap2430_timer1_mpu_irqs[] = {
@@ -503,6 +513,7 @@ static struct omap_hwmod omap2430_timer1_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer1_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer1_slaves), .class = &omap2430_timer_hwmod_class,
@@ -553,6 +564,7 @@ static struct omap_hwmod omap2430_timer2_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer2_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer2_slaves), .class = &omap2430_timer_hwmod_class,
@@ -603,6 +615,7 @@ static struct omap_hwmod omap2430_timer3_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer3_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer3_slaves), .class = &omap2430_timer_hwmod_class,
@@ -653,6 +666,7 @@ static struct omap_hwmod omap2430_timer4_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer4_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer4_slaves), .class = &omap2430_timer_hwmod_class,
@@ -703,6 +717,7 @@ static struct omap_hwmod omap2430_timer5_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer5_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer5_slaves), .class = &omap2430_timer_hwmod_class,
@@ -753,6 +768,7 @@ static struct omap_hwmod omap2430_timer6_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer6_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer6_slaves), .class = &omap2430_timer_hwmod_class,
@@ -803,6 +819,7 @@ static struct omap_hwmod omap2430_timer7_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer7_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer7_slaves), .class = &omap2430_timer_hwmod_class,
@@ -853,6 +870,7 @@ static struct omap_hwmod omap2430_timer8_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap2430_timer8_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer8_slaves), .class = &omap2430_timer_hwmod_class,
@@ -903,6 +921,7 @@ static struct omap_hwmod omap2430_timer9_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2430_timer9_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer9_slaves), .class = &omap2430_timer_hwmod_class,
@@ -953,6 +972,7 @@ static struct omap_hwmod omap2430_timer10_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2430_timer10_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer10_slaves), .class = &omap2430_timer_hwmod_class,
@@ -1003,6 +1023,7 @@ static struct omap_hwmod omap2430_timer11_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2430_timer11_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer11_slaves), .class = &omap2430_timer_hwmod_class,
@@ -1053,6 +1074,7 @@ static struct omap_hwmod omap2430_timer12_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap2430_timer12_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_timer12_slaves), .class = &omap2430_timer_hwmod_class,
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +27 -0
@@ -609,6 +609,21 @@ static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { .rev = OMAP_TIMER_IP_VERSION_1, }; +/* secure timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_secure_dev_attr = { + .timer_capability =OMAP_TIMER_SECURE , +}; + +/* always-on timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { + .timer_capability =OMAP_TIMER_ALWON , +}; + +/* pwm timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { + .timer_capability =OMAP_TIMER_HAS_PWM , +}; +/* timer1 */ static struct omap_hwmod omap3xxx_timer1_hwmod;static struct omap_hwmod_irq_info omap3xxx_timer1_mpu_irqs[] = {
@@ -653,6 +668,7 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap3xxx_timer1_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer1_slaves), .class = &omap3xxx_timer_1ms_hwmod_class,
@@ -703,6 +719,7 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap3xxx_timer2_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer2_slaves), .class = &omap3xxx_timer_1ms_hwmod_class,
@@ -753,6 +770,7 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap3xxx_timer3_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer3_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -803,6 +821,7 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap3xxx_timer4_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer4_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -853,6 +872,7 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap3xxx_timer5_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer5_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -903,6 +923,7 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap3xxx_timer6_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer6_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -953,6 +974,7 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap3xxx_timer7_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer7_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -1003,6 +1025,7 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap3xxx_timer8_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer8_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -1053,6 +1076,7 @@ static struct omap_hwmod omap3xxx_timer9_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT9_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap3xxx_timer9_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer9_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -1103,6 +1127,7 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap3xxx_timer10_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer10_slaves), .class = &omap3xxx_timer_1ms_hwmod_class,
@@ -1153,6 +1178,7 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT11_SHIFT, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap3xxx_timer11_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer11_slaves), .class = &omap3xxx_timer_hwmod_class,
@@ -1203,6 +1229,7 @@ static struct omap_hwmod omap3xxx_timer12_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT, }, }, + .dev_attr = &capability_secure_dev_attr, .slaves = omap3xxx_timer12_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_timer12_slaves), .class = &omap3xxx_timer_hwmod_class,
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +21 -0
@@ -4014,6 +4014,16 @@ static struct omap_hwmod_class omap44xx_timer_hwmod_class = { .rev = OMAP_TIMER_IP_VERSION_2, }; +/* always-on timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { + .timer_capability =OMAP_TIMER_ALWON , +}; + +/* pwm timers dev attribute */ +static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { + .timer_capability =OMAP_TIMER_HAS_PWM , +}; +/* timer1 */ static struct omap_hwmod omap44xx_timer1_hwmod;static struct omap_hwmod_irq_info omap44xx_timer1_irqs[] = {
@@ -4054,6 +4064,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = { .clkctrl_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap44xx_timer1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer1_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4099,6 +4110,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap44xx_timer2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer2_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4144,6 +4156,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap44xx_timer3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer3_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4189,6 +4202,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap44xx_timer4_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer4_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4253,6 +4267,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = { .clkctrl_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap44xx_timer5_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer5_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4317,6 +4332,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = { .clkctrl_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap44xx_timer6_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer6_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4381,6 +4397,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = { .clkctrl_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL, }, }, + .dev_attr = &capability_alwon_dev_attr, .slaves = omap44xx_timer7_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer7_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4445,6 +4462,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = { .clkctrl_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap44xx_timer8_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer8_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4490,6 +4508,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap44xx_timer9_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer9_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4535,6 +4554,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap44xx_timer10_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer10_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
@@ -4580,6 +4600,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = { .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, }, }, + .dev_attr = &capability_pwm_dev_attr, .slaves = omap44xx_timer11_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_timer11_slaves), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
arch/arm/mach-omap2/timer.c +136 -0
151 lines not on this page · raw message
arch/arm/plat-omap/include/plat/dmtimer.h +9 -1
@@ -1,5 +1,5 @@/* -* arch/arm/plat-omap/include/mach/dmtimer.h +* arch/arm/plat-omap/include/plat/dmtimer.h * * OMAP Dual-Mode Timers *
@@ -61,6 +61,14 @@#define OMAP_TIMER_IP_VERSION_1 0x1#define OMAP_TIMER_IP_VERSION_2 0x2 +/* timer capabilities used in hwmod database */ +#define OMAP_TIMER_SECURE 0x80000000 +#define OMAP_TIMER_ALWON 0x40000000 +#define OMAP_TIMER_HAS_PWM 0x20000000 + +struct omap_timer_capability_dev_attr { +u32 timer_capability; +};struct omap_dm_timer ;struct clk ;
Signature · 1 line
1.6.0.4
PATCH v14 4/12 OMAP2+: dmtimer: convert to platform devices
Quoted 9 lines · Tarun Kanti DebBarma
Add routines to converts dmtimers to platform devices. The device data is obtained from hwmod database of respective platform and is registered to device model after successful binding to driver.
In addition, capability attribute of each of the timers is added in hwmod database.Signed-off-by Tarun Kanti DebBarma<[email protected]>Signed-off-by Thara Gopinath<[email protected]>Acked-by Cousson, Benoit<[email protected]>
Quoted 9 lines
--- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 22 +++++ arch/arm/mach-omap2/omap_hwmod_2430_data.c | 22 +++++ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 27 ++++++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 21 +++++ arch/arm/mach-omap2/timer.c | 136 ++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/dmtimer.h | 10 ++- 6 files changed, 237 insertions(+), 1 deletions(-)
Regards
Santosh
PATCH v14 5/12 OMAP: dmtimer: platform driver
In reply to Tarun Kanti DebBarmaAdd dmtimer platform driver functions which include:
(1) platform driver initialization
(2) driver probe function
(3) driver remove function
--- arch/arm/plat-omap/dmtimer.c | 145 +++++++++++++++++++++++++++-- arch/arm/plat-omap/include/plat/dmtimer.h | 11 ++ 2 files changed, 149 insertions(+), 7 deletions(-)
arch/arm/plat-omap/dmtimer.c +138 -7
@@ -35,14 +35,9 @@* 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/init.h> -#include <linux/spinlock.h> -#include <linux/errno.h> -#include <linux/list.h> -#include <linux/clk.h> -#include <linux/delay.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/slab.h> #include <mach/hardware.h> #include <plat/dmtimer.h> #include <mach/irqs.h>
@@ -149,6 +144,7 @@ static const char **dm_source_names;static struct clk **dm_source_clocks;static spinlock_t dm_timer_lock; +static LIST_HEAD (omap_timer_list);/* * Reads timer registers in posted and non-posted mode. The posted mode bit
@@ -544,7 +540,142 @@ int omap_dm_timers_active(void) }EXPORT_SYMBOL_GPL (omap_dm_timers_active); -static int __init omap_dm_timer_init (void ) +/** +* omap_dm_timer_probe - probe function called for every registered device +* @pdev: pointer to current timer platform device +* +* Called by driver framework at the end of device registration for all +* timer devices. +*/ +static int __devinit omap_dm_timer_probe (struct platform_device *pdev) +{ +int ret; +unsigned long flags; +struct omap_dm_timer *timer; +struct resource *mem, *irq, *ioarea; +struct dmtimer_platform_data *pdata = pdev->dev.platform_data; + +if (!pdata) { +dev_err (&pdev->dev,"%s: no platform data.\n" , __func__); +return -ENODEV ; + } + + irq =platform_get_resource (pdev,IORESOURCE_IRQ ,0 ); +if (unlikely (!irq)) { +dev_err (&pdev->dev,"%s: no IRQ resource.\n" , __func__); +return -ENODEV ; + } + + mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (unlikely (!mem)) { +dev_err (&pdev->dev,"%s: no memory resource.\n" , __func__); +return -ENODEV ; + } + + ioarea =request_mem_region (mem->start,resource_size (mem), + pdev->name); +if (!ioarea) { +dev_err (&pdev->dev,"%s: region already claimed.\n" , __func__); +return -EBUSY ; + } + + timer =kzalloc (sizeof (struct omap_dm_timer ),GFP_KERNEL ); +if (!timer) { +dev_err (&pdev->dev,"%s: no memory for omap_dm_timer.\n" , + __func__); + ret = -ENOMEM ; + goto err_free_ioregion; + } + + timer->io_base =ioremap (mem->start,resource_size (mem)); +if (!timer->io_base) { +dev_err (&pdev->dev,"%s: ioremap failed.\n" , __func__); + ret = -ENOMEM ; + goto err_free_mem; + } + +if (pdata->timer_ip_type ==OMAP_TIMER_IP_VERSION_2 ) { + timer->func_offset =VERSION2_TIMER_WAKEUP_EN_REG_OFFSET ; + timer->intr_offset =VERSION2_TIMER_STAT_REG_OFFSET ; + } + + timer->id = pdev->id; + timer->irq = irq->start; + timer->pdev = pdev; + +/* add the timer element to the list */ +spin_lock_irqsave (&dm_timer_lock, flags); +list_add_tail (&timer->node, &omap_timer_list); +spin_unlock_irqrestore (&dm_timer_lock, flags); + +dev_dbg (&pdev->dev,"Device Probed.\n" ); + +return 0 ; + +err_free_mem: +kfree (timer); + +err_free_ioregion: +release_mem_region (mem->start,resource_size (mem)); + +return ret; +} + +/** +* omap_dm_timer_remove - cleanup a registered timer device +* @pdev: pointer to current timer platform device +* +* Called by driver framework whenever a timer device is unregistered. +* In addition to freeing platform resources it also deletes the timer +* entry from the local list. +*/ +static int __devexit omap_dm_timer_remove(struct platform_device *pdev) +{ +struct omap_dm_timer *timer; +unsigned long flags; +int ret = -EINVAL ; + +spin_lock_irqsave (&dm_timer_lock, flags); +list_for_each_entry (timer, &omap_timer_list, node) +if (timer->pdev->id == pdev->id) { +list_del (&timer->node); +kfree (timer); + ret =0 ; +break ; + } +spin_unlock_irqrestore (&dm_timer_lock, flags); + +return ret; +} + +static struct platform_driver omap_dm_timer_driver = { + .probe = omap_dm_timer_probe, + .remove = omap_dm_timer_remove, + .driver = { + .name ="omap_timer" , + }, +}; + +static int __init omap_dm_timer_driver_init (void ) +{ +return platform_driver_register (&omap_dm_timer_driver); +} + +static void __exit omap_dm_timer_driver_exit(void) +{ +platform_driver_unregister (&omap_dm_timer_driver); +} + +early_platform_init ("earlytimer" , &omap_dm_timer_driver); +module_init (omap_dm_timer_driver_init); +module_exit (omap_dm_timer_driver_exit); + +MODULE_DESCRIPTION ("OMAP Dual-Mode Timer Driver" ); +MODULE_LICENSE ("GPL" ); +MODULE_ALIAS ("platform:" DRIVER_NAME ); +MODULE_AUTHOR ("Texas Instruments Inc" ); + +int __init omap_dm_timer_init (void ) {struct omap_dm_timer *timer;int i, map_size =SZ_8K ;/* Module 4KB + L4 4KB except on omap1 */
arch/arm/plat-omap/include/plat/dmtimer.h +11 -0
@@ -61,6 +61,13 @@#define OMAP_TIMER_IP_VERSION_1 0x1#define OMAP_TIMER_IP_VERSION_2 0x2 +/* +* OMAP4 IP revision has different register offsets +* for interrupt registers and functional registers. +*/ +#define VERSION2_TIMER_WAKEUP_EN_REG_OFFSET 0x14 +#define VERSION2_TIMER_STAT_REG_OFFSET 0x10 +/* timer capabilities used in hwmod database */ #define OMAP_TIMER_SECURE 0x80000000#define OMAP_TIMER_ALWON 0x40000000
@@ -225,6 +232,7 @@ int omap_dm_timers_active(void);struct omap_dm_timer {unsigned long phys_base; +int id;int irq;#ifdef CONFIG_ARCH_OMAP2PLUS struct clk *iclk, *fclk;
@@ -234,7 +242,10 @@ struct omap_dm_timer { unsigned reserved:1; unsigned enabled:1; unsigned posted:1; +u8 func_offset; +u8 intr_offset;struct platform_device *pdev; +struct list_head node; };extern u32 sys_timer_reserved;
Signature · 1 line
1.6.0.4
PATCH v14 5/12 OMAP: dmtimer: platform driver
Quoted 9 lines · Tarun Kanti DebBarma
Add dmtimer platform driver functions which include:
(1) platform driver initialization
(2) driver probe function
(3) driver remove functionSigned-off-by Tarun Kanti DebBarma<[email protected]>Signed-off-by Thara Gopinath<[email protected]>Acked-by Cousson, Benoit<[email protected]>---
Regards
Santosh
PATCH v14 6/12 OMAP: dmtimer: switch-over to platform device driver
In reply to Tarun Kanti DebBarmaRegister timer devices by going through hwmod database using hwmod API. The driver probes each of the registered devices. Functionality which are already performed by hwmod framework are removed from timer code. New set of timers present on OMAP4 are now supported.
--- arch/arm/mach-omap2/timer.c | 48 +++- arch/arm/plat-omap/dmtimer.c | 356 +++++++++-------------------- arch/arm/plat-omap/include/plat/dmtimer.h | 80 ++++--- 3 files changed, 195 insertions(+), 289 deletions(-)
arch/arm/mach-omap2/timer.c +37 -11
@@ -80,7 +80,8 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) {struct clock_event_device *evt = &clockevent_gpt; -__omap_dm_timer_write_status (clkev.io_base,OMAP_TIMER_INT_OVERFLOW ); +__omap_dm_timer_write_status (clkev.io_base,OMAP_TIMER_INT_OVERFLOW , + clkev.intr_offset, clkev.func_offset); evt->event_handler (evt);return IRQ_HANDLED ;
@@ -96,7 +97,7 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) {__omap_dm_timer_load_start (clkev.io_base,OMAP_TIMER_CTRL_ST , -0xffffffff - cycles,1 ); +0xffffffff - cycles,1 , clkev.func_offset);return 0 ; }
@@ -106,7 +107,8 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, {u32 period; -__omap_dm_timer_stop (clkev.io_base,1 , clkev.rate); +__omap_dm_timer_stop (clkev.io_base,1 , clkev.rate, true, + clkev.intr_offset, clkev.func_offset);switch (mode) {case CLOCK_EVT_MODE_PERIODIC :
@@ -114,10 +116,10 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, period -=1 ;/* Looks like we need to first set the load value separately */ __omap_dm_timer_write (clkev.io_base,OMAP_TIMER_LOAD_REG , -0xffffffff - period,1 ); +0xffffffff - period,1 , clkev.func_offset);__omap_dm_timer_load_start (clkev.io_base, -OMAP_TIMER_CTRL_AR |OMAP_TIMER_CTRL_ST , -0xffffffff - period,1 ); +OMAP_TIMER_CTRL_AR |OMAP_TIMER_CTRL_ST , +0xffffffff - period,1 , clkev.func_offset);break ;case CLOCK_EVT_MODE_ONESHOT :break ;
@@ -191,7 +193,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,clk_put (src); } } -__omap_dm_timer_reset (timer->io_base,1 ,1 ); +__omap_dm_timer_reset (timer->io_base,1 ,1 , timer->func_offset); timer->posted =1 ; timer->rate =clk_get_rate (timer->fclk);
@@ -212,7 +214,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, omap2_gp_timer_irq.dev_id = (void *)&clkev;setup_irq (clkev.irq, &omap2_gp_timer_irq); -__omap_dm_timer_int_enable (clkev.io_base,OMAP_TIMER_INT_OVERFLOW ); +__omap_dm_timer_int_enable (clkev.io_base,OMAP_TIMER_INT_OVERFLOW , + clkev.intr_offset, clkev.func_offset); clockevent_gpt.mult =div_sc (clkev.rate,NSEC_PER_SEC , clockevent_gpt.shift);
@@ -253,7 +256,8 @@ static struct omap_dm_timer clksrc;static DEFINE_CLOCK_DATA (cd);static cycle_t clocksource_read_cycles (struct clocksource *cs) { -return (cycle_t )__omap_dm_timer_read_counter (clksrc.io_base,1 ); +return (cycle_t )__omap_dm_timer_read_counter (clksrc.io_base,1 , + clksrc.func_offset); }static struct clocksource clocksource_gpt = {
@@ -268,7 +272,8 @@ static void notrace dmtimer_update_sched_clock(void) {u32 cyc; - cyc =__omap_dm_timer_read_counter (clksrc.io_base,1 ); + cyc =__omap_dm_timer_read_counter (clksrc.io_base,1 , + clksrc.func_offset);update_sched_clock (&cd, cyc, (u32 )~0 ); }
@@ -278,7 +283,8 @@ unsigned long long notrace sched_clock(void)u32 cyc =0 ;if (clksrc.reserved) - cyc =__omap_dm_timer_read_counter (clksrc.io_base,1 ); + cyc =__omap_dm_timer_read_counter (clksrc.io_base,1 , + clksrc.func_offset);return cyc_to_sched_clock (&cd, cyc, (u32 )~0 ); }
@@ -476,3 +482,23 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)return ret; } + +/** +* omap2_dm_timer_init - top level regular device initialization +* +* Uses dedicated hwmod api to parse through hwmod database for +* given class name and then build and register the timer device. +*/ +static int __init omap2_dm_timer_init (void ) +{ +int ret; + + ret =omap_hwmod_for_each_by_class ("timer" , omap_timer_init,NULL ); +if (unlikely (ret)) { +pr_err ("%s: device registration failed.\n" , __func__); +return -EINVAL ; + } + +return 0 ; +} +arch_initcall (omap2_dm_timer_init);
arch/arm/plat-omap/dmtimer.c +113 -243
520 lines not on this page · raw message
arch/arm/plat-omap/include/plat/dmtimer.h +45 -35
150 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH v14 6/12 OMAP: dmtimer: switch-over to platform device driver
Quoted 18 lines · Tarun Kanti DebBarma
Register timer devices by going through hwmod database using hwmod API. The driver probes each of the registered devices. Functionality which are already performed by hwmod framework are removed from timer code. New set of timers present on OMAP4 are now supported.
Signed-off-by Tarun Kanti DebBarma<[email protected]>Acked-by Cousson, Benoit<[email protected]>--- arch/arm/mach-omap2/timer.c | 48 +++- arch/arm/plat-omap/dmtimer.c | 356 +++++++++-------------------- arch/arm/plat-omap/include/plat/dmtimer.h | 80 ++++--- 3 files changed, 195 insertions(+), 289 deletions(-)arch/arm/mach-omap2/timer.c +0
-0
[....]
Quoted 20 lines
arch/arm/mach-omap2/timer.c +6
-7@@ -238,23 +159,23 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request);struct omap_dm_timer *omap_dm_timer_request_specific (int id) { -struct omap_dm_timer *timer; +struct omap_dm_timer *timer =NULL , *t;unsigned long flags;spin_lock_irqsave (&dm_timer_lock, flags); -if (id<=0 || id> dm_timer_count || dm_timers[id-1 ].reserved) { -spin_unlock_irqrestore (&dm_timer_lock, flags); -printk ("BUG: warning at %s:%d/%s(): unable to get timer %d\n" , - __FILE__, __LINE__, __func__, id); -dump_stack (); -return NULL ; +list_for_each_entry (t,&omap_timer_list, node) { +if (t->pdev->id == id&& !t->reserved) { + timer = t; + timer->reserved =1 ; +break ;
arch/arm/mach-omap2/timer.c EXPORT_SYMBOL_GPL(omap_dm_timer_request); · line 176
Quoted 10 lines
arch/arm/mach-omap2/timer.c +3
-4+ } } - - timer =&dm_timers[id-1 ]; - timer->reserved =1 ;spin_unlock_irqrestore (&dm_timer_lock, flags); -omap_dm_timer_prepare (timer); +if (timer) +omap_dm_timer_prepare (timer);
What if omap_dm_timer_prepare() fails?
This should be handled.
a/arch/arm/plat-omap/include/plat/dmtimer.hb/arch/arm/plat-omap/include/plat/dmtimer.h
Quoted 4 lines
index 833a33b..90a504a 100644
arch/arm/plat-omap/include/plat/dmtimer.h +0
-0@@ -234,9 +234,7 @@ struct omap_dm_timer {
[...]
Quoted 18 lines
arch/arm/plat-omap/include/plat/dmtimer.h +3
-3@@ -289,11 +289,11 @@ static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle,if (wakeup) l |=1 <<2 ; -__omap_dm_timer_write (base,OMAP_TIMER_OCP_CFG_REG , l,0 ); +__omap_dm_timer_write (base,OMAP_TIMER_OCP_CFG_REG , l,0 , func_offset);/* Match hardware reset default of posted mode */ -__omap_dm_timer_write (base,OMAP_TIMER_IF_CTRL_REG , -OMAP_TIMER_CTRL_POSTED ,0 ); +__omap_dm_timer_write (base,OMAP_TIMER_IF_CTRL_REG + func_offset, +OMAP_TIMER_CTRL_POSTED ,0 , func_offset); } static inline int __omap_dm_timer_set_source(struct clk *timer_fck,@@ -315,54 +315,64 @@ static inline int __omap_dm_timer_set_source(struct clk *timer_fck, }
arch/arm/plat-omap/include/plat/dmtimer.h static inline int __omap_dm_timer_set_source(struct clk *timer_fck, · line 323
Quoted 10 lines
arch/arm/plat-omap/include/plat/dmtimer.h +3
-2static inline void __omap_dm_timer_stop (void __iomem *base,int posted, -unsigned long rate) +unsigned long rate,bool is_omap2,u8 intr_offset,u8 func_offset) {u32 l; - l =__omap_dm_timer_read (base,OMAP_TIMER_CTRL_REG , posted); + l =__omap_dm_timer_read (base,OMAP_TIMER_CTRL_REG + func_offset, + posted, func_offset);
As mentioned earlier, if the 'func_offset' isn't populated in init code, these functions won't work for highlander IPs.
With above fixed, you can add my
Regards
Santosh
Regards
Santosh
PATCH v14 7/12 OMAP: dmtimer: pm_runtime support
In reply to Tarun Kanti DebBarmaAdd pm_runtime feature to dmtimer whereby _get_sync() is called within omap_dm_timer_enable(), _put_sync() is called in omap_dm_timer_disable().
--- arch/arm/plat-omap/dmtimer.c | 31 +++++++--------------------- arch/arm/plat-omap/include/plat/dmtimer.h | 1 - 2 files changed, 8 insertions(+), 24 deletions(-)
arch/arm/plat-omap/dmtimer.c +8 -23
@@ -38,6 +38,7 @@#include <linux/io.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/pm_runtime.h> #include <plat/dmtimer.h>
@@ -193,33 +194,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free);void omap_dm_timer_enable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; - -if (timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_enable (timer->fclk); -clk_enable (timer->iclk); - } - - timer->enabled =1 ; +pm_runtime_get_sync (&timer->pdev->dev); }EXPORT_SYMBOL_GPL (omap_dm_timer_enable);void omap_dm_timer_disable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; - -if (!timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_disable (timer->iclk); -clk_disable (timer->fclk); - } - - timer->enabled =0 ; +pm_runtime_put_sync (&timer->pdev->dev); }EXPORT_SYMBOL_GPL (omap_dm_timer_disable);
@@ -461,7 +442,7 @@ int omap_dm_timers_active(void)struct omap_dm_timer *timer;list_for_each_entry (timer, &omap_timer_list, node) { -if (!timer->enabled) +if (!timer->reserved)continue ; if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
@@ -536,6 +517,10 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->pdev = pdev; +/* Skip pm_runtime_enable for OMAP1 */ +if (!pdata->needs_manual_reset) +pm_runtime_enable (&pdev->dev); +/* add the timer element to the list */ spin_lock_irqsave (&dm_timer_lock, flags);list_add_tail (&timer->node, &omap_timer_list);
arch/arm/plat-omap/include/plat/dmtimer.h +0 -1
@@ -238,7 +238,6 @@ struct omap_dm_timer {void __iomem *io_base;unsigned long rate; unsigned reserved:1; - unsigned enabled:1; unsigned posted:1;u8 func_offset;u8 intr_offset;
Signature · 1 line
1.6.0.4
PATCH v14 7/12 OMAP: dmtimer: pm_runtime support
Quoted 48 lines · Tarun Kanti DebBarma
Add
pm_runtimefeature to dmtimer whereby_get_sync()is called withinomap_dm_timer_enable(),_put_sync()is called inomap_dm_timer_disable().Signed-off-by Tarun Kanti DebBarma<[email protected]>[p-basak2 at ti.com: added pm_runtime logic in probe()]Signed-off-by Partha Basak<[email protected]>Reviewed-by Varadarajan, Charulatha<[email protected]>Acked-by Cousson, Benoit<[email protected]>--- arch/arm/plat-omap/dmtimer.c | 31 +++++++--------------------- arch/arm/plat-omap/include/plat/dmtimer.h | 1 - 2 files changed, 8 insertions(+), 24 deletions(-)arch/arm/plat-omap/dmtimer.c +2
-13@@ -38,6 +38,7 @@#include <linux/io.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/pm_runtime.h> #include <plat/dmtimer.h> @@ -193,33 +194,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free);void omap_dm_timer_enable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; - -if (timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_enable (timer->fclk); -clk_enable (timer->iclk); - } - - timer->enabled =1 ; +pm_runtime_get_sync (&timer->pdev->dev); }EXPORT_SYMBOL_GPL (omap_dm_timer_enable);void omap_dm_timer_disable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; -
arch/arm/plat-omap/dmtimer.c EXPORT_SYMBOL_GPL(omap_dm_timer_free); · line 203
Quoted 10 lines
arch/arm/plat-omap/dmtimer.c +1
-9-if (!timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_disable (timer->iclk); -clk_disable (timer->fclk); - } - - timer->enabled =0 ; +pm_runtime_put_sync (&timer->pdev->dev);
Better to use pm_runtime_put_sync_suspend() to make it irq safe.
Quoted 13 lines
arch/arm/plat-omap/dmtimer.c +1
-1}EXPORT_SYMBOL_GPL (omap_dm_timer_disable);@@ -461,7 +442,7 @@ int omap_dm_timers_active(void)struct omap_dm_timer *timer;list_for_each_entry (timer,&omap_timer_list, node) { -if (!timer->enabled) +if (!timer->reserved)continue ; if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG)&
arch/arm/plat-omap/dmtimer.c static int __devinit omap_dm_timer_probe(struct platform_device *pdev) · line 523
Quoted 7 lines
arch/arm/plat-omap/dmtimer.c +4
-0@@ -536,6 +517,10 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->pdev = pdev; +/* Skip pm_runtime_enable for OMAP1 */ +if (!pdata->needs_manual_reset) +pm_runtime_enable (&pdev->dev); +
Here too.
/s /pm_runtime_enable /pm_runtime_irq_safe
Quoted 8 lines
arch/arm/plat-omap/dmtimer.c +0
-0/* add the timer element to the list */ spin_lock_irqsave (&dm_timer_lock, flags);list_add_tail (&timer->node,&omap_timer_list);arch/arm/plat-omap/include/plat/dmtimer.h +0
-0
arch/arm/plat-omap/include/plat/dmtimer.h struct omap_dm_timer { · line 243
Quoted 7 lines
arch/arm/plat-omap/include/plat/dmtimer.h +0
-1@@ -238,7 +238,6 @@ struct omap_dm_timer {void __iomem *io_base;unsigned long rate; unsigned reserved:1; - unsigned enabled:1; unsigned posted:1;u8 func_offset;u8 intr_offset;
With above fixed, you can add,
Regards
Santosh
PATCH v14 7/12 OMAP: dmtimer: pm_runtime support
Quoted 45 lines · Santosh
Quoted 44 lines · Tarun Kanti DebBarma
Add
pm_runtimefeature to dmtimer whereby_get_sync()is called withinomap_dm_timer_enable(),_put_sync()is called inomap_dm_timer_disable().Signed-off-by Tarun Kanti DebBarma<[email protected]>[p-basak2 at ti.com: added pm_runtime logic in probe()]Signed-off-by Partha Basak<[email protected]>Reviewed-by Varadarajan, Charulatha<[email protected]>Acked-by Cousson, Benoit<[email protected]>--- arch/arm/plat-omap/dmtimer.c | 31 +++++++--------------------- arch/arm/plat-omap/include/plat/dmtimer.h | 1 - 2 files changed, 8 insertions(+), 24 deletions(-)arch/arm/plat-omap/dmtimer.c +2
-11@@ -38,6 +38,7 @@#include <linux/io.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/pm_runtime.h> #include <plat/dmtimer.h> @@ -193,33 +194,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free);void omap_dm_timer_enable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; - -if (timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_enable (timer->fclk); -clk_enable (timer->iclk); - } - - timer->enabled =1 ; +pm_runtime_get_sync (&timer->pdev->dev); }EXPORT_SYMBOL_GPL (omap_dm_timer_enable);
Quoted 16 lines
Quoted 4 lines
arch/arm/plat-omap/dmtimer.c +0
-2void omap_dm_timer_disable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; -arch/arm/plat-omap/dmtimer.c EXPORT_SYMBOL_GPL(omap_dm_timer_free); · line 203
Quoted 10 lines
arch/arm/plat-omap/dmtimer.c +1
-9-if (!timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_disable (timer->iclk); -clk_disable (timer->fclk); - } - - timer->enabled =0 ; +pm_runtime_put_sync (&timer->pdev->dev);Better to use
pm_runtime_put_sync_suspend()to make it irq safe.
Actually, better to just use the async version: pm_runtime_put()
Why does it need to be IRQ safe?
Quoted 16 lines
Quoted 16 lines
arch/arm/plat-omap/dmtimer.c +1
-1}EXPORT_SYMBOL_GPL (omap_dm_timer_disable);@@ -461,7 +442,7 @@ int omap_dm_timers_active(void)struct omap_dm_timer *timer;list_for_each_entry (timer,&omap_timer_list, node) { -if (!timer->enabled) +if (!timer->reserved)continue ; if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG)&@@ -536,6 +517,10 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->pdev = pdev;
Quoted 6 lines
arch/arm/plat-omap/dmtimer.c static int __devinit omap_dm_timer_probe(struct platform_device *pdev) · line 523
Quoted 4 lines
arch/arm/plat-omap/dmtimer.c +4
-0+/* Skip pm_runtime_enable for OMAP1 */ +if (!pdata->needs_manual_reset) +pm_runtime_enable (&pdev->dev); +Here too.
/s /pm_runtime_enable /pm_runtime_irq_safe
I think you mean adding _irq_safe, not removing the _enable?
I disagree with the IRQ-safe part. Let's avoid using IRQ-safe unless *really* needed, and justified.
Kevin
Quoted 21 lines
Quoted 8 lines
arch/arm/plat-omap/dmtimer.c +0
-0/* add the timer element to the list */ spin_lock_irqsave (&dm_timer_lock, flags);list_add_tail (&timer->node,&omap_timer_list);arch/arm/plat-omap/include/plat/dmtimer.h +0
-0arch/arm/plat-omap/include/plat/dmtimer.h struct omap_dm_timer { · line 243
Quoted 7 lines
arch/arm/plat-omap/include/plat/dmtimer.h +0
-1@@ -238,7 +238,6 @@ struct omap_dm_timer {void __iomem *io_base;unsigned long rate; unsigned reserved:1; - unsigned enabled:1; unsigned posted:1;u8 func_offset;u8 intr_offset;With above fixed, you can add,
Reviewed-by Santosh Shilimkar <[email protected]>Regards
Santosh
PATCH v14 7/12 OMAP: dmtimer: pm_runtime support
Quoted 91 lines · Kevin Hilman
Quoted 45 lines · Santosh
Quoted 44 lines · Tarun Kanti DebBarma
Add
pm_runtimefeature to dmtimer whereby_get_sync()is called withinomap_dm_timer_enable(),_put_sync()is called inomap_dm_timer_disable().Signed-off-by Tarun Kanti DebBarma<[email protected]>[p-basak2 at ti.com: added pm_runtime logic in probe()]Signed-off-by Partha Basak<[email protected]>Reviewed-by Varadarajan, Charulatha<[email protected]>Acked-by Cousson, Benoit<[email protected]>--- arch/arm/plat-omap/dmtimer.c | 31 +++++++--------------------- arch/arm/plat-omap/include/plat/dmtimer.h | 1 - 2 files changed, 8 insertions(+), 24 deletions(-)arch/arm/plat-omap/dmtimer.c +2
-11@@ -38,6 +38,7 @@#include <linux/io.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/pm_runtime.h> #include <plat/dmtimer.h> @@ -193,33 +194,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free);void omap_dm_timer_enable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; - -if (timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_enable (timer->fclk); -clk_enable (timer->iclk); - } - - timer->enabled =1 ; +pm_runtime_get_sync (&timer->pdev->dev); }EXPORT_SYMBOL_GPL (omap_dm_timer_enable);Quoted 16 lines
Quoted 4 lines
arch/arm/plat-omap/dmtimer.c +0
-2void omap_dm_timer_disable (struct omap_dm_timer *timer) { -struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data; -arch/arm/plat-omap/dmtimer.c EXPORT_SYMBOL_GPL(omap_dm_timer_free); · line 203
Quoted 10 lines
arch/arm/plat-omap/dmtimer.c +1
-9-if (!timer->enabled) -return ; - -if (!pdata->needs_manual_reset) { -clk_disable (timer->iclk); -clk_disable (timer->fclk); - } - - timer->enabled =0 ; +pm_runtime_put_sync (&timer->pdev->dev);Better to use
pm_runtime_put_sync_suspend()to make it irq safe.Actually, better to just use the async version:
pm_runtime_put()Why does it need to be IRQ safe?
Quoted 16 lines
Quoted 16 lines
arch/arm/plat-omap/dmtimer.c +1
-1}EXPORT_SYMBOL_GPL (omap_dm_timer_disable);@@ -461,7 +442,7 @@ int omap_dm_timers_active(void)struct omap_dm_timer *timer;list_for_each_entry (timer,&omap_timer_list, node) { -if (!timer->enabled) +if (!timer->reserved)continue ; if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG)&@@ -536,6 +517,10 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->pdev = pdev;Quoted 6 lines
arch/arm/plat-omap/dmtimer.c static int __devinit omap_dm_timer_probe(struct platform_device *pdev) · line 523
Quoted 4 lines
arch/arm/plat-omap/dmtimer.c +4
-0+/* Skip pm_runtime_enable for OMAP1 */ +if (!pdata->needs_manual_reset) +pm_runtime_enable (&pdev->dev); +Here too.
/s /pm_runtime_enable /pm_runtime_irq_safe
Quoted 5 lines
I think you mean adding
_irq_safe, not removing the_enable?I disagree with the IRQ-safe part. Let's avoid using IRQ-safe unless *really* needed, and justified.
The reason may not be satisfactory, bust some the client drivers are calling the timer APIs from IRQ context that created regressions on internal trees. That's was the only reason behind my comment.
On other hand, none of this client drivers are supported in mainline, so my comment from mainline point of is void.
Regards
Santosh
PATCH v14 8/12 OMAP: dmtimer: add timeout to low-level routines
In reply to Tarun Kanti DebBarmaThe low-level read and write access routines wait on write-pending register in posted mode to make sure that previous write is complete on respective registers. This waiting is done in an infinite while loop. Now it is being modified to use timeout instead.
--- arch/arm/plat-omap/include/plat/dmtimer.h | 34 ++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 10 deletions(-)
arch/arm/plat-omap/include/plat/dmtimer.h +24 -10
@@ -36,6 +36,8 @@#include <linux/delay.h> #include <linux/platform_device.h> +#include <plat/common.h> +#ifndef __ASM_ARCH_DMTIMER_H#define __ASM_ARCH_DMTIMER_H
@@ -230,6 +232,8 @@ int omap_dm_timers_active(void);#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) +#define MAX_WRITE_PEND_WAIT 10000/* 10ms timeout delay */ +struct omap_dm_timer {unsigned long phys_base;int id;
@@ -251,11 +255,16 @@ void omap_dm_timer_prepare(struct omap_dm_timer *timer);static inline u32 __omap_dm_timer_read (void __iomem *base,u32 reg,int posted,u8 func_offset) { -if (posted) -while (__raw_readl (base + - ((OMAP_TIMER_WRITE_PEND_REG + func_offset) &0xff )) - & (reg >>WPSHIFT )) -cpu_relax (); +int i =0 ; + +if (posted) { +omap_test_timeout (!(__raw_readl (base + + ((OMAP_TIMER_WRITE_PEND_REG + func_offset) &0xff )) & + (reg >>WPSHIFT )),MAX_WRITE_PEND_WAIT , i); + +if (WARN_ON_ONCE (i ==MAX_WRITE_PEND_WAIT )) +pr_err ("read timeout.\n" ); + }return __raw_readl (base + (reg &0xff )); }
@@ -263,11 +272,16 @@ static inline u32 __omap_dm_timer_read(void __iomem *base, u32 reg,static inline void __omap_dm_timer_write (void __iomem *base,u32 reg,u32 val,int posted,u8 func_offset) { -if (posted) -while (__raw_readl (base + - ((OMAP_TIMER_WRITE_PEND_REG + func_offset) &0xff )) - & (reg >>WPSHIFT )) -cpu_relax (); +int i =0 ; + +if (posted) { +omap_test_timeout (!(__raw_readl (base + + ((OMAP_TIMER_WRITE_PEND_REG + func_offset) &0xff )) & + (reg >>WPSHIFT )),MAX_WRITE_PEND_WAIT , i); + +if (WARN_ON (i ==MAX_WRITE_PEND_WAIT )) +pr_err ("write timeout.\n" ); + }__raw_writel (val, base + (reg &0xff )); }
Signature · 1 line
1.6.0.4
PATCH v14 8/12 OMAP: dmtimer: add timeout to low-level routines
Quoted 26 lines · Tarun Kanti DebBarma
The low-level read and write access routines wait on write-pending register in posted mode to make sure that previous write is complete on respective registers. This waiting is done in an infinite while loop. Now it is being modified to use timeout instead.
Signed-off-by Tarun Kanti DebBarma<[email protected]>Reviewed-by Varadarajan, Charulatha<[email protected]>Acked-by Cousson, Benoit<[email protected]>--- arch/arm/plat-omap/include/plat/dmtimer.h | 34 ++++++++++++++++++++-------- 1 files changed, 24 insertions(+), 10 deletions(-)arch/arm/plat-omap/include/plat/dmtimer.h +2
-0@@ -36,6 +36,8 @@#include <linux/delay.h> #include <linux/platform_device.h> +#include <plat/common.h> +#ifndef __ASM_ARCH_DMTIMER_H#define __ASM_ARCH_DMTIMER_H
arch/arm/plat-omap/include/plat/dmtimer.h int omap_dm_timers_active(void); · line 235
Quoted 4 lines
arch/arm/plat-omap/include/plat/dmtimer.h +1
-0@@ -230,6 +232,8 @@ int omap_dm_timers_active(void);#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR<< WPSHIFT)) +#define MAX_WRITE_PEND_WAIT 10000/* 10ms timeout delay */
Minor comment.
Space out the comment with the tab or put it up.
Regards
Santosh
PATCH v14 9/12 OMAP: dmtimer: use mutex instead of spinlock
In reply to Tarun Kanti DebBarmaSince the spinlock is not used in any interrupt context we can replace it with mutex instead.
--- arch/arm/plat-omap/dmtimer.c | 27 +++++++++++---------------- 1 files changed, 11 insertions(+), 16 deletions(-)
arch/arm/plat-omap/dmtimer.c +11 -16
@@ -43,7 +43,7 @@#include <plat/dmtimer.h> static LIST_HEAD (omap_timer_list); -static DEFINE_SPINLOCK (dm_timer_lock); +static DEFINE_MUTEX (dm_timer_mutex);/** * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
@@ -136,9 +136,8 @@ void omap_dm_timer_prepare(struct omap_dm_timer *timer)struct omap_dm_timer *omap_dm_timer_request (void ) {struct omap_dm_timer *timer =NULL , *t; -unsigned long flags; -spin_lock_irqsave (&dm_timer_lock, flags); +mutex_lock (&dm_timer_mutex);list_for_each_entry (t, &omap_timer_list, node) {if (t->reserved)continue ;
@@ -147,7 +146,7 @@ struct omap_dm_timer *omap_dm_timer_request(void) timer->reserved =1 ;break ; } -spin_unlock_irqrestore (&dm_timer_lock, flags); +mutex_unlock (&dm_timer_mutex);if (timer)omap_dm_timer_prepare (timer);
@@ -161,9 +160,8 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request);struct omap_dm_timer *omap_dm_timer_request_specific (int id) {struct omap_dm_timer *timer =NULL , *t; -unsigned long flags; -spin_lock_irqsave (&dm_timer_lock, flags); +mutex_lock (&dm_timer_mutex);list_for_each_entry (t, &omap_timer_list, node) {if (t->pdev->id == id && !t->reserved) { timer = t;
@@ -171,7 +169,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)break ; } } -spin_unlock_irqrestore (&dm_timer_lock, flags); +mutex_unlock (&dm_timer_mutex);if (timer)omap_dm_timer_prepare (timer);
@@ -220,14 +218,13 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) {int i =0 ;struct omap_dm_timer *timer =NULL ; -unsigned long flags;/* If ARMXOR cannot be idled this function call is unnecessary */ if (!(inputmask & (1 <<1 )))return inputmask;/* If any active timer is using ARMXOR return modified mask */ -spin_lock_irqsave (&dm_timer_lock, flags); +mutex_lock (&dm_timer_mutex);list_for_each_entry (timer, &omap_timer_list, node) {u32 l;
@@ -240,7 +237,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) } i++; } -spin_unlock_irqrestore (&dm_timer_lock, flags); +mutex_unlock (&dm_timer_mutex);return inputmask; }
@@ -464,7 +461,6 @@ EXPORT_SYMBOL_GPL(omap_dm_timers_active);static int __devinit omap_dm_timer_probe (struct platform_device *pdev) {int ret; -unsigned long flags;struct omap_dm_timer *timer;struct resource *mem, *irq, *ioarea;struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
@@ -522,9 +518,9 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)pm_runtime_enable (&pdev->dev);/* add the timer element to the list */ -spin_lock_irqsave (&dm_timer_lock, flags); +mutex_lock (&dm_timer_mutex);list_add_tail (&timer->node, &omap_timer_list); -spin_unlock_irqrestore (&dm_timer_lock, flags); +mutex_unlock (&dm_timer_mutex);dev_dbg (&pdev->dev,"Device Probed.\n" );
@@ -550,10 +546,9 @@ err_free_ioregion: static int __devexit omap_dm_timer_remove(struct platform_device *pdev) {struct omap_dm_timer *timer; -unsigned long flags;int ret = -EINVAL ; -spin_lock_irqsave (&dm_timer_lock, flags); +mutex_lock (&dm_timer_mutex);list_for_each_entry (timer, &omap_timer_list, node)if (timer->pdev->id == pdev->id) {list_del (&timer->node);
@@ -561,7 +556,7 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev) ret =0 ;break ; } -spin_unlock_irqrestore (&dm_timer_lock, flags); +mutex_unlock (&dm_timer_mutex);return ret; }
Signature · 1 line
1.6.0.4
PATCH v14 9/12 OMAP: dmtimer: use mutex instead of spinlock
Quoted 5 lines · Tarun Kanti DebBarma
Since the spinlock is not used in any interrupt context we can replace it with mutex instead.
Signed-off-by Tarun Kanti DebBarma<[email protected]>---
Patch looks good but change log doesn't reflect it. Do you want to say that below API's are not used from interrupt context, so mutex should be good enough ?
Regards
Santosh
PATCH v14 9/12 OMAP: dmtimer: use mutex instead of spinlock
Quoted 10 lines · Santosh
Quoted 5 lines · Tarun Kanti DebBarma
Since the spinlock is not used in any interrupt context we can replace it with mutex instead.
Signed-off-by Tarun Kanti DebBarma<[email protected]>---
Patch looks good but change log doesn't reflect it. Do you want to say that below API's are not used from interrupt context, so mutex should be good enough ?
This assumption is really not true. Time APIs can get called from IRQ context from client drivers. You can just drop this patch.
Regards
Santosh
PATCH v14 10/12 OMAP: dmtimer: mark clocksource and clockevent timers reserved
In reply to Tarun Kanti DebBarmaIn driver probe use sys_timer_reserved to identify which all timers have already been used for clocksource and clockevent. Mark all those timers as reserved so that no one else can use them.
--- arch/arm/mach-omap1/timer.c | 2 ++ arch/arm/plat-omap/dmtimer.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/arm/mach-omap1/timer.c +2 -0
@@ -41,6 +41,8 @@#define OMAP1_DM_TIMER_COUNT 8 +u32 sys_timer_reserved; +static int omap1_dm_timer_set_src (struct platform_device *pdev,int source) {
arch/arm/plat-omap/dmtimer.c +6 -2
@@ -513,10 +513,14 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->pdev = pdev; -/* Skip pm_runtime_enable for OMAP1 */ -if (!pdata->needs_manual_reset) +if (!pdata->needs_manual_reset) {pm_runtime_enable (&pdev->dev); +/* Mark clocksource and clockevent timers as reserved */ +if ((sys_timer_reserved >> (pdev->id -1 )) &0x1 ) + timer->reserved =1 ; + } +/* add the timer element to the list */ mutex_lock (&dm_timer_mutex);list_add_tail (&timer->node, &omap_timer_list);
Signature · 1 line
1.6.0.4
PATCH v14 10/12 OMAP: dmtimer: mark clocksource and clockevent timers reserved
Quoted 6 lines · Tarun Kanti DebBarma
In driver probe use
sys_timer_reservedto identify which all timers have already been used for clocksource and clockevent. Mark all those timers as reserved so that no one else can use them.Signed-off-by Tarun Kanti DebBarma<[email protected]>---
Looks fine.
Regards
Santosh
PATCH v14 11/12 OMAP: dmtimer: add context save/restore routines
In reply to Tarun Kanti DebBarmaDefine context register structure and make it member of struct omap_dm_timer. Also define two routines to save and restore dmtimer context to be used subsequently.
--- arch/arm/plat-omap/dmtimer.c | 48 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/dmtimer.h | 24 ++++++++++++++ 2 files changed, 72 insertions(+), 0 deletions(-)
arch/arm/plat-omap/dmtimer.c +48 -0
@@ -87,6 +87,54 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, timer->func_offset); } +static void omap_timer_save_context (struct omap_dm_timer *timer) +{ + timer->context.tiocp_cfg = +omap_dm_timer_read_reg (timer,OMAP_TIMER_OCP_CFG_REG ); + timer->context.tistat = +omap_dm_timer_read_reg (timer,OMAP_TIMER_SYS_STAT_REG ); + timer->context.tisr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_STAT_REG ); + timer->context.tier = +omap_dm_timer_read_reg (timer,OMAP_TIMER_INT_EN_REG ); + timer->context.twer = +omap_dm_timer_read_reg (timer,OMAP_TIMER_WAKEUP_EN_REG ); + timer->context.tclr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_CTRL_REG ); + timer->context.tcrr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_COUNTER_REG ); + timer->context.tldr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_LOAD_REG ); + timer->context.tmar = +omap_dm_timer_read_reg (timer,OMAP_TIMER_MATCH_REG ); + timer->context.tsicr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_IF_CTRL_REG ); +} + +static void omap_timer_restore_context (struct omap_dm_timer *timer) +{ +omap_dm_timer_write_reg (timer,OMAP_TIMER_OCP_CFG_REG , + timer->context.tiocp_cfg); +omap_dm_timer_write_reg (timer,OMAP_TIMER_SYS_STAT_REG , + timer->context.tistat); +omap_dm_timer_write_reg (timer,OMAP_TIMER_STAT_REG , + timer->context.tisr); +omap_dm_timer_write_reg (timer,OMAP_TIMER_INT_EN_REG , + timer->context.tier); +omap_dm_timer_write_reg (timer,OMAP_TIMER_WAKEUP_EN_REG , + timer->context.twer); +omap_dm_timer_write_reg (timer,OMAP_TIMER_CTRL_REG , + timer->context.tclr); +omap_dm_timer_write_reg (timer,OMAP_TIMER_COUNTER_REG , + timer->context.tcrr); +omap_dm_timer_write_reg (timer,OMAP_TIMER_LOAD_REG , + timer->context.tldr); +omap_dm_timer_write_reg (timer,OMAP_TIMER_MATCH_REG , + timer->context.tmar); +omap_dm_timer_write_reg (timer,OMAP_TIMER_IF_CTRL_REG , + timer->context.tsicr); +} +static void omap_dm_timer_wait_for_reset (struct omap_dm_timer *timer) {int c;
arch/arm/plat-omap/include/plat/dmtimer.h +24 -0
@@ -234,6 +234,29 @@ int omap_dm_timers_active(void);#define MAX_WRITE_PEND_WAIT 10000/* 10ms timeout delay */ +struct timer_regs { +u32 tidr; +u32 tiocp_cfg; +u32 tistat; +u32 tisr; +u32 tier; +u32 twer; +u32 tclr; +u32 tcrr; +u32 tldr; +u32 ttrg; +u32 twps; +u32 tmar; +u32 tcar1; +u32 tsicr; +u32 tcar2; +u32 tpir; +u32 tnir; +u32 tcvr; +u32 tocr; +u32 towr; +}; +struct omap_dm_timer {unsigned long phys_base;int id;
@@ -245,6 +268,7 @@ struct omap_dm_timer { unsigned posted:1;u8 func_offset;u8 intr_offset; +struct timer_regs context;struct platform_device *pdev;struct list_head node; };
Signature · 1 line
1.6.0.4
PATCH v14 11/12 OMAP: dmtimer: add context save/restore routines
Quoted 56 lines · Tarun Kanti DebBarma
Define context register structure and make it member of struct
omap_dm_timer. Also define two routines to save and restore dmtimer context to be used subsequently.Signed-off-by Tarun Kanti DebBarma<[email protected]>--- arch/arm/plat-omap/dmtimer.c | 48 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/dmtimer.h | 24 ++++++++++++++ 2 files changed, 72 insertions(+), 0 deletions(-)arch/arm/plat-omap/dmtimer.c +38
-0@@ -87,6 +87,54 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, timer->func_offset); } +static void omap_timer_save_context (struct omap_dm_timer *timer) +{ + timer->context.tiocp_cfg = +omap_dm_timer_read_reg (timer,OMAP_TIMER_OCP_CFG_REG ); + timer->context.tistat = +omap_dm_timer_read_reg (timer,OMAP_TIMER_SYS_STAT_REG ); + timer->context.tisr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_STAT_REG ); + timer->context.tier = +omap_dm_timer_read_reg (timer,OMAP_TIMER_INT_EN_REG ); + timer->context.twer = +omap_dm_timer_read_reg (timer,OMAP_TIMER_WAKEUP_EN_REG ); + timer->context.tclr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_CTRL_REG ); + timer->context.tcrr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_COUNTER_REG ); + timer->context.tldr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_LOAD_REG ); + timer->context.tmar = +omap_dm_timer_read_reg (timer,OMAP_TIMER_MATCH_REG ); + timer->context.tsicr = +omap_dm_timer_read_reg (timer,OMAP_TIMER_IF_CTRL_REG ); +} + +static void omap_timer_restore_context (struct omap_dm_timer *timer) +{ +omap_dm_timer_write_reg (timer,OMAP_TIMER_OCP_CFG_REG , + timer->context.tiocp_cfg); +omap_dm_timer_write_reg (timer,OMAP_TIMER_SYS_STAT_REG , + timer->context.tistat); +omap_dm_timer_write_reg (timer,OMAP_TIMER_STAT_REG , + timer->context.tisr); +omap_dm_timer_write_reg (timer,OMAP_TIMER_INT_EN_REG , + timer->context.tier); +omap_dm_timer_write_reg (timer,OMAP_TIMER_WAKEUP_EN_REG , + timer->context.twer); +omap_dm_timer_write_reg (timer,OMAP_TIMER_CTRL_REG , + timer->context.tclr);
arch/arm/plat-omap/dmtimer.c static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, · line 137
Quoted 10 lines
arch/arm/plat-omap/dmtimer.c +10
-0+omap_dm_timer_write_reg (timer,OMAP_TIMER_COUNTER_REG , + timer->context.tcrr); +omap_dm_timer_write_reg (timer,OMAP_TIMER_LOAD_REG , + timer->context.tldr); +omap_dm_timer_write_reg (timer,OMAP_TIMER_MATCH_REG , + timer->context.tmar); +omap_dm_timer_write_reg (timer,OMAP_TIMER_IF_CTRL_REG , + timer->context.tsicr); +} +
Looks good.
Take care of ordering of the restore code similar to GPIO code.
Regards
Santosh
PATCH v14 12/12 OMAP: dmtimer: Off mode support
In reply to Tarun Kanti DebBarmaClock is enabled only when timer is started and disabled when the the timer is stopped. Therefore before accessing registers in functions clock is enabled and then disabled back at the end of access.
Context save and restore functions are called as needed based upon whether the context is lost or not.
--- arch/arm/mach-omap2/timer.c | 17 +++++ arch/arm/plat-omap/dmtimer.c | 97 +++++++++++++++++++++++++++-- arch/arm/plat-omap/include/plat/dmtimer.h | 9 +++ 3 files changed, 118 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/timer.c +17 -0
@@ -44,6 +44,9 @@#include <plat/common.h> #include <plat/omap_hwmod.h> #include <plat/omap_device.h> +#include <plat/omap-pm.h> + +#include "powerdomain.h" /* Parent clocks, eventually these will come from the clock framework */
@@ -409,6 +412,16 @@ static int omap2_dm_timer_set_src(struct platform_device *pdev, int source)return ret; } +#ifdef CONFIG_PM +static int omap_timer_get_context_loss (struct device *dev) +{ +return omap_pm_get_dev_context_loss_count (dev); +} + +#else +#define omap_gpio_get_context_loss NULL +#endif +struct omap_device_pm_latency omap2_dmtimer_latency[] = { { .deactivate_func = omap_device_idle_hwmods,
@@ -437,6 +450,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)struct dmtimer_platform_data *pdata;struct omap_device *od;struct omap_timer_capability_dev_attr *timer_dev_attr; +struct powerdomain *pwrdm;pr_debug ("%s: %s\n" , __func__, oh->name);
@@ -466,6 +480,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) pdata->set_timer_src = omap2_dm_timer_set_src; pdata->timer_ip_type = oh->class->rev; + pwrdm =omap_hwmod_get_pwrdm (oh); + pdata->loses_context =pwrdm_can_ever_lose_context (pwrdm); + pdata->get_context_loss_count = omap_timer_get_context_loss; od = omap_device_build(name, id, oh, pdata, sizeof(*pdata), omap2_dmtimer_latency,
arch/arm/plat-omap/dmtimer.c +92 -5
250 lines not on this page · raw message
arch/arm/plat-omap/include/plat/dmtimer.h +9 -0
@@ -85,6 +85,9 @@ struct dmtimer_platform_data {int (*set_timer_src)(struct platform_device *pdev,int source);int timer_ip_type; u32 needs_manual_reset:1; +bool loses_context; + +int (*get_context_loss_count)(struct device *dev); };struct omap_dm_timer *omap_dm_timer_request (void );
@@ -269,8 +272,14 @@ struct omap_dm_timer {u8 func_offset;u8 intr_offset;struct timer_regs context; +bool loses_context; +bool context_saved; +bool context_changed; +int ctx_loss_count;struct platform_device *pdev;struct list_head node; + +int (*get_context_loss_count)(struct device *dev); };extern u32 sys_timer_reserved;
Signature · 1 line
1.6.0.4
PATCH v14 12/12 OMAP: dmtimer: Off mode support
Quoted 84 lines · Tarun Kanti DebBarma
Clock is enabled only when timer is started and disabled when the the timer is stopped. Therefore before accessing registers in functions clock is enabled and then disabled back at the end of access.
Context save and restore functions are called as needed based upon whether the context is lost or not.Signed-off-by Tarun Kanti DebBarma<[email protected]>--- arch/arm/mach-omap2/timer.c | 17 +++++ arch/arm/plat-omap/dmtimer.c | 97 +++++++++++++++++++++++++++-- arch/arm/plat-omap/include/plat/dmtimer.h | 9 +++ 3 files changed, 118 insertions(+), 5 deletions(-)arch/arm/mach-omap2/timer.c +17
-0@@ -44,6 +44,9 @@#include <plat/common.h> #include <plat/omap_hwmod.h> #include <plat/omap_device.h> +#include <plat/omap-pm.h> + +#include "powerdomain.h" /* Parent clocks, eventually these will come from the clock framework */ @@ -409,6 +412,16 @@ static int omap2_dm_timer_set_src(struct platform_device *pdev, int source)return ret; } +#ifdef CONFIG_PM +static int omap_timer_get_context_loss (struct device *dev) +{ +return omap_pm_get_dev_context_loss_count (dev); +} + +#else +#define omap_gpio_get_context_loss NULL +#endif +struct omap_device_pm_latency omap2_dmtimer_latency[] = { { .deactivate_func = omap_device_idle_hwmods,@@ -437,6 +450,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)struct dmtimer_platform_data *pdata;struct omap_device *od;struct omap_timer_capability_dev_attr *timer_dev_attr; +struct powerdomain *pwrdm;pr_debug ("%s: %s\n" , __func__, oh->name);@@ -466,6 +480,9 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) pdata->set_timer_src = omap2_dm_timer_set_src; pdata->timer_ip_type = oh->class->rev; + pwrdm =omap_hwmod_get_pwrdm (oh); + pdata->loses_context =pwrdm_can_ever_lose_context (pwrdm); + pdata->get_context_loss_count = omap_timer_get_context_loss; od = omap_device_build(name, id, oh, pdata, sizeof(*pdata), omap2_dmtimer_latency,arch/arm/plat-omap/dmtimer.c +2
-0@@ -151,12 +151,14 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)static void omap_dm_timer_reset (struct omap_dm_timer *timer) { +omap_dm_timer_enable (timer);if (timer->pdev->id !=1 ) {omap_dm_timer_write_reg (timer,OMAP_TIMER_IF_CTRL_REG ,0x06 );omap_dm_timer_wait_for_reset (timer); }__omap_dm_timer_reset (timer->io_base,0 ,0 , timer->func_offset); +omap_dm_timer_disable (timer); timer->posted =1 ; }@@ -171,14 +173,13 @@ void omap_dm_timer_prepare(struct omap_dm_timer *timer)return ; }
arch/arm/plat-omap/dmtimer.c void omap_dm_timer_prepare(struct omap_dm_timer *timer) · line 182
Quoted 10 lines
arch/arm/plat-omap/dmtimer.c +1
-2-omap_dm_timer_enable (timer); -if (pdata->needs_manual_reset)omap_dm_timer_reset (timer);omap_dm_timer_set_source (timer,OMAP_TIMER_SRC_32_KHZ ); timer->posted =1 ; + timer->context_changed = true;
You should protect these variables from races.
Quoted 28 lines
arch/arm/plat-omap/dmtimer.c +6
-1}struct omap_dm_timer *omap_dm_timer_request (void )@@ -230,7 +231,6 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);void omap_dm_timer_free (struct omap_dm_timer *timer) { -omap_dm_timer_disable (timer);clk_put (timer->fclk);WARN_ON (!timer->reserved);@@ -311,6 +311,11 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);void omap_dm_timer_trigger (struct omap_dm_timer *timer) { +if (unlikely (!timer->reserved)) { +pr_err ("%s: timer%d not enabled.\n" , __func__, timer->id); +return ; + } +omap_dm_timer_write_reg (timer,OMAP_TIMER_TRIGGER_REG ,0 ); }EXPORT_SYMBOL_GPL (omap_dm_timer_trigger);@@ -319,6 +324,20 @@ void omap_dm_timer_start(struct omap_dm_timer *timer) {u32 l; +omap_dm_timer_enable (timer);
arch/arm/plat-omap/dmtimer.c void omap_dm_timer_start(struct omap_dm_timer *timer) · line 337
Quoted 10 lines
arch/arm/plat-omap/dmtimer.c +10
-0+ +if (timer->loses_context) { +u32 ctx_loss_cnt_after; + + ctx_loss_cnt_after = + timer->get_context_loss_count (&timer->pdev->dev); +if ((ctx_loss_cnt_after != timer->ctx_loss_count)&& + timer->context_saved) { +omap_timer_restore_context (timer); + timer->context_saved = false;
Ditto. It applies to rest of the patch.
Rest look ok.
Regards
Santosh