diff options
Diffstat (limited to 'arch/arm/mach-ixp4xx/common.c')
-rw-r--r-- | arch/arm/mach-ixp4xx/common.c | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 0bce09799d18..4dc68d6bb6be 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
36 | #include <asm/page.h> | 36 | #include <asm/page.h> |
37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
38 | #include <asm/sched_clock.h> | ||
38 | 39 | ||
39 | #include <asm/mach/map.h> | 40 | #include <asm/mach/map.h> |
40 | #include <asm/mach/irq.h> | 41 | #include <asm/mach/irq.h> |
@@ -127,9 +128,9 @@ int irq_to_gpio(unsigned int irq) | |||
127 | } | 128 | } |
128 | EXPORT_SYMBOL(irq_to_gpio); | 129 | EXPORT_SYMBOL(irq_to_gpio); |
129 | 130 | ||
130 | static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) | 131 | static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type) |
131 | { | 132 | { |
132 | int line = irq2gpio[irq]; | 133 | int line = irq2gpio[d->irq]; |
133 | u32 int_style; | 134 | u32 int_style; |
134 | enum ixp4xx_irq_type irq_type; | 135 | enum ixp4xx_irq_type irq_type; |
135 | volatile u32 *int_reg; | 136 | volatile u32 *int_reg; |
@@ -166,9 +167,9 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) | |||
166 | } | 167 | } |
167 | 168 | ||
168 | if (irq_type == IXP4XX_IRQ_EDGE) | 169 | if (irq_type == IXP4XX_IRQ_EDGE) |
169 | ixp4xx_irq_edge |= (1 << irq); | 170 | ixp4xx_irq_edge |= (1 << d->irq); |
170 | else | 171 | else |
171 | ixp4xx_irq_edge &= ~(1 << irq); | 172 | ixp4xx_irq_edge &= ~(1 << d->irq); |
172 | 173 | ||
173 | if (line >= 8) { /* pins 8-15 */ | 174 | if (line >= 8) { /* pins 8-15 */ |
174 | line -= 8; | 175 | line -= 8; |
@@ -187,22 +188,22 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) | |||
187 | *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); | 188 | *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); |
188 | 189 | ||
189 | /* Configure the line as an input */ | 190 | /* Configure the line as an input */ |
190 | gpio_line_config(irq2gpio[irq], IXP4XX_GPIO_IN); | 191 | gpio_line_config(irq2gpio[d->irq], IXP4XX_GPIO_IN); |
191 | 192 | ||
192 | return 0; | 193 | return 0; |
193 | } | 194 | } |
194 | 195 | ||
195 | static void ixp4xx_irq_mask(unsigned int irq) | 196 | static void ixp4xx_irq_mask(struct irq_data *d) |
196 | { | 197 | { |
197 | if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32) | 198 | if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32) |
198 | *IXP4XX_ICMR2 &= ~(1 << (irq - 32)); | 199 | *IXP4XX_ICMR2 &= ~(1 << (d->irq - 32)); |
199 | else | 200 | else |
200 | *IXP4XX_ICMR &= ~(1 << irq); | 201 | *IXP4XX_ICMR &= ~(1 << d->irq); |
201 | } | 202 | } |
202 | 203 | ||
203 | static void ixp4xx_irq_ack(unsigned int irq) | 204 | static void ixp4xx_irq_ack(struct irq_data *d) |
204 | { | 205 | { |
205 | int line = (irq < 32) ? irq2gpio[irq] : -1; | 206 | int line = (d->irq < 32) ? irq2gpio[d->irq] : -1; |
206 | 207 | ||
207 | if (line >= 0) | 208 | if (line >= 0) |
208 | *IXP4XX_GPIO_GPISR = (1 << line); | 209 | *IXP4XX_GPIO_GPISR = (1 << line); |
@@ -212,23 +213,23 @@ static void ixp4xx_irq_ack(unsigned int irq) | |||
212 | * Level triggered interrupts on GPIO lines can only be cleared when the | 213 | * Level triggered interrupts on GPIO lines can only be cleared when the |
213 | * interrupt condition disappears. | 214 | * interrupt condition disappears. |
214 | */ | 215 | */ |
215 | static void ixp4xx_irq_unmask(unsigned int irq) | 216 | static void ixp4xx_irq_unmask(struct irq_data *d) |
216 | { | 217 | { |
217 | if (!(ixp4xx_irq_edge & (1 << irq))) | 218 | if (!(ixp4xx_irq_edge & (1 << d->irq))) |
218 | ixp4xx_irq_ack(irq); | 219 | ixp4xx_irq_ack(d); |
219 | 220 | ||
220 | if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32) | 221 | if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32) |
221 | *IXP4XX_ICMR2 |= (1 << (irq - 32)); | 222 | *IXP4XX_ICMR2 |= (1 << (d->irq - 32)); |
222 | else | 223 | else |
223 | *IXP4XX_ICMR |= (1 << irq); | 224 | *IXP4XX_ICMR |= (1 << d->irq); |
224 | } | 225 | } |
225 | 226 | ||
226 | static struct irq_chip ixp4xx_irq_chip = { | 227 | static struct irq_chip ixp4xx_irq_chip = { |
227 | .name = "IXP4xx", | 228 | .name = "IXP4xx", |
228 | .ack = ixp4xx_irq_ack, | 229 | .irq_ack = ixp4xx_irq_ack, |
229 | .mask = ixp4xx_irq_mask, | 230 | .irq_mask = ixp4xx_irq_mask, |
230 | .unmask = ixp4xx_irq_unmask, | 231 | .irq_unmask = ixp4xx_irq_unmask, |
231 | .set_type = ixp4xx_set_irq_type, | 232 | .irq_set_type = ixp4xx_set_irq_type, |
232 | }; | 233 | }; |
233 | 234 | ||
234 | void __init ixp4xx_init_irq(void) | 235 | void __init ixp4xx_init_irq(void) |
@@ -399,6 +400,23 @@ void __init ixp4xx_sys_init(void) | |||
399 | } | 400 | } |
400 | 401 | ||
401 | /* | 402 | /* |
403 | * sched_clock() | ||
404 | */ | ||
405 | static DEFINE_CLOCK_DATA(cd); | ||
406 | |||
407 | unsigned long long notrace sched_clock(void) | ||
408 | { | ||
409 | u32 cyc = *IXP4XX_OSTS; | ||
410 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); | ||
411 | } | ||
412 | |||
413 | static void notrace ixp4xx_update_sched_clock(void) | ||
414 | { | ||
415 | u32 cyc = *IXP4XX_OSTS; | ||
416 | update_sched_clock(&cd, cyc, (u32)~0); | ||
417 | } | ||
418 | |||
419 | /* | ||
402 | * clocksource | 420 | * clocksource |
403 | */ | 421 | */ |
404 | static cycle_t ixp4xx_get_cycles(struct clocksource *cs) | 422 | static cycle_t ixp4xx_get_cycles(struct clocksource *cs) |
@@ -411,7 +429,6 @@ static struct clocksource clocksource_ixp4xx = { | |||
411 | .rating = 200, | 429 | .rating = 200, |
412 | .read = ixp4xx_get_cycles, | 430 | .read = ixp4xx_get_cycles, |
413 | .mask = CLOCKSOURCE_MASK(32), | 431 | .mask = CLOCKSOURCE_MASK(32), |
414 | .shift = 20, | ||
415 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 432 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
416 | }; | 433 | }; |
417 | 434 | ||
@@ -419,21 +436,9 @@ unsigned long ixp4xx_timer_freq = FREQ; | |||
419 | EXPORT_SYMBOL(ixp4xx_timer_freq); | 436 | EXPORT_SYMBOL(ixp4xx_timer_freq); |
420 | static void __init ixp4xx_clocksource_init(void) | 437 | static void __init ixp4xx_clocksource_init(void) |
421 | { | 438 | { |
422 | clocksource_ixp4xx.mult = | 439 | init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); |
423 | clocksource_hz2mult(ixp4xx_timer_freq, | ||
424 | clocksource_ixp4xx.shift); | ||
425 | clocksource_register(&clocksource_ixp4xx); | ||
426 | } | ||
427 | |||
428 | /* | ||
429 | * sched_clock() | ||
430 | */ | ||
431 | unsigned long long sched_clock(void) | ||
432 | { | ||
433 | cycle_t cyc = ixp4xx_get_cycles(NULL); | ||
434 | struct clocksource *cs = &clocksource_ixp4xx; | ||
435 | 440 | ||
436 | return clocksource_cyc2ns(cyc, cs->mult, cs->shift); | 441 | clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq); |
437 | } | 442 | } |
438 | 443 | ||
439 | /* | 444 | /* |