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/timer.c | |
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/timer.c')
-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); |