Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a88264c2 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 3777f774
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ config ARCH_PXA
	select GENERIC_GPIO
	select GENERIC_TIME
	select GENERIC_CLOCKEVENTS
	select TICK_ONESHOT
	help
	  Support for Intel/Marvell's PXA2xx/PXA3xx processor line.

+8 −53
Original line number Diff line number Diff line
@@ -59,55 +59,17 @@ unsigned long long sched_clock(void)
}


#define MIN_OSCR_DELTA 16

static irqreturn_t
pxa_ost0_interrupt(int irq, void *dev_id)
{
	int next_match;
	struct clock_event_device *c = 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
		 * to recover missed events, if any (if we update
		 * OSMR0 and OSCR0 is still ahead of us, we've missed
		 * the event).  As we're dealing with that, re-arm the
		 * compare/match for the next event.
		 *
		 * HACK ALERT:
		 *
		 * There's a latency between the instruction that
		 * writes to OSMR0 and the actual commit to the
		 * physical hardware, because the CPU doesn't (have
		 * to) run at bus speed, there's a write buffer
		 * between the CPU and the bus, etc. etc.  So if the
		 * target OSCR0 is "very close", to the OSMR0 load
		 * value, the update to OSMR0 might not get to the
		 * hardware in time and we'll miss that interrupt.
		 *
		 * To be safe, if the new OSMR0 is "very close" to the
		 * target OSCR0 value, we call the event_handler as
		 * though the event actually happened.  According to
		 * Nico's comment in the previous version of this
		 * code, experience has shown that 6 OSCR ticks is
		 * "very close" but he went with 8.  We will use 16,
		 * based on the results of testing on PXA270.
		 *
		 * To be doubly sure, we also tell clkevt via
		 * clockevents_register_device() not to ask for
		 * anything that might put us "very close".
	 */
#define MIN_OSCR_DELTA 16
		do {
			OSSR = OSSR_M0;
			next_match = (OSMR0 += LATCH);
			c->event_handler(c);
		} while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
			 && (c->mode == CLOCK_EVT_MODE_PERIODIC));
	}

	return IRQ_HANDLED;
}
@@ -133,14 +95,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
	unsigned long irqflags;

	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		raw_local_irq_save(irqflags);
		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;
@@ -158,13 +112,14 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
		break;

	case CLOCK_EVT_MODE_RESUME:
	case CLOCK_EVT_MODE_PERIODIC:
		break;
	}
}

static struct clock_event_device ckevt_pxa_osmr0 = {
	.name		= "osmr0",
	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
	.features	= CLOCK_EVT_FEAT_ONESHOT,
	.shift		= 32,
	.rating		= 200,
	.cpumask	= CPU_MASK_CPU0,