diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-11-12 17:45:16 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-01-26 10:07:50 -0500 |
commit | a88264c24c44924a549f3d596b86d611b7ee9909 (patch) | |
tree | 1f8e339e22743acf64b0d19a9b8328bbf5b66ac3 /arch/arm | |
parent | 3777f7748a5d10222a55ce88f753a19b16c17032 (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>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/time.c | 61 |
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 | |||
62 | static irqreturn_t | 64 | static irqreturn_t |
63 | pxa_ost0_interrupt(int irq, void *dev_id) | 65 | pxa_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 | ||
165 | static struct clock_event_device ckevt_pxa_osmr0 = { | 120 | static 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, |