linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v12 0/9] dmtimer adaptation to platform_driver
@ 2011-03-08 23:45 Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 1/9] OMAP2+: dmtimer: add device names to flck nodes Tarun Kanti DebBarma
                   ` (8 more replies)
  0 siblings, 9 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Tarun Kanti DebBarma

dmtimer adaptation to platform_driver.

This patch series is adaptation of dmtimer code to platform driver
using omap_device and omap_hwmod abstraction.

Baseline:
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
Branch: omap-for-linus

Test Info:
* OMAP3, OMAP4 testing: Functional tests done.
* OMAP2 testing: I have to merge to omap-testing branch and test again.
* OMAP1 testing: In progress. I am seeing some build issue with omap1_defconfig:
In file included from arch/arm/mm/init.c:27:
/home/working/linux-omap-2.6/arch/arm/include/asm/tlb.h: In function 'tlb_flush_mmu':
/home/working/linux-omap-2.6/arch/arm/include/asm/tlb.h:104: error: implicit declaration of function 'release_pages'
/home/working/linux-omap-2.6/arch/arm/include/asm/tlb.h: In function 'tlb_remove_page':
/home/working/linux-omap-2.6/arch/arm/include/asm/tlb.h:168: error: implicit declaration of function 'page_cache_release'
make[1]: *** [arch/arm/mm/init.o] Error 1
make: *** [arch/arm/mm] Error 2


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.

TODO:
Somehow pm_runtime_suspended() does not seem to be working as expected
when used in omap_dm_timer_enable() and omap_dm_timer_disable().
Because of this the 'enabled' flag could not be eliminated.


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 (7):
  OMAP4: hwmod data: add dmtimer version information
  OMAP2+: dmtimer: convert to platform devices
  OMAP: dmtimer: platform driver
  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

Thara Gopinath (2):
  OMAP2+: dmtimer: add device names to flck nodes
  OMAP1: dmtimer: conversion to platform devices

 arch/arm/mach-omap1/Makefile               |    2 +-
 arch/arm/mach-omap1/dmtimer.c              |  179 +++++++++
 arch/arm/mach-omap1/timer32k.c             |    4 -
 arch/arm/mach-omap2/Makefile               |    2 +-
 arch/arm/mach-omap2/clock2420_data.c       |   60 +++-
 arch/arm/mach-omap2/clock2430_data.c       |   60 +++-
 arch/arm/mach-omap2/clock3xxx_data.c       |   48 ++-
 arch/arm/mach-omap2/clock44xx_data.c       |   44 ++-
 arch/arm/mach-omap2/dmtimer.c              |  273 +++++++++++++
 arch/arm/mach-omap2/dmtimer.h              |   32 ++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    8 +
 arch/arm/mach-omap2/timer-gp.c             |   12 +-
 arch/arm/plat-omap/dmtimer.c               |  574 ++++++++++++++--------------
 arch/arm/plat-omap/include/plat/dmtimer.h  |   30 ++-
 14 files changed, 975 insertions(+), 353 deletions(-)
 create mode 100644 arch/arm/mach-omap1/dmtimer.c
 create mode 100755 arch/arm/mach-omap2/dmtimer.c
 create mode 100755 arch/arm/mach-omap2/dmtimer.h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v12 1/9] OMAP2+: dmtimer: add device names to flck nodes
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 2/9] OMAP4: hwmod data: add dmtimer version information Tarun Kanti DebBarma
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Thara Gopinath

From: Thara Gopinath <thara@ti.com>

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.

NOTE: gpt1_fck is modified in patch-10 when we switch to platform device
driver. This is to make sure that each patch compiles and boots.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com
Signed-off-by: Thara Gopinath <thara@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
---
 arch/arm/mach-omap2/clock2420_data.c |   58 +++++++++++++++++++++++++++------
 arch/arm/mach-omap2/clock2430_data.c |   58 +++++++++++++++++++++++++++------
 arch/arm/mach-omap2/clock3xxx_data.c |   46 ++++++++++++++++++++------
 arch/arm/mach-omap2/clock44xx_data.c |   42 ++++++++++++++++++------
 4 files changed, 161 insertions(+), 43 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 0a992bc..ee93d3c 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1803,27 +1803,27 @@ static struct omap_clk omap2420_clks[] = {
 	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_242X),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_242X),
 	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_242X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_242X),
+	CLK("omap_timer.2",	"fck",	&gpt2_fck,	CK_242X),
 	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_242X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_242X),
+	CLK("omap_timer.3",	"fck",	&gpt3_fck,	CK_242X),
 	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_242X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_242X),
+	CLK("omap_timer.4",	"fck",	&gpt4_fck,	CK_242X),
 	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_242X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_242X),
+	CLK("omap_timer.5",	"fck",	&gpt5_fck,	CK_242X),
 	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_242X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_242X),
+	CLK("omap_timer.6",	"fck",	&gpt6_fck,	CK_242X),
 	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_242X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_242X),
+	CLK("omap_timer.7",	"fck",	&gpt7_fck,	CK_242X),
 	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_242X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_242X),
+	CLK("omap_timer.8",	"fck",	&gpt8_fck,	CK_242X),
 	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_242X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_242X),
+	CLK("omap_timer.9",	"fck",	&gpt9_fck,	CK_242X),
 	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_242X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_242X),
+	CLK("omap_timer.10",	"fck",	&gpt10_fck,	CK_242X),
 	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_242X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_242X),
+	CLK("omap_timer.11",	"fck",	&gpt11_fck,	CK_242X),
 	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_242X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_242X),
+	CLK("omap_timer.12",	"fck",	&gpt12_fck,	CK_242X),
 	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_242X),
 	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_242X),
 	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_242X),
@@ -1878,6 +1878,42 @@ 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",	"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),
 };
 
 /*
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 5c647ce..899a3f6 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1907,27 +1907,27 @@ static struct omap_clk omap2430_clks[] = {
 	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X),
 	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_243X),
+	CLK("omap_timer.2",	"fck",	&gpt2_fck,	CK_243X),
 	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_243X),
+	CLK("omap_timer.3",	"fck",	&gpt3_fck,	CK_243X),
 	CLK(NULL,	"gpt4_ick",	&gpt4_ick,	CK_243X),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_243X),
+	CLK("omap_timer.4",	"fck",	&gpt4_fck,	CK_243X),
 	CLK(NULL,	"gpt5_ick",	&gpt5_ick,	CK_243X),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_243X),
+	CLK("omap_timer.5",	"fck",	&gpt5_fck,	CK_243X),
 	CLK(NULL,	"gpt6_ick",	&gpt6_ick,	CK_243X),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_243X),
+	CLK("omap_timer.6",	"fck",	&gpt6_fck,	CK_243X),
 	CLK(NULL,	"gpt7_ick",	&gpt7_ick,	CK_243X),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_243X),
+	CLK("omap_timer.7",	"fck",	&gpt7_fck,	CK_243X),
 	CLK(NULL,	"gpt8_ick",	&gpt8_ick,	CK_243X),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_243X),
+	CLK("omap_timer.8",	"fck",	&gpt8_fck,	CK_243X),
 	CLK(NULL,	"gpt9_ick",	&gpt9_ick,	CK_243X),
-	CLK(NULL,	"gpt9_fck",	&gpt9_fck,	CK_243X),
+	CLK("omap_timer.9",	"fck",	&gpt9_fck,	CK_243X),
 	CLK(NULL,	"gpt10_ick",	&gpt10_ick,	CK_243X),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_243X),
+	CLK("omap_timer.10",	"fck",	&gpt10_fck,	CK_243X),
 	CLK(NULL,	"gpt11_ick",	&gpt11_ick,	CK_243X),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_243X),
+	CLK("omap_timer.11",	"fck",	&gpt11_fck,	CK_243X),
 	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_243X),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_243X),
+	CLK("omap_timer.12",	"fck",	&gpt12_fck,	CK_243X),
 	CLK("omap-mcbsp.1", "ick",	&mcbsp1_ick,	CK_243X),
 	CLK("omap-mcbsp.1", "fck",	&mcbsp1_fck,	CK_243X),
 	CLK("omap-mcbsp.2", "ick",	&mcbsp2_ick,	CK_243X),
@@ -1993,6 +1993,42 @@ static struct omap_clk omap2430_clks[] = {
 	CLK(NULL,	"mdm_intc_ick",	&mdm_intc_ick,	CK_243X),
 	CLK("omap_hsmmc.0", "mmchsdb_fck",	&mmchsdb1_fck,	CK_243X),
 	CLK("omap_hsmmc.1", "mmchsdb_fck",	&mmchsdb2_fck,	CK_243X),
+	CLK("omap_timer.1",	"32k_ck",  &func_32k_ck,   CK_243X),
+	CLK("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),
 };
 
 /*
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 052ac32..f84a649 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3281,8 +3281,8 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"modem_fck",	&modem_fck,	CK_34XX | CK_36XX),
 	CLK(NULL,	"sad2d_ick",	&sad2d_ick,	CK_34XX | CK_36XX),
 	CLK(NULL,	"mad2d_ick",	&mad2d_ick,	CK_34XX | CK_36XX),
-	CLK(NULL,	"gpt10_fck",	&gpt10_fck,	CK_3XXX),
-	CLK(NULL,	"gpt11_fck",	&gpt11_fck,	CK_3XXX),
+	CLK("omap_timer.10",	"fck",	&gpt10_fck,	CK_3XXX),
+	CLK("omap_timer.11",	"fck",	&gpt11_fck,	CK_3XXX),
 	CLK(NULL,	"cpefuse_fck",	&cpefuse_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"ts_fck",	&ts_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usbtll_fck",	&usbtll_fck,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
@@ -3393,14 +3393,14 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"per_48m_fck",	&per_48m_fck,	CK_3XXX),
 	CLK(NULL,	"uart3_fck",	&uart3_fck,	CK_3XXX),
 	CLK(NULL,	"uart4_fck",	&uart4_fck,	CK_36XX),
-	CLK(NULL,	"gpt2_fck",	&gpt2_fck,	CK_3XXX),
-	CLK(NULL,	"gpt3_fck",	&gpt3_fck,	CK_3XXX),
-	CLK(NULL,	"gpt4_fck",	&gpt4_fck,	CK_3XXX),
-	CLK(NULL,	"gpt5_fck",	&gpt5_fck,	CK_3XXX),
-	CLK(NULL,	"gpt6_fck",	&gpt6_fck,	CK_3XXX),
-	CLK(NULL,	"gpt7_fck",	&gpt7_fck,	CK_3XXX),
-	CLK(NULL,	"gpt8_fck",	&gpt8_fck,	CK_3XXX),
-	CLK(NULL,	"gpt9_fck",	&gpt9_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(NULL,	"per_32k_alwon_fck", &per_32k_alwon_fck, CK_3XXX),
 	CLK(NULL,	"gpio6_dbck",	&gpio6_dbck,	CK_3XXX),
 	CLK(NULL,	"gpio5_dbck",	&gpio5_dbck,	CK_3XXX),
@@ -3441,7 +3441,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"sr2_fck",	&sr2_fck,	CK_34XX | CK_36XX),
 	CLK(NULL,	"sr_l4_ick",	&sr_l4_ick,	CK_34XX | CK_36XX),
 	CLK(NULL,	"secure_32k_fck", &secure_32k_fck, CK_3XXX),
-	CLK(NULL,	"gpt12_fck",	&gpt12_fck,	CK_3XXX),
+	CLK("omap_timer.12",	"fck",	&gpt12_fck,	CK_3XXX),
 	CLK(NULL,	"wdt1_fck",	&wdt1_fck,	CK_3XXX),
 	CLK(NULL,	"ipss_ick",	&ipss_ick,	CK_AM35XX),
 	CLK(NULL,	"rmii_ck",	&rmii_ck,	CK_AM35XX),
@@ -3454,6 +3454,30 @@ 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",	"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),
 };
 
 
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index fdbc042..0a6d80c 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3182,16 +3182,16 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"smartreflex_iva_fck",		&smartreflex_iva_fck,	CK_443X),
 	CLK(NULL,	"smartreflex_mpu_fck",		&smartreflex_mpu_fck,	CK_443X),
 	CLK(NULL,	"gpt1_fck",			&timer1_fck,	CK_443X),
-	CLK(NULL,	"gpt10_fck",			&timer10_fck,	CK_443X),
-	CLK(NULL,	"gpt11_fck",			&timer11_fck,	CK_443X),
-	CLK(NULL,	"gpt2_fck",			&timer2_fck,	CK_443X),
-	CLK(NULL,	"gpt3_fck",			&timer3_fck,	CK_443X),
-	CLK(NULL,	"gpt4_fck",			&timer4_fck,	CK_443X),
-	CLK(NULL,	"gpt5_fck",			&timer5_fck,	CK_443X),
-	CLK(NULL,	"gpt6_fck",			&timer6_fck,	CK_443X),
-	CLK(NULL,	"gpt7_fck",			&timer7_fck,	CK_443X),
-	CLK(NULL,	"gpt8_fck",			&timer8_fck,	CK_443X),
-	CLK(NULL,	"gpt9_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.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(NULL,	"uart1_fck",			&uart1_fck,	CK_443X),
 	CLK(NULL,	"uart2_fck",			&uart2_fck,	CK_443X),
 	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X),
@@ -3275,6 +3275,28 @@ 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",	"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)
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 2/9] OMAP4: hwmod data: add dmtimer version information
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 1/9] OMAP2+: dmtimer: add device names to flck nodes Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 3/9] OMAP1: dmtimer: conversion to platform devices Tarun Kanti DebBarma
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Tarun Kanti DebBarma, Cousson, Benoit

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 <tarun.kanti@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
Cc: Cousson, Benoit <b-cousson@ti.com>
---
 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(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 7dbcdf7..9a34e20 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -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"
 
@@ -3956,6 +3957,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 = {
@@ -3971,6 +3973,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 */
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index d6c70d2..e3d477d 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -54,7 +54,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;
 extern struct omap_dm_timer *gptimer_wakeup;
 extern struct sys_timer omap_timer;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 3/9] OMAP1: dmtimer: conversion to platform devices
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 1/9] OMAP2+: dmtimer: add device names to flck nodes Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 2/9] OMAP4: hwmod data: add dmtimer version information Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 4/9] OMAP2+: dmtimer: convert " Tarun Kanti DebBarma
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Thara Gopinath, Tarun Kanti DebBarma

From: Thara Gopinath <thara@ti.com>

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 <thara@ti.com>
Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
---
 arch/arm/mach-omap1/Makefile              |    2 +-
 arch/arm/mach-omap1/dmtimer.c             |  179 +++++++++++++++++++++++++++++
 arch/arm/mach-omap1/timer32k.c            |    4 -
 arch/arm/plat-omap/dmtimer.c              |   64 ++---------
 arch/arm/plat-omap/include/plat/dmtimer.h |   19 +++-
 5 files changed, 206 insertions(+), 62 deletions(-)
 create mode 100644 arch/arm/mach-omap1/dmtimer.c

diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index af98117..a0ae35f 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -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
+obj-y += clock.o clock_data.o opp_data.o reset.o dmtimer.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
diff --git a/arch/arm/mach-omap1/dmtimer.c b/arch/arm/mach-omap1/dmtimer.c
new file mode 100644
index 0000000..dbc189c
--- /dev/null
+++ b/arch/arm/mach-omap1/dmtimer.c
@@ -0,0 +1,179 @@
+/**
+ * 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/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * 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
+
+#define OMAP_TIMER_OCP_CFG_REG		0x10
+#define OMAP_TIMER_SYS_STAT_REG		0x14
+#define OMAP_TIMER_IF_CTRL_REG		0x40
+
+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);
+
+	return 0;
+}
+
+
+int __init omap1_dm_timer_init(void)
+{
+	int i;
+	int ret;
+	struct dmtimer_platform_data *pdata;
+	struct platform_device *pdev;
+
+	if (!cpu_is_omap16xx())
+		return 0;
+
+	for (i = 1; i <= OMAP1_DM_TIMER_COUNT; i++) {
+		struct resource res[2];
+		u32 base, irq;
+
+		switch (i) {
+		case 1:
+			base = OMAP1610_GPTIMER1_BASE;
+			irq = INT_1610_GPTIMER1;
+			break;
+		case 2:
+			base = OMAP1610_GPTIMER2_BASE;
+			irq = INT_1610_GPTIMER2;
+			break;
+		case 3:
+			base = OMAP1610_GPTIMER3_BASE;
+			irq = INT_1610_GPTIMER3;
+			break;
+		case 4:
+			base = OMAP1610_GPTIMER4_BASE;
+			irq = INT_1610_GPTIMER4;
+			break;
+		case 5:
+			base = OMAP1610_GPTIMER5_BASE;
+			irq = INT_1610_GPTIMER5;
+			break;
+		case 6:
+			base = OMAP1610_GPTIMER6_BASE;
+			irq = INT_1610_GPTIMER6;
+			break;
+		case 7:
+			base = OMAP1610_GPTIMER7_BASE;
+			irq = INT_1610_GPTIMER7;
+			break;
+		case 8:
+			base = OMAP1610_GPTIMER8_BASE;
+			irq = INT_1610_GPTIMER8;
+			break;
+		default:
+			/*
+			 * not supposed to reach here.
+			 * this is to remove warning.
+			 */
+			return -EINVAL;
+		}
+
+		pdev = platform_device_alloc("omap_timer", i);
+		if (!pdev) {
+			pr_err("%s: Failed to device alloc for dmtimer%d\n",
+				__func__, i);
+			return -ENOMEM;
+		}
+
+		memset(res, 0, 2 * sizeof(struct resource));
+		res[0].start = base;
+		res[0].end = base + 0x46;
+		res[0].flags = IORESOURCE_MEM;
+		res[1].start = irq;
+		res[1].end = irq;
+		res[1].flags = IORESOURCE_IRQ;
+		ret = platform_device_add_resources(pdev, res,
+				ARRAY_SIZE(res));
+		if (ret) {
+			dev_err(&pdev->dev, "%s: Failed to add resources.\n",
+				__func__);
+			goto err_free_pdev;
+		}
+
+		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&pdev->dev, "%s: Failed to allocate pdata.\n",
+				__func__);
+			ret = -ENOMEM;
+			goto err_free_pdata;
+		}
+
+		pdata->set_timer_src = omap1_dm_timer_set_src;
+		pdata->is_early_init = 0;
+		pdata->timer_ip_type = OMAP_TIMER_IP_VERSION_1;
+		pdata->needs_manual_reset = 1;
+
+		ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+		if (ret) {
+			dev_err(&pdev->dev, "%s: Failed to add platform data.\n",
+				__func__);
+			goto err_free_pdata;
+		}
+
+		ret = platform_device_add(pdev);
+		if (ret) {
+			dev_err(&pdev->dev, "%s: Failed to add platform device.\n",
+				__func__);
+			goto err_free_pdata;
+		}
+
+		dev_dbg(&pdev->dev, " Registered.\n");
+	}
+
+	return 0;
+
+err_free_pdata:
+	kfree(pdata);
+
+err_free_pdev:
+	platform_device_unregister(pdev);
+
+	return ret;
+}
+arch_initcall(omap1_dm_timer_init);
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 13d7b8f..dc4a8fd 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -53,7 +53,6 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <plat/common.h>
-#include <plat/dmtimer.h>
 
 /*
  * ---------------------------------------------------------------------------
@@ -184,9 +183,6 @@ bool __init omap_32k_timer_init(void)
 {
 	omap_init_clocksource_32k();
 
-#ifdef CONFIG_OMAP_DM_TIMER
-	omap_dm_timer_init();
-#endif
 	omap_init_32k_timer();
 
 	return true;
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 1d706cf..1bfaf09 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -3,6 +3,12 @@
  *
  * OMAP Dual-Mode Timers
  *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * dmtimer adaptation to platform_driver.
+ *
  * Copyright (C) 2005 Nokia Corporation
  * OMAP2 support by Juha Yrjola
  * API improvements and OMAP2 clock framework support by Timo Teras
@@ -150,39 +156,8 @@
 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG				\
 		(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
 
-struct omap_dm_timer {
-	unsigned long phys_base;
-	int irq;
-#ifdef CONFIG_ARCH_OMAP2PLUS
-	struct clk *iclk, *fclk;
-#endif
-	void __iomem *io_base;
-	unsigned reserved:1;
-	unsigned enabled:1;
-	unsigned posted:1;
-};
-
 static int dm_timer_count;
 
-#ifdef CONFIG_ARCH_OMAP1
-static struct omap_dm_timer omap1_dm_timers[] = {
-	{ .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
-	{ .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
-	{ .phys_base = 0xfffb2400, .irq = INT_1610_GPTIMER3 },
-	{ .phys_base = 0xfffb2c00, .irq = INT_1610_GPTIMER4 },
-	{ .phys_base = 0xfffb3400, .irq = INT_1610_GPTIMER5 },
-	{ .phys_base = 0xfffb3c00, .irq = INT_1610_GPTIMER6 },
-	{ .phys_base = 0xfffb7400, .irq = INT_1610_GPTIMER7 },
-	{ .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 },
-};
-
-static const int omap1_dm_timer_count = ARRAY_SIZE(omap1_dm_timers);
-
-#else
-#define omap1_dm_timers			NULL
-#define omap1_dm_timer_count		0
-#endif	/* CONFIG_ARCH_OMAP1 */
-
 #ifdef CONFIG_ARCH_OMAP2
 static struct omap_dm_timer omap2_dm_timers[] = {
 	{ .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
@@ -549,23 +524,6 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
-#ifdef CONFIG_ARCH_OMAP1
-
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
-{
-	int n = (timer - dm_timers) << 1;
-	u32 l;
-
-	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
-	l |= source << n;
-	omap_writel(l, MOD_CONF_CTRL_1);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
-
-#else
-
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 	int ret = -EINVAL;
@@ -587,8 +545,6 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
-#endif
-
 void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
 			    unsigned int load)
 {
@@ -738,16 +694,12 @@ 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 */
 
-	if (!(cpu_is_omap16xx() || cpu_class_is_omap2()))
+	if (!cpu_class_is_omap2())
 		return -ENODEV;
 
 	spin_lock_init(&dm_timer_lock);
 
-	if (cpu_class_is_omap1()) {
-		dm_timers = omap1_dm_timers;
-		dm_timer_count = omap1_dm_timer_count;
-		map_size = SZ_2K;
-	} else if (cpu_is_omap24xx()) {
+	if (cpu_is_omap24xx()) {
 		dm_timers = omap2_dm_timers;
 		dm_timer_count = omap2_dm_timer_count;
 		dm_source_names = omap2_dm_source_names;
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index e3d477d..377a00c 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -57,11 +57,28 @@
 #define OMAP_TIMER_IP_VERSION_1			0x1
 #define OMAP_TIMER_IP_VERSION_2			0x2
 
-struct omap_dm_timer;
+struct omap_dm_timer {
+	unsigned long phys_base;
+	int irq;
+	struct clk *iclk, *fclk;
+	void __iomem *io_base;
+	unsigned reserved:1;
+	unsigned enabled:1;
+	unsigned posted:1;
+	struct platform_device *pdev;
+};
+
 extern struct omap_dm_timer *gptimer_wakeup;
 extern struct sys_timer omap_timer;
 struct clk;
 
+struct dmtimer_platform_data {
+	int (*set_timer_src)(struct platform_device *pdev, int source);
+	int timer_ip_type;
+	u32 is_early_init:1;
+	u32 needs_manual_reset:1;
+};
+
 int omap_dm_timer_init(void);
 
 struct omap_dm_timer *omap_dm_timer_request(void);
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
                   ` (2 preceding siblings ...)
  2011-03-08 23:45 ` [PATCH v12 3/9] OMAP1: dmtimer: conversion to platform devices Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-09 21:42   ` Tony Lindgren
                     ` (3 more replies)
  2011-03-08 23:45 ` [PATCH v12 5/9] OMAP: dmtimer: platform driver Tarun Kanti DebBarma
                   ` (4 subsequent siblings)
  8 siblings, 4 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Tarun Kanti DebBarma, Thara Gopinath

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. It also provides
provision to access timers during early boot when pm_runtime framework
is not completely up and running.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Signed-off-by: Thara Gopinath <thara@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
---
 arch/arm/mach-omap2/Makefile               |    2 +-
 arch/arm/mach-omap2/dmtimer.c              |  190 ++++++++++++++++++++++++++++
 arch/arm/mach-omap2/dmtimer.h              |   32 +++++
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    5 +
 arch/arm/plat-omap/include/plat/dmtimer.h  |    4 +
 5 files changed, 232 insertions(+), 1 deletions(-)
 create mode 100755 arch/arm/mach-omap2/dmtimer.c
 create mode 100755 arch/arm/mach-omap2/dmtimer.h

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 1c3635d..7e5014b 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
-	 common.o gpio.o dma.o wd_timer.o
+	 common.o gpio.o dma.o wd_timer.o dmtimer.o
 
 omap-2-3-common				= irq.o sdrc.o
 hwmod-common				= omap_hwmod.o \
diff --git a/arch/arm/mach-omap2/dmtimer.c b/arch/arm/mach-omap2/dmtimer.c
new file mode 100755
index 0000000..60c410b
--- /dev/null
+++ b/arch/arm/mach-omap2/dmtimer.c
@@ -0,0 +1,190 @@
+/**
+ * OMAP2+ Dual-Mode Timers - platform device registration
+ *
+ * Contains first level initialization routines which extracts timers
+ * information from hwmod database and registers with linux device model.
+ * It also has low level function to change the timer input clock source.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * 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/err.h>
+#include <linux/slab.h>
+
+#include <plat/dmtimer.h>
+#include <plat/omap_device.h>
+#include <plat/cpu.h>
+#include <plat/omap_hwmod.h>
+
+static u8 __initdata system_timer_id;
+
+/**
+ * omap2_dm_timer_set_src - change the timer input clock source
+ * @pdev:	timer platform device pointer
+ * @source:	array index of parent clock source
+ */
+static int omap2_dm_timer_set_src(struct platform_device *pdev, int source)
+{
+	int ret;
+	struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
+	struct clk *fclk = clk_get(&pdev->dev, "fck");
+	struct clk *new_fclk;
+	char *fclk_name = "32k_ck"; /* default name */
+
+	switch (source) {
+	case OMAP_TIMER_SRC_SYS_CLK:
+		fclk_name = "sys_ck";
+		break;
+
+	case OMAP_TIMER_SRC_32_KHZ:
+		fclk_name = "32k_ck";
+		break;
+
+	case OMAP_TIMER_SRC_EXT_CLK:
+		if (pdata->timer_ip_type == OMAP_TIMER_IP_VERSION_1) {
+			fclk_name = "alt_ck";
+			break;
+		}
+		dev_err(&pdev->dev, "%s: %d: invalid clk src.\n",
+			__func__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (IS_ERR_OR_NULL(fclk)) {
+		dev_err(&pdev->dev, "%s: %d: clk_get() FAILED\n",
+			__func__, __LINE__);
+		return -EINVAL;
+	}
+
+	new_fclk = clk_get(&pdev->dev, fclk_name);
+	if (IS_ERR_OR_NULL(new_fclk)) {
+		dev_err(&pdev->dev, "%s: %d: clk_get() %s FAILED\n",
+			__func__, __LINE__, fclk_name);
+		clk_put(fclk);
+		return -EINVAL;
+	}
+
+	ret = clk_set_parent(fclk, new_fclk);
+	if (IS_ERR_VALUE(ret)) {
+		dev_err(&pdev->dev, "%s: clk_set_parent() to %s FAILED\n",
+			__func__, fclk_name);
+		ret = -EINVAL;
+	}
+
+	clk_put(new_fclk);
+	clk_put(fclk);
+
+	return ret;
+}
+
+struct omap_device_pm_latency omap2_dmtimer_latency[] = {
+	{
+		.deactivate_func = omap_device_idle_hwmods,
+		.activate_func   = omap_device_enable_hwmods,
+		.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+	},
+};
+
+/**
+ * omap_timer_init - build and register timer device with an
+ * associated timer hwmod
+ * @oh:	timer hwmod pointer to be used to build timer device
+ * @user:	parameter that can be passed from calling hwmod API
+ *
+ * Called by omap_hwmod_for_each_by_class to register each of the timer
+ * devices present in the system. The number of timer devices is known
+ * by parsing through the hwmod database for a given class name. At the
+ * end of function call memory is allocated for timer device and it is
+ * registered to the framework ready to be proved by the driver.
+ */
+static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
+{
+	int id;
+	int ret = 0;
+	char *name = "omap_timer";
+	struct dmtimer_platform_data *pdata;
+	struct omap_device *od;
+	struct omap_secure_timer_dev_attr *secure_timer_dev_attr;
+
+	/*
+	 * Extract the IDs from name field in hwmod database
+	 * and use the same for constructing ids' for the
+	 * timer devices. In a way, we are avoiding usage of
+	 * static variable witin the function to do the same.
+	 * CAUTION: We have to be careful and make sure the
+	 * name in hwmod database does not change in which case
+	 * we might either make corresponding change here or
+	 * switch back static variable mechanism.
+	 */
+	sscanf(oh->name, "timer%2d", &id);
+	if (unlikely(id == system_timer_id))
+		return ret;
+
+	pr_debug("%s: %s\n", __func__, oh->name);
+
+	/* do not register secure timer */
+	secure_timer_dev_attr = oh->dev_attr;
+	if (secure_timer_dev_attr)
+		if (secure_timer_dev_attr->is_secure_timer)
+			return ret;
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("%s: No memory for [%s]\n", __func__, oh->name);
+		return -ENOMEM;
+	}
+	pdata->is_early_init = 0;
+	pdata->set_timer_src = omap2_dm_timer_set_src;
+	pdata->timer_ip_type = oh->class->rev;
+	pdata->needs_manual_reset = 0;
+
+	od = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
+			omap2_dmtimer_latency,
+			ARRAY_SIZE(omap2_dmtimer_latency),
+			pdata->is_early_init);
+
+	if (IS_ERR(od)) {
+		pr_err("%s: Can't build omap_device for %s: %s.\n",
+			__func__, name, oh->name);
+		ret = -EINVAL;
+	}
+
+	kfree(pdata);
+
+	return ret;
+}
+
+/**
+ * omap2_system_timer_set_src - change the timer input clock source
+ * Allow system timer to program clock source before pm_runtime
+ * framework is available during system boot.
+ * @timer:       pointer to struct omap_dm_timer
+ * @source:     array index of parent clock source
+ */
+int __init omap2_system_timer_set_src(struct omap_dm_timer *timer, int source)
+{
+	int ret;
+
+	if (IS_ERR_OR_NULL(timer)) {
+		pr_warning("%s: invalid timer pointer.\n", __func__);
+		return -EINVAL;
+	}
+
+	clk_disable(timer->fclk);
+	ret = omap2_dm_timer_set_src(timer->pdev, source);
+	clk_enable(timer->fclk);
+
+	return ret;
+}
diff --git a/arch/arm/mach-omap2/dmtimer.h b/arch/arm/mach-omap2/dmtimer.h
new file mode 100755
index 0000000..4cfd580
--- /dev/null
+++ b/arch/arm/mach-omap2/dmtimer.h
@@ -0,0 +1,32 @@
+/**
+ * OMAP Dual-Mode Timers - early initialization interface
+ *
+ * Function interface called first to start dmtimer early initialization.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * 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.
+ */
+#ifndef __ASM_ARCH_OMAP2_DMTIMER_H
+#define __ASM_ARCH_OMAP2_DMTIMER_H
+
+#include <plat/dmtimer.h>
+
+/*
+ * dmtimer is required during early part of boot sequence even before
+ * device model and pm_runtime if fully up and running. This function
+ * is called from following sequence:
+ * start_kernel()->time_init()->timer->init()->omap2_gp_timer_init()
+ */
+extern int __init omap2_system_timer_init(u8 id);
+extern int __init omap2_system_timer_set_src(struct omap_dm_timer *, int);
+#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 9a34e20..93dd209 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -3976,6 +3976,11 @@ static struct omap_hwmod_class omap44xx_timer_hwmod_class = {
 	.rev	= OMAP_TIMER_IP_VERSION_2,
 };
 
+/* secure timer can assign this to .dev_attr field */
+static struct omap_secure_timer_dev_attr secure_timer_dev_attr = {
+	.is_secure_timer        = true,
+};
+
 /* timer1 */
 static struct omap_hwmod omap44xx_timer1_hwmod;
 static struct omap_hwmod_irq_info omap44xx_timer1_irqs[] = {
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 377a00c..0d1a571 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -57,6 +57,10 @@
 #define OMAP_TIMER_IP_VERSION_1			0x1
 #define OMAP_TIMER_IP_VERSION_2			0x2
 
+struct omap_secure_timer_dev_attr {
+	bool is_secure_timer;
+};
+
 struct omap_dm_timer {
 	unsigned long phys_base;
 	int irq;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 5/9] OMAP: dmtimer: platform driver
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
                   ` (3 preceding siblings ...)
  2011-03-08 23:45 ` [PATCH v12 4/9] OMAP2+: dmtimer: convert " Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 6/9] dmtimer: switch-over to platform device driver Tarun Kanti DebBarma
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Tarun Kanti DebBarma, Thara Gopinath

Add dmtimer platform driver functions which include:
(1) platform driver initialization
(2) driver probe function
(3) driver remove function

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Signed-off-by: Thara Gopinath <thara@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
---
 arch/arm/plat-omap/dmtimer.c              |  167 +++++++++++++++++++++++++++-
 arch/arm/plat-omap/include/plat/dmtimer.h |    4 +
 2 files changed, 165 insertions(+), 6 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 1bfaf09..51dc0b6 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -35,15 +35,13 @@
  * 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 <mach/hardware.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
 #include <plat/dmtimer.h>
 #include <mach/irqs.h>
 
@@ -156,6 +154,13 @@
 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG				\
 		(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
 
+/*
+ * 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
+
 static int dm_timer_count;
 
 #ifdef CONFIG_ARCH_OMAP2
@@ -258,6 +263,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
@@ -689,6 +695,155 @@ int omap_dm_timers_active(void)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 
+/**
+ * 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__);
+		ret = -ENODEV;
+		goto err_free_pdev;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (unlikely(!mem)) {
+		dev_err(&pdev->dev, "%s: no memory resource.\n", __func__);
+		ret = -ENODEV;
+		goto err_free_pdev;
+	}
+
+	ioarea = request_mem_region(mem->start, resource_size(mem),
+			pdev->name);
+	if (!ioarea) {
+		dev_err(&pdev->dev, "%s: region already claimed.\n", __func__);
+		ret = -EBUSY;
+		goto err_free_pdev;
+	}
+
+	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_release_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;
+	} else {
+		timer->func_offset = 0;
+		timer->intr_offset = 0;
+	}
+
+	timer->id = pdev->id;
+	timer->irq = irq->start;
+	timer->pdev = pdev;
+	timer->reserved = 0;
+
+	/* 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_release_ioregion:
+	release_mem_region(mem->start, resource_size(mem));
+
+err_free_pdev:
+	kfree(pdata);
+	platform_device_unregister(pdev);
+
+	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, *tmp;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&dm_timer_lock, flags);
+	list_for_each_entry_safe(timer, tmp, &omap_timer_list, node) {
+		if (timer->pdev->id == pdev->id) {
+			kfree(timer->pdev->dev.platform_data);
+			platform_device_del(timer->pdev);
+			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;
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 0d1a571..c184bf0 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -63,13 +63,17 @@ struct omap_secure_timer_dev_attr {
 
 struct omap_dm_timer {
 	unsigned long phys_base;
+	int id;
 	int irq;
 	struct clk *iclk, *fclk;
 	void __iomem *io_base;
 	unsigned reserved:1;
 	unsigned enabled:1;
 	unsigned posted:1;
+	u8 func_offset;
+	u8 intr_offset;
 	struct platform_device *pdev;
+	struct list_head node;
 };
 
 extern struct omap_dm_timer *gptimer_wakeup;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
                   ` (4 preceding siblings ...)
  2011-03-08 23:45 ` [PATCH v12 5/9] OMAP: dmtimer: platform driver Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-09 22:02   ` Tony Lindgren
  2011-03-08 23:45 ` [PATCH v12 7/9] OMAP: dmtimer: pm_runtime support Tarun Kanti DebBarma
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Tarun Kanti DebBarma

switch-over to platform device driver through following changes:
(a) initiate dmtimer early initialization from omap2_gp_timer_init()
in timer-gp.c. This is equivalent of timer_init()->timer->init().
(b) modify plat-omap/dmtimer routines to use new register map and
platform data.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
---
 arch/arm/mach-omap2/clock2420_data.c      |    2 +-
 arch/arm/mach-omap2/clock2430_data.c      |    2 +-
 arch/arm/mach-omap2/clock3xxx_data.c      |    2 +-
 arch/arm/mach-omap2/clock44xx_data.c      |    2 +-
 arch/arm/mach-omap2/dmtimer.c             |   89 ++++++++-
 arch/arm/mach-omap2/timer-gp.c            |   12 +-
 arch/arm/plat-omap/dmtimer.c              |  336 +++++++++--------------------
 arch/arm/plat-omap/include/plat/dmtimer.h |    5 +-
 8 files changed, 198 insertions(+), 252 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index ee93d3c..31373ab 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1801,7 +1801,7 @@ static struct omap_clk omap2420_clks[] = {
 	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_242X),
 	/* general l4 interface ck, multi-parent functional clk */
 	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_242X),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_242X),
+	CLK("omap_timer.1",	"gpt1_fck",	&gpt1_fck,	CK_242X),
 	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_242X),
 	CLK("omap_timer.2",	"fck",	&gpt2_fck,	CK_242X),
 	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 899a3f6..a0a7f51 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1905,7 +1905,7 @@ static struct omap_clk omap2430_clks[] = {
 	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X),
 	/* general l4 interface ck, multi-parent functional clk */
 	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_243X),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_243X),
+	CLK("omap_timer.1",	"gpt1_fck",	&gpt1_fck,	CK_243X),
 	CLK(NULL,	"gpt2_ick",	&gpt2_ick,	CK_243X),
 	CLK("omap_timer.2",	"fck",	&gpt2_fck,	CK_243X),
 	CLK(NULL,	"gpt3_ick",	&gpt3_ick,	CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index f84a649..cf973ca 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3374,7 +3374,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK("ehci-omap.0",	"usbhost_ick",	&usbhost_ick,	CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
 	CLK(NULL,	"usim_fck",	&usim_fck,	CK_3430ES2PLUS | CK_36XX),
-	CLK(NULL,	"gpt1_fck",	&gpt1_fck,	CK_3XXX),
+	CLK("omap_timer.1",	"fck",	&gpt1_fck,	CK_3XXX),
 	CLK(NULL,	"wkup_32k_fck",	&wkup_32k_fck,	CK_3XXX),
 	CLK(NULL,	"gpio1_dbck",	&gpio1_dbck,	CK_3XXX),
 	CLK("omap_wdt",	"fck",		&wdt2_fck,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index 0a6d80c..74de632 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3181,7 +3181,7 @@ static struct omap_clk omap44xx_clks[] = {
 	CLK(NULL,	"smartreflex_core_fck",		&smartreflex_core_fck,	CK_443X),
 	CLK(NULL,	"smartreflex_iva_fck",		&smartreflex_iva_fck,	CK_443X),
 	CLK(NULL,	"smartreflex_mpu_fck",		&smartreflex_mpu_fck,	CK_443X),
-	CLK(NULL,	"gpt1_fck",			&timer1_fck,	CK_443X),
+	CLK("omap_timer.1",	"fck",			&timer1_fck,	CK_443X),
 	CLK("omap_timer.10",	"fck",			&timer10_fck,	CK_443X),
 	CLK("omap_timer.11",	"fck",			&timer11_fck,	CK_443X),
 	CLK("omap_timer.2",	"fck",			&timer2_fck,	CK_443X),
diff --git a/arch/arm/mach-omap2/dmtimer.c b/arch/arm/mach-omap2/dmtimer.c
index 60c410b..abd48e9 100755
--- a/arch/arm/mach-omap2/dmtimer.c
+++ b/arch/arm/mach-omap2/dmtimer.c
@@ -167,6 +167,71 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
 }
 
 /**
+ * omap2_system_timer_init - top level system timer initialization
+ * called from omap2_gp_timer_init() in timer-gp.c
+ * @id	: system timer id
+ *
+ * This function does hwmod setup for the system timer entry needed
+ * prior to building and registering the device. After the device is
+ * registered early probe initiated.
+ */
+int __init omap2_system_timer_init(u8 id)
+{
+	int ret = 0;
+	char *name = "omap_timer";
+	struct dmtimer_platform_data *pdata;
+	struct omap_device *od;
+	struct omap_hwmod *oh;
+	char system_timer_name[8]; /* 8 = sizeof("timerXX0") */
+
+	system_timer_id = id;
+
+	sprintf(system_timer_name, "timer%d", id);
+	ret = omap_hwmod_setup_one(system_timer_name);
+	if (ret) {
+		pr_err("%s: omap_hwmod_setup_one(%s) failed.\n",
+				__func__, system_timer_name);
+		return ret;
+	}
+	oh = omap_hwmod_lookup(system_timer_name);
+	if (!oh) {
+		pr_debug("%s: could not find (%s) in omap_hwmod_list!\n",
+			__func__, system_timer_name);
+		return -EINVAL;
+	}
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("%s: No memory for [%s]\n", __func__, oh->name);
+		return -ENOMEM;
+	}
+	pdata->is_early_init = 1;
+	pdata->set_timer_src = omap2_dm_timer_set_src;
+	pdata->timer_ip_type = oh->class->rev;
+	pdata->needs_manual_reset = 0;
+
+	od = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
+			omap2_dmtimer_latency,
+			ARRAY_SIZE(omap2_dmtimer_latency),
+			pdata->is_early_init);
+
+	if (IS_ERR(od)) {
+		pr_err("%s: Can't build omap_device for %s: %s.\n",
+			__func__, name, oh->name);
+		ret = -EINVAL;
+	}
+
+	kfree(pdata);
+
+	if (!ret) {
+		early_platform_driver_register_all("earlytimer");
+		early_platform_driver_probe("earlytimer", 1, 0);
+	}
+
+	return 0;
+}
+
+/**
  * omap2_system_timer_set_src - change the timer input clock source
  * Allow system timer to program clock source before pm_runtime
  * framework is available during system boot.
@@ -177,10 +242,8 @@ int __init omap2_system_timer_set_src(struct omap_dm_timer *timer, int source)
 {
 	int ret;
 
-	if (IS_ERR_OR_NULL(timer)) {
-		pr_warning("%s: invalid timer pointer.\n", __func__);
+	if (IS_ERR_OR_NULL(timer) || IS_ERR_OR_NULL(timer->fclk))
 		return -EINVAL;
-	}
 
 	clk_disable(timer->fclk);
 	ret = omap2_dm_timer_set_src(timer->pdev, source);
@@ -188,3 +251,23 @@ int __init omap2_system_timer_set_src(struct omap_dm_timer *timer, int source)
 
 	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);
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 3b9cf85..bb5b3c5 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -44,7 +44,7 @@
 #include <plat/omap_hwmod.h>
 
 #include "timer-gp.h"
-
+#include "dmtimer.h"
 
 /* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
 #define MAX_GPTIMER_ID		12
@@ -134,13 +134,9 @@ static void __init omap2_gp_clockevent_init(void)
 {
 	u32 tick_rate;
 	int src;
-	char clockevent_hwmod_name[8]; /* 8 = sizeof("timerXX0") */
 
 	inited = 1;
 
-	sprintf(clockevent_hwmod_name, "timer%d", gptimer_id);
-	omap_hwmod_setup_one(clockevent_hwmod_name);
-
 	gptimer = omap_dm_timer_request_specific(gptimer_id);
 	BUG_ON(gptimer == NULL);
 	gptimer_wakeup = gptimer;
@@ -154,8 +150,8 @@ static void __init omap2_gp_clockevent_init(void)
 #endif
 
 	if (gptimer_id != 12)
-		WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)),
-		     "timer-gp: omap_dm_timer_set_source() failed\n");
+		WARN(IS_ERR_VALUE(omap2_system_timer_set_src(gptimer, src)),
+		     "timer-gp: omap2_system_timer_set_src() failed\n");
 
 	tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
 
@@ -255,7 +251,7 @@ static void __init omap2_gp_timer_init(void)
 		BUG_ON(!twd_base);
 	}
 #endif
-	omap_dm_timer_init();
+	omap2_system_timer_init(gptimer_id);
 
 	omap2_gp_clockevent_init();
 	omap2_gp_clocksource_init();
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 51dc0b6..6ac6ce7 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -43,7 +43,6 @@
 #include <linux/platform_device.h>
 
 #include <plat/dmtimer.h>
-#include <mach/irqs.h>
 
 /* register offsets */
 #define _OMAP_TIMER_ID_OFFSET		0x00
@@ -161,117 +160,25 @@
 #define VERSION2_TIMER_WAKEUP_EN_REG_OFFSET     0x14
 #define VERSION2_TIMER_STAT_REG_OFFSET          0x10
 
-static int dm_timer_count;
-
-#ifdef CONFIG_ARCH_OMAP2
-static struct omap_dm_timer omap2_dm_timers[] = {
-	{ .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
-	{ .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
-	{ .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 },
-	{ .phys_base = 0x4807a000, .irq = INT_24XX_GPTIMER4 },
-	{ .phys_base = 0x4807c000, .irq = INT_24XX_GPTIMER5 },
-	{ .phys_base = 0x4807e000, .irq = INT_24XX_GPTIMER6 },
-	{ .phys_base = 0x48080000, .irq = INT_24XX_GPTIMER7 },
-	{ .phys_base = 0x48082000, .irq = INT_24XX_GPTIMER8 },
-	{ .phys_base = 0x48084000, .irq = INT_24XX_GPTIMER9 },
-	{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
-	{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
-	{ .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 },
-};
-
-static const char *omap2_dm_source_names[] __initdata = {
-	"sys_ck",
-	"func_32k_ck",
-	"alt_ck",
-	NULL
-};
-
-static struct clk *omap2_dm_source_clocks[3];
-static const int omap2_dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
-
-#else
-#define omap2_dm_timers			NULL
-#define omap2_dm_timer_count		0
-#define omap2_dm_source_names		NULL
-#define omap2_dm_source_clocks		NULL
-#endif	/* CONFIG_ARCH_OMAP2 */
-
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap_dm_timer omap3_dm_timers[] = {
-	{ .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 },
-	{ .phys_base = 0x49032000, .irq = INT_24XX_GPTIMER2 },
-	{ .phys_base = 0x49034000, .irq = INT_24XX_GPTIMER3 },
-	{ .phys_base = 0x49036000, .irq = INT_24XX_GPTIMER4 },
-	{ .phys_base = 0x49038000, .irq = INT_24XX_GPTIMER5 },
-	{ .phys_base = 0x4903A000, .irq = INT_24XX_GPTIMER6 },
-	{ .phys_base = 0x4903C000, .irq = INT_24XX_GPTIMER7 },
-	{ .phys_base = 0x4903E000, .irq = INT_24XX_GPTIMER8 },
-	{ .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
-	{ .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
-	{ .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
-	{ .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
-};
-
-static const char *omap3_dm_source_names[] __initdata = {
-	"sys_ck",
-	"omap_32k_fck",
-	NULL
-};
-
-static struct clk *omap3_dm_source_clocks[2];
-static const int omap3_dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
-
-#else
-#define omap3_dm_timers			NULL
-#define omap3_dm_timer_count		0
-#define omap3_dm_source_names		NULL
-#define omap3_dm_source_clocks		NULL
-#endif	/* CONFIG_ARCH_OMAP3 */
-
-#ifdef CONFIG_ARCH_OMAP4
-static struct omap_dm_timer omap4_dm_timers[] = {
-	{ .phys_base = 0x4a318000, .irq = OMAP44XX_IRQ_GPT1 },
-	{ .phys_base = 0x48032000, .irq = OMAP44XX_IRQ_GPT2 },
-	{ .phys_base = 0x48034000, .irq = OMAP44XX_IRQ_GPT3 },
-	{ .phys_base = 0x48036000, .irq = OMAP44XX_IRQ_GPT4 },
-	{ .phys_base = 0x40138000, .irq = OMAP44XX_IRQ_GPT5 },
-	{ .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT6 },
-	{ .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT7 },
-	{ .phys_base = 0x4013e000, .irq = OMAP44XX_IRQ_GPT8 },
-	{ .phys_base = 0x4803e000, .irq = OMAP44XX_IRQ_GPT9 },
-	{ .phys_base = 0x48086000, .irq = OMAP44XX_IRQ_GPT10 },
-	{ .phys_base = 0x48088000, .irq = OMAP44XX_IRQ_GPT11 },
-	{ .phys_base = 0x4a320000, .irq = OMAP44XX_IRQ_GPT12 },
-};
-static const char *omap4_dm_source_names[] __initdata = {
-	"sys_clkin_ck",
-	"sys_32k_ck",
-	NULL
-};
-static struct clk *omap4_dm_source_clocks[2];
-static const int omap4_dm_timer_count = ARRAY_SIZE(omap4_dm_timers);
-
-#else
-#define omap4_dm_timers			NULL
-#define omap4_dm_timer_count		0
-#define omap4_dm_source_names		NULL
-#define omap4_dm_source_clocks		NULL
-#endif	/* CONFIG_ARCH_OMAP4 */
-
-static struct omap_dm_timer *dm_timers;
-static const char **dm_source_names;
-static struct clk **dm_source_clocks;
-
-static spinlock_t dm_timer_lock;
 static LIST_HEAD(omap_timer_list);
+static DEFINE_SPINLOCK(dm_timer_lock);
 
-/*
- * Reads timer registers in posted and non-posted mode. The posted mode bit
- * is encoded in reg. Note that in posted mode write pending bit must be
- * checked. Otherwise a read of a non completed write will produce an error.
+/**
+ * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
+ * @timer:      timer pointer over which read operation to perform
+ * @reg:        lowest byte holds the register offset
+ *
+ * The posted mode bit is encoded in reg. Note that in posted mode write
+ * pending bit must be checked. Otherwise a read of a non completed write
+ * will produce an error.
  */
 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
 {
+	if (reg >= OMAP_TIMER_WAKEUP_EN_REG)
+		reg += timer->func_offset;
+	else if (reg >= OMAP_TIMER_STAT_REG)
+		reg += timer->intr_offset;
+
 	if (timer->posted)
 		while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
 				& (reg >> WPSHIFT))
@@ -279,15 +186,24 @@ static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
 	return readl(timer->io_base + (reg & 0xff));
 }
 
-/*
- * Writes timer registers in posted and non-posted mode. The posted mode bit
- * is encoded in reg. Note that in posted mode the write pending bit must be
- * checked. Otherwise a write on a register which has a pending write will be
- * lost.
+/**
+ * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
+ * @timer:      timer pointer over which write operation is to perform
+ * @reg:        lowest byte holds the register offset
+ * @value:      data to write into the register
+ *
+ * The posted mode bit is encoded in reg. Note that in posted mode the write
+ * pending bit must be checked. Otherwise a write on a register which has a
+ * pending write will be lost.
  */
 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
 						u32 value)
 {
+	if (reg >= OMAP_TIMER_WAKEUP_EN_REG)
+		reg += timer->func_offset;
+	else if (reg >= OMAP_TIMER_STAT_REG)
+		reg += timer->intr_offset;
+
 	if (timer->posted)
 		while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
 				& (reg >> WPSHIFT))
@@ -313,54 +229,67 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
 {
 	u32 l;
 
-	if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
+	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_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
 
 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
 	l |= 0x02 << 3;  /* Set to smart-idle mode */
 	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
-
-	/*
-	 * Enable wake-up on OMAP2 CPUs.
-	 */
-	if (cpu_class_is_omap2())
-		l |= 1 << 2;
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
-
-	/* Match hardware reset default of posted mode */
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
-			OMAP_TIMER_CTRL_POSTED);
-	timer->posted = 1;
 }
 
 static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
 {
+	struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
+
+	timer->fclk = clk_get(&timer->pdev->dev, "fck");
+	if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
+		timer->fclk = NULL;
+		dev_err(&timer->pdev->dev, ": No fclk handle.\n");
+		return;
+	}
+
+	if (unlikely(pdata->is_early_init)) {
+		clk_enable(timer->fclk);
+		goto end;
+	}
+
 	omap_dm_timer_enable(timer);
-	omap_dm_timer_reset(timer);
+
+	if (pdata->needs_manual_reset)
+		omap_dm_timer_reset(timer);
+
+	omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+
+end:
+	/* Match hardware reset default of posted mode */
+	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+			OMAP_TIMER_CTRL_POSTED);
+	timer->posted = 1;
 }
 
 struct omap_dm_timer *omap_dm_timer_request(void)
 {
-	struct omap_dm_timer *timer = NULL;
+	struct omap_dm_timer *timer = NULL, *t;
 	unsigned long flags;
-	int i;
 
 	spin_lock_irqsave(&dm_timer_lock, flags);
-	for (i = 0; i < dm_timer_count; i++) {
-		if (dm_timers[i].reserved)
+	list_for_each_entry(t, &omap_timer_list, node) {
+		if (t->reserved)
 			continue;
 
-		timer = &dm_timers[i];
+		timer = t;
 		timer->reserved = 1;
 		break;
 	}
 	spin_unlock_irqrestore(&dm_timer_lock, flags);
 
-	if (timer != NULL)
+	if (timer)
 		omap_dm_timer_prepare(timer);
+	else
+		pr_debug("%s: free timer not available.\n", __func__);
 
 	return timer;
 }
@@ -368,23 +297,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;
+		}
 	}
-
-	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);
+	else
+		pr_debug("%s: timer%d not available.\n", __func__, id);
 
 	return timer;
 }
@@ -392,10 +321,10 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
 void omap_dm_timer_free(struct omap_dm_timer *timer)
 {
-	omap_dm_timer_enable(timer);
-	omap_dm_timer_reset(timer);
 	omap_dm_timer_disable(timer);
 
+	clk_put(timer->fclk);
+
 	WARN_ON(!timer->reserved);
 	timer->reserved = 0;
 }
@@ -406,12 +335,7 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer)
 	if (timer->enabled)
 		return;
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-	if (cpu_class_is_omap2()) {
-		clk_enable(timer->fclk);
-		clk_enable(timer->iclk);
-	}
-#endif
+	clk_enable(timer->fclk);
 
 	timer->enabled = 1;
 }
@@ -422,12 +346,7 @@ void omap_dm_timer_disable(struct omap_dm_timer *timer)
 	if (!timer->enabled)
 		return;
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-	if (cpu_class_is_omap2()) {
-		clk_disable(timer->iclk);
-		clk_disable(timer->fclk);
-	}
-#endif
+	clk_disable(timer->fclk);
 
 	timer->enabled = 0;
 }
@@ -447,24 +366,30 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
  */
 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 {
-	int i;
+	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 */
-	for (i = 0; i < dm_timer_count; i++) {
+	spin_lock_irqsave(&dm_timer_lock, flags);
+	list_for_each_entry(timer, &omap_timer_list, node) {
+
 		u32 l;
 
-		l = omap_dm_timer_read_reg(&dm_timers[i], OMAP_TIMER_CTRL_REG);
+		l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
 		if (l & OMAP_TIMER_CTRL_ST) {
 			if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
 				inputmask &= ~(1 << 1);
 			else
 				inputmask &= ~(1 << 2);
 		}
+		i++;
 	}
+	spin_unlock_irqrestore(&dm_timer_lock, flags);
 
 	return inputmask;
 }
@@ -509,20 +434,22 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start);
 void omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
 	u32 l;
+	struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
 
 	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
 	if (l & OMAP_TIMER_CTRL_ST) {
 		l &= ~0x1;
 		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
-#ifdef CONFIG_ARCH_OMAP2PLUS
-		/* Readback to make sure write has completed */
-		omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
-		 /*
-		  * Wait for functional clock period x 3.5 to make sure that
-		  * timer is stopped
-		  */
-		udelay(3500000 / clk_get_rate(timer->fclk) + 1);
-#endif
+
+		if (!pdata->needs_manual_reset) {
+			/* Readback to make sure write has completed */
+			omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+			/*
+			 * Wait for functional clock period x 3.5 to make
+			 * sure that timer is stopped
+			 */
+			udelay(3500000 / clk_get_rate(timer->fclk) + 1);
+		}
 	}
 	/* Ack possibly pending interrupt */
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
@@ -533,13 +460,15 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
 	int ret = -EINVAL;
+	struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
 
 	if (source < 0 || source >= 3)
 		return -EINVAL;
 
-	clk_disable(timer->fclk);
-	ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
-	clk_enable(timer->fclk);
+	omap_dm_timer_disable(timer);
+	/* change the timer clock source */
+	ret = pdata->set_timer_src(timer->pdev, source);
+	omap_dm_timer_enable(timer);
 
 	/*
 	 * When the functional clock disappears, too quick writes seem
@@ -676,13 +605,9 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
 
 int omap_dm_timers_active(void)
 {
-	int i;
-
-	for (i = 0; i < dm_timer_count; i++) {
-		struct omap_dm_timer *timer;
-
-		timer = &dm_timers[i];
+	struct omap_dm_timer *timer;
 
+	list_for_each_entry(timer, &omap_timer_list, node) {
 		if (!timer->enabled)
 			continue;
 
@@ -843,58 +768,3 @@ 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 */
-
-	if (!cpu_class_is_omap2())
-		return -ENODEV;
-
-	spin_lock_init(&dm_timer_lock);
-
-	if (cpu_is_omap24xx()) {
-		dm_timers = omap2_dm_timers;
-		dm_timer_count = omap2_dm_timer_count;
-		dm_source_names = omap2_dm_source_names;
-		dm_source_clocks = omap2_dm_source_clocks;
-	} else if (cpu_is_omap34xx()) {
-		dm_timers = omap3_dm_timers;
-		dm_timer_count = omap3_dm_timer_count;
-		dm_source_names = omap3_dm_source_names;
-		dm_source_clocks = omap3_dm_source_clocks;
-	} else if (cpu_is_omap44xx()) {
-		dm_timers = omap4_dm_timers;
-		dm_timer_count = omap4_dm_timer_count;
-		dm_source_names = omap4_dm_source_names;
-		dm_source_clocks = omap4_dm_source_clocks;
-	}
-
-	if (cpu_class_is_omap2())
-		for (i = 0; dm_source_names[i] != NULL; i++)
-			dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]);
-
-	if (cpu_is_omap243x())
-		dm_timers[0].phys_base = 0x49018000;
-
-	for (i = 0; i < dm_timer_count; i++) {
-		timer = &dm_timers[i];
-
-		/* Static mapping, never released */
-		timer->io_base = ioremap(timer->phys_base, map_size);
-		BUG_ON(!timer->io_base);
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-		if (cpu_class_is_omap2()) {
-			char clk_name[16];
-			sprintf(clk_name, "gpt%d_ick", i + 1);
-			timer->iclk = clk_get(NULL, clk_name);
-			sprintf(clk_name, "gpt%d_fck", i + 1);
-			timer->fclk = clk_get(NULL, clk_name);
-		}
-#endif
-	}
-
-	return 0;
-}
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index c184bf0..f77d3b8 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -62,10 +62,9 @@ struct omap_secure_timer_dev_attr {
 };
 
 struct omap_dm_timer {
-	unsigned long phys_base;
 	int id;
 	int irq;
-	struct clk *iclk, *fclk;
+	struct clk *fclk;
 	void __iomem *io_base;
 	unsigned reserved:1;
 	unsigned enabled:1;
@@ -87,8 +86,6 @@ struct dmtimer_platform_data {
 	u32 needs_manual_reset:1;
 };
 
-int omap_dm_timer_init(void);
-
 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);
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 7/9] OMAP: dmtimer: pm_runtime support
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
                   ` (5 preceding siblings ...)
  2011-03-08 23:45 ` [PATCH v12 6/9] dmtimer: switch-over to platform device driver Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 8/9] OMAP: dmtimer: add timeout to low-level routines Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 9/9] OMAP: dmtimer: use mutex instead of spinlock Tarun Kanti DebBarma
  8 siblings, 0 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: Tarun Kanti DebBarma, Partha Basak

Add pm_runtime feature to dmtimer whereby _get_sync() is called within
omap_dm_timer_enable(), _put_sync() is called in omap_dm_timer_disable().
As part of this, I am getting rid of the 'enabled' flag since this is
no longer needed. This has been replaced by pm_runtime_suspended() check.

Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
[p-basak2@ti.com: added pm_runtime logic in probe()]
Signed-off-by: Partha Basak <p-basak2@ti.com>
Reviewed-by: Varadarajan, Charulatha <charu@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
---
 arch/arm/plat-omap/dmtimer.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 6ac6ce7..29d675e 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -39,6 +39,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 
@@ -335,7 +336,7 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer)
 	if (timer->enabled)
 		return;
 
-	clk_enable(timer->fclk);
+	pm_runtime_get_sync(&timer->pdev->dev);
 
 	timer->enabled = 1;
 }
@@ -346,7 +347,7 @@ void omap_dm_timer_disable(struct omap_dm_timer *timer)
 	if (!timer->enabled)
 		return;
 
-	clk_disable(timer->fclk);
+	pm_runtime_put_sync(&timer->pdev->dev);
 
 	timer->enabled = 0;
 }
@@ -690,6 +691,10 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
 	timer->pdev = pdev;
 	timer->reserved = 0;
 
+	 /* Skip pm_runtime_enable during early boot and for OMAP1 */
+	if (!pdata->is_early_init && !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);
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 8/9] OMAP: dmtimer: add timeout to low-level routines
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
                   ` (6 preceding siblings ...)
  2011-03-08 23:45 ` [PATCH v12 7/9] OMAP: dmtimer: pm_runtime support Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  2011-03-08 23:45 ` [PATCH v12 9/9] OMAP: dmtimer: use mutex instead of spinlock Tarun Kanti DebBarma
  8 siblings, 0 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: 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 <tarun.kanti@ti.com>
