aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2016-06-06 17:28:01 -0400
committerDaniel Lezcano <daniel.lezcano@linaro.org>2016-06-28 04:19:30 -0400
commit2ef2538bc613af45baf9f2a032c9a8259c4c6672 (patch)
treef3f7068ae8b1f65c288b345a84626582a2049451
parent53186505802c8845d5af4ed40ddb84e221acb92f (diff)
clocksource/drivers/sp804: 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>
-rw-r--r--drivers/clocksource/timer-sp804.c90
-rw-r--r--include/clocksource/timer-sp804.h8
2 files changed, 63 insertions, 35 deletions
diff --git a/drivers/clocksource/timer-sp804.c b/drivers/clocksource/timer-sp804.c
index 5f45b9adef60..3dc47efc9298 100644
--- a/drivers/clocksource/timer-sp804.c
+++ b/drivers/clocksource/timer-sp804.c
@@ -77,7 +77,7 @@ void __init sp804_timer_disable(void __iomem *base)
77 writel(0, base + TIMER_CTRL); 77 writel(0, base + TIMER_CTRL);
78} 78}
79 79
80void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base, 80int __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
81 const char *name, 81 const char *name,
82 struct clk *clk, 82 struct clk *clk,
83 int use_sched_clock) 83 int use_sched_clock)
@@ -89,14 +89,13 @@ void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
89 if (IS_ERR(clk)) { 89 if (IS_ERR(clk)) {
90 pr_err("sp804: clock not found: %d\n", 90 pr_err("sp804: clock not found: %d\n",
91 (int)PTR_ERR(clk)); 91 (int)PTR_ERR(clk));
92 return; 92 return PTR_ERR(clk);
93 } 93 }
94 } 94 }
95 95
96 rate = sp804_get_clock_rate(clk); 96 rate = sp804_get_clock_rate(clk);
97
98 if (rate < 0) 97 if (rate < 0)
99 return; 98 return -EINVAL;
100 99
101 /* setup timer 0 as free-running clocksource */ 100 /* setup timer 0 as free-running clocksource */
102 writel(0, base + TIMER_CTRL); 101 writel(0, base + TIMER_CTRL);
@@ -112,6 +111,8 @@ void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
112 sched_clock_base = base; 111 sched_clock_base = base;
113 sched_clock_register(sp804_read, 32, rate); 112 sched_clock_register(sp804_read, 32, rate);
114 } 113 }
114
115 return 0;
115} 116}
116 117
117 118
@@ -186,7 +187,7 @@ static struct irqaction sp804_timer_irq = {
186 .dev_id = &sp804_clockevent, 187 .dev_id = &sp804_clockevent,
187}; 188};
188 189
189void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name) 190int __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name)
190{ 191{
191 struct clock_event_device *evt = &sp804_clockevent; 192 struct clock_event_device *evt = &sp804_clockevent;
192 long rate; 193 long rate;
@@ -196,12 +197,12 @@ void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struc
196 if (IS_ERR(clk)) { 197 if (IS_ERR(clk)) {
197 pr_err("sp804: %s clock not found: %d\n", name, 198 pr_err("sp804: %s clock not found: %d\n", name,
198 (int)PTR_ERR(clk)); 199 (int)PTR_ERR(clk));
199 return; 200 return PTR_ERR(clk);
200 } 201 }
201 202
202 rate = sp804_get_clock_rate(clk); 203 rate = sp804_get_clock_rate(clk);
203 if (rate < 0) 204 if (rate < 0)
204 return; 205 return -EINVAL;
205 206
206 clkevt_base = base; 207 clkevt_base = base;
207 clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); 208 clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
@@ -213,27 +214,31 @@ void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struc
213 214
214 setup_irq(irq, &sp804_timer_irq); 215 setup_irq(irq, &sp804_timer_irq);
215 clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); 216 clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
217
218 return 0;
216} 219}
217 220
218static void __init sp804_of_init(struct device_node *np) 221static int __init sp804_of_init(struct device_node *np)
219{ 222{
220 static bool initialized = false; 223 static bool initialized = false;
221 void __iomem *base; 224 void __iomem *base;
222 int irq; 225 int irq, ret = -EINVAL;
223 u32 irq_num = 0; 226 u32 irq_num = 0;
224 struct clk *clk1, *clk2; 227 struct clk *clk1, *clk2;
225 const char *name = of_get_property(np, "compatible", NULL); 228 const char *name = of_get_property(np, "compatible", NULL);
226 229
227 base = of_iomap(np, 0); 230 base = of_iomap(np, 0);
228 if (WARN_ON(!base)) 231 if (!base)
229 return; 232 return -ENXIO;
230 233
231 /* Ensure timers are disabled */ 234 /* Ensure timers are disabled */
232 writel(0, base + TIMER_CTRL); 235 writel(0, base + TIMER_CTRL);
233 writel(0, base + TIMER_2_BASE + TIMER_CTRL); 236 writel(0, base + TIMER_2_BASE + TIMER_CTRL);
234 237
235 if (initialized || !of_device_is_available(np)) 238 if (initialized || !of_device_is_available(np)) {
239 ret = -EINVAL;
236 goto err; 240 goto err;
241 }
237 242
238 clk1 = of_clk_get(np, 0); 243 clk1 = of_clk_get(np, 0);
239 if (IS_ERR(clk1)) 244 if (IS_ERR(clk1))
@@ -256,35 +261,53 @@ static void __init sp804_of_init(struct device_node *np)
256 261
257 of_property_read_u32(np, "arm,sp804-has-irq", &irq_num); 262 of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
258 if (irq_num == 2) { 263 if (irq_num == 2) {
259 __sp804_clockevents_init(base + TIMER_2_BASE, irq, clk2, name); 264
260 __sp804_clocksource_and_sched_clock_init(base, name, clk1, 1); 265 ret = __sp804_clockevents_init(base + TIMER_2_BASE, irq, clk2, name);
266 if (ret)
267 goto err;
268
269 ret = __sp804_clocksource_and_sched_clock_init(base, name, clk1, 1);
270 if (ret)
271 goto err;
261 } else { 272 } else {
262 __sp804_clockevents_init(base, irq, clk1 , name); 273
263 __sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE, 274 ret = __sp804_clockevents_init(base, irq, clk1 , name);
264 name, clk2, 1); 275 if (ret)
276 goto err;
277
278 ret =__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE,
279 name, clk2, 1);
280 if (ret)
281 goto err;
265 } 282 }
266 initialized = true; 283 initialized = true;
267 284
268 return; 285 return 0;
269err: 286err:
270 iounmap(base); 287 iounmap(base);
288 return ret;
271} 289}
272CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init); 290CLOCKSOURCE_OF_DECLARE_RET(sp804, "arm,sp804", sp804_of_init);
273 291
274static void __init integrator_cp_of_init(struct device_node *np) 292static int __init integrator_cp_of_init(struct device_node *np)
275{ 293{
276 static int init_count = 0; 294 static int init_count = 0;
277 void __iomem *base; 295 void __iomem *base;
278 int irq; 296 int irq, ret = -EINVAL;
279 const char *name = of_get_property(np, "compatible", NULL); 297 const char *name = of_get_property(np, "compatible", NULL);
280 struct clk *clk; 298 struct clk *clk;
281 299
282 base = of_iomap(np, 0); 300 base = of_iomap(np, 0);
283 if (WARN_ON(!base)) 301 if (!base) {
284 return; 302 pr_err("Failed to iomap");
303 return -ENXIO;
304 }
305
285 clk = of_clk_get(np, 0); 306 clk = of_clk_get(np, 0);
286 if (WARN_ON(IS_ERR(clk))) 307 if (IS_ERR(clk)) {
287 return; 308 pr_err("Failed to get clock");
309 return PTR_ERR(clk);
310 }
288 311
289 /* Ensure timer is disabled */ 312 /* Ensure timer is disabled */
290 writel(0, base + TIMER_CTRL); 313 writel(0, base + TIMER_CTRL);
@@ -292,19 +315,24 @@ static void __init integrator_cp_of_init(struct device_node *np)
292 if (init_count == 2 || !of_device_is_available(np)) 315 if (init_count == 2 || !of_device_is_available(np))
293 goto err; 316 goto err;
294 317
295 if (!init_count) 318 if (!init_count) {
296 __sp804_clocksource_and_sched_clock_init(base, name, clk, 0); 319 ret = __sp804_clocksource_and_sched_clock_init(base, name, clk, 0);
297 else { 320 if (ret)
321 goto err;
322 } else {
298 irq = irq_of_parse_and_map(np, 0); 323 irq = irq_of_parse_and_map(np, 0);
299 if (irq <= 0) 324 if (irq <= 0)
300 goto err; 325 goto err;
301 326
302 __sp804_clockevents_init(base, irq, clk, name); 327 ret = __sp804_clockevents_init(base, irq, clk, name);
328 if (ret)
329 goto err;
303 } 330 }
304 331
305 init_count++; 332 init_count++;
306 return; 333 return 0;
307err: 334err:
308 iounmap(base); 335 iounmap(base);
336 return ret;
309} 337}
310CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init); 338CLOCKSOURCE_OF_DECLARE_RET(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
diff --git a/include/clocksource/timer-sp804.h b/include/clocksource/timer-sp804.h
index 1f8a1caa7cb4..7654d71243dd 100644
--- a/include/clocksource/timer-sp804.h
+++ b/include/clocksource/timer-sp804.h
@@ -3,10 +3,10 @@
3 3
4struct clk; 4struct clk;
5 5
6void __sp804_clocksource_and_sched_clock_init(void __iomem *, 6int __sp804_clocksource_and_sched_clock_init(void __iomem *,
7 const char *, struct clk *, int); 7 const char *, struct clk *, int);
8void __sp804_clockevents_init(void __iomem *, unsigned int, 8int __sp804_clockevents_init(void __iomem *, unsigned int,
9 struct clk *, const char *); 9 struct clk *, const char *);
10void sp804_timer_disable(void __iomem *); 10void sp804_timer_disable(void __iomem *);
11 11
12static inline void sp804_clocksource_init(void __iomem *base, const char *name) 12static inline void sp804_clocksource_init(void __iomem *base, const char *name)