clocksource/drivers/u300: 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: Linus Walleij <linus.walleij@linaro.org>hifive-unleashed-5.1
parent
0a8e7d49d5
commit
1ee078facf
|
@ -359,27 +359,37 @@ static struct delay_timer u300_delay_timer;
|
||||||
/*
|
/*
|
||||||
* This sets up the system timers, clock source and clock event.
|
* This sets up the system timers, clock source and clock event.
|
||||||
*/
|
*/
|
||||||
static void __init u300_timer_init_of(struct device_node *np)
|
static int __init u300_timer_init_of(struct device_node *np)
|
||||||
{
|
{
|
||||||
unsigned int irq;
|
unsigned int irq;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
unsigned long rate;
|
unsigned long rate;
|
||||||
|
int ret;
|
||||||
|
|
||||||
u300_timer_base = of_iomap(np, 0);
|
u300_timer_base = of_iomap(np, 0);
|
||||||
if (!u300_timer_base)
|
if (!u300_timer_base) {
|
||||||
panic("could not ioremap system timer\n");
|
pr_err("could not ioremap system timer\n");
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the IRQ for the GP1 timer */
|
/* Get the IRQ for the GP1 timer */
|
||||||
irq = irq_of_parse_and_map(np, 2);
|
irq = irq_of_parse_and_map(np, 2);
|
||||||
if (!irq)
|
if (!irq) {
|
||||||
panic("no IRQ for system timer\n");
|
pr_err("no IRQ for system timer\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq);
|
pr_info("U300 GP1 timer @ base: %p, IRQ: %u\n", u300_timer_base, irq);
|
||||||
|
|
||||||
/* Clock the interrupt controller */
|
/* Clock the interrupt controller */
|
||||||
clk = of_clk_get(np, 0);
|
clk = of_clk_get(np, 0);
|
||||||
BUG_ON(IS_ERR(clk));
|
if (IS_ERR(clk))
|
||||||
clk_prepare_enable(clk);
|
return PTR_ERR(clk);
|
||||||
|
|
||||||
|
ret = clk_prepare_enable(clk);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
rate = clk_get_rate(clk);
|
rate = clk_get_rate(clk);
|
||||||
|
|
||||||
u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
|
u300_clockevent_data.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
|
||||||
|
@ -410,7 +420,9 @@ static void __init u300_timer_init_of(struct device_node *np)
|
||||||
u300_timer_base + U300_TIMER_APP_RGPT1);
|
u300_timer_base + U300_TIMER_APP_RGPT1);
|
||||||
|
|
||||||
/* Set up the IRQ handler */
|
/* Set up the IRQ handler */
|
||||||
setup_irq(irq, &u300_timer_irq);
|
ret = setup_irq(irq, &u300_timer_irq);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Reset the General Purpose timer 2 */
|
/* Reset the General Purpose timer 2 */
|
||||||
writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
|
writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
|
||||||
|
@ -428,9 +440,12 @@ static void __init u300_timer_init_of(struct device_node *np)
|
||||||
u300_timer_base + U300_TIMER_APP_EGPT2);
|
u300_timer_base + U300_TIMER_APP_EGPT2);
|
||||||
|
|
||||||
/* Use general purpose timer 2 as clock source */
|
/* Use general purpose timer 2 as clock source */
|
||||||
if (clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC,
|
ret = clocksource_mmio_init(u300_timer_base + U300_TIMER_APP_GPT2CC,
|
||||||
"GPT2", rate, 300, 32, clocksource_mmio_readl_up))
|
"GPT2", rate, 300, 32, clocksource_mmio_readl_up);
|
||||||
|
if (ret) {
|
||||||
pr_err("timer: failed to initialize U300 clock source\n");
|
pr_err("timer: failed to initialize U300 clock source\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Configure and register the clockevent */
|
/* Configure and register the clockevent */
|
||||||
clockevents_config_and_register(&u300_clockevent_data.cevd, rate,
|
clockevents_config_and_register(&u300_clockevent_data.cevd, rate,
|
||||||
|
@ -440,7 +455,8 @@ static void __init u300_timer_init_of(struct device_node *np)
|
||||||
* TODO: init and register the rest of the timers too, they can be
|
* TODO: init and register the rest of the timers too, they can be
|
||||||
* used by hrtimers!
|
* used by hrtimers!
|
||||||
*/
|
*/
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLOCKSOURCE_OF_DECLARE(u300_timer, "stericsson,u300-apptimer",
|
CLOCKSOURCE_OF_DECLARE_RET(u300_timer, "stericsson,u300-apptimer",
|
||||||
u300_timer_init_of);
|
u300_timer_init_of);
|
||||||
|
|
Loading…
Reference in New Issue