Reviewed-by: Varadarajan, Charulatha <charu@ti.com>
Acked-by: Cousson, Benoit <b-cousson@ti.com>
---
 arch/arm/plat-omap/dmtimer.c |   35 +++++++++++++++++++++++++++--------
 1 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index fe258a2..aea0b5d 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -44,6 +44,7 @@
 #include <linux/platform_device.h>
 
 #include <plat/dmtimer.h>
+#include <plat/common.h>
 
 /* register offsets */
 #define _OMAP_TIMER_ID_OFFSET		0x00
@@ -161,6 +162,8 @@
 #define VERSION2_TIMER_WAKEUP_EN_REG_OFFSET     0x14
 #define VERSION2_TIMER_STAT_REG_OFFSET          0x10
 
+#define MAX_WRITE_PEND_WAIT		10000 /* 10ms timeout delay */
+
 static LIST_HEAD(omap_timer_list);
 static DEFINE_SPINLOCK(dm_timer_lock);
 
@@ -175,15 +178,23 @@ static DEFINE_SPINLOCK(dm_timer_lock);
  */
 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
 {
+	int i = 0;
+
 	if (reg >= OMAP_TIMER_WAKEUP_EN_REG)
 		reg += timer->func_offset;
 	else if (reg >= OMAP_TIMER_STAT_REG)
 		reg += timer->intr_offset;
 
-	if (timer->posted)
-		while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
-				& (reg >> WPSHIFT))
-			cpu_relax();
+	if (timer->posted) {
+		omap_test_timeout(!(readl(timer->io_base +
+			((OMAP_TIMER_WRITE_PEND_REG +
+			timer->func_offset) & 0xff)) & (reg >> WPSHIFT)),
+			MAX_WRITE_PEND_WAIT, i);
+
+		if (WARN_ON_ONCE(i == MAX_WRITE_PEND_WAIT))
+			dev_err(&timer->pdev->dev, "read timeout.\n");
+	}
+
 	return readl(timer->io_base + (reg & 0xff));
 }
 
