|
@@ -68,6 +68,7 @@ pxa_ost0_interrupt(int irq, void *dev_id)
|
|
|
if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
|
|
|
/* Disarm the compare/match, signal the event. */
|
|
|
OIER &= ~OIER_E0;
|
|
|
+ OSSR = OSSR_M0;
|
|
|
c->event_handler(c);
|
|
|
} else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
|
|
|
/* Call the event handler as many times as necessary
|
|
@@ -100,9 +101,9 @@ pxa_ost0_interrupt(int irq, void *dev_id)
|
|
|
* anything that might put us "very close".
|
|
|
*/
|
|
|
#define MIN_OSCR_DELTA 16
|
|
|
- do {
|
|
|
+ do {
|
|
|
OSSR = OSSR_M0;
|
|
|
- next_match = (OSMR0 += LATCH);
|
|
|
+ next_match = (OSMR0 += LATCH);
|
|
|
c->event_handler(c);
|
|
|
} while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
|
|
|
&& (c->mode == CLOCK_EVT_MODE_PERIODIC));
|
|
@@ -114,14 +115,16 @@ pxa_ost0_interrupt(int irq, void *dev_id)
|
|
|
static int
|
|
|
pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
|
|
|
{
|
|
|
- unsigned long irqflags;
|
|
|
+ unsigned long flags, next, oscr;
|
|
|
|
|
|
- raw_local_irq_save(irqflags);
|
|
|
- OSMR0 = OSCR + delta;
|
|
|
- OSSR = OSSR_M0;
|
|
|
+ raw_local_irq_save(flags);
|
|
|
OIER |= OIER_E0;
|
|
|
- raw_local_irq_restore(irqflags);
|
|
|
- return 0;
|
|
|
+ next = OSCR + delta;
|
|
|
+ OSMR0 = next;
|
|
|
+ oscr = OSCR;
|
|
|
+ raw_local_irq_restore(flags);
|
|
|
+
|
|
|
+ return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
|
|
|
}
|
|
|
|
|
|
static void
|
|
@@ -132,15 +135,16 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
|
|
|
switch (mode) {
|
|
|
case CLOCK_EVT_MODE_PERIODIC:
|
|
|
raw_local_irq_save(irqflags);
|
|
|
- OSMR0 = OSCR + LATCH;
|
|
|
OSSR = OSSR_M0;
|
|
|
OIER |= OIER_E0;
|
|
|
+ OSMR0 = OSCR + LATCH;
|
|
|
raw_local_irq_restore(irqflags);
|
|
|
break;
|
|
|
|
|
|
case CLOCK_EVT_MODE_ONESHOT:
|
|
|
raw_local_irq_save(irqflags);
|
|
|
OIER &= ~OIER_E0;
|
|
|
+ OSSR = OSSR_M0;
|
|
|
raw_local_irq_restore(irqflags);
|
|
|
break;
|
|
|
|
|
@@ -149,6 +153,7 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
|
|
|
/* initializing, released, or preparing for suspend */
|
|
|
raw_local_irq_save(irqflags);
|
|
|
OIER &= ~OIER_E0;
|
|
|
+ OSSR = OSSR_M0;
|
|
|
raw_local_irq_restore(irqflags);
|
|
|
break;
|
|
|
|