Skip to content

Commit

Permalink
clocksource/drivers/rockchip_timer: Convert init function to return e…
Browse files Browse the repository at this point in the history
…rror

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>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>

on a rk3399-evb
Tested-by: Heiko Stuebner <heiko@sntech.de>
  • Loading branch information
Daniel Lezcano committed Jun 28, 2016
1 parent b7c4db8 commit 8bdd5a2
Showing 1 changed file with 21 additions and 14 deletions.
35 changes: 21 additions & 14 deletions drivers/clocksource/rockchip_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,38 +113,42 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}

static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
{
struct clock_event_device *ce = &bc_timer.ce;
struct clk *timer_clk;
struct clk *pclk;
int ret, irq;
int ret = -EINVAL, irq;

bc_timer.base = of_iomap(np, 0);
if (!bc_timer.base) {
pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
return;
return -ENXIO;
}
bc_timer.ctrl = bc_timer.base + ctrl_reg;

pclk = of_clk_get_by_name(np, "pclk");
if (IS_ERR(pclk)) {
ret = PTR_ERR(pclk);
pr_err("Failed to get pclk for '%s'\n", TIMER_NAME);
goto out_unmap;
}

if (clk_prepare_enable(pclk)) {
ret = clk_prepare_enable(pclk);
if (ret) {
pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME);
goto out_unmap;
}

timer_clk = of_clk_get_by_name(np, "timer");
if (IS_ERR(timer_clk)) {
ret = PTR_ERR(timer_clk);
pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME);
goto out_timer_clk;
}

if (clk_prepare_enable(timer_clk)) {
ret = clk_prepare_enable(timer_clk);
if (ret) {
pr_err("Failed to enable timer clock\n");
goto out_timer_clk;
}
Expand All @@ -153,6 +157,7 @@ static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg)

irq = irq_of_parse_and_map(np, 0);
if (!irq) {
ret = -EINVAL;
pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME);
goto out_irq;
}
Expand All @@ -178,27 +183,29 @@ static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg)

clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX);

return;
return 0;

out_irq:
clk_disable_unprepare(timer_clk);
out_timer_clk:
clk_disable_unprepare(pclk);
out_unmap:
iounmap(bc_timer.base);

return ret;
}

static void __init rk3288_timer_init(struct device_node *np)
static int __init rk3288_timer_init(struct device_node *np)
{
rk_timer_init(np, TIMER_CONTROL_REG3288);
return rk_timer_init(np, TIMER_CONTROL_REG3288);
}

static void __init rk3399_timer_init(struct device_node *np)
static int __init rk3399_timer_init(struct device_node *np)
{
rk_timer_init(np, TIMER_CONTROL_REG3399);
return rk_timer_init(np, TIMER_CONTROL_REG3399);
}

CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer",
rk3288_timer_init);
CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer",
rk3399_timer_init);
CLOCKSOURCE_OF_DECLARE_RET(rk3288_timer, "rockchip,rk3288-timer",
rk3288_timer_init);
CLOCKSOURCE_OF_DECLARE_RET(rk3399_timer, "rockchip,rk3399-timer",
rk3399_timer_init);

0 comments on commit 8bdd5a2

Please sign in to comment.