aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/timer-atmel-pit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource/timer-atmel-pit.c')
-rw-r--r--drivers/clocksource/timer-atmel-pit.c96
1 files changed, 37 insertions, 59 deletions
diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c
index 7f0f5b26d8c5..6555821bbdae 100644
--- a/drivers/clocksource/timer-atmel-pit.c
+++ b/drivers/clocksource/timer-atmel-pit.c
@@ -149,24 +149,13 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
149{ 149{
150 struct pit_data *data = dev_id; 150 struct pit_data *data = dev_id;
151 151
152 /*
153 * irqs should be disabled here, but as the irq is shared they are only
154 * guaranteed to be off if the timer irq is registered first.
155 */
156 WARN_ON_ONCE(!irqs_disabled());
157
158 /* The PIT interrupt may be disabled, and is shared */ 152 /* The PIT interrupt may be disabled, and is shared */
159 if (clockevent_state_periodic(&data->clkevt) && 153 if (clockevent_state_periodic(&data->clkevt) &&
160 (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) { 154 (pit_read(data->base, AT91_PIT_SR) & AT91_PIT_PITS)) {
161 unsigned nr_ticks;
162
163 /* Get number of ticks performed before irq, and ack it */ 155 /* Get number of ticks performed before irq, and ack it */
164 nr_ticks = PIT_PICNT(pit_read(data->base, AT91_PIT_PIVR)); 156 data->cnt += data->cycle * PIT_PICNT(pit_read(data->base,
165 do { 157 AT91_PIT_PIVR));
166 data->cnt += data->cycle; 158 data->clkevt.event_handler(&data->clkevt);
167 data->clkevt.event_handler(&data->clkevt);
168 nr_ticks--;
169 } while (nr_ticks);
170 159
171 return IRQ_HANDLED; 160 return IRQ_HANDLED;
172 } 161 }
@@ -177,11 +166,41 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
177/* 166/*
178 * Set up both clocksource and clockevent support. 167 * Set up both clocksource and clockevent support.
179 */ 168 */
180static int __init at91sam926x_pit_common_init(struct pit_data *data) 169static int __init at91sam926x_pit_dt_init(struct device_node *node)
181{ 170{
182 unsigned long pit_rate; 171 unsigned long pit_rate;
183 unsigned bits; 172 unsigned bits;
184 int ret; 173 int ret;
174 struct pit_data *data;
175
176 data = kzalloc(sizeof(*data), GFP_KERNEL);
177 if (!data)
178 return -ENOMEM;
179
180 data->base = of_iomap(node, 0);
181 if (!data->base) {
182 pr_err("Could not map PIT address\n");
183 return -ENXIO;
184 }
185
186 data->mck = of_clk_get(node, 0);
187 if (IS_ERR(data->mck)) {
188 pr_err("Unable to get mck clk\n");
189 return PTR_ERR(data->mck);
190 }
191
192 ret = clk_prepare_enable(data->mck);
193 if (ret) {
194 pr_err("Unable to enable mck\n");
195 return ret;
196 }
197
198 /* Get the interrupts property */
199 data->irq = irq_of_parse_and_map(node, 0);
200 if (!data->irq) {
201 pr_err("Unable to get IRQ from DT\n");
202 return -EINVAL;
203 }
185 204
186 /* 205 /*
187 * Use our actual MCK to figure out how many MCK/16 ticks per 206 * Use our actual MCK to figure out how many MCK/16 ticks per
@@ -236,46 +255,5 @@ static int __init at91sam926x_pit_common_init(struct pit_data *data)
236 255
237 return 0; 256 return 0;
238} 257}
239
240static int __init at91sam926x_pit_dt_init(struct device_node *node)
241{
242 struct pit_data *data;
243 int ret;
244
245 data = kzalloc(sizeof(*data), GFP_KERNEL);
246 if (!data)
247 return -ENOMEM;
248
249 data->base = of_iomap(node, 0);
250 if (!data->base) {
251 pr_err("Could not map PIT address\n");
252 return -ENXIO;
253 }
254
255 data->mck = of_clk_get(node, 0);
256 if (IS_ERR(data->mck))
257 /* Fallback on clkdev for !CCF-based boards */
258 data->mck = clk_get(NULL, "mck");
259
260 if (IS_ERR(data->mck)) {
261 pr_err("Unable to get mck clk\n");
262 return PTR_ERR(data->mck);
263 }
264
265 ret = clk_prepare_enable(data->mck);
266 if (ret) {
267 pr_err("Unable to enable mck\n");
268 return ret;
269 }
270
271 /* Get the interrupts property */
272 data->irq = irq_of_parse_and_map(node, 0);
273 if (!data->irq) {
274 pr_err("Unable to get IRQ from DT\n");
275 return -EINVAL;
276 }
277
278 return at91sam926x_pit_common_init(data);
279}
280CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit", 258CLOCKSOURCE_OF_DECLARE(at91sam926x_pit, "atmel,at91sam9260-pit",
281 at91sam926x_pit_dt_init); 259 at91sam926x_pit_dt_init);