From 24167e4577d7a883aa764d846cb2bb467b1f271b Mon Sep 17 00:00:00 2001 From: Koen Kooi Date: Thu, 31 Jul 2008 15:19:47 +0000 Subject: linux omap2 git: add v2 of serial hang patches --- .../01-gptimer_maintain_tldr_lt_0xffffffff | 6 +- .../beagleboard/02-gptimer_clear_tocr | 35 +++---- .../beagleboard/03-gptimer_double_write_tocr | 25 +++++ .../beagleboard/04-gptimer_add_debug | 105 +++++++++++++++++++++ packages/linux/linux-omap2_git.bb | 4 +- 5 files changed, 155 insertions(+), 20 deletions(-) create mode 100644 packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr create mode 100644 packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug (limited to 'packages/linux') diff --git a/packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff b/packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff index ed62a6fb4b..f80f899dee 100644 --- a/packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff +++ b/packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff @@ -1,8 +1,10 @@ -3430 TRM 16.2.4.2 states: +OMAP2/3 GPTIMER: don't load GPTIMER with 0xffffffff From: Paul Walmsley -Do not put the overflow value (0xFFFFFFFF) in the GPTi.TLDR register +3430 TRM 16.2.4.2 states: + + Do not put the overflow value (0xFFFFFFFF) in the GPTi.TLDR register because it can lead to undesired results. 3430 TRM 16.2.4.7 states: diff --git a/packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr index b92c5dd126..433608132e 100644 --- a/packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr +++ b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr @@ -23,19 +23,19 @@ OMAP3530ES2.2 lots. This patch fixes the "serial hangs" reported by some BeagleBoard users. During these hangs, characters are still received from the serial port, so magic SysRq will still work; but characters are never -delivered on to the underlying line discipline. This since -tty_flip_buffer_push() uses schedule_delayed_work() to defer passing -the input buffer to the line discipline, but the delayed work function -is never called since no timer tick ever arrives. +delivered on to the underlying line discipline. The 8250 serial code +calls tty_flip_buffer_push(), which calls schedule_delayed_work() to +defer passing the input buffer to the line discipline, but since no +timer tick ever arrives, the delayed work function is never called . The patch should also fix some other sporadic boot hangs reported by BeagleBoard users that are due to timer interrupt non-delivery. --- arch/arm/mach-omap2/timer-gp.c | 1 + - arch/arm/plat-omap/dmtimer.c | 8 ++++++++ + arch/arm/plat-omap/dmtimer.c | 9 ++++++++- include/asm-arm/arch-omap/dmtimer.h | 2 ++ - 3 files changed, 11 insertions(+), 0 deletions(-) + 3 files changed, 11 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index edc0c9e..869fe14 100644 @@ -50,14 +50,14 @@ index edc0c9e..869fe14 100644 evt->event_handler(evt); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c -index f22506a..2cbb4cc 100644 +index f22506a..18a1e68 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -543,6 +543,8 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))) cpu_relax(); -+ omap_dm_timer_write_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG, 0); ++ omap_dm_timer_clear_ovf_cnt(timer); + omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); } @@ -66,22 +66,23 @@ index f22506a..2cbb4cc 100644 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load); omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); -+ omap_dm_timer_write_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG, 0); ++ omap_dm_timer_clear_ovf_cnt(timer); omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); } -@@ -614,6 +617,11 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, - omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value); - } - +@@ -611,7 +614,11 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, + unsigned int value) + { + omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); +- omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value); ++} ++ +void omap_dm_timer_clear_ovf_cnt(struct omap_dm_timer *timer) +{ + omap_dm_timer_write_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG, 0); -+} -+ + } + 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..7b1138b 100644 --- a/include/asm-arm/arch-omap/dmtimer.h diff --git a/packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr b/packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr new file mode 100644 index 0000000000..4b3d757bdc --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr @@ -0,0 +1,25 @@ +OMAP3 GPTIMER: TOCR clears sometimes require two writes + +From: Paul Walmsley + +Some GPTIMER register changes do not take effect with a single write; +they require two writes for some reason. Could be related to the +existing 3430 errata "GPTimer 1,2, and 10: first write access to TCRR +register discarded" +--- + + arch/arm/plat-omap/dmtimer.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c +index 18a1e68..4a5ada7 100644 +--- a/arch/arm/plat-omap/dmtimer.c ++++ b/arch/arm/plat-omap/dmtimer.c +@@ -619,6 +619,7 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, + void omap_dm_timer_clear_ovf_cnt(struct omap_dm_timer *timer) + { + omap_dm_timer_write_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG, 0); ++ omap_dm_timer_write_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG, 0); + } + + unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) diff --git a/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug b/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug new file mode 100644 index 0000000000..8ae6a6f22e --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug @@ -0,0 +1,105 @@ +Add extra debug for the q_d_w_o() when work fn is already active. + +From: Paul Walmsley + + +--- + + arch/arm/mach-omap2/timer-gp.c | 3 ++- + arch/arm/plat-omap/dmtimer.c | 18 ++++++++++++++++++ + include/asm-arm/arch-omap/dmtimer.h | 1 + + kernel/workqueue.c | 12 ++++++++++++ + 4 files changed, 33 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c +index 869fe14..4db3252 100644 +--- a/arch/arm/mach-omap2/timer-gp.c ++++ b/arch/arm/mach-omap2/timer-gp.c +@@ -37,6 +37,7 @@ + #include + + static struct omap_dm_timer *gptimer; ++struct omap_dm_timer *gptimer_pub; + static struct clock_event_device clockevent_gpt; + + static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) +@@ -114,7 +115,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 4a5ada7..3242495 100644 +--- a/arch/arm/plat-omap/dmtimer.c ++++ b/arch/arm/plat-omap/dmtimer.c +@@ -622,6 +622,24 @@ void omap_dm_timer_clear_ovf_cnt(struct omap_dm_timer *timer) + omap_dm_timer_write_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG, 0); + } + ++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_STAT_REG); ++ pr_err("GPT TISR: %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); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_POS_REG); ++ pr_err("GPT TPIR: %08x\n", l); ++ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_NEG_REG); ++ pr_err("GPT TNIR: %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 7b1138b..db57015 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); + void omap_dm_timer_clear_ovf_cnt(struct omap_dm_timer *timer); + + unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer); +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index ce77995..65b3b9a 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -33,6 +33,9 @@ + #include + #include + #include ++#include ++ ++extern struct omap_dm_timer *gptimer_pub; + + /* + * The per-CPU workqueue (if single thread, we always use the first +@@ -235,6 +238,15 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, + else + add_timer(timer); + ret = 1; ++ } else { ++ s64 texp; ++ u64 now = ktime_to_ns(ktime_get()); ++ u64 ens = jiffies_to_usecs(dwork->timer.expires) * 1000; ++ texp = ens - now; ++ if (texp < 0) { ++ pr_err("** Timer workaround\n"); ++ omap_dm_timer_dump_int_enable(gptimer_pub); ++ } + } + return ret; + } diff --git a/packages/linux/linux-omap2_git.bb b/packages/linux/linux-omap2_git.bb index c744cb1d6d..22643987b4 100644 --- a/packages/linux/linux-omap2_git.bb +++ b/packages/linux/linux-omap2_git.bb @@ -6,7 +6,7 @@ SRCREV = "d3b3ae0fe6c71641da19c8de466ec366d39847e3" PV = "2.6.26" #PV = "2.6.26+2.6.27-rc1+${PR}+git${SRCREV}" -PR = "r51" +PR = "r52" SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \ file://defconfig" @@ -47,6 +47,8 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.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 \ " SRC_URI_append_omap3evm = " file://no-harry-potter.diff;patch=1 \ -- cgit v1.2.3