diff options
author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-06 11:56:04 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-28 04:19:22 -0400 |
commit | 5a54c1873f29411c769f8ebb044980ba0397eb1d (patch) | |
tree | 056e011948bab1b2759d42683e229a7f0279085b /drivers/clocksource/arm_global_timer.c | |
parent | 3c0731db1540ef3cd08fc76c66f6e9d9865b96d2 (diff) |
clocksource/drivers/arm_global_timer: Convert init function to return error
The init functions do not return any error. They behave as the following:
- panic, thus leading to a kernel crash while another timer may work and
make the system boot up correctly
or
- print an error and let the caller unaware if the state of the system
Change that by converting the init functions to return an error conforming
to the CLOCKSOURCE_OF_RET prototype.
Proper error handling (rollback, errno value) will be changed later case
by case, thus this change just return back an error or success in the init
function.
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Maxime Coquelin <maxime.coquelin@st.com>
Diffstat (limited to 'drivers/clocksource/arm_global_timer.c')
-rw-r--r-- | drivers/clocksource/arm_global_timer.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index 9df0d1699d22..40104fc93f24 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c | |||
@@ -238,7 +238,7 @@ static void __init gt_delay_timer_init(void) | |||
238 | register_current_timer_delay(>_delay_timer); | 238 | register_current_timer_delay(>_delay_timer); |
239 | } | 239 | } |
240 | 240 | ||
241 | static void __init gt_clocksource_init(void) | 241 | static int __init gt_clocksource_init(void) |
242 | { | 242 | { |
243 | writel(0, gt_base + GT_CONTROL); | 243 | writel(0, gt_base + GT_CONTROL); |
244 | writel(0, gt_base + GT_COUNTER0); | 244 | writel(0, gt_base + GT_COUNTER0); |
@@ -249,7 +249,7 @@ static void __init gt_clocksource_init(void) | |||
249 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | 249 | #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
250 | sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate); | 250 | sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate); |
251 | #endif | 251 | #endif |
252 | clocksource_register_hz(>_clocksource, gt_clk_rate); | 252 | return clocksource_register_hz(>_clocksource, gt_clk_rate); |
253 | } | 253 | } |
254 | 254 | ||
255 | static int gt_cpu_notify(struct notifier_block *self, unsigned long action, | 255 | static int gt_cpu_notify(struct notifier_block *self, unsigned long action, |
@@ -270,7 +270,7 @@ static struct notifier_block gt_cpu_nb = { | |||
270 | .notifier_call = gt_cpu_notify, | 270 | .notifier_call = gt_cpu_notify, |
271 | }; | 271 | }; |
272 | 272 | ||
273 | static void __init global_timer_of_register(struct device_node *np) | 273 | static int __init global_timer_of_register(struct device_node *np) |
274 | { | 274 | { |
275 | struct clk *gt_clk; | 275 | struct clk *gt_clk; |
276 | int err = 0; | 276 | int err = 0; |
@@ -283,19 +283,19 @@ static void __init global_timer_of_register(struct device_node *np) | |||
283 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9 | 283 | if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9 |
284 | && (read_cpuid_id() & 0xf0000f) < 0x200000) { | 284 | && (read_cpuid_id() & 0xf0000f) < 0x200000) { |
285 | pr_warn("global-timer: non support for this cpu version.\n"); | 285 | pr_warn("global-timer: non support for this cpu version.\n"); |
286 | return; | 286 | return -ENOSYS; |
287 | } | 287 | } |
288 | 288 | ||
289 | gt_ppi = irq_of_parse_and_map(np, 0); | 289 | gt_ppi = irq_of_parse_and_map(np, 0); |
290 | if (!gt_ppi) { | 290 | if (!gt_ppi) { |
291 | pr_warn("global-timer: unable to parse irq\n"); | 291 | pr_warn("global-timer: unable to parse irq\n"); |
292 | return; | 292 | return -EINVAL; |
293 | } | 293 | } |
294 | 294 | ||
295 | gt_base = of_iomap(np, 0); | 295 | gt_base = of_iomap(np, 0); |
296 | if (!gt_base) { | 296 | if (!gt_base) { |
297 | pr_warn("global-timer: invalid base address\n"); | 297 | pr_warn("global-timer: invalid base address\n"); |
298 | return; | 298 | return -ENXIO; |
299 | } | 299 | } |
300 | 300 | ||
301 | gt_clk = of_clk_get(np, 0); | 301 | gt_clk = of_clk_get(np, 0); |
@@ -332,11 +332,17 @@ static void __init global_timer_of_register(struct device_node *np) | |||
332 | } | 332 | } |
333 | 333 | ||
334 | /* Immediately configure the timer on the boot CPU */ | 334 | /* Immediately configure the timer on the boot CPU */ |
335 | gt_clocksource_init(); | 335 | err = gt_clocksource_init(); |
336 | gt_clockevents_init(this_cpu_ptr(gt_evt)); | 336 | if (err) |
337 | goto out_irq; | ||
338 | |||
339 | err = gt_clockevents_init(this_cpu_ptr(gt_evt)); | ||
340 | if (err) | ||
341 | goto out_irq; | ||
342 | |||
337 | gt_delay_timer_init(); | 343 | gt_delay_timer_init(); |
338 | 344 | ||
339 | return; | 345 | return 0; |
340 | 346 | ||
341 | out_irq: | 347 | out_irq: |
342 | free_percpu_irq(gt_ppi, gt_evt); | 348 | free_percpu_irq(gt_ppi, gt_evt); |
@@ -347,8 +353,10 @@ out_clk: | |||
347 | out_unmap: | 353 | out_unmap: |
348 | iounmap(gt_base); | 354 | iounmap(gt_base); |
349 | WARN(err, "ARM Global timer register failed (%d)\n", err); | 355 | WARN(err, "ARM Global timer register failed (%d)\n", err); |
356 | |||
357 | return err; | ||
350 | } | 358 | } |
351 | 359 | ||
352 | /* Only tested on r2p2 and r3p0 */ | 360 | /* Only tested on r2p2 and r3p0 */ |
353 | CLOCKSOURCE_OF_DECLARE(arm_gt, "arm,cortex-a9-global-timer", | 361 | CLOCKSOURCE_OF_DECLARE_RET(arm_gt, "arm,cortex-a9-global-timer", |
354 | global_timer_of_register); | 362 | global_timer_of_register); |