@@ -200,15 +211,23 @@ static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
 						u32 value)
 {
+	int i = 0;
+
 	if (reg >= OMAP_TIMER_WAKEUP_EN_REG)
 		reg += timer->func_offset;
 	else if (reg >= OMAP_TIMER_STAT_REG)
 		reg += timer->intr_offset;
 
-	if (timer->posted)
-		while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
-				& (reg >> WPSHIFT))
-			cpu_relax();
+	if (timer->posted) {
+		omap_test_timeout(!(readl(timer->io_base +
+			((OMAP_TIMER_WRITE_PEND_REG +
+			timer->func_offset) & 0xff)) & (reg >> WPSHIFT)),
+			MAX_WRITE_PEND_WAIT, i);
+
+		if (WARN_ON(i == MAX_WRITE_PEND_WAIT))
+			dev_err(&timer->pdev->dev, "write timeout.\n");
+	}
+
 	writel(value, timer->io_base + (reg & 0xff));
 }
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v12 9/9] OMAP: dmtimer: use mutex instead of spinlock
  2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
                   ` (7 preceding siblings ...)
  2011-03-08 23:45 ` [PATCH v12 8/9] OMAP: dmtimer: add timeout to low-level routines Tarun Kanti DebBarma
@ 2011-03-08 23:45 ` Tarun Kanti DebBarma
  8 siblings, 0 replies; 40+ messages in thread
From: Tarun Kanti DebBarma @ 2011-03-08 23:45 UTC (permalink / raw)
  To: linux-omap; +Cc: 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 <tarun.kanti@ti.com>
---
 arch/arm/plat-omap/dmtimer.c |   27 +++++++++++----------------
 1 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index aea0b5d..b85f89b 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -165,7 +165,7 @@
 #define MAX_WRITE_PEND_WAIT		10000 /* 10ms timeout delay */
 
 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
@@ -293,9 +293,8 @@ end:
 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;
@@ -304,7 +303,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);
@@ -318,9 +317,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;
@@ -328,7 +326,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);
@@ -390,14 +388,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;
@@ -411,7 +408,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;
 }
@@ -652,7 +649,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;
@@ -717,9 +713,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");
 
@@ -749,10 +745,9 @@ err_free_pdev:
 static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
 {
 	struct omap_dm_timer *timer, *tmp;
-	unsigned long flags;
 	int ret = -EINVAL;
 
-	spin_lock_irqsave(&dm_timer_lock, flags);
+	mutex_lock(&dm_timer_mutex);
 	list_for_each_entry_safe(timer, tmp, &omap_timer_list, node) {
 		if (timer->pdev->id == pdev->id) {
 			kfree(timer->pdev->dev.platform_data);
@@ -763,7 +758,7 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
 			break;
 		}
 	}
-	spin_unlock_irqrestore(&dm_timer_lock, flags);
+	mutex_unlock(&dm_timer_mutex);
 
 	return ret;
 }
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-08 23:45 ` [PATCH v12 4/9] OMAP2+: dmtimer: convert " Tarun Kanti DebBarma
@ 2011-03-09 21:42   ` Tony Lindgren
  2011-03-10 15:29     ` DebBarma, Tarun Kanti
  2011-03-10 22:52   ` Kevin Hilman
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-09 21:42 UTC (permalink / raw)
  To: Tarun Kanti DebBarma; +Cc: linux-omap, Thara Gopinath

* Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> 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. It also provides
> provision to access timers during early boot when pm_runtime framework
> is not completely up and running.
> +	 common.o gpio.o dma.o wd_timer.o dmtimer.o

> new file mode 100755
> index 0000000..60c410b
> --- /dev/null
> +++ b/arch/arm/mach-omap2/dmtimer.c

Uhh please check the mode changes for this series..

> new file mode 100755
> index 0000000..4cfd580
> --- /dev/null
> +++ b/arch/arm/mach-omap2/dmtimer.h

Here too and maybe other places also.

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-08 23:45 ` [PATCH v12 6/9] dmtimer: switch-over to platform device driver Tarun Kanti DebBarma
@ 2011-03-09 22:02   ` Tony Lindgren
  2011-03-10 15:27     ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-09 22:02 UTC (permalink / raw)
  To: Tarun Kanti DebBarma; +Cc: linux-omap

* Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> switch-over to platform device driver through following changes:
> (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> in timer-gp.c. This is equivalent of timer_init()->timer->init().
> (b) modify plat-omap/dmtimer routines to use new register map and
> platform data.

This patch breaks booting for 2420 and makes boot hang early
on 2430. Note that to test with omap-for-linus branch you need
to disable the following in omap2plus_defconfig:

CONFIG_ARCH_OMAP3
CONFIG_ARCH_OMAP4
CONFIG_CPU_32v6K

In general, let's continue with this series after the merge
window. We must merge intrusive changes like this early around
-rc2, not late in the merge window.

Regards,

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-09 22:02   ` Tony Lindgren
@ 2011-03-10 15:27     ` DebBarma, Tarun Kanti
  2011-03-10 17:56       ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-10 15:27 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap@vger.kernel.org

> -----Original Message-----
> From: Tony Lindgren [mailto:tony@atomide.com]
> Sent: Thursday, March 10, 2011 3:33 AM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org
> Subject: Re: [PATCH v12 6/9] dmtimer: switch-over to platform device
> driver
> 
> * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > switch-over to platform device driver through following changes:
> > (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> > in timer-gp.c. This is equivalent of timer_init()->timer->init().
> > (b) modify plat-omap/dmtimer routines to use new register map and
> > platform data.
> 
> This patch breaks booting for 2420 and makes boot hang early
> on 2430. Note that to test with omap-for-linus branch you need
> to disable the following in omap2plus_defconfig:
> 
> CONFIG_ARCH_OMAP3
> CONFIG_ARCH_OMAP4
> CONFIG_CPU_32v6K
I disabled above options on omap-for-linus *WITHOUT* my patch series.
I am still seeing crash. Here is the log.
I tried on two different setups. Not sure if I am missing something.

[...]
[    0.000000] WARNING: at arch/arm/kernel/hw_breakpoint.c:142 get_debug_arch+0x3c/0x68()
[    0.000000] CPUID feature registers not supported. Assuming v6 debug is present.
[    0.000000] Modules linked in:
[    0.000000] [<c073f9b0>] (unwind_backtrace+0x0/0xec) from [<c0762348>] (warn_slowpath_common+0x4c/0x64)
[    0.000000] [<c0762348>] (warn_slowpath_common+0x4c/0x64) from [<c07623e0>] (warn_slowpath_fmt+0x2c/0x3c)
[    0.000000] [<c07623e0>] (warn_slowpath_fmt+0x2c/0x3c) from [<c074029c>] (get_debug_arch+0x3c/0x68)
[    0.000000] [<c074029c>] (get_debug_arch+0x3c/0x68) from [<c07402d0>] (debug_arch_supported+0x8/0x20)
[    0.000000] [<c07402d0>] (debug_arch_supported+0x8/0x20) from [<c074038c>] (hw_breakpoint_slots+0xc/0x50)
[    0.000000] [<c074038c>] (hw_breakpoint_slots+0xc/0x50) from [<c0016a54>] (init_hw_breakpoint+0xc/0x98)
[    0.000000] [<c0016a54>] (init_hw_breakpoint+0xc/0x98) from [<c00169e4>] (perf_event_init+0xb8/0x11c)
[    0.000000] [<c00169e4>] (perf_event_init+0xb8/0x11c) from [<c0008ad0>] (start_kernel+0x150/0x2d8)
[    0.000000] [<c0008ad0>] (start_kernel+0x150/0x2d8) from [<80008034>] (0x80008034)
[    0.000000] ---[ end trace 1b75b31a2719ed1c ]---
[    0.000000] NR_IRQS:409
[    0.000000] IRQ: Found an INTC at 0xfa0fe000 (revision 2.0) with 96 interrupts
[    0.000000] Total of 96 interrupts on 1 active controller
[    0.000000] Unable to handle kernel NULL pointer dereference at virtual address 00000078
[    0.000000] pgd = c0004000
[    0.000000] [00000078] *pgd=00000000
[    0.000000] Internal error: Oops: 5 [#1]
[    0.000000] last sysfs file:
[    0.000000] Modules linked in:
[    0.000000] CPU: 0    Tainted: G        W    (2.6.38-rc7-00165-g0dde52a #199)
[    0.000000] PC is at gpmc_cs_read_reg+0x14/0x20
[    0.000000] LR is at gpmc_cs_mem_enabled+0xc/0x14
[    0.000000] pc : [<c07469b0>]    lr : [<c07469c8>]    psr: 600001d3
[    0.000000] sp : c0c2bf80  ip : 00000028  fp : c0c2bfc4
[    0.000000] r10: 00000000  r9 : 4107b362  r8 : 8002b490
[    0.000000] r7 : c0c3087c  r6 : 00000000  r5 : c0c7a700  r4 : 04000000
[    0.000000] r3 : 00000000  r2 : 00000000  r1 : 00000078  r0 : 00000000
[    0.000000] Flags: nZCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment kernel
[    0.000000] Control: 00c5387f  Table: 80004000  DAC: 00000017
[    0.000000] Process swapper (pid: 0, stack limit = 0xc0c2a268)
[    0.000000] Stack: (0xc0c2bf80 to 0xc0c2c000)
[    0.000000] bf80: 04000000 c0746f9c c0722578 c0c3087c c0c49868 c0ab3a50 0000005f c072257c
[    0.000000] bfa0: c0c7a700 c0722578 c0c3087c 8002b490 4107b362 8002b3f0 00000000 c00114a8
[    0.000000] bfc0: 00000000 00000001 c0008000 c000b314 c072257c c0008adc c0008744 00000000
[    0.000000] bfe0: 00000000 c072257c 00000000 00c5387d c0c2c080 80008034 00000000 00000000
[    0.000000] [<c07469b0>] (gpmc_cs_read_reg+0x14/0x20) from [<c07469c8>] (gpmc_cs_mem_enabled+0xc/0x14)
[    0.000000] [<c07469c8>] (gpmc_cs_mem_enabled+0xc/0x14) from [<c0746f9c>] (gpmc_cs_request+0x60/0x134)
[    0.000000] [<c0746f9c>] (gpmc_cs_request+0x60/0x134) from [<c00114a8>] (omap_h4_init_irq+0x18/0x48)
[    0.000000] [<c00114a8>] (omap_h4_init_irq+0x18/0x48) from [<c000b314>] (init_IRQ+0x14/0x1c)
[    0.000000] [<c000b314>] (init_IRQ+0x14/0x1c) from [<c0008adc>] (start_kernel+0x15c/0x2d8)
[    0.000000] [<c0008adc>] (start_kernel+0x15c/0x2d8) from [<80008034>] (0x80008034)
[    0.000000] Code: e0211093 e59f300c e2811060 e5933000 (e7930001)
[    0.000000] ---[ end trace 1b75b31a2719ed1d ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!

- Tarun

> 
> In general, let's continue with this series after the merge
> window. We must merge intrusive changes like this early around
> -rc2, not late in the merge window.
> 
> Regards,
> 
> Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-09 21:42   ` Tony Lindgren
@ 2011-03-10 15:29     ` DebBarma, Tarun Kanti
  0 siblings, 0 replies; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-10 15:29 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap@vger.kernel.org, Gopinath, Thara

> -----Original Message-----
> From: Tony Lindgren [mailto:tony@atomide.com]
> Sent: Thursday, March 10, 2011 3:12 AM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Gopinath, Thara
> Subject: Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
> 
> * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > 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. It also provides
> > provision to access timers during early boot when pm_runtime framework
> > is not completely up and running.
> > +	 common.o gpio.o dma.o wd_timer.o dmtimer.o
> 
> > new file mode 100755
> > index 0000000..60c410b
> > --- /dev/null
> > +++ b/arch/arm/mach-omap2/dmtimer.c
> 
> Uhh please check the mode changes for this series..
> 
> > new file mode 100755
> > index 0000000..4cfd580
> > --- /dev/null
> > +++ b/arch/arm/mach-omap2/dmtimer.h
> 
> Here too and maybe other places also.
Sorry for the mistake. I will correct and repost. Thanks.
--
Tarun

> 
> Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-10 15:27     ` DebBarma, Tarun Kanti
@ 2011-03-10 17:56       ` Tony Lindgren
  2011-03-11  5:35         ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-10 17:56 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti; +Cc: linux-omap@vger.kernel.org

* DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110310 07:25]:
> > -----Original Message-----
> > From: Tony Lindgren [mailto:tony@atomide.com]
> > Sent: Thursday, March 10, 2011 3:33 AM
> > To: DebBarma, Tarun Kanti
> > Cc: linux-omap@vger.kernel.org
> > Subject: Re: [PATCH v12 6/9] dmtimer: switch-over to platform device
> > driver
> > 
> > * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > > switch-over to platform device driver through following changes:
> > > (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> > > in timer-gp.c. This is equivalent of timer_init()->timer->init().
> > > (b) modify plat-omap/dmtimer routines to use new register map and
> > > platform data.
> > 
> > This patch breaks booting for 2420 and makes boot hang early
> > on 2430. Note that to test with omap-for-linus branch you need
> > to disable the following in omap2plus_defconfig:
> > 
> > CONFIG_ARCH_OMAP3
> > CONFIG_ARCH_OMAP4
> > CONFIG_CPU_32v6K
> I disabled above options on omap-for-linus *WITHOUT* my patch series.
> I am still seeing crash. Here is the log.
> I tried on two different setups. Not sure if I am missing something.

Hmm sounds like H4 needs some attention. Can you try the following
completely untested patch?

Tony

From: Tony Lindgren <tony@atomide.com>
Date: Thu, 10 Mar 2011 09:51:29 -0800
Subject: [PATCH] omap: Fix H4 init_irq to not call h4_init_flash

There should be no reason to call h4_init_flash this
early. It causes problems as things are not yet initialized.

Note: This patch has not been tested.

Not-Yet-Signed-off-by: Tony Lindgren <tony@atomide.com>

--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -299,7 +299,6 @@ static void __init omap_h4_init_early(void)
 static void __init omap_h4_init_irq(void)
 {
 	omap_init_irq();
-	h4_init_flash();
 }
 
 static struct at24_platform_data m24c01 = {
@@ -372,6 +371,7 @@ static void __init omap_h4_init(void)
 	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
 	omap2_usbfs_init(&h4_usb_config);
 	omap_serial_init();
+	h4_init_flash();
 }
 
 static void __init omap_h4_map_io(void)

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-08 23:45 ` [PATCH v12 4/9] OMAP2+: dmtimer: convert " Tarun Kanti DebBarma
  2011-03-09 21:42   ` Tony Lindgren
@ 2011-03-10 22:52   ` Kevin Hilman
  2011-03-11  4:36     ` DebBarma, Tarun Kanti
  2011-03-10 23:14   ` Kevin Hilman
  2011-03-10 23:21   ` Kevin Hilman
  3 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-03-10 22:52 UTC (permalink / raw)
  To: Tarun Kanti DebBarma; +Cc: linux-omap, Thara Gopinath

Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:

> 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. It also provides
> provision to access timers during early boot when pm_runtime framework
> is not completely up and running.
>
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> Acked-by: Cousson, Benoit <b-cousson@ti.com>
> ---
>  arch/arm/mach-omap2/Makefile               |    2 +-
>  arch/arm/mach-omap2/dmtimer.c              |  190 ++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/dmtimer.h              |   32 +++++
>  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    5 +
>  arch/arm/plat-omap/include/plat/dmtimer.h  |    4 +
>  5 files changed, 232 insertions(+), 1 deletions(-)
>  create mode 100755 arch/arm/mach-omap2/dmtimer.c
>  create mode 100755 arch/arm/mach-omap2/dmtimer.h
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 1c3635d..7e5014b 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -4,7 +4,7 @@
>  
>  # Common support
>  obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
> -	 common.o gpio.o dma.o wd_timer.o
> +	 common.o gpio.o dma.o wd_timer.o dmtimer.o
>  
>  omap-2-3-common				= irq.o sdrc.o
>  hwmod-common				= omap_hwmod.o \
> diff --git a/arch/arm/mach-omap2/dmtimer.c b/arch/arm/mach-omap2/dmtimer.c
> new file mode 100755
> index 0000000..60c410b
> --- /dev/null
> +++ b/arch/arm/mach-omap2/dmtimer.c
> @@ -0,0 +1,190 @@
> +/**
> + * OMAP2+ Dual-Mode Timers - platform device registration
> + *
> + * Contains first level initialization routines which extracts timers
> + * information from hwmod database and registers with linux device model.
> + * It also has low level function to change the timer input clock source.
> + *
> + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
> + * Tarun Kanti DebBarma <tarun.kanti@ti.com>
> + * Thara Gopinath <thara@ti.com>
> + *
> + * 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/err.h>
> +#include <linux/slab.h>
> +
> +#include <plat/dmtimer.h>
> +#include <plat/omap_device.h>
> +#include <plat/cpu.h>
> +#include <plat/omap_hwmod.h>
> +
> +static u8 __initdata system_timer_id;

This will initialize to zero, but is never assigned in this patch.
Fortunately it works since there is no "timer0".

Rather than add this here, It should be added in the patch where it is
used (and assigned) (PATCH 6/9).

[...]

> +/**
> + * omap_timer_init - build and register timer device with an
> + * associated timer hwmod
> + * @oh:	timer hwmod pointer to be used to build timer device
> + * @user:	parameter that can be passed from calling hwmod API
> + *
> + * Called by omap_hwmod_for_each_by_class to register each of the timer
> + * devices present in the system. The number of timer devices is known
> + * by parsing through the hwmod database for a given class name. At the
> + * end of function call memory is allocated for timer device and it is
> + * registered to the framework ready to be proved by the driver.
> + */
> +static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
> +{
> +	int id;
> +	int ret = 0;
> +	char *name = "omap_timer";
> +	struct dmtimer_platform_data *pdata;
> +	struct omap_device *od;
> +	struct omap_secure_timer_dev_attr *secure_timer_dev_attr;
> +
> +	/*
> +	 * Extract the IDs from name field in hwmod database
> +	 * and use the same for constructing ids' for the
> +	 * timer devices. In a way, we are avoiding usage of
> +	 * static variable witin the function to do the same.
> +	 * CAUTION: We have to be careful and make sure the
> +	 * name in hwmod database does not change in which case
> +	 * we might either make corresponding change here or
> +	 * switch back static variable mechanism.
> +	 */
> +	sscanf(oh->name, "timer%2d", &id);
> +	if (unlikely(id == system_timer_id))
> +		return ret;
> +
> +	pr_debug("%s: %s\n", __func__, oh->name);
> +
> +	/* do not register secure timer */

Why not?

On GP devices, the secure time should be registered, otherwise boards
using timer12 (Beagle and clones) will stop working.  They work now
because OMAP3 timer12 has not been flagged as secure yet.  That should
be done in this series too.

> +	secure_timer_dev_attr = oh->dev_attr;
> +	if (secure_timer_dev_attr)
> +		if (secure_timer_dev_attr->is_secure_timer)
> +			return ret;
> +

[...]

> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> index 9a34e20..93dd209 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> @@ -3976,6 +3976,11 @@ static struct omap_hwmod_class omap44xx_timer_hwmod_class = {
>  	.rev	= OMAP_TIMER_IP_VERSION_2,
>  };
>  
> +/* secure timer can assign this to .dev_attr field */
> +static struct omap_secure_timer_dev_attr secure_timer_dev_attr = {
> +	.is_secure_timer        = true,
> +};
> +

OK, going in the right direction now, but this is attr is never
associated with any timer since timer12 is still missing from the db.
Please work with Benoit to add GPT12 to the OMAP4 hwmod db.

Also, OMAP3 timer12 needs to be flagged as secure.

Kevin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-08 23:45 ` [PATCH v12 4/9] OMAP2+: dmtimer: convert " Tarun Kanti DebBarma
  2011-03-09 21:42   ` Tony Lindgren
  2011-03-10 22:52   ` Kevin Hilman
