diff options
Diffstat (limited to 'drivers/clocksource/timer-atmel-pit.c')
-rw-r--r-- | drivers/clocksource/timer-atmel-pit.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c index d911c5dca8f1..ffaca7c2c996 100644 --- a/drivers/clocksource/timer-atmel-pit.c +++ b/drivers/clocksource/timer-atmel-pit.c | |||
@@ -177,7 +177,7 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) | |||
177 | /* | 177 | /* |
178 | * Set up both clocksource and clockevent support. | 178 | * Set up both clocksource and clockevent support. |
179 | */ | 179 | */ |
180 | static void __init at91sam926x_pit_common_init(struct pit_data *data) | 180 | static int __init at91sam926x_pit_common_init(struct pit_data *data) |
181 | { | 181 | { |
182 | unsigned long pit_rate; | 182 | unsigned long pit_rate; |
183 | unsigned bits; | 183 | unsigned bits; |
@@ -204,14 +204,21 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data) | |||
204 | data->clksrc.rating = 175; | 204 | data->clksrc.rating = 175; |
205 | data->clksrc.read = read_pit_clk; | 205 | data->clksrc.read = read_pit_clk; |
206 | data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; | 206 | data->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; |
207 | clocksource_register_hz(&data->clksrc, pit_rate); | 207 | |
208 | ret = clocksource_register_hz(&data->clksrc, pit_rate); | ||
209 | if (ret) { | ||
210 | pr_err("Failed to register clocksource"); | ||
211 | return ret; | ||
212 | } | ||
208 | 213 | ||
209 | /* Set up irq handler */ | 214 | /* Set up irq handler */ |
210 | ret = request_irq(data->irq, at91sam926x_pit_interrupt, | 215 | ret = request_irq(data->irq, at91sam926x_pit_interrupt, |
211 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, | 216 | IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, |
212 | "at91_tick", data); | 217 | "at91_tick", data); |
213 | if (ret) | 218 | if (ret) { |
214 | panic(pr_fmt("Unable to setup IRQ\n")); | 219 | pr_err("Unable to setup IRQ\n"); |
220 | return ret; | ||
221 | } | ||
215 | 222 | ||
216 | /* Set up and register clockevents */ | 223 | /* Set up and register clockevents */ |
217 | data->clkevt.name = "pit"; | 224 | data->clkevt.name = "pit"; |
@@ -226,34 +233,42 @@ static void __init at91sam926x_pit_common_init(struct pit_data *data) | |||
226 | data->clkevt.resume = at91sam926x_pit_resume; | 233 | data->clkevt.resume = at91sam926x_pit_resume; |
227 | data->clkevt.suspend = at91sam926x_pit_suspend; | 234 | data->clkevt.suspend = at91sam926x_pit_suspend; |
228 | clockevents_register_device(&data->clkevt); | 235 | clockevents_register_device(&data->clkevt); |
236 | |||
237 | return 0; | ||
229 | } | 238 | } |
230 | 239 | ||
231 | static void __init at91sam926x_pit_dt_init(struct device_node *node) | 240 | static int __init at91sam926x_pit_dt_init(struct device_node *node) |
232 | { | 241 | { |
233 | struct pit_data *data; | 242 | struct pit_data *data; |
234 | 243 | ||
235 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 244 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
236 | if (!data) | 245 | if (!data) |
237 | panic(pr_fmt("Unable to allocate memory\n")); | 246 | return -ENOMEM; |
238 | 247 | ||
239 | data->base = of_iomap(node, 0); | 248 | data->base = of_iomap(node, 0); |
240 | if (!data->base) | 249 | if (!data->base) { |
241 | panic(pr_fmt("Could not map PIT address\n")); | 250 | pr_err("Could not map PIT address\n"); |
251 | return -ENXIO; | ||
252 | } | ||
242 | 253 | ||
243 | data->mck = of_clk_get(node, 0); | 254 | data->mck = of_clk_get(node, 0); |
244 | if (IS_ERR(data->mck)) | 255 | if (IS_ERR(data->mck)) |
245 | /* Fallback on clkdev for !CCF-based boards */ | 256 | /* Fallback on clkdev for !CCF-based boards */ |
246 | data->mck = clk_get(NULL, "mck"); | 257 | data->mck = clk_get(NULL, "mck"); |
247 | 258 | ||
248 | if (IS_ERR(data->mck)) | 259 | if (IS_ERR(data->mck)) { |
249 | panic(pr_fmt("Unable to get mck clk\n")); | 260 | pr_err("Unable to get mck clk\n"); |
261 | return PTR_ERR(data->mck); | ||
262 | } | ||
250 | 263 | ||
251 | /* Get the interrupts property */ | 264 | /* Get the interrupts property */ |
252 | data->irq = irq_of_parse_and_map(node, 0); | 265 | data->irq = irq_of_parse_and_map(node, 0); |
253 | if (!data->irq) | 266 | if (!data->irq) { |
254 | panic(pr_fmt("Unable to get IRQ from DT\n")); | 267 | pr_err("Unable to get IRQ from DT\n"); |
268 | return -EINVAL; | ||
269 | } | ||
255 | 270 | ||
256 | at91sam926x_pit_common_init(data); | 271 | return at91sam926x_pit_common_init(data); |
257 | } | 272 | } |
258 | CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", | 273 | CLOCKSOURCE_OF_DECLARE_RET(at91sam926x_pit, "atmel,at91sam9260-pit", |
259 | at91sam926x_pit_dt_init); | 274 | at91sam926x_pit_dt_init); |