diff options
| author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-06 18:03:34 -0400 |
|---|---|---|
| committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-28 04:19:33 -0400 |
| commit | 0586421746ef2bc33898d2d7f3dbb0eec6b234c3 (patch) | |
| tree | f8843bea7a357c4c3db2b682b5663af491f5cc8f /arch/microblaze/kernel | |
| parent | 42452508bd7a6527221fff84f3da2b0197b726ae (diff) | |
clocksource/drivers/microblaze: 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>
Diffstat (limited to 'arch/microblaze/kernel')
| -rw-r--r-- | arch/microblaze/kernel/timer.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 67e2ef48d2d0..7f35e7b50f1b 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c | |||
| @@ -170,7 +170,7 @@ static struct irqaction timer_irqaction = { | |||
| 170 | .dev_id = &clockevent_xilinx_timer, | 170 | .dev_id = &clockevent_xilinx_timer, |
| 171 | }; | 171 | }; |
| 172 | 172 | ||
| 173 | static __init void xilinx_clockevent_init(void) | 173 | static __init int xilinx_clockevent_init(void) |
| 174 | { | 174 | { |
| 175 | clockevent_xilinx_timer.mult = | 175 | clockevent_xilinx_timer.mult = |
| 176 | div_sc(timer_clock_freq, NSEC_PER_SEC, | 176 | div_sc(timer_clock_freq, NSEC_PER_SEC, |
| @@ -181,6 +181,8 @@ static __init void xilinx_clockevent_init(void) | |||
| 181 | clockevent_delta2ns(1, &clockevent_xilinx_timer); | 181 | clockevent_delta2ns(1, &clockevent_xilinx_timer); |
| 182 | clockevent_xilinx_timer.cpumask = cpumask_of(0); | 182 | clockevent_xilinx_timer.cpumask = cpumask_of(0); |
| 183 | clockevents_register_device(&clockevent_xilinx_timer); | 183 | clockevents_register_device(&clockevent_xilinx_timer); |
| 184 | |||
| 185 | return 0; | ||
| 184 | } | 186 | } |
| 185 | 187 | ||
| 186 | static u64 xilinx_clock_read(void) | 188 | static u64 xilinx_clock_read(void) |
| @@ -229,8 +231,14 @@ static struct clocksource clocksource_microblaze = { | |||
| 229 | 231 | ||
| 230 | static int __init xilinx_clocksource_init(void) | 232 | static int __init xilinx_clocksource_init(void) |
| 231 | { | 233 | { |
| 232 | if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq)) | 234 | int ret; |
| 233 | panic("failed to register clocksource"); | 235 | |
| 236 | ret = clocksource_register_hz(&clocksource_microblaze, | ||
| 237 | timer_clock_freq); | ||
| 238 | if (ret) { | ||
| 239 | pr_err("failed to register clocksource"); | ||
| 240 | return ret; | ||
| 241 | } | ||
| 234 | 242 | ||
| 235 | /* stop timer1 */ | 243 | /* stop timer1 */ |
| 236 | write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT, | 244 | write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT, |
| @@ -239,16 +247,16 @@ static int __init xilinx_clocksource_init(void) | |||
| 239 | write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1); | 247 | write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1); |
| 240 | 248 | ||
| 241 | /* register timecounter - for ftrace support */ | 249 | /* register timecounter - for ftrace support */ |
| 242 | init_xilinx_timecounter(); | 250 | return init_xilinx_timecounter(); |
| 243 | return 0; | ||
| 244 | } | 251 | } |
| 245 | 252 | ||
| 246 | static void __init xilinx_timer_init(struct device_node *timer) | 253 | static int __init xilinx_timer_init(struct device_node *timer) |
| 247 | { | 254 | { |
| 248 | struct clk *clk; | 255 | struct clk *clk; |
| 249 | static int initialized; | 256 | static int initialized; |
| 250 | u32 irq; | 257 | u32 irq; |
| 251 | u32 timer_num = 1; | 258 | u32 timer_num = 1; |
| 259 | int ret; | ||
| 252 | 260 | ||
| 253 | if (initialized) | 261 | if (initialized) |
| 254 | return; | 262 | return; |
| @@ -258,7 +266,7 @@ static void __init xilinx_timer_init(struct device_node *timer) | |||
| 258 | timer_baseaddr = of_iomap(timer, 0); | 266 | timer_baseaddr = of_iomap(timer, 0); |
| 259 | if (!timer_baseaddr) { | 267 | if (!timer_baseaddr) { |
| 260 | pr_err("ERROR: invalid timer base address\n"); | 268 | pr_err("ERROR: invalid timer base address\n"); |
| 261 | BUG(); | 269 | return -ENXIO; |
| 262 | } | 270 | } |
| 263 | 271 | ||
| 264 | write_fn = timer_write32; | 272 | write_fn = timer_write32; |
| @@ -271,11 +279,15 @@ static void __init xilinx_timer_init(struct device_node *timer) | |||
| 271 | } | 279 | } |
| 272 | 280 | ||
| 273 | irq = irq_of_parse_and_map(timer, 0); | 281 | irq = irq_of_parse_and_map(timer, 0); |
| 282 | if (irq <= 0) { | ||
| 283 | pr_err("Failed to parse and map irq"); | ||
| 284 | return -EINVAL; | ||
| 285 | } | ||
| 274 | 286 | ||
| 275 | of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num); | 287 | of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num); |
| 276 | if (timer_num) { | 288 | if (timer_num) { |
| 277 | pr_emerg("Please enable two timers in HW\n"); | 289 | pr_err("Please enable two timers in HW\n"); |
| 278 | BUG(); | 290 | return -EINVAL; |
| 279 | } | 291 | } |
| 280 | 292 | ||
| 281 | pr_info("%s: irq=%d\n", timer->full_name, irq); | 293 | pr_info("%s: irq=%d\n", timer->full_name, irq); |
| @@ -297,15 +309,28 @@ static void __init xilinx_timer_init(struct device_node *timer) | |||
| 297 | 309 | ||
| 298 | freq_div_hz = timer_clock_freq / HZ; | 310 | freq_div_hz = timer_clock_freq / HZ; |
| 299 | 311 | ||
| 300 | setup_irq(irq, &timer_irqaction); | 312 | ret = setup_irq(irq, &timer_irqaction); |
| 313 | if (ret) { | ||
| 314 | pr_err("Failed to setup IRQ"); | ||
| 315 | return ret; | ||
| 316 | } | ||
| 317 | |||
| 301 | #ifdef CONFIG_HEART_BEAT | 318 | #ifdef CONFIG_HEART_BEAT |
| 302 | microblaze_setup_heartbeat(); | 319 | microblaze_setup_heartbeat(); |
| 303 | #endif | 320 | #endif |
| 304 | xilinx_clocksource_init(); | 321 | |
| 305 | xilinx_clockevent_init(); | 322 | ret = xilinx_clocksource_init(); |
| 323 | if (ret) | ||
| 324 | return ret; | ||
| 325 | |||
| 326 | ret = xilinx_clockevent_init(); | ||
| 327 | if (ret) | ||
| 328 | return ret; | ||
| 306 | 329 | ||
| 307 | sched_clock_register(xilinx_clock_read, 32, timer_clock_freq); | 330 | sched_clock_register(xilinx_clock_read, 32, timer_clock_freq); |
| 331 | |||
| 332 | return 0; | ||
| 308 | } | 333 | } |
| 309 | 334 | ||
| 310 | CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a", | 335 | CLOCKSOURCE_OF_DECLARE_RET(xilinx_timer, "xlnx,xps-timer-1.00.a", |
| 311 | xilinx_timer_init); | 336 | xilinx_timer_init); |