@ 2011-03-10 23:14   ` Kevin Hilman
  2011-03-11  4:20     ` DebBarma, Tarun Kanti
  2011-03-10 23:21   ` Kevin Hilman
  3 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-03-10 23:14 UTC (permalink / raw)
  To: Tarun Kanti DebBarma; +Cc: linux-omap, Thara Gopinath

Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:

> 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. It also provides
> provision to access timers during early boot when pm_runtime framework
> is not completely up and running.
>
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> Acked-by: Cousson, Benoit <b-cousson@ti.com>

[...]

> +/**
> + * omap_timer_init - build and register timer device with an
> + * associated timer hwmod
> + * @oh:	timer hwmod pointer to be used to build timer device
> + * @user:	parameter that can be passed from calling hwmod API
> + *
> + * Called by omap_hwmod_for_each_by_class to register each of the timer
> + * devices present in the system. The number of timer devices is known
> + * by parsing through the hwmod database for a given class name. At the
> + * end of function call memory is allocated for timer device and it is
> + * registered to the framework ready to be proved by the driver.
> + */
> +static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
> +{
> +	int id;
> +	int ret = 0;
> +	char *name = "omap_timer";
> +	struct dmtimer_platform_data *pdata;
> +	struct omap_device *od;
> +	struct omap_secure_timer_dev_attr *secure_timer_dev_attr;
> +
> +	/*
> +	 * Extract the IDs from name field in hwmod database
> +	 * and use the same for constructing ids' for the
> +	 * timer devices. In a way, we are avoiding usage of
> +	 * static variable witin the function to do the same.
> +	 * CAUTION: We have to be careful and make sure the
> +	 * name in hwmod database does not change in which case
> +	 * we might either make corresponding change here or
> +	 * switch back static variable mechanism.
> +	 */
> +	sscanf(oh->name, "timer%2d", &id);
> +	if (unlikely(id == system_timer_id))
> +		return ret;

As mentioned already, this check belongs in the patch where the
system_timer is setup.

In addition, I'm not sure this is completely right.

With this check, the system timer will never be converted from an early
device to a real platform_device.   As a result, runtime PM will never
be enabled for this device.

I guess Tony has the final say here, but personally, I don't really like
the special treatment of a system timer, unless it is an init-time only
special treatment.  Since we now have dynamically configurable
clocksources, the concept of a system timer doesn't really exist (except
for in early boot.)  At any time during runtime, we could dynamically
switch the clocksource to a different timer device.  At this point, one
would expect runtime PM for the previous timer to kick in and idle the
timer.  That cannot happen with this approach.

Kevin




^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-08 23:45 ` [PATCH v12 4/9] OMAP2+: dmtimer: convert " Tarun Kanti DebBarma
                     ` (2 preceding siblings ...)
  2011-03-10 23:14   ` Kevin Hilman
