aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJon Hunter <jon-hunter@ti.com>2012-06-05 13:34:51 -0400
committerTony Lindgren <tony@atomide.com>2012-06-14 05:39:06 -0400
commitb7b4ff764f7bf903e47eebdab661b1c38e791c6d (patch)
tree1f56e292fa0b1a4069ce4a359dac905169257412 /arch
parent26fe4e454bfee3248bc7f7bab38b4888db33528e (diff)
ARM: OMAP2+: Add dmtimer platform function to reserve systimers
During early boot, one or two dmtimers are reserved by the kernel as system timers (for clocksource and clockevents). These timers are marked as reserved and the dmtimer driver is notified which timers have been reserved via the platform data information. For OMAP2+ devices the timers reserved may vary depending on device and compile flags. Therefore, it is not easy to assume which timers we be reserved for the system timers. In order to migrate the dmtimer driver to support device-tree we need a way to pass the timers reserved for system timers to the dmtimer driver. Using the platform data structure will not work in the same way as it is currently used because the platform data structure will be stored statically in the dmtimer itself and the platform data will be selected via the device-tree match device function (of_match_device). There are a couple ways to workaround this. One option is to store the system timers reserved for the kernel in the device-tree and query them on boot. The downside of this approach is that it adds some delay to parse the DT blob to search for the system timers. Secondly, for OMAP3 devices we have a dependency on compile time flags and the device-tree would not be aware of that kernel compile flags and so we would need to address that. The second option is to add a function to the dmtimer code to reserved the system timers during boot and so the dmtimer knows exactly which timers are being used for system timers. This also allows us to remove the "reserved" member from the timer platform data. This seemed like the simpler approach and so was implemented here. Signed-off-by: Jon Hunter <jon-hunter@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/timer.c9
-rw-r--r--arch/arm/plat-omap/dmtimer.c18
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h3
3 files changed, 20 insertions, 10 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index c030dfeee76a..b0b208077c96 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -69,8 +69,6 @@
69#define OMAP3_SECURE_TIMER 1 69#define OMAP3_SECURE_TIMER 1
70#endif 70#endif
71 71
72static u32 sys_timer_reserved;
73
74/* Clockevent code */ 72/* Clockevent code */
75 73
76static struct omap_dm_timer clkev; 74static struct omap_dm_timer clkev;
@@ -177,7 +175,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
177 175
178 omap_hwmod_enable(oh); 176 omap_hwmod_enable(oh);
179 177
180 sys_timer_reserved |= (1 << (gptimer_id - 1)); 178 if (omap_dm_timer_reserve_systimer(gptimer_id))
179 return -ENODEV;
181 180
182 if (gptimer_id != 12) { 181 if (gptimer_id != 12) {
183 struct clk *src; 182 struct clk *src;
@@ -501,10 +500,6 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
501 pdata->set_timer_src = omap2_dm_timer_set_src; 500 pdata->set_timer_src = omap2_dm_timer_set_src;
502 pdata->timer_ip_version = oh->class->rev; 501 pdata->timer_ip_version = oh->class->rev;
503 502
504 /* Mark clocksource and clockevent timers as reserved */
505 if ((sys_timer_reserved >> (id - 1)) & 0x1)
506 pdata->reserved = 1;
507
508 pwrdm = omap_hwmod_get_pwrdm(oh); 503 pwrdm = omap_hwmod_get_pwrdm(oh);
509 pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); 504 pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
510#ifdef CONFIG_PM 505#ifdef CONFIG_PM
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 3b0cfeb33d05..f5b5c89ac7c2 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -45,6 +45,7 @@
45 45
46#include <mach/hardware.h> 46#include <mach/hardware.h>
47 47
48static u32 omap_reserved_systimers;
48static LIST_HEAD(omap_timer_list); 49static LIST_HEAD(omap_timer_list);
49static DEFINE_SPINLOCK(dm_timer_lock); 50static DEFINE_SPINLOCK(dm_timer_lock);
50 51
@@ -152,6 +153,21 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
152 return ret; 153 return ret;
153} 154}
154 155
156static inline u32 omap_dm_timer_reserved_systimer(int id)
157{
158 return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
159}
160
161int omap_dm_timer_reserve_systimer(int id)
162{
163 if (omap_dm_timer_reserved_systimer(id))
164 return -ENODEV;
165
166 omap_reserved_systimers |= (1 << (id - 1));
167
168 return 0;
169}
170
155struct omap_dm_timer *omap_dm_timer_request(void) 171struct omap_dm_timer *omap_dm_timer_request(void)
156{ 172{
157 struct omap_dm_timer *timer = NULL, *t; 173 struct omap_dm_timer *timer = NULL, *t;
@@ -674,7 +690,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
674 690
675 timer->id = pdev->id; 691 timer->id = pdev->id;
676 timer->irq = irq->start; 692 timer->irq = irq->start;
677 timer->reserved = pdata->reserved; 693 timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
678 timer->pdev = pdev; 694 timer->pdev = pdev;
679 timer->loses_context = pdata->loses_context; 695 timer->loses_context = pdata->loses_context;
680 timer->get_context_loss_count = pdata->get_context_loss_count; 696 timer->get_context_loss_count = pdata->get_context_loss_count;
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 5fdfaa481259..1e5ce5d56240 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -98,13 +98,12 @@ struct dmtimer_platform_data {
98 int (*set_timer_src)(struct platform_device *pdev, int source); 98 int (*set_timer_src)(struct platform_device *pdev, int source);
99 int timer_ip_version; 99 int timer_ip_version;
100 u32 needs_manual_reset:1; 100 u32 needs_manual_reset:1;
101 bool reserved;
102
103 bool loses_context; 101 bool loses_context;
104 102
105 int (*get_context_loss_count)(struct device *dev); 103 int (*get_context_loss_count)(struct device *dev);
106}; 104};
107 105
106int omap_dm_timer_reserve_systimer(int id);
108struct omap_dm_timer *omap_dm_timer_request(void); 107struct omap_dm_timer *omap_dm_timer_request(void);
109struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); 108struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
110int omap_dm_timer_free(struct omap_dm_timer *timer); 109int omap_dm_timer_free(struct omap_dm_timer *timer);