summaryrefslogtreecommitdiff
path: root/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf')
-rw-r--r--meta/recipes-kernel/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf94
1 files changed, 0 insertions, 94 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf b/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf
deleted file mode 100644
index 3de6e0504..000000000
--- a/meta/recipes-kernel/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf
+++ /dev/null
@@ -1,94 +0,0 @@
-OMAP2/3 system tick GPTIMER: use overflow interrupts to detect missing match interrupts
-
-From: Paul Walmsley <paul@pwsan.com>
-
-GPTIMER1 on some OMAP3 chips occasionally misses match conditions
-between the timer counter and the target register value, and does not
-interrupt to the MPU. This patch adds another line of defense by
-setting the timer to generate an overflow interrupt 0.5 seconds after the
-timer passes the original comparison value.
-
-If interrupts are masked for a long period of time, one would expect
-both a match and an overflow interrupt to be logged. This is considered
-a normal condition. However, if only an overflow interrupt is logged,
-this is considered evidence of a hardware bug and the kernel will issue
-a warning.
-
-This workaround is unlikely to be 100% effective, since GPTIMER1 has
-also been observed to lose overflow interrupts occasionally. It is
-hoped that the probability of losing both will be significantly lower
-than the probability of losing either one.
----
-
- arch/arm/mach-omap2/timer-gp.c | 36 ++++++++++++++++++++++++++++++++----
- 1 files changed, 32 insertions(+), 4 deletions(-)
-
-diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
-index 51996ba..ce5c2b4 100644
---- a/arch/arm/mach-omap2/timer-gp.c
-+++ b/arch/arm/mach-omap2/timer-gp.c
-@@ -36,17 +36,43 @@
- #include <asm/mach/time.h>
- #include <asm/arch/dmtimer.h>
-
--#define GPTIMER_MATCH_VAL 0xffff0000
-+/*
-+ * The number of timer ticks to delay will be subtracted from
-+ * GPTIMER_MATCH_VAL before loading into the timer. So GPTIMER_MATCH_VAL
-+ * constrains the longest delay that can be generated with the timer.
-+ * Since the current code uses overflow interrupts as protection against
-+ * missed comparison interrupts, this value should also be sufficiently
-+ * large such that there is not an excessively long delay between ticks
-+ * if the comparison interrupt fails to arrive. The 0xfffff800 value
-+ * below results in a half-second delay in such a case when using
-+ * the 32kHz timer as source.
-+ */
-+#define GPTIMER_MATCH_VAL (0xffffffff - (32768/2))
-
- static struct omap_dm_timer *gptimer;
- static struct clock_event_device clockevent_gpt;
-
-+static u32 last_load;
-+
- static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
- {
- struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id;
- struct clock_event_device *evt = &clockevent_gpt;
--
-- omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH);
-+ u32 v;
-+
-+ v = omap_dm_timer_read_status(gpt);
-+ if ((v & OMAP_TIMER_INT_OVERFLOW) && !(v & OMAP_TIMER_INT_MATCH)) {
-+ /*
-+ * Should never happen. Current belief is that this is
-+ * due to a hardware bug in the GPTIMER block on some
-+ * OMAP3 revisions.
-+ */
-+ pr_err("*** GPTIMER missed match interrupt! last load: %08x\n",
-+ last_load);
-+ WARN_ON(1);
-+ }
-+
-+ omap_dm_timer_write_status(gpt, v);
-
- evt->event_handler(evt);
- return IRQ_HANDLED;
-@@ -61,6 +87,7 @@ static struct irqaction omap2_gp_timer_irq = {
- static int omap2_gp_timer_set_next_event(unsigned long cycles,
- struct clock_event_device *evt)
- {
-+ last_load = GPTIMER_MATCH_VAL - cycles;
- omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles);
-
- return 0;
-@@ -99,7 +126,8 @@ static void __init omap2_gp_clockevent_init(void)
- omap_dm_timer_stop(gptimer);
- /* omap_dm_timer_set_load(gptimer, 0, 0);*/
- omap_dm_timer_set_match(gptimer, 1, GPTIMER_MATCH_VAL);
-- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH);
-+ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH |
-+ OMAP_TIMER_INT_OVERFLOW);
-
- clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
- clockevent_gpt.shift);