@ 2011-03-10 23:21   ` Kevin Hilman
  2011-03-11  4:13     ` DebBarma, Tarun Kanti
  3 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-03-10 23:21 UTC (permalink / raw)
  To: Tarun Kanti DebBarma; +Cc: linux-omap, Thara Gopinath

Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:

> 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. It also provides
> provision to access timers during early boot when pm_runtime framework
> is not completely up and running.
>
> Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> Signed-off-by: Thara Gopinath <thara@ti.com>
> Acked-by: Cousson, Benoit <b-cousson@ti.com>

To make this series more readable, all the system_timer related
additions added in this patch (varialbles and functions) should not be
here since they are not used.  Instead, they should be added in the
patch that uses them.

Kevin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-10 23:21   ` Kevin Hilman
@ 2011-03-11  4:13     ` DebBarma, Tarun Kanti
  0 siblings, 0 replies; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-11  4:13 UTC (permalink / raw)
  To: Hilman, Kevin; +Cc: linux-omap@vger.kernel.org, Gopinath, Thara

> -----Original Message-----
> From: Hilman, Kevin
> Sent: Friday, March 11, 2011 4:51 AM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Gopinath, Thara
> Subject: Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
> 
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> 
> > 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. It also provides
> > provision to access timers during early boot when pm_runtime framework
> > is not completely up and running.
> >
> > Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> > Signed-off-by: Thara Gopinath <thara@ti.com>
> > Acked-by: Cousson, Benoit <b-cousson@ti.com>
> 
> To make this series more readable, all the system_timer related
> additions added in this patch (varialbles and functions) should not be
> here since they are not used.  Instead, they should be added in the
> patch that uses them.
Sure, I will make this change.
--
Tarun
> 
> Kevin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-10 23:14   ` Kevin Hilman
@ 2011-03-11  4:20     ` DebBarma, Tarun Kanti
  2011-03-11 19:13       ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-11  4:20 UTC (permalink / raw)
  To: Hilman, Kevin; +Cc: linux-omap@vger.kernel.org, Gopinath, Thara

> -----Original Message-----
> From: Hilman, Kevin
> Sent: Friday, March 11, 2011 4:44 AM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Gopinath, Thara
> Subject: Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
> 
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> 
> > 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. It also provides
> > provision to access timers during early boot when pm_runtime framework
> > is not completely up and running.
> >
> > Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> > Signed-off-by: Thara Gopinath <thara@ti.com>
> > Acked-by: Cousson, Benoit <b-cousson@ti.com>
> 
> [...]
> 
> > +/**
> > + * omap_timer_init - build and register timer device with an
> > + * associated timer hwmod
> > + * @oh:	timer hwmod pointer to be used to build timer device
> > + * @user:	parameter that can be passed from calling hwmod API
> > + *
> > + * Called by omap_hwmod_for_each_by_class to register each of the timer
> > + * devices present in the system. The number of timer devices is known
> > + * by parsing through the hwmod database for a given class name. At the
> > + * end of function call memory is allocated for timer device and it is
> > + * registered to the framework ready to be proved by the driver.
> > + */
> > +static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
> > +{
> > +	int id;
> > +	int ret = 0;
> > +	char *name = "omap_timer";
> > +	struct dmtimer_platform_data *pdata;
> > +	struct omap_device *od;
> > +	struct omap_secure_timer_dev_attr *secure_timer_dev_attr;
> > +
> > +	/*
> > +	 * Extract the IDs from name field in hwmod database
> > +	 * and use the same for constructing ids' for the
> > +	 * timer devices. In a way, we are avoiding usage of
> > +	 * static variable witin the function to do the same.
> > +	 * CAUTION: We have to be careful and make sure the
> > +	 * name in hwmod database does not change in which case
> > +	 * we might either make corresponding change here or
> > +	 * switch back static variable mechanism.
> > +	 */
> > +	sscanf(oh->name, "timer%2d", &id);
> > +	if (unlikely(id == system_timer_id))
> > +		return ret;
> 
> As mentioned already, this check belongs in the patch where the
> system_timer is setup.
Right, I will change.

> 
> In addition, I'm not sure this is completely right.
> 
> With this check, the system timer will never be converted from an early
> device to a real platform_device.   As a result, runtime PM will never
> be enabled for this device.
That's right.

> 
> I guess Tony has the final say here, but personally, I don't really like
> the special treatment of a system timer, unless it is an init-time only
> special treatment.  Since we now have dynamically configurable
> clocksources, the concept of a system timer doesn't really exist (except
> for in early boot.)  At any time during runtime, we could dynamically
> switch the clocksource to a different timer device.  At this point, one
> would expect runtime PM for the previous timer to kick in and idle the
> timer.  That cannot happen with this approach.
I am open to suggestions.

> 
> Kevin
> 
> 


