4b4107d655940a485b6e50e2efe3c9b56f5f54c1
[openembedded.git] /
1 From bda65817167cce5294e1d84670f36815262ed550 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk@dyn-67.arm.linux.org.uk>
3 Date: Sun, 3 Feb 2008 21:58:12 +0300
4 Subject: [PATCH 19/64] pxa: remove periodic mode emulation support
5
6 Apparantly, the generic time subsystem can accurately emulate periodic
7 mode via the one-shot support code, so we don't need our own periodic
8 emulation code anymore.  Just ensure that we build support for one shot
9 into the generic time subsystem.
10
11 Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
12 ---
13  arch/arm/Kconfig         |    1 +
14  arch/arm/mach-pxa/time.c |   61 ++++++----------------------------------------
15  2 files changed, 9 insertions(+), 53 deletions(-)
16
17 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
18 index a04f507..1be7182 100644
19 --- a/arch/arm/Kconfig
20 +++ b/arch/arm/Kconfig
21 @@ -345,6 +345,7 @@ config ARCH_PXA
22         select GENERIC_GPIO
23         select GENERIC_TIME
24         select GENERIC_CLOCKEVENTS
25 +       select TICK_ONESHOT
26         help
27           Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
28  
29 diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
30 index fbfa192..3c4abbf 100644
31 --- a/arch/arm/mach-pxa/time.c
32 +++ b/arch/arm/mach-pxa/time.c
33 @@ -59,55 +59,17 @@ unsigned long long sched_clock(void)
34  }
35  
36  
37 +#define MIN_OSCR_DELTA 16
38 +
39  static irqreturn_t
40  pxa_ost0_interrupt(int irq, void *dev_id)
41  {
42 -       int next_match;
43         struct clock_event_device *c = dev_id;
44  
45 -       if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
46 -               /* Disarm the compare/match, signal the event. */
47 -               OIER &= ~OIER_E0;
48 -               OSSR = OSSR_M0;
49 -               c->event_handler(c);
50 -       } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
51 -               /* Call the event handler as many times as necessary
52 -                * to recover missed events, if any (if we update
53 -                * OSMR0 and OSCR0 is still ahead of us, we've missed
54 -                * the event).  As we're dealing with that, re-arm the
55 -                * compare/match for the next event.
56 -                *
57 -                * HACK ALERT:
58 -                *
59 -                * There's a latency between the instruction that
60 -                * writes to OSMR0 and the actual commit to the
61 -                * physical hardware, because the CPU doesn't (have
62 -                * to) run at bus speed, there's a write buffer
63 -                * between the CPU and the bus, etc. etc.  So if the
64 -                * target OSCR0 is "very close", to the OSMR0 load
65 -                * value, the update to OSMR0 might not get to the
66 -                * hardware in time and we'll miss that interrupt.
67 -                *
68 -                * To be safe, if the new OSMR0 is "very close" to the
69 -                * target OSCR0 value, we call the event_handler as
70 -                * though the event actually happened.  According to
71 -                * Nico's comment in the previous version of this
72 -                * code, experience has shown that 6 OSCR ticks is
73 -                * "very close" but he went with 8.  We will use 16,
74 -                * based on the results of testing on PXA270.
75 -                *
76 -                * To be doubly sure, we also tell clkevt via
77 -                * clockevents_register_device() not to ask for
78 -                * anything that might put us "very close".
79 -        */
80 -#define MIN_OSCR_DELTA 16
81 -               do {
82 -                       OSSR = OSSR_M0;
83 -                       next_match = (OSMR0 += LATCH);
84 -                       c->event_handler(c);
85 -               } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
86 -                        && (c->mode == CLOCK_EVT_MODE_PERIODIC));
87 -       }
88 +       /* Disarm the compare/match, signal the event. */
89 +       OIER &= ~OIER_E0;
90 +       OSSR = OSSR_M0;
91 +       c->event_handler(c);
92  
93         return IRQ_HANDLED;
94  }
95 @@ -133,14 +95,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
96         unsigned long irqflags;
97  
98         switch (mode) {
99 -       case CLOCK_EVT_MODE_PERIODIC:
100 -               raw_local_irq_save(irqflags);
101 -               OSSR = OSSR_M0;
102 -               OIER |= OIER_E0;
103 -               OSMR0 = OSCR + LATCH;
104 -               raw_local_irq_restore(irqflags);
105 -               break;
106 -
107         case CLOCK_EVT_MODE_ONESHOT:
108                 raw_local_irq_save(irqflags);
109                 OIER &= ~OIER_E0;
110 @@ -158,13 +112,14 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
111                 break;
112  
113         case CLOCK_EVT_MODE_RESUME:
114 +       case CLOCK_EVT_MODE_PERIODIC:
115                 break;
116         }
117  }
118  
119  static struct clock_event_device ckevt_pxa_osmr0 = {
120         .name           = "osmr0",
121 -       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
122 +       .features       = CLOCK_EVT_FEAT_ONESHOT,
123         .shift          = 32,
124         .rating         = 200,
125         .cpumask        = CPU_MASK_CPU0,
126 -- 
127 1.5.3.8
128