aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2007-11-12 17:45:16 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-01-26 10:07:50 -0500
commita88264c24c44924a549f3d596b86d611b7ee9909 (patch)
tree1f8e339e22743acf64b0d19a9b8328bbf5b66ac3
parent3777f7748a5d10222a55ce88f753a19b16c17032 (diff)
[ARM] pxa: remove periodic mode emulation support
Apparantly, the generic time subsystem can accurately emulate periodic mode via the one-shot support code, so we don't need our own periodic emulation code anymore. Just ensure that we build support for one shot into the generic time subsystem. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-pxa/time.c61
2 files changed, 9 insertions, 53 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a04f507e7f2c..1be718208704 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -345,6 +345,7 @@ config ARCH_PXA
345 select GENERIC_GPIO 345 select GENERIC_GPIO
346 select GENERIC_TIME 346 select GENERIC_TIME
347 select GENERIC_CLOCKEVENTS 347 select GENERIC_CLOCKEVENTS
348 select TICK_ONESHOT
348 help 349 help
349 Support for Intel/Marvell's PXA2xx/PXA3xx processor line. 350 Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
350 351
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index fbfa1920353d..3c4abbf31803 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -59,55 +59,17 @@ unsigned long long sched_clock(void)
59} 59}
60 60
61 61
62#define MIN_OSCR_DELTA 16
63
62static irqreturn_t 64static irqreturn_t
63pxa_ost0_interrupt(int irq, void *dev_id) 65pxa_ost0_interrupt(int irq, void *dev_id)
64{ 66{
65 int next_match;
66 struct clock_event_device *c = dev_id; 67 struct clock_event_device *c = dev_id;
67 68
68 if (c->mode == CLOCK_EVT_MODE_ONESHOT) { 69 /* Disarm the compare/match, signal the event. */
69 /* Disarm the compare/match, signal the event. */ 70 OIER &= ~OIER_E0;
70 OIER &= ~OIER_E0; 71 OSSR = OSSR_M0;
71 OSSR = OSSR_M0; 72 c->event_handler(c);
72 c->event_handler(c);
73 } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
74 /* Call the event handler as many times as necessary
75 * to recover missed events, if any (if we update
76 * OSMR0 and OSCR0 is still ahead of us, we've missed
77 * the event). As we're dealing with that, re-arm the
78 * compare/match for the next event.
79 *
80 * HACK ALERT:
81 *
82 * There's a latency between the instruction that
83 * writes to OSMR0 and the actual commit to the
84 * physical hardware, because the CPU doesn't (have
85 * to) run at bus speed, there's a write buffer
86 * between the CPU and the bus, etc. etc. So if the
87 * target OSCR0 is "very close", to the OSMR0 load
88 * value, the update to OSMR0 might not get to the
89 * hardware in time and we'll miss that interrupt.
90 *
91 * To be safe, if the new OSMR0 is "very close" to the
92 * target OSCR0 value, we call the event_handler as
93 * though the event actually happened. According to
94 * Nico's comment in the previous version of this
95 * code, experience has shown that 6 OSCR ticks is
96 * "very close" but he went with 8. We will use 16,
97 * based on the results of testing on PXA270.
98 *
99 * To be doubly sure, we also tell clkevt via
100 * clockevents_register_device() not to ask for
101 * anything that might put us "very close".
102 */
103#define MIN_OSCR_DELTA 16
104 do {
105 OSSR = OSSR_M0;
106 next_match = (OSMR0 += LATCH);
107 c->event_handler(c);
108 } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
109 && (c->mode == CLOCK_EVT_MODE_PERIODIC));
110 }
111 73
112 return IRQ_HANDLED; 74 return IRQ_HANDLED;
113} 75}
@@ -133,14 +95,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
133 unsigned long irqflags; 95 unsigned long irqflags;
134 96
135 switch (mode) { 97 switch (mode) {
136 case CLOCK_EVT_MODE_PERIODIC:
137 raw_local_irq_save(irqflags);
138 OSSR = OSSR_M0;
139 OIER |= OIER_E0;
140 OSMR0 = OSCR + LATCH;
141 raw_local_irq_restore(irqflags);
142 break;
143
144 case CLOCK_EVT_MODE_ONESHOT: 98 case CLOCK_EVT_MODE_ONESHOT:
145 raw_local_irq_save(irqflags); 99 raw_local_irq_save(irqflags);
146 OIER &= ~OIER_E0; 100 OIER &= ~OIER_E0;
@@ -158,13 +112,14 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
158 break; 112 break;
159 113
160 case CLOCK_EVT_MODE_RESUME: 114 case CLOCK_EVT_MODE_RESUME:
115 case CLOCK_EVT_MODE_PERIODIC:
161 break; 116 break;
162 } 117 }
163} 118}
164 119
165static struct clock_event_device ckevt_pxa_osmr0 = { 120static struct clock_event_device ckevt_pxa_osmr0 = {
166 .name = "osmr0", 121 .name = "osmr0",
167 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 122 .features = CLOCK_EVT_FEAT_ONESHOT,
168 .shift = 32, 123 .shift = 32,
169 .rating = 200, 124 .rating = 200,
170 .cpumask = CPU_MASK_CPU0, 125 .cpumask = CPU_MASK_CPU0,