^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-10 22:52   ` Kevin Hilman
@ 2011-03-11  4:36     ` DebBarma, Tarun Kanti
  0 siblings, 0 replies; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-11  4:36 UTC (permalink / raw)
  To: Hilman, Kevin; +Cc: linux-omap@vger.kernel.org, Gopinath, Thara

> -----Original Message-----
> From: Hilman, Kevin
> Sent: Friday, March 11, 2011 4:22 AM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org; Gopinath, Thara
> Subject: Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
> 
> Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> 
> > 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. It also provides
> > provision to access timers during early boot when pm_runtime framework
> > is not completely up and running.
> >
> > Signed-off-by: Tarun Kanti DebBarma <tarun.kanti@ti.com>
> > Signed-off-by: Thara Gopinath <thara@ti.com>
> > Acked-by: Cousson, Benoit <b-cousson@ti.com>
> > ---
> >  arch/arm/mach-omap2/Makefile               |    2 +-
> >  arch/arm/mach-omap2/dmtimer.c              |  190
> ++++++++++++++++++++++++++++
> >  arch/arm/mach-omap2/dmtimer.h              |   32 +++++
> >  arch/arm/mach-omap2/omap_hwmod_44xx_data.c |    5 +
> >  arch/arm/plat-omap/include/plat/dmtimer.h  |    4 +
> >  5 files changed, 232 insertions(+), 1 deletions(-)
> >  create mode 100755 arch/arm/mach-omap2/dmtimer.c
> >  create mode 100755 arch/arm/mach-omap2/dmtimer.h
> >
> > diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> > index 1c3635d..7e5014b 100644
> > --- a/arch/arm/mach-omap2/Makefile
> > +++ b/arch/arm/mach-omap2/Makefile
> > @@ -4,7 +4,7 @@
> >
> >  # Common support
> >  obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
> pm.o \
> > -	 common.o gpio.o dma.o wd_timer.o
> > +	 common.o gpio.o dma.o wd_timer.o dmtimer.o
> >
> >  omap-2-3-common				= irq.o sdrc.o
> >  hwmod-common				= omap_hwmod.o \
> > diff --git a/arch/arm/mach-omap2/dmtimer.c b/arch/arm/mach-
> omap2/dmtimer.c
> > new file mode 100755
> > index 0000000..60c410b
> > --- /dev/null
> > +++ b/arch/arm/mach-omap2/dmtimer.c
> > @@ -0,0 +1,190 @@
> > +/**
> > + * OMAP2+ Dual-Mode Timers - platform device registration
> > + *
> > + * Contains first level initialization routines which extracts timers
> > + * information from hwmod database and registers with linux device
> model.
> > + * It also has low level function to change the timer input clock
> source.
> > + *
> > + * Copyright (C) 2010 Texas Instruments Incorporated -
> http://www.ti.com/
> > + * Tarun Kanti DebBarma <tarun.kanti@ti.com>
> > + * Thara Gopinath <thara@ti.com>
> > + *
> > + * 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/err.h>
> > +#include <linux/slab.h>
> > +
> > +#include <plat/dmtimer.h>
> > +#include <plat/omap_device.h>
> > +#include <plat/cpu.h>
> > +#include <plat/omap_hwmod.h>
> > +
> > +static u8 __initdata system_timer_id;
> 
> This will initialize to zero, but is never assigned in this patch.
> Fortunately it works since there is no "timer0".
Right, thanks.

> 
> Rather than add this here, It should be added in the patch where it is
> used (and assigned) (PATCH 6/9).
Yes.

> 
> [...]
> 
> > +/**
> > + * omap_timer_init - build and register timer device with an
> > + * associated timer hwmod
> > + * @oh:	timer hwmod pointer to be used to build timer device
> > + * @user:	parameter that can be passed from calling hwmod API
> > + *
> > + * Called by omap_hwmod_for_each_by_class to register each of the timer
> > + * devices present in the system. The number of timer devices is known
> > + * by parsing through the hwmod database for a given class name. At the
> > + * end of function call memory is allocated for timer device and it is
> > + * registered to the framework ready to be proved by the driver.
> > + */
> > +static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
> > +{
> > +	int id;
> > +	int ret = 0;
> > +	char *name = "omap_timer";
> > +	struct dmtimer_platform_data *pdata;
> > +	struct omap_device *od;
> > +	struct omap_secure_timer_dev_attr *secure_timer_dev_attr;
> > +
> > +	/*
> > +	 * Extract the IDs from name field in hwmod database
> > +	 * and use the same for constructing ids' for the
> > +	 * timer devices. In a way, we are avoiding usage of
> > +	 * static variable witin the function to do the same.
> > +	 * CAUTION: We have to be careful and make sure the
> > +	 * name in hwmod database does not change in which case
> > +	 * we might either make corresponding change here or
> > +	 * switch back static variable mechanism.
> > +	 */
> > +	sscanf(oh->name, "timer%2d", &id);
> > +	if (unlikely(id == system_timer_id))
> > +		return ret;
> > +
> > +	pr_debug("%s: %s\n", __func__, oh->name);
> > +
> > +	/* do not register secure timer */
> 
> Why not?
> 
> On GP devices, the secure time should be registered, otherwise boards
> using timer12 (Beagle and clones) will stop working.  They work now
> because OMAP3 timer12 has not been flagged as secure yet.  That should
> be done in this series too.
OK, I got it. Thanks.
> 
> > +	secure_timer_dev_attr = oh->dev_attr;
> > +	if (secure_timer_dev_attr)
> > +		if (secure_timer_dev_attr->is_secure_timer)
> > +			return ret;
> > +
> 
> [...]
> 
> > diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-
> omap2/omap_hwmod_44xx_data.c
> > index 9a34e20..93dd209 100644
> > --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> > +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> > @@ -3976,6 +3976,11 @@ static struct omap_hwmod_class
> omap44xx_timer_hwmod_class = {
> >  	.rev	= OMAP_TIMER_IP_VERSION_2,
> >  };
> >
> > +/* secure timer can assign this to .dev_attr field */
> > +static struct omap_secure_timer_dev_attr secure_timer_dev_attr = {
> > +	.is_secure_timer        = true,
> > +};
> > +
> 
> OK, going in the right direction now, but this is attr is never
> associated with any timer since timer12 is still missing from the db.
> Please work with Benoit to add GPT12 to the OMAP4 hwmod db.
Yes, I will work with him and get this done.

> 
> Also, OMAP3 timer12 needs to be flagged as secure.
Sure.
--
Tarun
> 
> Kevin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-10 17:56       ` Tony Lindgren
@ 2011-03-11  5:35         ` DebBarma, Tarun Kanti
  2011-03-11 12:45           ` G, Manjunath Kondaiah
  2011-03-11 19:14           ` Tony Lindgren
  0 siblings, 2 replies; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-11  5:35 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap@vger.kernel.org

[...]
> > >
> > > * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > > > switch-over to platform device driver through following changes:
> > > > (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> > > > in timer-gp.c. This is equivalent of timer_init()->timer->init().
> > > > (b) modify plat-omap/dmtimer routines to use new register map and
> > > > platform data.
> > >
> > > This patch breaks booting for 2420 and makes boot hang early
> > > on 2430. Note that to test with omap-for-linus branch you need
> > > to disable the following in omap2plus_defconfig:
> > >
> > > CONFIG_ARCH_OMAP3
> > > CONFIG_ARCH_OMAP4
> > > CONFIG_CPU_32v6K
> > I disabled above options on omap-for-linus *WITHOUT* my patch series.
> > I am still seeing crash. Here is the log.
> > I tried on two different setups. Not sure if I am missing something.
> 
> Hmm sounds like H4 needs some attention. Can you try the following
> completely untested patch?

This works fine!
--
Tarun

> 
> Tony
> 
> From: Tony Lindgren <tony@atomide.com>
> Date: Thu, 10 Mar 2011 09:51:29 -0800
> Subject: [PATCH] omap: Fix H4 init_irq to not call h4_init_flash
> 
> There should be no reason to call h4_init_flash this
> early. It causes problems as things are not yet initialized.
> 
> Note: This patch has not been tested.
> 
> Not-Yet-Signed-off-by: Tony Lindgren <tony@atomide.com>
> 
> --- a/arch/arm/mach-omap2/board-h4.c
> +++ b/arch/arm/mach-omap2/board-h4.c
> @@ -299,7 +299,6 @@ static void __init omap_h4_init_early(void)
>  static void __init omap_h4_init_irq(void)
>  {
>  	omap_init_irq();
> -	h4_init_flash();
>  }
> 
>  static struct at24_platform_data m24c01 = {
> @@ -372,6 +371,7 @@ static void __init omap_h4_init(void)
>  	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
>  	omap2_usbfs_init(&h4_usb_config);
>  	omap_serial_init();
> +	h4_init_flash();
>  }
> 
>  static void __init omap_h4_map_io(void)

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-11  5:35         ` DebBarma, Tarun Kanti
@ 2011-03-11 12:45           ` G, Manjunath Kondaiah
  2011-03-11 19:15             ` Tony Lindgren
  2011-03-11 19:14           ` Tony Lindgren
  1 sibling, 1 reply; 40+ messages in thread
From: G, Manjunath Kondaiah @ 2011-03-11 12:45 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

On Fri, Mar 11, 2011 at 11:05:25AM +0530, DebBarma, Tarun Kanti wrote:
> [...]
> > > >
> > > > * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > > > > switch-over to platform device driver through following changes:
> > > > > (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> > > > > in timer-gp.c. This is equivalent of timer_init()->timer->init().
> > > > > (b) modify plat-omap/dmtimer routines to use new register map and
> > > > > platform data.
> > > >
> > > > This patch breaks booting for 2420 and makes boot hang early
> > > > on 2430. Note that to test with omap-for-linus branch you need
> > > > to disable the following in omap2plus_defconfig:
> > > >
> > > > CONFIG_ARCH_OMAP3
> > > > CONFIG_ARCH_OMAP4
> > > > CONFIG_CPU_32v6K
> > > I disabled above options on omap-for-linus *WITHOUT* my patch series.
> > > I am still seeing crash. Here is the log.
> > > I tried on two different setups. Not sure if I am missing something.
> > 
> > Hmm sounds like H4 needs some attention. Can you try the following
> > completely untested patch?
> 
> This works fine!

I tried to use below patch for booting  OMAP2420 H4 on top of:
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
Branch: omap-for-linus
commit 94a06b74e724caabcf0464c81527cfbcae0c8aff
Merge: 0dde52a 9062511
Author: Tony Lindgren <tony@atomide.com>
Merge branch 'for_2.6.39/pm-misc' of
ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm
into omap-for-linus

Looks like it stops after uncompressing kernel. Same setup works fine
with tag v2.6.37.

OMAP242x H4 # boot                                                              
Using MAC Address 10:20:30:40:50:61                                             
TFTP from server 10.24.244.97; our IP address is 10.24.244.196                  
Filename 'uImage'.                                                              
Load address: 0x80300000                                                        
Loading:
#################################################################      
         #################################################################      
         #################################################################      
         #################################################################      
         #################################################################      
         #################################################################      
         #################################################################      
         #################################################################      
         #########################################################              
done                                                                            
Bytes transferred = 2950216 (2d0448 hex)                                        
## Booting image at 80300000 ...                                                
   Image Name:   Linux-2.6.38-rc8-00188-g94a06b7-                               
   Image Type:   ARM Linux Kernel Image (uncompressed)                          
   Data Size:    2950152 Bytes =  2.8 MB                                        
   Load Address: 80008000                                                       
   Entry Point:  80008000                                                       
   Verifying Checksum ... OK                                                    
OK                                                                              
                                                                                
Starting kernel ...                                                             
                                                                                
Uncompressing Linux... done, booting the kernel.                                

-Manjunath

> --
> Tarun
> 
> > 
> > Tony
> > 
> > From: Tony Lindgren <tony@atomide.com>
> > Date: Thu, 10 Mar 2011 09:51:29 -0800
> > Subject: [PATCH] omap: Fix H4 init_irq to not call h4_init_flash
> > 
> > There should be no reason to call h4_init_flash this
> > early. It causes problems as things are not yet initialized.
> > 
> > Note: This patch has not been tested.
> > 
> > Not-Yet-Signed-off-by: Tony Lindgren <tony@atomide.com>
> > 
> > --- a/arch/arm/mach-omap2/board-h4.c
> > +++ b/arch/arm/mach-omap2/board-h4.c
> > @@ -299,7 +299,6 @@ static void __init omap_h4_init_early(void)
> >  static void __init omap_h4_init_irq(void)
> >  {
> >  	omap_init_irq();
> > -	h4_init_flash();
> >  }
> > 
> >  static struct at24_platform_data m24c01 = {
> > @@ -372,6 +371,7 @@ static void __init omap_h4_init(void)
> >  	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
> >  	omap2_usbfs_init(&h4_usb_config);
> >  	omap_serial_init();
> > +	h4_init_flash();
> >  }
> > 
> >  static void __init omap_h4_map_io(void)
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-11  4:20     ` DebBarma, Tarun Kanti
@ 2011-03-11 19:13       ` Tony Lindgren
  2011-03-12  0:03         ` Kevin Hilman
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-11 19:13 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Hilman, Kevin, linux-omap@vger.kernel.org, Gopinath, Thara

* DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110310 20:18]:
> > From: Hilman, Kevin
> > 
> > I guess Tony has the final say here, but personally, I don't really like
> > the special treatment of a system timer, unless it is an init-time only
> > special treatment.  Since we now have dynamically configurable
> > clocksources, the concept of a system timer doesn't really exist (except
> > for in early boot.)  At any time during runtime, we could dynamically
> > switch the clocksource to a different timer device.  At this point, one
> > would expect runtime PM for the previous timer to kick in and idle the
> > timer.  That cannot happen with this approach.
>
> I am open to suggestions.

There's no need to dynamically change the clocksource. We can to set up
things so we have a system timer running with minimal code and faster
clock rate. Then we can use a separate timer with the 32KiHZ source
just to provide wake-up events for idle modes. And this second wake-up
timer can be just a regular device driver.

The system timer code needs to be fast. And I don't want to add any
dependencies to anything except clock framework. Like I've said, the
rest of the timers can be just a regular device driver.

I'll post some patches after the merge window for the system timer
related code.

Regards,

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-11  5:35         ` DebBarma, Tarun Kanti
  2011-03-11 12:45           ` G, Manjunath Kondaiah
@ 2011-03-11 19:14           ` Tony Lindgren
  2011-03-14  6:48             ` DebBarma, Tarun Kanti
  1 sibling, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-11 19:14 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti; +Cc: linux-omap@vger.kernel.org

* DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110310 21:33]:
> [...]
> > > >
> > > > * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > > > > switch-over to platform device driver through following changes:
> > > > > (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> > > > > in timer-gp.c. This is equivalent of timer_init()->timer->init().
> > > > > (b) modify plat-omap/dmtimer routines to use new register map and
> > > > > platform data.
> > > >
> > > > This patch breaks booting for 2420 and makes boot hang early
> > > > on 2430. Note that to test with omap-for-linus branch you need
> > > > to disable the following in omap2plus_defconfig:
> > > >
> > > > CONFIG_ARCH_OMAP3
> > > > CONFIG_ARCH_OMAP4
> > > > CONFIG_CPU_32v6K
> > > I disabled above options on omap-for-linus *WITHOUT* my patch series.
> > > I am still seeing crash. Here is the log.
> > > I tried on two different setups. Not sure if I am missing something.
> > 
> > Hmm sounds like H4 needs some attention. Can you try the following
> > completely untested patch?
> 
> This works fine!

OK thanks, can I add your Tested-by then?

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-11 12:45           ` G, Manjunath Kondaiah
@ 2011-03-11 19:15             ` Tony Lindgren
  2011-03-12  4:20               ` G, Manjunath Kondaiah
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-11 19:15 UTC (permalink / raw)
  To: G, Manjunath Kondaiah; +Cc: DebBarma, Tarun Kanti, linux-omap@vger.kernel.org

* G, Manjunath Kondaiah <manjugk@ti.com> [110311 04:45]:
> On Fri, Mar 11, 2011 at 11:05:25AM +0530, DebBarma, Tarun Kanti wrote:
> > [...]
> > > > >
> > > > > * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > > > > > switch-over to platform device driver through following changes:
> > > > > > (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> > > > > > in timer-gp.c. This is equivalent of timer_init()->timer->init().
> > > > > > (b) modify plat-omap/dmtimer routines to use new register map and
> > > > > > platform data.
> > > > >
> > > > > This patch breaks booting for 2420 and makes boot hang early
> > > > > on 2430. Note that to test with omap-for-linus branch you need
> > > > > to disable the following in omap2plus_defconfig:
> > > > >
> > > > > CONFIG_ARCH_OMAP3
> > > > > CONFIG_ARCH_OMAP4
> > > > > CONFIG_CPU_32v6K
> > > > I disabled above options on omap-for-linus *WITHOUT* my patch series.
> > > > I am still seeing crash. Here is the log.
> > > > I tried on two different setups. Not sure if I am missing something.
> > > 
> > > Hmm sounds like H4 needs some attention. Can you try the following
> > > completely untested patch?
> > 
> > This works fine!
> 
> I tried to use below patch for booting  OMAP2420 H4 on top of:
> git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
> Branch: omap-for-linus
> commit 94a06b74e724caabcf0464c81527cfbcae0c8aff
> Merge: 0dde52a 9062511
> Author: Tony Lindgren <tony@atomide.com>
> Merge branch 'for_2.6.39/pm-misc' of
> ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm
> into omap-for-linus
> 
> Looks like it stops after uncompressing kernel. Same setup works fine
> with tag v2.6.37.

See the mails earlier in this thread on what you currently need to
disable in .config in omap-for-linus branch to boot omap2 machines.
This will get sorted out in mainline when Russell's ARMv6K related
patches get merged during the merge window.

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-11 19:13       ` Tony Lindgren
@ 2011-03-12  0:03         ` Kevin Hilman
  2011-03-14 17:12           ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-03-12  0:03 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: DebBarma, Tarun Kanti, linux-omap@vger.kernel.org,
	Gopinath, Thara

Tony Lindgren <tony@atomide.com> writes:

> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110310 20:18]:
>> > From: Hilman, Kevin
>> > 
>> > I guess Tony has the final say here, but personally, I don't really like
>> > the special treatment of a system timer, unless it is an init-time only
>> > special treatment.  Since we now have dynamically configurable
>> > clocksources, the concept of a system timer doesn't really exist (except
>> > for in early boot.)  At any time during runtime, we could dynamically
>> > switch the clocksource to a different timer device.  At this point, one
>> > would expect runtime PM for the previous timer to kick in and idle the
>> > timer.  That cannot happen with this approach.
>>
>> I am open to suggestions.
>
> There's no need to dynamically change the clocksource. We can to set up
> things so we have a system timer running with minimal code and faster
> clock rate. Then we can use a separate timer with the 32KiHZ source
> just to provide wake-up events for idle modes. And this second wake-up
> timer can be just a regular device driver.
>
> The system timer code needs to be fast. And I don't want to add any
> dependencies to anything except clock framework. Like I've said, the
> rest of the timers can be just a regular device driver.

There are a couple problems with this approach.  The special case
handling of a "system" timer leads to duplicate code (this series is a
good example.)

The other problem is PM.

If we switch away from the original system timer (for whatever reason),
since it is not a regular device, it will not have runtime PM We'll then
need special case PM code for the system timer, which I think is wasted
effort.

If this can be done such that the system timer is eventually a regular
device driver, then that should be fine. 

Kevin

> I'll post some patches after the merge window for the system timer
> related code.
>
> Regards,
>
> Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-11 19:15             ` Tony Lindgren
@ 2011-03-12  4:20               ` G, Manjunath Kondaiah
  0 siblings, 0 replies; 40+ messages in thread
From: G, Manjunath Kondaiah @ 2011-03-12  4:20 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: G, Manjunath Kondaiah, DebBarma, Tarun Kanti,
	linux-omap@vger.kernel.org

On Fri, Mar 11, 2011 at 11:15:48AM -0800, Tony Lindgren wrote:
> * G, Manjunath Kondaiah <manjugk@ti.com> [110311 04:45]:
> > On Fri, Mar 11, 2011 at 11:05:25AM +0530, DebBarma, Tarun Kanti wrote:
> > > [...]
> > > > > >
> > > > > > * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > > > > > > switch-over to platform device driver through following changes:
> > > > > > > (a) initiate dmtimer early initialization from omap2_gp_timer_init()
> > > > > > > in timer-gp.c. This is equivalent of timer_init()->timer->init().
> > > > > > > (b) modify plat-omap/dmtimer routines to use new register map and
> > > > > > > platform data.
> > > > > >
> > > > > > This patch breaks booting for 2420 and makes boot hang early
> > > > > > on 2430. Note that to test with omap-for-linus branch you need
> > > > > > to disable the following in omap2plus_defconfig:
> > > > > >
> > > > > > CONFIG_ARCH_OMAP3
> > > > > > CONFIG_ARCH_OMAP4
> > > > > > CONFIG_CPU_32v6K
> > > > > I disabled above options on omap-for-linus *WITHOUT* my patch series.
> > > > > I am still seeing crash. Here is the log.
> > > > > I tried on two different setups. Not sure if I am missing something.
> > > > 
> > > > Hmm sounds like H4 needs some attention. Can you try the following
> > > > completely untested patch?
> > > 
> > > This works fine!
> > 
> > I tried to use below patch for booting  OMAP2420 H4 on top of:
> > git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
> > Branch: omap-for-linus
> > commit 94a06b74e724caabcf0464c81527cfbcae0c8aff
> > Merge: 0dde52a 9062511
> > Author: Tony Lindgren <tony@atomide.com>
> > Merge branch 'for_2.6.39/pm-misc' of
> > ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm
> > into omap-for-linus
> > 
> > Looks like it stops after uncompressing kernel. Same setup works fine
> > with tag v2.6.37.
> 
> See the mails earlier in this thread on what you currently need to
> disable in .config in omap-for-linus branch to boot omap2 machines.
> This will get sorted out in mainline when Russell's ARMv6K related
> patches get merged during the merge window.

Thanks. Disabling OMAP3 and OMAP4 along with this patch is working fine.
Tested on OMAP2420-H4 and OMAP2430-SDP.

-Manjunath 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 6/9] dmtimer: switch-over to platform device driver
  2011-03-11 19:14           ` Tony Lindgren
@ 2011-03-14  6:48             ` DebBarma, Tarun Kanti
  0 siblings, 0 replies; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-14  6:48 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap@vger.kernel.org

> -----Original Message-----
> From: Tony Lindgren [mailto:tony@atomide.com]
> Sent: Saturday, March 12, 2011 12:44 AM
> To: DebBarma, Tarun Kanti
> Cc: linux-omap@vger.kernel.org
> Subject: Re: [PATCH v12 6/9] dmtimer: switch-over to platform device
> driver
> 
> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110310 21:33]:
> > [...]
> > > > >
> > > > > * Tarun Kanti DebBarma <tarun.kanti@ti.com> [110308 15:41]:
> > > > > > switch-over to platform device driver through following changes:
> > > > > > (a) initiate dmtimer early initialization from
> omap2_gp_timer_init()
> > > > > > in timer-gp.c. This is equivalent of timer_init()->timer-
> >init().
> > > > > > (b) modify plat-omap/dmtimer routines to use new register map
> and
> > > > > > platform data.
> > > > >
> > > > > This patch breaks booting for 2420 and makes boot hang early
> > > > > on 2430. Note that to test with omap-for-linus branch you need
> > > > > to disable the following in omap2plus_defconfig:
> > > > >
> > > > > CONFIG_ARCH_OMAP3
> > > > > CONFIG_ARCH_OMAP4
> > > > > CONFIG_CPU_32v6K
> > > > I disabled above options on omap-for-linus *WITHOUT* my patch
> series.
> > > > I am still seeing crash. Here is the log.
> > > > I tried on two different setups. Not sure if I am missing something.
> > >
> > > Hmm sounds like H4 needs some attention. Can you try the following
> > > completely untested patch?
> >
> > This works fine!
> 
> OK thanks, can I add your Tested-by then?
YES.

