aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/timer-atmel-pit.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 21:09:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 21:09:13 -0400
commit5e1b834b27fb2c27cde33a0752425f11d10c0b2d (patch)
tree055c2c7165dcf0ccd73a273b16ad493ff48823a6 /drivers/clocksource/timer-atmel-pit.c
parent49deffe0b0e4c2030696c7a6fd680bacf4761069 (diff)
parentb536fd587044af02183b3c02690431b93154f0fa (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "A rather smalish set of updates for timers and timekeeping: - Two core fixes to prevent potential undefinded behaviour about which gcc is complaining rightfully. - A fix to prevent stopping the tick on an (soon) offline CPU so it can complete the shutdown procedure. - Wait for clocks to stabilize before making decisions, so a not yet validated clock is not rejected. - The usual pile of fixes to the various clocksource drivers. - Core code typo and include fixlets" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: timekeeping: Include the correct header for errno definitions clocksource/drivers/ti-32k: Prevent ftrace recursion clocksource/mips-gic-timer: Stop checking cpu_has_counter clocksource/mips-gic-timer: Print an error if IRQ setup fails tick/nohz: Prevent stopping the tick on an offline CPU clocksource/drivers/oxnas: Add OX820 compatible clocksource/drivers/timer-atmel-pit: Simplify IRQ handler clocksource/drivers/timer-atmel-pit: Remove uselesss WARN_ON_ONCE clocksource/drivers/timer-atmel-pit: Drop at91sam926x_pit_common_init clocksource/drivers/moxart: Replace panic by pr_err clocksource/drivers/moxart: Replace setup_irq by request_irq clocksource/drivers/moxart: Add Aspeed support clocksource/drivers/moxart: Use struct to hold state clocksource/drivers/moxart: Refactor enable/disable time: Avoid undefined behaviour in ktime_add_safe() time: Avoid undefined behaviour in timespec64_add_safe() timekeeping: Prints the amounts of time spent during suspend clocksource: Defer override invalidation unless clock is unstable hrtimer: Spelling fixes
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);