hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/arch/arm/mach-omap2/timer.c
....@@ -26,35 +26,12 @@
2626 * License. See the file "COPYING" in the main directory of this archive
2727 * for more details.
2828 */
29
-#include <linux/init.h>
30
-#include <linux/time.h>
31
-#include <linux/interrupt.h>
32
-#include <linux/err.h>
3329 #include <linux/clk.h>
34
-#include <linux/delay.h>
35
-#include <linux/irq.h>
3630 #include <linux/clocksource.h>
37
-#include <linux/clockchips.h>
38
-#include <linux/slab.h>
39
-#include <linux/of.h>
40
-#include <linux/of_address.h>
41
-#include <linux/of_irq.h>
42
-#include <linux/platform_device.h>
43
-#include <linux/platform_data/dmtimer-omap.h>
44
-#include <linux/sched_clock.h>
45
-
46
-#include <asm/mach/time.h>
47
-#include <asm/smp_twd.h>
48
-
49
-#include "omap_hwmod.h"
50
-#include "omap_device.h"
51
-#include <plat/counter-32k.h>
52
-#include <clocksource/timer-ti-dm.h>
5331
5432 #include "soc.h"
5533 #include "common.h"
5634 #include "control.h"
57
-#include "powerdomain.h"
5835 #include "omap-secure.h"
5936
6037 #define REALTIME_COUNTER_BASE 0x48243200
....@@ -62,562 +39,12 @@
6239 #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14
6340 #define NUMERATOR_DENUMERATOR_MASK 0xfffff000
6441
65
-/* Clockevent code */
66
-
67
-/* Clockevent hwmod for am335x and am437x suspend */
68
-static struct omap_hwmod *clockevent_gpt_hwmod;
69
-
70
-/* Clockesource hwmod for am437x suspend */
71
-static struct omap_hwmod *clocksource_gpt_hwmod;
72
-
73
-struct dmtimer_clockevent {
74
- struct clock_event_device dev;
75
- struct omap_dm_timer timer;
76
-};
77
-
78
-static struct dmtimer_clockevent clockevent;
79
-
80
-static struct omap_dm_timer *to_dmtimer(struct clock_event_device *clockevent)
81
-{
82
- struct dmtimer_clockevent *clkevt =
83
- container_of(clockevent, struct dmtimer_clockevent, dev);
84
- struct omap_dm_timer *timer = &clkevt->timer;
85
-
86
- return timer;
87
-}
88
-
89
-#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
9042 static unsigned long arch_timer_freq;
9143
9244 void set_cntfreq(void)
9345 {
9446 omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq);
9547 }
96
-#endif
97
-
98
-static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
99
-{
100
- struct dmtimer_clockevent *clkevt = dev_id;
101
- struct clock_event_device *evt = &clkevt->dev;
102
- struct omap_dm_timer *timer = &clkevt->timer;
103
-
104
- __omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW);
105
- evt->event_handler(evt);
106
- return IRQ_HANDLED;
107
-}
108
-
109
-static int omap2_gp_timer_set_next_event(unsigned long cycles,
110
- struct clock_event_device *evt)
111
-{
112
- struct omap_dm_timer *timer = to_dmtimer(evt);
113
-
114
- __omap_dm_timer_load_start(timer, OMAP_TIMER_CTRL_ST,
115
- 0xffffffff - cycles, OMAP_TIMER_POSTED);
116
-
117
- return 0;
118
-}
119
-
120
-static int omap2_gp_timer_shutdown(struct clock_event_device *evt)
121
-{
122
- struct omap_dm_timer *timer = to_dmtimer(evt);
123
-
124
- __omap_dm_timer_stop(timer, OMAP_TIMER_POSTED, timer->rate);
125
-
126
- return 0;
127
-}
128
-
129
-static int omap2_gp_timer_set_periodic(struct clock_event_device *evt)
130
-{
131
- struct omap_dm_timer *timer = to_dmtimer(evt);
132
- u32 period;
133
-
134
- __omap_dm_timer_stop(timer, OMAP_TIMER_POSTED, timer->rate);
135
-
136
- period = timer->rate / HZ;
137
- period -= 1;
138
- /* Looks like we need to first set the load value separately */
139
- __omap_dm_timer_write(timer, OMAP_TIMER_LOAD_REG, 0xffffffff - period,
140
- OMAP_TIMER_POSTED);
141
- __omap_dm_timer_load_start(timer,
142
- OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
143
- 0xffffffff - period, OMAP_TIMER_POSTED);
144
- return 0;
145
-}
146
-
147
-static void omap_clkevt_idle(struct clock_event_device *unused)
148
-{
149
- if (!clockevent_gpt_hwmod)
150
- return;
151
-
152
- omap_hwmod_idle(clockevent_gpt_hwmod);
153
-}
154
-
155
-static void omap_clkevt_unidle(struct clock_event_device *evt)
156
-{
157
- struct omap_dm_timer *timer = to_dmtimer(evt);
158
-
159
- if (!clockevent_gpt_hwmod)
160
- return;
161
-
162
- omap_hwmod_enable(clockevent_gpt_hwmod);
163
- __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW);
164
-}
165
-
166
-static const struct of_device_id omap_timer_match[] __initconst = {
167
- { .compatible = "ti,omap2420-timer", },
168
- { .compatible = "ti,omap3430-timer", },
169
- { .compatible = "ti,omap4430-timer", },
170
- { .compatible = "ti,omap5430-timer", },
171
- { .compatible = "ti,dm814-timer", },
172
- { .compatible = "ti,dm816-timer", },
173
- { .compatible = "ti,am335x-timer", },
174
- { .compatible = "ti,am335x-timer-1ms", },
175
- { }
176
-};
177
-
178
-static int omap_timer_add_disabled_property(struct device_node *np)
179
-{
180
- struct property *prop;
181
-
182
- prop = kzalloc(sizeof(*prop), GFP_KERNEL);
183
- if (!prop)
184
- return -ENOMEM;
185
-
186
- prop->name = "status";
187
- prop->value = "disabled";
188
- prop->length = strlen(prop->value);
189
-
190
- return of_add_property(np, prop);
191
-}
192
-
193
-static int omap_timer_update_dt(struct device_node *np)
194
-{
195
- int error = 0;
196
-
197
- if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
198
- error = omap_timer_add_disabled_property(np);
199
- if (error)
200
- return error;
201
- }
202
-
203
- /* No parent interconnect target module configured? */
204
- if (of_get_property(np, "ti,hwmods", NULL))
205
- return error;
206
-
207
- /* Tag parent interconnect target module disabled */
208
- error = omap_timer_add_disabled_property(np->parent);
209
- if (error)
210
- return error;
211
-
212
- return 0;
213
-}
214
-
215
-/**
216
- * omap_get_timer_dt - get a timer using device-tree
217
- * @match - device-tree match structure for matching a device type
218
- * @property - optional timer property to match
219
- *
220
- * Helper function to get a timer during early boot using device-tree for use
221
- * as kernel system timer. Optionally, the property argument can be used to
222
- * select a timer with a specific property. Once a timer is found then mark
223
- * the timer node in device-tree as disabled, to prevent the kernel from
224
- * registering this timer as a platform device and so no one else can use it.
225
- */
226
-static struct device_node * __init omap_get_timer_dt(const struct of_device_id *match,
227
- const char *property)
228
-{
229
- struct device_node *np;
230
- int error;
231
-
232
- for_each_matching_node(np, match) {
233
- if (!of_device_is_available(np))
234
- continue;
235
-
236
- if (property && !of_get_property(np, property, NULL))
237
- continue;
238
-
239
- if (!property && (of_get_property(np, "ti,timer-alwon", NULL) ||
240
- of_get_property(np, "ti,timer-dsp", NULL) ||
241
- of_get_property(np, "ti,timer-pwm", NULL) ||
242
- of_get_property(np, "ti,timer-secure", NULL)))
243
- continue;
244
-
245
- error = omap_timer_update_dt(np);
246
- WARN(error, "%s: Could not update dt: %i\n", __func__, error);
247
-
248
- return np;
249
- }
250
-
251
- return NULL;
252
-}
253
-
254
-/**
255
- * omap_dmtimer_init - initialisation function when device tree is used
256
- *
257
- * For secure OMAP3/DRA7xx devices, timers with device type "timer-secure"
258
- * cannot be used by the kernel as they are reserved. Therefore, to prevent the
259
- * kernel registering these devices remove them dynamically from the device
260
- * tree on boot.
261
- */
262
-static void __init omap_dmtimer_init(void)
263
-{
264
- struct device_node *np;
265
-
266
- if (!cpu_is_omap34xx() && !soc_is_dra7xx())
267
- return;
268
-
269
- /* If we are a secure device, remove any secure timer nodes */
270
- if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) {
271
- np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure");
272
- of_node_put(np);
273
- }
274
-}
275
-
276
-/**
277
- * omap_dm_timer_get_errata - get errata flags for a timer
278
- *
279
- * Get the timer errata flags that are specific to the OMAP device being used.
280
- */
281
-static u32 __init omap_dm_timer_get_errata(void)
282
-{
283
- if (cpu_is_omap24xx())
284
- return 0;
285
-
286
- return OMAP_TIMER_ERRATA_I103_I767;
287
-}
288
-
289
-static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
290
- const char *fck_source,
291
- const char *property,
292
- const char **timer_name,
293
- int posted)
294
-{
295
- const char *oh_name = NULL;
296
- struct device_node *np;
297
- struct omap_hwmod *oh;
298
- struct clk *src;
299
- int r = 0;
300
-
301
- np = omap_get_timer_dt(omap_timer_match, property);
302
- if (!np)
303
- return -ENODEV;
304
-
305
- of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
306
- if (!oh_name) {
307
- of_property_read_string_index(np->parent, "ti,hwmods", 0,
308
- &oh_name);
309
- if (!oh_name)
310
- return -ENODEV;
311
- }
312
-
313
- timer->irq = irq_of_parse_and_map(np, 0);
314
- if (!timer->irq)
315
- return -ENXIO;
316
-
317
- timer->io_base = of_iomap(np, 0);
318
-
319
- timer->fclk = of_clk_get_by_name(np, "fck");
320
-
321
- of_node_put(np);
322
-
323
- oh = omap_hwmod_lookup(oh_name);
324
- if (!oh)
325
- return -ENODEV;
326
-
327
- *timer_name = oh->name;
328
-
329
- if (!timer->io_base)
330
- return -ENXIO;
331
-
332
- omap_hwmod_setup_one(oh_name);
333
-
334
- /* After the dmtimer is using hwmod these clocks won't be needed */
335
- if (IS_ERR_OR_NULL(timer->fclk))
336
- timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));
337
- if (IS_ERR(timer->fclk))
338
- return PTR_ERR(timer->fclk);
339
-
340
- src = clk_get(NULL, fck_source);
341
- if (IS_ERR(src))
342
- return PTR_ERR(src);
343
-
344
- WARN(clk_set_parent(timer->fclk, src) < 0,
345
- "Cannot set timer parent clock, no PLL clock driver?");
346
-
347
- clk_put(src);
348
-
349
- omap_hwmod_enable(oh);
350
- __omap_dm_timer_init_regs(timer);
351
-
352
- if (posted)
353
- __omap_dm_timer_enable_posted(timer);
354
-
355
- /* Check that the intended posted configuration matches the actual */
356
- if (posted != timer->posted)
357
- return -EINVAL;
358
-
359
- timer->rate = clk_get_rate(timer->fclk);
360
- timer->reserved = 1;
361
-
362
- return r;
363
-}
364
-
365
-#if !defined(CONFIG_SMP) && defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
366
-void tick_broadcast(const struct cpumask *mask)
367
-{
368
-}
369
-#endif
370
-
371
-static void __init dmtimer_clkevt_init_common(struct dmtimer_clockevent *clkevt,
372
- int gptimer_id,
373
- const char *fck_source,
374
- unsigned int features,
375
- const struct cpumask *cpumask,
376
- const char *property,
377
- int rating, const char *name)
378
-{
379
- struct omap_dm_timer *timer = &clkevt->timer;
380
- int res;
381
-
382
- timer->id = gptimer_id;
383
- timer->errata = omap_dm_timer_get_errata();
384
- clkevt->dev.features = features;
385
- clkevt->dev.rating = rating;
386
- clkevt->dev.set_next_event = omap2_gp_timer_set_next_event;
387
- clkevt->dev.set_state_shutdown = omap2_gp_timer_shutdown;
388
- clkevt->dev.set_state_periodic = omap2_gp_timer_set_periodic;
389
- clkevt->dev.set_state_oneshot = omap2_gp_timer_shutdown;
390
- clkevt->dev.tick_resume = omap2_gp_timer_shutdown;
391
-
392
- /*
393
- * For clock-event timers we never read the timer counter and
394
- * so we are not impacted by errata i103 and i767. Therefore,
395
- * we can safely ignore this errata for clock-event timers.
396
- */
397
- __omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767);
398
-
399
- res = omap_dm_timer_init_one(timer, fck_source, property,
400
- &clkevt->dev.name, OMAP_TIMER_POSTED);
401
- BUG_ON(res);
402
-
403
- clkevt->dev.cpumask = cpumask;
404
- clkevt->dev.irq = omap_dm_timer_get_irq(timer);
405
-
406
- if (request_irq(clkevt->dev.irq, omap2_gp_timer_interrupt,
407
- IRQF_TIMER | IRQF_IRQPOLL, name, clkevt))
408
- pr_err("Failed to request irq %d (gp_timer)\n", clkevt->dev.irq);
409
-
410
- __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW);
411
-
412
- if (soc_is_am33xx() || soc_is_am43xx()) {
413
- clkevt->dev.suspend = omap_clkevt_idle;
414
- clkevt->dev.resume = omap_clkevt_unidle;
415
-
416
- clockevent_gpt_hwmod =
417
- omap_hwmod_lookup(clkevt->dev.name);
418
- }
419
-
420
- pr_info("OMAP clockevent source: %s at %lu Hz\n", clkevt->dev.name,
421
- timer->rate);
422
-}
423
-
424
-/* Clocksource code */
425
-static struct omap_dm_timer clksrc;
426
-static bool use_gptimer_clksrc __initdata;
427
-
428
-/*
429
- * clocksource
430
- */
431
-static u64 clocksource_read_cycles(struct clocksource *cs)
432
-{
433
- return (u64)__omap_dm_timer_read_counter(&clksrc,
434
- OMAP_TIMER_NONPOSTED);
435
-}
436
-
437
-static struct clocksource clocksource_gpt = {
438
- .rating = 300,
439
- .read = clocksource_read_cycles,
440
- .mask = CLOCKSOURCE_MASK(32),
441
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
442
-};
443
-
444
-static u64 notrace dmtimer_read_sched_clock(void)
445
-{
446
- if (clksrc.reserved)
447
- return __omap_dm_timer_read_counter(&clksrc,
448
- OMAP_TIMER_NONPOSTED);
449
-
450
- return 0;
451
-}
452
-
453
-static const struct of_device_id omap_counter_match[] __initconst = {
454
- { .compatible = "ti,omap-counter32k", },
455
- { }
456
-};
457
-
458
-/* Setup free-running counter for clocksource */
459
-static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
460
-{
461
- int ret;
462
- struct device_node *np = NULL;
463
- struct omap_hwmod *oh;
464
- const char *oh_name = "counter_32k";
465
-
466
- /*
467
- * See if the 32kHz counter is supported.
468
- */
469
- np = omap_get_timer_dt(omap_counter_match, NULL);
470
- if (!np)
471
- return -ENODEV;
472
-
473
- of_property_read_string_index(np->parent, "ti,hwmods", 0, &oh_name);
474
- if (!oh_name) {
475
- of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
476
- if (!oh_name)
477
- return -ENODEV;
478
- }
479
-
480
- /*
481
- * First check hwmod data is available for sync32k counter
482
- */
483
- oh = omap_hwmod_lookup(oh_name);
484
- if (!oh || oh->slaves_cnt == 0)
485
- return -ENODEV;
486
-
487
- omap_hwmod_setup_one(oh_name);
488
-
489
- ret = omap_hwmod_enable(oh);
490
- if (ret) {
491
- pr_warn("%s: failed to enable counter_32k module (%d)\n",
492
- __func__, ret);
493
- return ret;
494
- }
495
-
496
- return ret;
497
-}
498
-
499
-static unsigned int omap2_gptimer_clksrc_load;
500
-
501
-static void omap2_gptimer_clksrc_suspend(struct clocksource *unused)
502
-{
503
- omap2_gptimer_clksrc_load =
504
- __omap_dm_timer_read_counter(&clksrc, OMAP_TIMER_NONPOSTED);
505
-
506
- omap_hwmod_idle(clocksource_gpt_hwmod);
507
-}
508
-
509
-static void omap2_gptimer_clksrc_resume(struct clocksource *unused)
510
-{
511
- omap_hwmod_enable(clocksource_gpt_hwmod);
512
-
513
- __omap_dm_timer_load_start(&clksrc,
514
- OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR,
515
- omap2_gptimer_clksrc_load,
516
- OMAP_TIMER_NONPOSTED);
517
-}
518
-
519
-static void __init omap2_gptimer_clocksource_init(int gptimer_id,
520
- const char *fck_source,
521
- const char *property)
522
-{
523
- int res;
524
-
525
- clksrc.id = gptimer_id;
526
- clksrc.errata = omap_dm_timer_get_errata();
527
-
528
- res = omap_dm_timer_init_one(&clksrc, fck_source, property,
529
- &clocksource_gpt.name,
530
- OMAP_TIMER_NONPOSTED);
531
-
532
- if (soc_is_am43xx()) {
533
- clocksource_gpt.suspend = omap2_gptimer_clksrc_suspend;
534
- clocksource_gpt.resume = omap2_gptimer_clksrc_resume;
535
-
536
- clocksource_gpt_hwmod =
537
- omap_hwmod_lookup(clocksource_gpt.name);
538
- }
539
-
540
- BUG_ON(res);
541
-
542
- __omap_dm_timer_load_start(&clksrc,
543
- OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
544
- OMAP_TIMER_NONPOSTED);
545
- sched_clock_register(dmtimer_read_sched_clock, 32, clksrc.rate);
546
-
547
- if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
548
- pr_err("Could not register clocksource %s\n",
549
- clocksource_gpt.name);
550
- else
551
- pr_info("OMAP clocksource: %s at %lu Hz\n",
552
- clocksource_gpt.name, clksrc.rate);
553
-}
554
-
555
-static void __init __omap_sync32k_timer_init(int clkev_nr, const char *clkev_src,
556
- const char *clkev_prop, int clksrc_nr, const char *clksrc_src,
557
- const char *clksrc_prop, bool gptimer)
558
-{
559
- omap_clk_init();
560
- omap_dmtimer_init();
561
- dmtimer_clkevt_init_common(&clockevent, clkev_nr, clkev_src,
562
- CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
563
- cpu_possible_mask, clkev_prop, 300, "clockevent");
564
- clockevents_config_and_register(&clockevent.dev, clockevent.timer.rate,
565
- 3, /* Timer internal resynch latency */
566
- 0xffffffff);
567
-
568
- /* Enable the use of clocksource="gp_timer" kernel parameter */
569
- if (use_gptimer_clksrc || gptimer)
570
- omap2_gptimer_clocksource_init(clksrc_nr, clksrc_src,
571
- clksrc_prop);
572
- else
573
- omap2_sync32k_clocksource_init();
574
-}
575
-
576
-void __init omap_init_time(void)
577
-{
578
- __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
579
- 2, "timer_sys_ck", NULL, false);
580
-
581
- timer_probe();
582
-}
583
-
584
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM43XX)
585
-void __init omap3_secure_sync32k_timer_init(void)
586
-{
587
- __omap_sync32k_timer_init(12, "secure_32k_fck", "ti,timer-secure",
588
- 2, "timer_sys_ck", NULL, false);
589
-
590
- timer_probe();
591
-}
592
-#endif /* CONFIG_ARCH_OMAP3 */
593
-
594
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \
595
- defined(CONFIG_SOC_AM43XX)
596
-void __init omap3_gptimer_timer_init(void)
597
-{
598
- __omap_sync32k_timer_init(2, "timer_sys_ck", NULL,
599
- 1, "timer_sys_ck", "ti,timer-alwon", true);
600
- if (of_have_populated_dt())
601
- timer_probe();
602
-}
603
-#endif
604
-
605
-#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
606
- defined(CONFIG_SOC_DRA7XX)
607
-static void __init omap4_sync32k_timer_init(void)
608
-{
609
- __omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
610
- 2, "sys_clkin_ck", NULL, false);
611
-}
612
-
613
-void __init omap4_local_timer_init(void)
614
-{
615
- omap4_sync32k_timer_init();
616
- timer_probe();
617
-}
618
-#endif
619
-
620
-#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX)
62148
62249 /*
62350 * The realtime counter also called master counter, is a free-running
....@@ -630,7 +57,6 @@
63057 */
63158 static void __init realtime_counter_init(void)
63259 {
633
-#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
63460 void __iomem *base;
63561 static struct clk *sys_clk;
63662 unsigned long rate;
....@@ -650,6 +76,7 @@
65076 }
65177
65278 rate = clk_get_rate(sys_clk);
79
+ clk_put(sys_clk);
65380
65481 if (soc_is_dra7xx()) {
65582 /*
....@@ -729,39 +156,12 @@
729156 set_cntfreq();
730157
731158 iounmap(base);
732
-#endif
733159 }
734160
735161 void __init omap5_realtime_timer_init(void)
736162 {
737
- omap4_sync32k_timer_init();
163
+ omap_clk_init();
738164 realtime_counter_init();
739165
740166 timer_probe();
741167 }
742
-#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */
743
-
744
-/**
745
- * omap2_override_clocksource - clocksource override with user configuration
746
- *
747
- * Allows user to override default clocksource, using kernel parameter
748
- * clocksource="gp_timer" (For all OMAP2PLUS architectures)
749
- *
750
- * Note that, here we are using same standard kernel parameter "clocksource=",
751
- * and not introducing any OMAP specific interface.
752
- */
753
-static int __init omap2_override_clocksource(char *str)
754
-{
755
- if (!str)
756
- return 0;
757
- /*
758
- * For OMAP architecture, we only have two options
759
- * - sync_32k (default)
760
- * - gp_timer (sys_clk based)
761
- */
762
- if (!strcmp(str, "gp_timer"))
763
- use_gptimer_clksrc = true;
764
-
765
- return 0;
766
-}
767
-early_param("clocksource", omap2_override_clocksource);