> 
> Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-12  0:03         ` Kevin Hilman
@ 2011-03-14 17:12           ` Tony Lindgren
  2011-03-17 22:00             ` Kevin Hilman
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-14 17:12 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: DebBarma, Tarun Kanti, linux-omap@vger.kernel.org,
	Gopinath, Thara

* Kevin Hilman <khilman@ti.com> [110311 16:00]:
> Tony Lindgren <tony@atomide.com> writes:
> 
> > * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110310 20:18]:
> >> > From: Hilman, Kevin
> >> > 
> >> > I guess Tony has the final say here, but personally, I don't really like
> >> > the special treatment of a system timer, unless it is an init-time only
> >> > special treatment.  Since we now have dynamically configurable
> >> > clocksources, the concept of a system timer doesn't really exist (except
> >> > for in early boot.)  At any time during runtime, we could dynamically
> >> > switch the clocksource to a different timer device.  At this point, one
> >> > would expect runtime PM for the previous timer to kick in and idle the
> >> > timer.  That cannot happen with this approach.
> >>
> >> I am open to suggestions.
> >
> > There's no need to dynamically change the clocksource. We can to set up
> > things so we have a system timer running with minimal code and faster
> > clock rate. Then we can use a separate timer with the 32KiHZ source
> > just to provide wake-up events for idle modes. And this second wake-up
> > timer can be just a regular device driver.
> >
> > The system timer code needs to be fast. And I don't want to add any
> > dependencies to anything except clock framework. Like I've said, the
> > rest of the timers can be just a regular device driver.
> 
> There are a couple problems with this approach.  The special case
> handling of a "system" timer leads to duplicate code (this series is a
> good example.)

I think the related inline functions can be shared.
 
> The other problem is PM.
> 
> If we switch away from the original system timer (for whatever reason),
> since it is not a regular device, it will not have runtime PM We'll then
> need special case PM code for the system timer, which I think is wasted
> effort.

This should not cause problems either, there should not be any need to
switch the timers in the setup what I'm thinking.

In the long run, think "local timer" for runtime, and then "wakeup timer"
that gets only programmed when we enter idle. The "local timer" will
continue operating normally after we wake-up and the "wakeup timer"
will be just one shot event. Of course in the omap[23] case the
"local timer" is really a faster dmtimer, but in the omap4+ case there's
are real local timers.

> If this can be done such that the system timer is eventually a regular
> device driver, then that should be fine. 

In this setup there should not be need to mess with the system timer
after boot as we don't need to switch clock sources.

Regards,

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-14 17:12           ` Tony Lindgren
@ 2011-03-17 22:00             ` Kevin Hilman
  2011-03-19  0:27               ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-03-17 22:00 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: DebBarma, Tarun Kanti, linux-omap@vger.kernel.org,
	Gopinath, Thara

Tony Lindgren <tony@atomide.com> writes:

> * Kevin Hilman <khilman@ti.com> [110311 16:00]:
>> Tony Lindgren <tony@atomide.com> writes:
>> 
>> > * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110310 20:18]:
>> >> > From: Hilman, Kevin
>> >> > 
>> >> > I guess Tony has the final say here, but personally, I don't really like
>> >> > the special treatment of a system timer, unless it is an init-time only
>> >> > special treatment.  Since we now have dynamically configurable
>> >> > clocksources, the concept of a system timer doesn't really exist (except
>> >> > for in early boot.)  At any time during runtime, we could dynamically
>> >> > switch the clocksource to a different timer device.  At this point, one
>> >> > would expect runtime PM for the previous timer to kick in and idle the
>> >> > timer.  That cannot happen with this approach.
>> >>
>> >> I am open to suggestions.
>> >
>> > There's no need to dynamically change the clocksource. We can to set up
>> > things so we have a system timer running with minimal code and faster
>> > clock rate. Then we can use a separate timer with the 32KiHZ source
>> > just to provide wake-up events for idle modes. And this second wake-up
>> > timer can be just a regular device driver.
>> >
>> > The system timer code needs to be fast. And I don't want to add any
>> > dependencies to anything except clock framework. Like I've said, the
>> > rest of the timers can be just a regular device driver.
>> 
>> There are a couple problems with this approach.  The special case
>> handling of a "system" timer leads to duplicate code (this series is a
>> good example.)
>
> I think the related inline functions can be shared.
>  

The way it is currently coded results in duplicate code.  One of them
uses the clock API directly, the other uses runtime PM.

>> The other problem is PM.
>> 
>> If we switch away from the original system timer (for whatever reason),
>> since it is not a regular device, it will not have runtime PM We'll then
>> need special case PM code for the system timer, which I think is wasted
>> effort.
>
> This should not cause problems either, there should not be any need to
> switch the timers in the setup what I'm thinking.
>
> In the long run, think "local timer" for runtime, and then "wakeup timer"
> that gets only programmed when we enter idle. The "local timer" will
> continue operating normally after we wake-up and the "wakeup timer"
> will be just one shot event. Of course in the omap[23] case the
> "local timer" is really a faster dmtimer, but in the omap4+ case there's
> are real local timers.

>> If this can be done such that the system timer is eventually a regular
>> device driver, then that should be fine. 
>
> In this setup there should not be need to mess with the system timer
> after boot as we don't need to switch clock sources.

I think we're confusing terminology.  By system timer, I think you mean
the clockevent, right?

The situation you described above requires switching clockevents for
sure.  

In addition, we already have a usecase for switching the clocksource as
well.  We currently setup a single clocksource using the timer_32k (not
a dmtimer.)  However, we already have use-cases where we would like to
switch to a higher resolution clocksource (e.g. trace infrastructure for
PM instrumentation.)

The whole point of switching these to real drivers is so they can use
runtime PM.    Then, as soon as they are unused, runtime PM will kick in
and ensure the hardware is properly idle.

Kevin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-17 22:00             ` Kevin Hilman
@ 2011-03-19  0:27               ` Tony Lindgren
  2011-03-19  4:34                 ` Santosh Shilimkar
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-19  0:27 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: DebBarma, Tarun Kanti, linux-omap@vger.kernel.org,
	Gopinath, Thara

* Kevin Hilman <khilman@ti.com> [110317 14:58]:
> Tony Lindgren <tony@atomide.com> writes:
> >
> > In the long run, think "local timer" for runtime, and then "wakeup timer"
> > that gets only programmed when we enter idle. The "local timer" will
> > continue operating normally after we wake-up and the "wakeup timer"
> > will be just one shot event. Of course in the omap[23] case the
> > "local timer" is really a faster dmtimer, but in the omap4+ case there's
> > are real local timers.
> 
> >> If this can be done such that the system timer is eventually a regular
> >> device driver, then that should be fine. 
> >
> > In this setup there should not be need to mess with the system timer
> > after boot as we don't need to switch clock sources.
> 
> I think we're confusing terminology.  By system timer, I think you mean
> the clockevent, right?

Yes.
 
> The situation you described above requires switching clockevents for
> sure.  

No it won't, because we can use a separate physical timer for runtime and
wake-up events.
 
> In addition, we already have a usecase for switching the clocksource as
> well.  We currently setup a single clocksource using the timer_32k (not
> a dmtimer.)  However, we already have use-cases where we would like to
> switch to a higher resolution clocksource (e.g. trace infrastructure for
> PM instrumentation.)

Again that can be done with a separate physical timer, no need to switch
and reprogram the clocksource.
 
> The whole point of switching these to real drivers is so they can use
> runtime PM.    Then, as soon as they are unused, runtime PM will kick in
> and ensure the hardware is properly idle.

Yes that makes sense for the device driver used timers and for the
wake-up timer.

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-19  0:27               ` Tony Lindgren
@ 2011-03-19  4:34                 ` Santosh Shilimkar
  2011-03-21 17:07                   ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: Santosh Shilimkar @ 2011-03-19  4:34 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Tarun Kanti DebBarma, linux-omap, Thara Gopinath, Kevin Hilman

> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> owner@vger.kernel.org] On Behalf Of Tony Lindgren
> Sent: Saturday, March 19, 2011 5:57 AM
> To: Kevin Hilman
> Cc: DebBarma, Tarun Kanti; linux-omap@vger.kernel.org; Gopinath,
> Thara
> Subject: Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform
> devices
>
> * Kevin Hilman <khilman@ti.com> [110317 14:58]:
> > Tony Lindgren <tony@atomide.com> writes:
> > >
> > > In the long run, think "local timer" for runtime, and then
> > > "wakeup timer" that gets only programmed when we enter idle.
> > >  The "local timer" will continue operating normally after we
> > > wake-up and the "wakeuptimer" will be just one shot event.
> > > Of course in the omap[23] case the "local timer" is really a
> > > there's are real local timers.

This is already the case for OMAP4 with PM series. But it doesn't
work the way it is stated above. Wakeup timer is always programmed
and kept handy by the timer framework because switching of
clock event happened dynamically and it's too late to reprogram
the next timer expiry etc. What framework does, is just switch
the clock-event to wakeup capable clock-event.

> > >> If this can be done such that the system timer is eventually a
> > >> regular device driver, then that should be fine.
> > >
> > > In this setup there should not be need to mess with the system
> > > timer  after boot as we don't need to switch clock sources.
> >
> > I think we're confusing terminology.  By system timer, I think you
> > mean the clockevent, right?
>
> Yes.
>
> > The situation you described above requires switching clockevents
> > for sure.
>
> No it won't, because we can use a separate physical timer for
> runtime and wake-up events.
>
Why do you want to waste one timer hardware for this purpose
alone especially when generic framework has a support?

> > In addition, we already have a usecase for switching the
> > clocksource as well.  We currently setup a single clocksource
> > (not using the timer_32ka dmtimer.)  However, we already have
> > use-cases where we would like to switch to a higher resolution
> > clocksource (e.g. trace infrastructure for PM instrumentation.)
>
I agree with Kevin. Infact I tried prototyping this one. Clock-event
switching works seamlessly. Clock-source switching though isn't
supported yet by generic timer framework.

> Again that can be done with a separate physical timer, no need to
> switch and reprogram the clocksource.
>
If this can done via existing timer framework, I don't see point
wasting another physical timer for this.

