diff options
author | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-06 13:11:12 -0400 |
---|---|---|
committer | Daniel Lezcano <daniel.lezcano@linaro.org> | 2016-06-28 04:19:29 -0400 |
commit | adbaf5254152f322b873d0a9cd0f150dd30c64aa (patch) | |
tree | c9e563a6d9ac86242d1ad246b592fecb78e03c93 /drivers/clocksource/timer-atmel-st.c | |
parent | 504f34c9e45cf81731734ea1c80429a5116b23ca (diff) |
clocksource/drivers/atmel-st: 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 'drivers/clocksource/timer-atmel-st.c')
-rw-r--r-- | drivers/clocksource/timer-atmel-st.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c index 29d21d68df5a..e9331d36965b 100644 --- a/drivers/clocksource/timer-atmel-st.c +++ b/drivers/clocksource/timer-atmel-st.c | |||
@@ -194,15 +194,17 @@ static struct clock_event_device clkevt = { | |||
194 | /* | 194 | /* |
195 | * ST (system timer) module supports both clockevents and clocksource. | 195 | * ST (system timer) module supports both clockevents and clocksource. |
196 | */ | 196 | */ |
197 | static void __init atmel_st_timer_init(struct device_node *node) | 197 | static int __init atmel_st_timer_init(struct device_node *node) |
198 | { | 198 | { |
199 | struct clk *sclk; | 199 | struct clk *sclk; |
200 | unsigned int sclk_rate, val; | 200 | unsigned int sclk_rate, val; |
201 | int irq, ret; | 201 | int irq, ret; |
202 | 202 | ||
203 | regmap_st = syscon_node_to_regmap(node); | 203 | regmap_st = syscon_node_to_regmap(node); |
204 | if (IS_ERR(regmap_st)) | 204 | if (IS_ERR(regmap_st)) { |
205 | panic(pr_fmt("Unable to get regmap\n")); | 205 | pr_err("Unable to get regmap\n"); |
206 | return PTR_ERR(regmap_st); | ||
207 | } | ||
206 | 208 | ||
207 | /* Disable all timer interrupts, and clear any pending ones */ | 209 | /* Disable all timer interrupts, and clear any pending ones */ |
208 | regmap_write(regmap_st, AT91_ST_IDR, | 210 | regmap_write(regmap_st, AT91_ST_IDR, |
@@ -211,27 +213,37 @@ static void __init atmel_st_timer_init(struct device_node *node) | |||
211 | 213 | ||
212 | /* Get the interrupts property */ | 214 | /* Get the interrupts property */ |
213 | irq = irq_of_parse_and_map(node, 0); | 215 | irq = irq_of_parse_and_map(node, 0); |
214 | if (!irq) | 216 | if (!irq) { |
215 | panic(pr_fmt("Unable to get IRQ from DT\n")); | 217 | pr_err("Unable to get IRQ from DT\n"); |
218 | return -EINVAL; | ||
219 | } | ||
216 | 220 | ||
217 | /* Make IRQs happen for the system timer */ | 221 | /* Make IRQs happen for the system timer */ |
218 | ret = request_irq(irq, at91rm9200_timer_interrupt, | 222 | ret = request_irq(irq, at91rm9200_timer_interrupt, |
219 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, | 223 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, |
220 | "at91_tick", regmap_st); | 224 | "at91_tick", regmap_st); |
221 | if (ret) | 225 | if (ret) { |
222 | panic(pr_fmt("Unable to setup IRQ\n")); | 226 | pr_err("Unable to setup IRQ\n"); |
227 | return ret; | ||
228 | } | ||
223 | 229 | ||
224 | sclk = of_clk_get(node, 0); | 230 | sclk = of_clk_get(node, 0); |
225 | if (IS_ERR(sclk)) | 231 | if (IS_ERR(sclk)) { |
226 | panic(pr_fmt("Unable to get slow clock\n")); | 232 | pr_err("Unable to get slow clock\n"); |
233 | return PTR_ERR(sclk); | ||
234 | } | ||
227 | 235 | ||
228 | clk_prepare_enable(sclk); | 236 | ret = clk_prepare_enable(sclk); |
229 | if (ret) | 237 | if (ret) { |
230 | panic(pr_fmt("Could not enable slow clock\n")); | 238 | pr_err("Could not enable slow clock\n"); |
239 | return ret; | ||
240 | } | ||
231 | 241 | ||
232 | sclk_rate = clk_get_rate(sclk); | 242 | sclk_rate = clk_get_rate(sclk); |
233 | if (!sclk_rate) | 243 | if (!sclk_rate) { |
234 | panic(pr_fmt("Invalid slow clock rate\n")); | 244 | pr_err("Invalid slow clock rate\n"); |
245 | return -EINVAL; | ||
246 | } | ||
235 | timer_latch = (sclk_rate + HZ / 2) / HZ; | 247 | timer_latch = (sclk_rate + HZ / 2) / HZ; |
236 | 248 | ||
237 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used | 249 | /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used |
@@ -246,7 +258,7 @@ static void __init atmel_st_timer_init(struct device_node *node) | |||
246 | 2, AT91_ST_ALMV); | 258 | 2, AT91_ST_ALMV); |
247 | 259 | ||
248 | /* register clocksource */ | 260 | /* register clocksource */ |
249 | clocksource_register_hz(&clk32k, sclk_rate); | 261 | return clocksource_register_hz(&clk32k, sclk_rate); |
250 | } | 262 | } |
251 | CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st", | 263 | CLOCKSOURCE_OF_DECLARE_RET(atmel_st_timer, "atmel,at91rm9200-st", |
252 | atmel_st_timer_init); | 264 | atmel_st_timer_init); |