Merge branch 'for-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-ep93xx / timer-ep93xx.c
index 932236b348bc7e319a0ee39b147bb5d1398b7e9c..e5f791145bd00dc4cb9424101564ef60c0c2f6bb 100644 (file)
  * is free-running, and can't generate interrupts.
  *
  * The 508 kHz timers are ideal for use for the timer interrupt, as the
- * most common values of HZ divide 508 kHz nicely.  We pick one of the 16
- * bit timers (timer 1) since we don't need more than 16 bits of reload
- * value as long as HZ >= 8.
+ * most common values of HZ divide 508 kHz nicely.  We pick the 32 bit
+ * timer (timer 3) to get as long sleep intervals as possible when using
+ * CONFIG_NO_HZ.
  *
  * The higher clock rate of timer 4 makes it a better choice than the
- * other timers for use in gettimeoffset(), while the fact that it can't
- * generate interrupts means we don't have to worry about not being able
- * to use this timer for something else.  We also use timer 4 for keeping
- * track of lost jiffies.
+ * other timers for use as clock source and for sched_clock(), providing
+ * a stable 40 bit time base.
+ *************************************************************************
  */
 #define EP93XX_TIMER_REG(x)            (EP93XX_TIMER_BASE + (x))
 #define EP93XX_TIMER1_LOAD             EP93XX_TIMER_REG(0x00)
@@ -55,8 +54,8 @@ static u64 notrace ep93xx_read_sched_clock(void)
 {
        u64 ret;
 
-       ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW);
-       ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
+       ret = readl(EP93XX_TIMER4_VALUE_LOW);
+       ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
        return ret;
 }
 
@@ -64,8 +63,8 @@ cycle_t ep93xx_clocksource_read(struct clocksource *c)
 {
        u64 ret;
 
-       ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW);
-       ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
+       ret = readl(EP93XX_TIMER4_VALUE_LOW);
+       ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
        return (cycle_t) ret;
 }
 
@@ -77,29 +76,32 @@ static int ep93xx_clkevt_set_next_event(unsigned long next,
                    EP93XX_TIMER123_CONTROL_CLKSEL;
 
        /* Clear timer */
-       __raw_writel(tmode, EP93XX_TIMER1_CONTROL);
+       writel(tmode, EP93XX_TIMER3_CONTROL);
 
        /* Set next event */
-       __raw_writel(next, EP93XX_TIMER1_LOAD);
-       __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
-                    EP93XX_TIMER1_CONTROL);
+       writel(next, EP93XX_TIMER3_LOAD);
+       writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
+              EP93XX_TIMER3_CONTROL);
         return 0;
 }
 
 
-static void ep93xx_clkevt_set_mode(enum clock_event_mode mode,
-                                  struct clock_event_device *evt)
+static int ep93xx_clkevt_shutdown(struct clock_event_device *evt)
 {
        /* Disable timer */
-       __raw_writel(0, EP93XX_TIMER1_CONTROL);
+       writel(0, EP93XX_TIMER3_CONTROL);
+
+       return 0;
 }
 
 static struct clock_event_device ep93xx_clockevent = {
-       .name           = "timer1",
-       .features       = CLOCK_EVT_FEAT_ONESHOT,
-       .set_mode       = ep93xx_clkevt_set_mode,
-       .set_next_event = ep93xx_clkevt_set_next_event,
-       .rating         = 300,
+       .name                   = "timer1",
+       .features               = CLOCK_EVT_FEAT_ONESHOT,
+       .set_state_shutdown     = ep93xx_clkevt_shutdown,
+       .set_state_oneshot      = ep93xx_clkevt_shutdown,
+       .tick_resume            = ep93xx_clkevt_shutdown,
+       .set_next_event         = ep93xx_clkevt_set_next_event,
+       .rating                 = 300,
 };
 
 static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
@@ -107,7 +109,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
        struct clock_event_device *evt = dev_id;
 
        /* Writing any value clears the timer interrupt */
-       __raw_writel(1, EP93XX_TIMER1_CLEAR);
+       writel(1, EP93XX_TIMER3_CLEAR);
 
        evt->event_handler(evt);
 
@@ -124,19 +126,18 @@ static struct irqaction ep93xx_timer_irq = {
 void __init ep93xx_timer_init(void)
 {
        /* Enable and register clocksource and sched_clock on timer 4 */
-       __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
-                       EP93XX_TIMER4_VALUE_HIGH);
+       writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
+              EP93XX_TIMER4_VALUE_HIGH);
        clocksource_mmio_init(NULL, "timer4",
                              EP93XX_TIMER4_RATE, 200, 40,
                              ep93xx_clocksource_read);
        sched_clock_register(ep93xx_read_sched_clock, 40,
                             EP93XX_TIMER4_RATE);
 
-       /* Set up clockevent on timer 1 */
-       setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
-       // FIXME: timer one is 16 bits 1-ffff use timer 3 1-ffffffff */
+       /* Set up clockevent on timer 3 */
+       setup_irq(IRQ_EP93XX_TIMER3, &ep93xx_timer_irq);
        clockevents_config_and_register(&ep93xx_clockevent,
                                        EP93XX_TIMER123_RATE,
                                        1,
-                                       0xffffU);
+                                       0xffffffffU);
 }