I agree your basic point of making clock-source and clock-event
not depend on any frameworks. This is probably essential
considering any generic kernel changes can impact these. Recent
early_init() was a good example. May be I hold on my comments
since you plan to do some patches for system timer handling.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-19  4:34                 ` Santosh Shilimkar
@ 2011-03-21 17:07                   ` Tony Lindgren
  2011-03-21 18:33                     ` Kevin Hilman
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-21 17:07 UTC (permalink / raw)
  To: Santosh Shilimkar
  Cc: Tarun Kanti DebBarma, linux-omap, Thara Gopinath, Kevin Hilman

* Santosh Shilimkar <santosh.shilimkar@ti.com> [110318 21:31]:
> > * Kevin Hilman <khilman@ti.com> [110317 14:58]:
> > > Tony Lindgren <tony@atomide.com> writes:
> > > >
> > > > In the long run, think "local timer" for runtime, and then
> > > > "wakeup timer" that gets only programmed when we enter idle.
> > > >  The "local timer" will continue operating normally after we
> > > > wake-up and the "wakeuptimer" will be just one shot event.
> > > > Of course in the omap[23] case the "local timer" is really a
> > > > there's are real local timers.
> 
> This is already the case for OMAP4 with PM series. But it doesn't
> work the way it is stated above. Wakeup timer is always programmed
> and kept handy by the timer framework because switching of
> clock event happened dynamically and it's too late to reprogram
> the next timer expiry etc. What framework does, is just switch
> the clock-event to wakeup capable clock-event.

Hmm, the next_timer_interrupt gets called before we enter idle, is
that what you mean maybe?

Assuming so, to set up the wake-up timer we can read the programmed
value from hardware to program the wake-up timer when entering
suspend-idle or off-idle. That part can be done just fine with
dmtimer framework.

But in general, we don't really want to start changing the physical
clock for WFI idle because of the time it takes to lock it. For
retention-idle and off-idle, we have much more time. But in these
case there's really no need to change the sources, all we care
about is the physical timer wake-up event and can then restore the
"local timer".
 
> Why do you want to waste one timer hardware for this purpose
> alone especially when generic framework has a support?

In this setup the additional wake-up timer is "only" needed in the
retention-idle and off-idle cases.

For keeping the wake-up timer separate, there are at least three
reasons that I can think of:

1. We don't need to touch the clockevent and clocksource code
   after init except to restore them when waking from retention-idle
   or off-idle.

2. We don't need to initialize anything early for omaps except
   clock framework to set up the clockevent and clocksource.

3. We can avoid switching the physical clock for the timer which
   cuts down latencies at least for the basic WFI case.

> > > In addition, we already have a usecase for switching the
> > > clocksource as well.  We currently setup a single clocksource
> > > (not using the timer_32ka dmtimer.)  However, we already have
> > > use-cases where we would like to switch to a higher resolution
> > > clocksource (e.g. trace infrastructure for PM instrumentation.)
> >
> I agree with Kevin. Infact I tried prototyping this one. Clock-event
> switching works seamlessly. Clock-source switching though isn't
> supported yet by generic timer framework.

Sure. We need to be able to change between the local timer and
the dmtimer also, and I don't see how the current dmtimer series
would make that any easier.
 
> > Again that can be done with a separate physical timer, no need to
> > switch and reprogram the clocksource.
> >
> If this can done via existing timer framework, I don't see point
> wasting another physical timer for this.

In this setup we don't really need to do anything via existing timer
framework, except to restore the clockevent and clocksource when
waking up from retention-idle or off-idle.
 
> I agree your basic point of making clock-source and clock-event
> not depend on any frameworks. This is probably essential
> considering any generic kernel changes can impact these. Recent
> early_init() was a good example. May be I hold on my comments
> since you plan to do some patches for system timer handling.

Yes, we need to cut down the early_init dependencies to minimum.

The reason for that is that then we can initialize everything else
that's omap specific in normal way much later than we do currently.

For the timer, clock framework is essential to init early, but
hwmod is not.

Regards,

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-21 17:07                   ` Tony Lindgren
@ 2011-03-21 18:33                     ` Kevin Hilman
  2011-03-21 19:11                       ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: Kevin Hilman @ 2011-03-21 18:33 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Santosh Shilimkar, Tarun Kanti DebBarma, linux-omap,
	Thara Gopinath

Tony Lindgren <tony@atomide.com> writes:

> * Santosh Shilimkar <santosh.shilimkar@ti.com> [110318 21:31]:
>> > * Kevin Hilman <khilman@ti.com> [110317 14:58]:
>> > > Tony Lindgren <tony@atomide.com> writes:
>> > > >
>> > > > In the long run, think "local timer" for runtime, and then
>> > > > "wakeup timer" that gets only programmed when we enter idle.
>> > > >  The "local timer" will continue operating normally after we
>> > > > wake-up and the "wakeuptimer" will be just one shot event.
>> > > > Of course in the omap[23] case the "local timer" is really a
>> > > > there's are real local timers.
>> 
>> This is already the case for OMAP4 with PM series. But it doesn't
>> work the way it is stated above. Wakeup timer is always programmed
>> and kept handy by the timer framework because switching of
>> clock event happened dynamically and it's too late to reprogram
>> the next timer expiry etc. What framework does, is just switch
>> the clock-event to wakeup capable clock-event.
>
> Hmm, the next_timer_interrupt gets called before we enter idle, is
> that what you mean maybe?
>
> Assuming so, to set up the wake-up timer we can read the programmed
> value from hardware to program the wake-up timer when entering
> suspend-idle or off-idle. That part can be done just fine with
> dmtimer framework.
>
> But in general, we don't really want to start changing the physical
> clock for WFI idle because of the time it takes to lock it. For
> retention-idle and off-idle, we have much more time. But in these
> case there's really no need to change the sources, all we care
> about is the physical timer wake-up event and can then restore the
> "local timer".
>  
>> Why do you want to waste one timer hardware for this purpose
>> alone especially when generic framework has a support?
>
> In this setup the additional wake-up timer is "only" needed in the
> retention-idle and off-idle cases.
>
> For keeping the wake-up timer separate, there are at least three
> reasons that I can think of:
>
> 1. We don't need to touch the clockevent and clocksource code
>    after init except to restore them when waking from retention-idle
>    or off-idle.
>
> 2. We don't need to initialize anything early for omaps except
>    clock framework to set up the clockevent and clocksource.
>
> 3. We can avoid switching the physical clock for the timer which
>    cuts down latencies at least for the basic WFI case.
>

Not sure I fully understand what you're proposing.  Maybe it's time to
see some patches.

What it sounds like you're proposing is to to have up to 3 physical
timers "reserved" and not managed by the dmtimer driver 1) clocksource
2) clockevent and 3) wakeup timer.

This sounds fine in theory, but I suspect it will lead to a couple
things that I don't like.  1) duplicated code that managages these
"reserved" timers and the dmtimer driver: init, read, (re)program,
reset, etc.  And 2) the "reserved" timers will have no PM, again, unless
the code is duplicated from the dmtimer driver.

Maybe I'm not fully understanding your proposal.  I'll wait until I see
patches.  The one thing I do like with the above approach, assuming I
understood it, is that the dmtimer driver would not need the support for
the "early" platform devices.  That is hacky, but frankly I prefer early
platform devices to what I understand above.


>> > > In addition, we already have a usecase for switching the
>> > > clocksource as well.  We currently setup a single clocksource
>> > > (not using the timer_32ka dmtimer.)  However, we already have
>> > > use-cases where we would like to switch to a higher resolution
>> > > clocksource (e.g. trace infrastructure for PM instrumentation.)
>> >
>> I agree with Kevin. Infact I tried prototyping this one. Clock-event
>> switching works seamlessly. Clock-source switching though isn't
>> supported yet by generic timer framework.
>
> Sure. We need to be able to change between the local timer and
> the dmtimer also, and I don't see how the current dmtimer series
> would make that any easier.
>  
>> > Again that can be done with a separate physical timer, no need to
>> > switch and reprogram the clocksource.
>> >
>> If this can done via existing timer framework, I don't see point
>> wasting another physical timer for this.
>
> In this setup we don't really need to do anything via existing timer
> framework, except to restore the clockevent and clocksource when
> waking up from retention-idle or off-idle.
>  
>> I agree your basic point of making clock-source and clock-event
>> not depend on any frameworks. This is probably essential
>> considering any generic kernel changes can impact these. Recent
>> early_init() was a good example. May be I hold on my comments
>> since you plan to do some patches for system timer handling.
>
> Yes, we need to cut down the early_init dependencies to minimum.
>
> The reason for that is that then we can initialize everything else
> that's omap specific in normal way much later than we do currently.
>
> For the timer, clock framework is essential to init early, but
> hwmod is not.

IMO, the hwmod for a given timer should be considered lower
level framework than the clock framework, and the hwmod for a timer
should be initialized before a timer is used for anything, including a
clocksource, clockevent etc.

Kevin


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-21 18:33                     ` Kevin Hilman
@ 2011-03-21 19:11                       ` Tony Lindgren
  2011-03-25  6:55                         ` DebBarma, Tarun Kanti
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-21 19:11 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: Santosh Shilimkar, Tarun Kanti DebBarma, linux-omap,
	Thara Gopinath

* Kevin Hilman <khilman@ti.com> [110321 11:31]:
> Tony Lindgren <tony@atomide.com> writes:
> 
> > * Santosh Shilimkar <santosh.shilimkar@ti.com> [110318 21:31]:
> >> > * Kevin Hilman <khilman@ti.com> [110317 14:58]:
> >> > > Tony Lindgren <tony@atomide.com> writes:
> >> > > >
> >> > > > In the long run, think "local timer" for runtime, and then
> >> > > > "wakeup timer" that gets only programmed when we enter idle.
> >> > > >  The "local timer" will continue operating normally after we
> >> > > > wake-up and the "wakeuptimer" will be just one shot event.
> >> > > > Of course in the omap[23] case the "local timer" is really a
> >> > > > there's are real local timers.
> >> 
> >> This is already the case for OMAP4 with PM series. But it doesn't
> >> work the way it is stated above. Wakeup timer is always programmed
> >> and kept handy by the timer framework because switching of
> >> clock event happened dynamically and it's too late to reprogram
> >> the next timer expiry etc. What framework does, is just switch
> >> the clock-event to wakeup capable clock-event.
> >
> > Hmm, the next_timer_interrupt gets called before we enter idle, is
> > that what you mean maybe?
> >
> > Assuming so, to set up the wake-up timer we can read the programmed
> > value from hardware to program the wake-up timer when entering
> > suspend-idle or off-idle. That part can be done just fine with
> > dmtimer framework.
> >
> > But in general, we don't really want to start changing the physical
> > clock for WFI idle because of the time it takes to lock it. For
> > retention-idle and off-idle, we have much more time. But in these
> > case there's really no need to change the sources, all we care
> > about is the physical timer wake-up event and can then restore the
> > "local timer".
> >  
> >> Why do you want to waste one timer hardware for this purpose
> >> alone especially when generic framework has a support?
> >
> > In this setup the additional wake-up timer is "only" needed in the
> > retention-idle and off-idle cases.
> >
> > For keeping the wake-up timer separate, there are at least three
> > reasons that I can think of:
> >
> > 1. We don't need to touch the clockevent and clocksource code
> >    after init except to restore them when waking from retention-idle
> >    or off-idle.
> >
> > 2. We don't need to initialize anything early for omaps except
> >    clock framework to set up the clockevent and clocksource.
> >
> > 3. We can avoid switching the physical clock for the timer which
> >    cuts down latencies at least for the basic WFI case.
> >
> 
> Not sure I fully understand what you're proposing.  Maybe it's time to
> see some patches.
> 
> What it sounds like you're proposing is to to have up to 3 physical
> timers "reserved" and not managed by the dmtimer driver 1) clocksource
> 2) clockevent and 3) wakeup timer.

Only the clocksource and clockevent timers are reserved and not managed
by dmtimer code. And this is only for omap2 and 3.

For omap4+, clocksource and clockevent should eventually use the
local timers instead of dmtimers during the runtime.

The wake-up timer can be done the same way for omap2, 3 and 4+, and
that can be managed by the dmtimer code and it can be a regular
device driver.
 
> This sounds fine in theory, but I suspect it will lead to a couple
> things that I don't like.  1) duplicated code that managages these
> "reserved" timers and the dmtimer driver: init, read, (re)program,
> reset, etc.  And 2) the "reserved" timers will have no PM, again, unless
> the code is duplicated from the dmtimer driver.

There should not be a problem with duplicated code, that can be avoided.
And I believe the only PM needed on omap2 & 3 is to stop the clock, so that
code can be shared too. For omap4+, the dmtimer is only needed for wake-up.
 
> Maybe I'm not fully understanding your proposal.  I'll wait until I see
> patches.  The one thing I do like with the above approach, assuming I
> understood it, is that the dmtimer driver would not need the support for
> the "early" platform devices.  That is hacky, but frankly I prefer early
> platform devices to what I understand above.

Well the dmtimer code can then become just a regular platform_device
based driver, except for clockevent and clocksource on omap2 & 3.
 
> > Yes, we need to cut down the early_init dependencies to minimum.
> >
> > The reason for that is that then we can initialize everything else
> > that's omap specific in normal way much later than we do currently.
> >
> > For the timer, clock framework is essential to init early, but
> > hwmod is not.
> 
> IMO, the hwmod for a given timer should be considered lower
> level framework than the clock framework, and the hwmod for a timer
> should be initialized before a timer is used for anything, including a
> clocksource, clockevent etc.

Yes that's true for all the other drivers. But the irq handler code,
clockevent and clocksource are special cases as they are needed
early. So in this case it makes sense to treat them separately to
avoid the additional dependencies.

Regards,

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-21 19:11                       ` Tony Lindgren
@ 2011-03-25  6:55                         ` DebBarma, Tarun Kanti
  2011-03-25 15:55                           ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: DebBarma, Tarun Kanti @ 2011-03-25  6:55 UTC (permalink / raw)
  To: Tony Lindgren, Hilman, Kevin
  Cc: Shilimkar, Santosh, linux-omap@vger.kernel.org, Gopinath, Thara

Hi Tony,
[...]
> Well the dmtimer code can then become just a regular platform_device
> based driver, except for clockevent and clocksource on omap2 & 3.
Should I re-post the patch series with removal of duplicate initialization
Which Kevin pointed out + other relevant comments?
Or, wait for your patch series!
--
Tarun
[...]

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-25  6:55                         ` DebBarma, Tarun Kanti
@ 2011-03-25 15:55                           ` Tony Lindgren
  2011-03-29 17:13                             ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-25 15:55 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Hilman, Kevin, Shilimkar, Santosh, linux-omap@vger.kernel.org,
	Gopinath, Thara

* DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110324 23:53]:
> Hi Tony,
> [...]
> > Well the dmtimer code can then become just a regular platform_device
> > based driver, except for clockevent and clocksource on omap2 & 3.
> Should I re-post the patch series with removal of duplicate initialization
> Which Kevin pointed out + other relevant comments?
> Or, wait for your patch series!

Just wait few days please, I should have something available that mostly
deals with timer-gp.c, so it should not cause too many issues with your
patches.

Thanks,

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-25 15:55                           ` Tony Lindgren
@ 2011-03-29 17:13                             ` Tony Lindgren
  2011-03-29 17:52                               ` Tony Lindgren
  0 siblings, 1 reply; 40+ messages in thread
From: Tony Lindgren @ 2011-03-29 17:13 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Hilman, Kevin, Shilimkar, Santosh, linux-omap@vger.kernel.org,
	Gopinath, Thara

* Tony Lindgren <tony@atomide.com> [110325 08:54]:
> * DebBarma, Tarun Kanti <tarun.kanti@ti.com> [110324 23:53]:
> > Hi Tony,
> > [...]
> > > Well the dmtimer code can then become just a regular platform_device
> > > based driver, except for clockevent and clocksource on omap2 & 3.
> > Should I re-post the patch series with removal of duplicate initialization
> > Which Kevin pointed out + other relevant comments?
> > Or, wait for your patch series!
> 
> Just wait few days please, I should have something available that mostly
> deals with timer-gp.c, so it should not cause too many issues with your
> patches.

FYI, posted some patches in the "omap init_early changes for irq and
timer init" thread, also available in devel-timer branch. Few notes
regarding updating your dmtimer series:

- Add the dmtimer arch_initcall into arch/arm/mach-omap2/timer.c so
  we don't end up with yet another timer*.c file there

- Make use of omap_dm_timer_init_one in the dmtimer arch_initcall so
  sys_timer initialized struct omap_dm_timer can be picked up

- You can pick the reserved clockevent and clocksource timers based
  on the sys_timer_reserved mask and then create proper dev entries
  for those too later on during the init

- Now arch/arm/plat-omap/dmtimer.c can become just a driver module
  living under drivers somewhere

Other than that, your patches should be pretty easy to rebase.

Regards,

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v12 4/9] OMAP2+: dmtimer: convert to platform devices
  2011-03-29 17:13                             ` Tony Lindgren
@ 2011-03-29 17:52                               ` Tony Lindgren
  0 siblings, 0 replies; 40+ messages in thread
From: Tony Lindgren @ 2011-03-29 17:52 UTC (permalink / raw)
  To: DebBarma, Tarun Kanti
  Cc: Hilman, Kevin, Shilimkar, Santosh, linux-omap@vger.kernel.org,
	Gopinath, Thara

* Tony Lindgren <tony@atomide.com> [110329 10:11]:
> 
> - You can pick the reserved clockevent and clocksource timers based
>   on the sys_timer_reserved mask and then create proper dev entries
>   for those too later on during the init

Actually you can now just register (but not reset) the struct
omap_dm_timer pointers for clockevent and clocksource directly in
arch/arm/mach-omap2/timer.c, so sys_timer_reserved probably becomes
unnecessary after your patches.

Tony

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2011-03-29 17:52 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-08 23:45 [PATCH v12 0/9] dmtimer adaptation to platform_driver Tarun Kanti DebBarma
2011-03-08 23:45 ` [PATCH v12 1/9] OMAP2+: dmtimer: add device names to flck nodes Tarun Kanti DebBarma
2011-03-08 23:45 ` [PATCH v12 2/9] OMAP4: hwmod data: add dmtimer version information Tarun Kanti DebBarma
2011-03-08 23:45 ` [PATCH v12 3/9] OMAP1: dmtimer: conversion to platform devices Tarun Kanti DebBarma
2011-03-08 23:45 ` [PATCH v12 4/9] OMAP2+: dmtimer: convert " Tarun Kanti DebBarma
2011-03-09 21:42   ` Tony Lindgren
2011-03-10 15:29     ` DebBarma, Tarun Kanti
2011-03-10 22:52   ` Kevin Hilman
2011-03-11  4:36     ` DebBarma, Tarun Kanti
2011-03-10 23:14   ` Kevin Hilman
2011-03-11  4:20     ` DebBarma, Tarun Kanti
2011-03-11 19:13       ` Tony Lindgren
2011-03-12  0:03         ` Kevin Hilman
2011-03-14 17:12           ` Tony Lindgren
2011-03-17 22:00             ` Kevin Hilman
2011-03-19  0:27               ` Tony Lindgren
2011-03-19  4:34                 ` Santosh Shilimkar
2011-03-21 17:07                   ` Tony Lindgren
2011-03-21 18:33                     ` Kevin Hilman
2011-03-21 19:11                       ` Tony Lindgren
2011-03-25  6:55                         ` DebBarma, Tarun Kanti
2011-03-25 15:55                           ` Tony Lindgren
2011-03-29 17:13                             ` Tony Lindgren
2011-03-29 17:52                               ` Tony Lindgren
2011-03-10 23:21   ` Kevin Hilman
2011-03-11  4:13     ` DebBarma, Tarun Kanti
2011-03-08 23:45 ` [PATCH v12 5/9] OMAP: dmtimer: platform driver Tarun Kanti DebBarma
2011-03-08 23:45 ` [PATCH v12 6/9] dmtimer: switch-over to platform device driver Tarun Kanti DebBarma
2011-03-09 22:02   ` Tony Lindgren
2011-03-10 15:27     ` DebBarma, Tarun Kanti
2011-03-10 17:56       ` Tony Lindgren
2011-03-11  5:35         ` DebBarma, Tarun Kanti
2011-03-11 12:45           ` G, Manjunath Kondaiah
2011-03-11 19:15             ` Tony Lindgren
2011-03-12  4:20               ` G, Manjunath Kondaiah
2011-03-11 19:14           ` Tony Lindgren
2011-03-14  6:48             ` DebBarma, Tarun Kanti
2011-03-08 23:45 ` [PATCH v12 7/9] OMAP: dmtimer: pm_runtime support Tarun Kanti DebBarma
2011-03-08 23:45 ` [PATCH v12 8/9] OMAP: dmtimer: add timeout to low-level routines Tarun Kanti DebBarma
2011-03-08 23:45 ` [PATCH v12 9/9] OMAP: dmtimer: use mutex instead of spinlock Tarun Kanti DebBarma

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).