aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ixp4xx/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ixp4xx/common.c')
-rw-r--r--arch/arm/mach-ixp4xx/common.c77
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}
128EXPORT_SYMBOL(irq_to_gpio); 129EXPORT_SYMBOL(irq_to_gpio);
129 130
130static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) 131static 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
195static void ixp4xx_irq_mask(unsigned int irq) 196static 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
203static void ixp4xx_irq_ack(unsigned int irq) 204static 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 */
215static void ixp4xx_irq_unmask(unsigned int irq) 216static 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
226static struct irq_chip ixp4xx_irq_chip = { 227static 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
234void __init ixp4xx_init_irq(void) 235void __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 */
405static DEFINE_CLOCK_DATA(cd);
406
407unsigned long long notrace sched_clock(void)
408{
409 u32 cyc = *IXP4XX_OSTS;
410 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
411}
412
413static 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 */
404static cycle_t ixp4xx_get_cycles(struct clocksource *cs) 422static 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;
419EXPORT_SYMBOL(ixp4xx_timer_freq); 436EXPORT_SYMBOL(ixp4xx_timer_freq);
420static void __init ixp4xx_clocksource_init(void) 437static 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 */
431unsigned 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/*