]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/mach-ixp4xx/common.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / arch / arm / mach-ixp4xx / common.c
index 0bce09799d1841cd6c2ad5ea776b6710091d6a9e..9fd894271d5d0b353ca1e5214af258d22f99f686 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/irq.h>
+#include <asm/sched_clock.h>
 
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
@@ -127,9 +128,9 @@ int irq_to_gpio(unsigned int irq)
 }
 EXPORT_SYMBOL(irq_to_gpio);
 
-static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
+static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
 {
-       int line = irq2gpio[irq];
+       int line = irq2gpio[d->irq];
        u32 int_style;
        enum ixp4xx_irq_type irq_type;
        volatile u32 *int_reg;
@@ -166,9 +167,9 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
        }
 
        if (irq_type == IXP4XX_IRQ_EDGE)
-               ixp4xx_irq_edge |= (1 << irq);
+               ixp4xx_irq_edge |= (1 << d->irq);
        else
-               ixp4xx_irq_edge &= ~(1 << irq);
+               ixp4xx_irq_edge &= ~(1 << d->irq);
 
        if (line >= 8) {        /* pins 8-15 */
                line -= 8;
@@ -187,22 +188,22 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
        *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
 
        /* Configure the line as an input */
-       gpio_line_config(irq2gpio[irq], IXP4XX_GPIO_IN);
+       gpio_line_config(irq2gpio[d->irq], IXP4XX_GPIO_IN);
 
        return 0;
 }
 
-static void ixp4xx_irq_mask(unsigned int irq)
+static void ixp4xx_irq_mask(struct irq_data *d)
 {
-       if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
-               *IXP4XX_ICMR2 &= ~(1 << (irq - 32));
+       if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32)
+               *IXP4XX_ICMR2 &= ~(1 << (d->irq - 32));
        else
-               *IXP4XX_ICMR &= ~(1 << irq);
+               *IXP4XX_ICMR &= ~(1 << d->irq);
 }
 
-static void ixp4xx_irq_ack(unsigned int irq)
+static void ixp4xx_irq_ack(struct irq_data *d)
 {
-       int line = (irq < 32) ? irq2gpio[irq] : -1;
+       int line = (d->irq < 32) ? irq2gpio[d->irq] : -1;
 
        if (line >= 0)
                *IXP4XX_GPIO_GPISR = (1 << line);
@@ -212,23 +213,23 @@ static void ixp4xx_irq_ack(unsigned int irq)
  * Level triggered interrupts on GPIO lines can only be cleared when the
  * interrupt condition disappears.
  */
-static void ixp4xx_irq_unmask(unsigned int irq)
+static void ixp4xx_irq_unmask(struct irq_data *d)
 {
-       if (!(ixp4xx_irq_edge & (1 << irq)))
-               ixp4xx_irq_ack(irq);
+       if (!(ixp4xx_irq_edge & (1 << d->irq)))
+               ixp4xx_irq_ack(d);
 
-       if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
-               *IXP4XX_ICMR2 |= (1 << (irq - 32));
+       if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32)
+               *IXP4XX_ICMR2 |= (1 << (d->irq - 32));
        else
-               *IXP4XX_ICMR |= (1 << irq);
+               *IXP4XX_ICMR |= (1 << d->irq);
 }
 
 static struct irq_chip ixp4xx_irq_chip = {
        .name           = "IXP4xx",
-       .ack            = ixp4xx_irq_ack,
-       .mask           = ixp4xx_irq_mask,
-       .unmask         = ixp4xx_irq_unmask,
-       .set_type       = ixp4xx_set_irq_type,
+       .irq_ack        = ixp4xx_irq_ack,
+       .irq_mask       = ixp4xx_irq_mask,
+       .irq_unmask     = ixp4xx_irq_unmask,
+       .irq_set_type   = ixp4xx_set_irq_type,
 };
 
 void __init ixp4xx_init_irq(void)
@@ -398,6 +399,23 @@ void __init ixp4xx_sys_init(void)
                        ixp4xx_exp_bus_size >> 20);
 }
 
+/*
+ * sched_clock()
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+       u32 cyc = *IXP4XX_OSTS;
+       return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace ixp4xx_update_sched_clock(void)
+{
+       u32 cyc = *IXP4XX_OSTS;
+       update_sched_clock(&cd, cyc, (u32)~0);
+}
+
 /*
  * clocksource
  */
@@ -411,29 +429,16 @@ static struct clocksource clocksource_ixp4xx = {
        .rating         = 200,
        .read           = ixp4xx_get_cycles,
        .mask           = CLOCKSOURCE_MASK(32),
-       .shift          = 20,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-unsigned long ixp4xx_timer_freq = FREQ;
+unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
 EXPORT_SYMBOL(ixp4xx_timer_freq);
 static void __init ixp4xx_clocksource_init(void)
 {
-       clocksource_ixp4xx.mult =
-               clocksource_hz2mult(ixp4xx_timer_freq,
-                                   clocksource_ixp4xx.shift);
-       clocksource_register(&clocksource_ixp4xx);
-}
-
-/*
- * sched_clock()
- */
-unsigned long long sched_clock(void)
-{
-       cycle_t cyc = ixp4xx_get_cycles(NULL);
-       struct clocksource *cs = &clocksource_ixp4xx;
+       init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq);
 
-       return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
+       clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq);
 }
 
 /*
@@ -491,7 +496,7 @@ static struct clock_event_device clockevent_ixp4xx = {
 
 static void __init ixp4xx_clockevent_init(void)
 {
-       clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC,
+       clockevent_ixp4xx.mult = div_sc(IXP4XX_TIMER_FREQ, NSEC_PER_SEC,
                                        clockevent_ixp4xx.shift);
        clockevent_ixp4xx.max_delta_ns =
                clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx);