diff options
author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-05-31 11:28:55 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-28 04:19:17 -0400 |
commit | 8bdd5a2e7c479dcdb632c614b0d9bb1ac6ed5be7 (patch) | |
tree | d9095161a5f490873e00a39f9fb0f19475df0bde | |
parent | b7c4db861683af5fc50ac3cb3751cf847d765211 (diff) |
clocksource/drivers/rockchip_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>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
on a rk3399-evb
Tested-by: Heiko Stuebner <heiko@sntech.de>
-rw-r--r-- | drivers/clocksource/rockchip_timer.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c index a3f22b03f94f..85aee6953944 100644 --- a/drivers/clocksource/rockchip_timer.c +++ b/drivers/clocksource/rockchip_timer.c | |||
@@ -113,38 +113,42 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) | |||
113 | return IRQ_HANDLED; | 113 | return IRQ_HANDLED; |
114 | } | 114 | } |
115 | 115 | ||
116 | static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg) | 116 | static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg) |
117 | { | 117 | { |
118 | struct clock_event_device *ce = &bc_timer.ce; | 118 | struct clock_event_device *ce = &bc_timer.ce; |
119 | struct clk *timer_clk; | 119 | struct clk *timer_clk; |
120 | struct clk *pclk; | 120 | struct clk *pclk; |
121 | int ret, irq; | 121 | int ret = -EINVAL, irq; |
122 | 122 | ||
123 | bc_timer.base = of_iomap(np, 0); | 123 | bc_timer.base = of_iomap(np, 0); |
124 | if (!bc_timer.base) { | 124 | if (!bc_timer.base) { |
125 | pr_err("Failed to get base address for '%s'\n", TIMER_NAME); | 125 | pr_err("Failed to get base address for '%s'\n", TIMER_NAME); |
126 | return; | 126 | return -ENXIO; |
127 | } | 127 | } |
128 | bc_timer.ctrl = bc_timer.base + ctrl_reg; | 128 | bc_timer.ctrl = bc_timer.base + ctrl_reg; |
129 | 129 | ||
130 | pclk = of_clk_get_by_name(np, "pclk"); | 130 | pclk = of_clk_get_by_name(np, "pclk"); |
131 | if (IS_ERR(pclk)) { | 131 | if (IS_ERR(pclk)) { |
132 | ret = PTR_ERR(pclk); | ||
132 | pr_err("Failed to get pclk for '%s'\n", TIMER_NAME); | 133 | pr_err("Failed to get pclk for '%s'\n", TIMER_NAME); |
133 | goto out_unmap; | 134 | goto out_unmap; |
134 | } | 135 | } |
135 | 136 | ||
136 | if (clk_prepare_enable(pclk)) { | 137 | ret = clk_prepare_enable(pclk); |
138 | if (ret) { | ||
137 | pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME); | 139 | pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME); |
138 | goto out_unmap; | 140 | goto out_unmap; |
139 | } | 141 | } |
140 | 142 | ||
141 | timer_clk = of_clk_get_by_name(np, "timer"); | 143 | timer_clk = of_clk_get_by_name(np, "timer"); |
142 | if (IS_ERR(timer_clk)) { | 144 | if (IS_ERR(timer_clk)) { |
145 | ret = PTR_ERR(timer_clk); | ||
143 | pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME); | 146 | pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME); |
144 | goto out_timer_clk; | 147 | goto out_timer_clk; |
145 | } | 148 | } |
146 | 149 | ||
147 | if (clk_prepare_enable(timer_clk)) { | 150 | ret = clk_prepare_enable(timer_clk); |
151 | if (ret) { | ||
148 | pr_err("Failed to enable timer clock\n"); | 152 | pr_err("Failed to enable timer clock\n"); |
149 | goto out_timer_clk; | 153 | goto out_timer_clk; |
150 | } | 154 | } |
@@ -153,6 +157,7 @@ static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg) | |||
153 | 157 | ||
154 | irq = irq_of_parse_and_map(np, 0); | 158 | irq = irq_of_parse_and_map(np, 0); |
155 | if (!irq) { | 159 | if (!irq) { |
160 | ret = -EINVAL; | ||
156 | pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME); | 161 | pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME); |
157 | goto out_irq; | 162 | goto out_irq; |
158 | } | 163 | } |
@@ -178,7 +183,7 @@ static void __init rk_timer_init(struct device_node *np, u32 ctrl_reg) | |||
178 | 183 | ||
179 | clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX); | 184 | clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX); |
180 | 185 | ||
181 | return; | 186 | return 0; |
182 | 187 | ||
183 | out_irq: | 188 | out_irq: |
184 | clk_disable_unprepare(timer_clk); | 189 | clk_disable_unprepare(timer_clk); |
@@ -186,19 +191,21 @@ out_timer_clk: | |||
186 | clk_disable_unprepare(pclk); | 191 | clk_disable_unprepare(pclk); |
187 | out_unmap: | 192 | out_unmap: |
188 | iounmap(bc_timer.base); | 193 | iounmap(bc_timer.base); |
194 | |||
195 | return ret; | ||
189 | } | 196 | } |
190 | 197 | ||
191 | static void __init rk3288_timer_init(struct device_node *np) | 198 | static int __init rk3288_timer_init(struct device_node *np) |
192 | { | 199 | { |
193 | rk_timer_init(np, TIMER_CONTROL_REG3288); | 200 | return rk_timer_init(np, TIMER_CONTROL_REG3288); |
194 | } | 201 | } |
195 | 202 | ||
196 | static void __init rk3399_timer_init(struct device_node *np) | 203 | static int __init rk3399_timer_init(struct device_node *np) |
197 | { | 204 | { |
198 | rk_timer_init(np, TIMER_CONTROL_REG3399); | 205 | return rk_timer_init(np, TIMER_CONTROL_REG3399); |
199 | } | 206 | } |
200 | 207 | ||
201 | CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", | 208 | CLOCKSOURCE_OF_DECLARE_RET(rk3288_timer, "rockchip,rk3288-timer", |
202 | rk3288_timer_init); | 209 | rk3288_timer_init); |
203 | CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", | 210 | CLOCKSOURCE_OF_DECLARE_RET(rk3399_timer, "rockchip,rk3399-timer", |
204 | rk3399_timer_init); | 211 | rk3399_timer_init); |