[oe-commits] org.oe.dev linux omap2 git: update serial hang patches for beagleboard
koen commit
oe at amethyst.openembedded.net
Mon Sep 1 17:45:54 UTC 2008
linux omap2 git: update serial hang patches for beagleboard
Author: koen at openembedded.org
Branch: org.openembedded.dev
Revision: 7be05a03996e1d9091ababb078b62638219b354f
ViewMTN: http://monotone.openembedded.org/revision/info/7be05a03996e1d9091ababb078b62638219b354f
Files:
1
packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff
packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr
packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr
packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug
packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init
packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick
packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf
packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q
packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch
packages/linux/linux-omap2_git.bb
Diffs:
#
# mt diff -r89505bb1c87fc351630659146cb6d39e531382bb -r7be05a03996e1d9091ababb078b62638219b354f
#
#
#
# delete "packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff"
#
# delete "packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr"
#
# delete "packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr"
#
# delete "packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug"
#
# add_file "packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init"
# content [7538fc0fde9dc51b0f7705a2c30ee1bc38301b19]
#
# add_file "packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick"
# content [d92f980465e1355fe21c3b707c734ccaa3986748]
#
# add_file "packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf"
# content [df0ce4c29eca91ab8258a4d8254614eff25b984c]
#
# add_file "packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q"
# content [0e75629e115c657b7ad59821bd56afb8cfb50725]
#
# add_file "packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch"
# content [0862bf2e52bd583da7567a0fa1e076d5f3f6240d]
#
# patch "packages/linux/linux-omap2_git.bb"
# from [df75156ba05c33c4903ee65406bd8aecc88a7c49]
# to [8152324919d576b2c9511c66c908fa44391f2123]
#
============================================================
--- packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init 7538fc0fde9dc51b0f7705a2c30ee1bc38301b19
+++ packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init 7538fc0fde9dc51b0f7705a2c30ee1bc38301b19
@@ -0,0 +1,25 @@
+clear
+
+From: Paul Walmsley <paul at pwsan.com>
+
+
+---
+
+ arch/arm/plat-omap/dmtimer.c | 4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
+index f22506a..e38a11e 100644
+--- a/arch/arm/plat-omap/dmtimer.c
++++ b/arch/arm/plat-omap/dmtimer.c
+@@ -703,6 +703,10 @@ int __init omap_dm_timer_init(void)
+ timer->fclk = clk_get(NULL, clk_name);
+ }
+ #endif
++ omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW |
++ OMAP_TIMER_INT_MATCH |
++ OMAP_TIMER_INT_CAPTURE);
++
+ }
+
+ return 0;
============================================================
--- packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick d92f980465e1355fe21c3b707c734ccaa3986748
+++ packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick d92f980465e1355fe21c3b707c734ccaa3986748
@@ -0,0 +1,97 @@
+OMAP2/3 system tick GPTIMER: use match interrupts rather than overflow interrupts
+
+From: Paul Walmsley <paul at pwsan.com>
+
+On some OMAP3 chips, GPTIMER1 will occasionally decline to interrupt
+the MPU when a timer overflow event occurs. The timer stops running;
+and TOCR is sometimes incremented; but the MPU apparently never receives
+the interrupt. This patch was an experiment in using the GPTIMER
+match interrupt to determine if it resolves the problem.
+Unfortunately, it does not; the same problem occurs with match
+interrupts; but this patch is preserved as the base for a
+match+overflow interrupt workaround used in a following patch.
+---
+
+ arch/arm/mach-omap2/timer-gp.c | 32 ++++++++++----------------------
+ 1 files changed, 10 insertions(+), 22 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
+index 557603f..51996ba 100644
+--- a/arch/arm/mach-omap2/timer-gp.c
++++ b/arch/arm/mach-omap2/timer-gp.c
+@@ -36,6 +36,8 @@
+ #include <asm/mach/time.h>
+ #include <asm/arch/dmtimer.h>
+
++#define GPTIMER_MATCH_VAL 0xffff0000
++
+ static struct omap_dm_timer *gptimer;
+ static struct clock_event_device clockevent_gpt;
+
+@@ -44,7 +46,7 @@ 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_OVERFLOW);
++ omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH);
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+@@ -59,7 +61,7 @@ static struct irqaction omap2_gp_timer_irq = {
+ static int omap2_gp_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+ {
+- omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles);
++ omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles);
+
+ return 0;
+ }
+@@ -67,29 +69,12 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
+ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+ {
+- u32 period;
+-
+ omap_dm_timer_stop(gptimer);
+-
+- switch (mode) {
+- case CLOCK_EVT_MODE_PERIODIC:
+- period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
+- period -= 1;
+-
+- omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
+- break;
+- case CLOCK_EVT_MODE_ONESHOT:
+- break;
+- case CLOCK_EVT_MODE_UNUSED:
+- case CLOCK_EVT_MODE_SHUTDOWN:
+- case CLOCK_EVT_MODE_RESUME:
+- break;
+- }
+ }
+
+ static struct clock_event_device clockevent_gpt = {
+ .name = "gp timer",
+- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = omap2_gp_timer_set_next_event,
+ .set_mode = omap2_gp_timer_set_mode,
+@@ -111,12 +96,15 @@ static void __init omap2_gp_clockevent_init(void)
+
+ omap2_gp_timer_irq.dev_id = (void *)gptimer;
+ setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
+- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
++ 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);
+
+ clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
+ clockevent_gpt.shift);
+ clockevent_gpt.max_delta_ns =
+- clockevent_delta2ns(0xffffffff, &clockevent_gpt);
++ clockevent_delta2ns(GPTIMER_MATCH_VAL, &clockevent_gpt);
+ clockevent_gpt.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_gpt);
+
============================================================
--- packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf df0ce4c29eca91ab8258a4d8254614eff25b984c
+++ packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf df0ce4c29eca91ab8258a4d8254614eff25b984c
@@ -0,0 +1,94 @@
+OMAP2/3 system tick GPTIMER: use overflow interrupts to detect missing match interrupts
+
+From: Paul Walmsley <paul at 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);
============================================================
--- packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q 0e75629e115c657b7ad59821bd56afb8cfb50725
+++ packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q 0e75629e115c657b7ad59821bd56afb8cfb50725
@@ -0,0 +1,110 @@
+Add extra debug for the q_d_w_o() when work fn is already active.
+
+From: Paul Walmsley <paul at pwsan.com>
+
+
+---
+
+ arch/arm/mach-omap2/timer-gp.c | 3 ++-
+ arch/arm/plat-omap/dmtimer.c | 20 ++++++++++++++++++++
+ include/asm-arm/arch-omap/dmtimer.h | 1 +
+ kernel/time/timer_list.c | 8 ++++++++
+ 4 files changed, 31 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
+index ce5c2b4..e3ed368 100644
+--- a/arch/arm/mach-omap2/timer-gp.c
++++ b/arch/arm/mach-omap2/timer-gp.c
+@@ -50,6 +50,7 @@
+ #define GPTIMER_MATCH_VAL (0xffffffff - (32768/2))
+
+ static struct omap_dm_timer *gptimer;
++struct omap_dm_timer *gptimer_pub;
+ static struct clock_event_device clockevent_gpt;
+
+ static u32 last_load;
+@@ -111,7 +112,7 @@ static void __init omap2_gp_clockevent_init(void)
+ {
+ u32 tick_rate;
+
+- gptimer = omap_dm_timer_request_specific(1);
++ gptimer = gptimer_pub = omap_dm_timer_request_specific(1);
+ BUG_ON(gptimer == NULL);
+
+ #if defined(CONFIG_OMAP_32K_TIMER)
+diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
+index e38a11e..b10f8ac 100644
+--- a/arch/arm/plat-omap/dmtimer.c
++++ b/arch/arm/plat-omap/dmtimer.c
+@@ -614,6 +614,26 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
+ }
+
++void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer)
++{
++ u32 l;
++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
++ pr_err("GPT TCRR: %08x\n", l);
++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG);
++ pr_err("GPT TMAT: %08x\n", l);
++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
++ pr_err("GPT TISR: %08x\n", l);
++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_INT_EN_REG);
++ pr_err("GPT TIER: %08x\n", l);
++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
++ pr_err("GPT TCLR: %08x\n", l);
++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG);
++ pr_err("GPT TOCR: %08x\n", l);
++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_COUNT_REG);
++ pr_err("GPT TOWR: %08x\n", l);
++}
++
++
+ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+ {
+ unsigned int l;
+diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
+index 02b29e8..a8123e9 100644
+--- a/include/asm-arm/arch-omap/dmtimer.h
++++ b/include/asm-arm/arch-omap/dmtimer.h
+@@ -73,6 +73,7 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
+
+ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
+
++void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer);
+ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
+ void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
+ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
+diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
+index a40e20f..452eab7 100644
+--- a/kernel/time/timer_list.c
++++ b/kernel/time/timer_list.c
+@@ -18,6 +18,8 @@
+ #include <linux/kallsyms.h>
+ #include <linux/tick.h>
+
++#include <asm/arch/dmtimer.h>
++
+ #include <asm/uaccess.h>
+
+ typedef void (*print_fn_t)(struct seq_file *m, unsigned int *classes);
+@@ -239,6 +241,8 @@ static void timer_list_show_tickdevices(struct seq_file *m)
+ static void timer_list_show_tickdevices(struct seq_file *m) { }
+ #endif
+
++extern struct omap_dm_timer *gptimer_pub;
++
+ static int timer_list_show(struct seq_file *m, void *v)
+ {
+ u64 now = ktime_to_ns(ktime_get());
+@@ -254,6 +258,10 @@ static int timer_list_show(struct seq_file *m, void *v)
+ SEQ_printf(m, "\n");
+ timer_list_show_tickdevices(m);
+
++ SEQ_printf(m, "\n");
++
++ omap_dm_timer_dump_int_enable(gptimer_pub);
++
+ return 0;
+ }
+
============================================================
--- packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch 0862bf2e52bd583da7567a0fa1e076d5f3f6240d
+++ packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch 0862bf2e52bd583da7567a0fa1e076d5f3f6240d
@@ -0,0 +1,23 @@
+OMAP2/3 TAP: enable debug messages
+
+From: Paul Walmsley <paul at pwsan.com>
+
+This patch causes the OMAP2/3 chip ID code to display the full DIE_ID registers at boot.
+
+---
+
+ arch/arm/mach-omap2/id.c | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
+index c7f9ab7..a154b5e 100644
+--- a/arch/arm/mach-omap2/id.c
++++ b/arch/arm/mach-omap2/id.c
+@@ -10,6 +10,7 @@
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
++#define DEBUG
+
+ #include <linux/module.h>
+ #include <linux/kernel.h>
============================================================
--- packages/linux/linux-omap2_git.bb df75156ba05c33c4903ee65406bd8aecc88a7c49
+++ packages/linux/linux-omap2_git.bb 8152324919d576b2c9511c66c908fa44391f2123
@@ -6,7 +6,7 @@ PV = "2.6.26"
PV = "2.6.26"
#PV = "2.6.26+2.6.27-rc1+${PR}+git${SRCREV}"
-PR = "r52"
+PR = "r53"
SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \
file://defconfig"
@@ -45,10 +45,11 @@ SRC_URI_append_beagleboard = " file://no
file://4bitmmc.diff;patch=1 \
file://400khz-i2c.diff;patch=1 \
file://no-cortex-deadlock.patch;patch=1 \
- file://01-gptimer_maintain_tldr_lt_0xffffffff;patch=1 \
- file://02-gptimer_clear_tocr;patch=1 \
- file://03-gptimer_double_write_tocr;patch=1 \
- file://04-gptimer_add_debug;patch=1 \
+ file://01-gptimer_clear_isrs_on_init;patch=1 \
+ file://02-gptimer_use_match_for_tick;patch=1 \
+ file://03-gptimer_match_plus_ovf;patch=1 \
+ file://04-gptimer_add_debug_to_sysrq_q;patch=1 \
+ file://read_die_ids.pat%s
>>> DIFF TRUNCATED @ 16K
More information about the Openembedded-commits
mailing list