diff options
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init | 25 | ||||
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff | 64 | ||||
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr | 98 | ||||
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick | 97 | ||||
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr | 25 | ||||
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf | 94 | ||||
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q (renamed from packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug) | 89 | ||||
-rw-r--r-- | packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch | 23 | ||||
-rw-r--r-- | packages/linux/linux-omap2_git.bb | 11 |
9 files changed, 292 insertions, 234 deletions
diff --git a/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init b/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init new file mode 100644 index 0000000000..5123bafe54 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init @@ -0,0 +1,25 @@ +clear + +From: Paul Walmsley <paul@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; 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 deleted file mode 100644 index f80f899dee..0000000000 --- a/packages/linux/linux-omap2-git/beagleboard/01-gptimer_maintain_tldr_lt_0xffffffff +++ /dev/null @@ -1,64 +0,0 @@ -OMAP2/3 GPTIMER: don't load GPTIMER with 0xffffffff - -From: Paul Walmsley <paul@pwsan.com> - -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: - - In the non-PWM mode, GTPi.TLDR must be maintained at less than or - equal to 0xFFFF FFFE. - -This patch contains some debugging code, and so is not yet intended for -merging into linux-omap. ---- - - arch/arm/mach-omap2/timer-gp.c | 17 ++++++++++++++++- - 1 files changed, 16 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c -index 557603f..edc0c9e 100644 ---- a/arch/arm/mach-omap2/timer-gp.c -+++ b/arch/arm/mach-omap2/timer-gp.c -@@ -59,6 +59,11 @@ static struct irqaction omap2_gp_timer_irq = { - static int omap2_gp_timer_set_next_event(unsigned long cycles, - struct clock_event_device *evt) - { -+ if (cycles == 0) { -+ pr_err("*** cycles = 0! fixing\n"); -+ cycles = 1; -+ } -+ - omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles); - - return 0; -@@ -76,6 +81,15 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, - period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; - period -= 1; - -+ /* -+ * Unlikely that this will ever be hit since periodic -+ * mode is rarely used -+ */ -+ if (period == 0) { -+ pr_err("*** period = 0! fixing\n"); -+ period = 1; -+ } -+ - omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period); - break; - case CLOCK_EVT_MODE_ONESHOT: -@@ -117,8 +131,9 @@ static void __init omap2_gp_clockevent_init(void) - clockevent_gpt.shift); - clockevent_gpt.max_delta_ns = - clockevent_delta2ns(0xffffffff, &clockevent_gpt); -+ /* per 3430 TRM table 16-11 */ - clockevent_gpt.min_delta_ns = -- clockevent_delta2ns(1, &clockevent_gpt); -+ clockevent_delta2ns(2, &clockevent_gpt); - - clockevent_gpt.cpumask = cpumask_of_cpu(0); - clockevents_register_device(&clockevent_gpt); diff --git a/packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr deleted file mode 100644 index 433608132e..0000000000 --- a/packages/linux/linux-omap2-git/beagleboard/02-gptimer_clear_tocr +++ /dev/null @@ -1,98 +0,0 @@ -OMAP2/3 GPTIMER: clear TOCR register after timer overflow interrupt and during load - -From: Paul Walmsley <paul@pwsan.com> - -There appears to be a hardware bug in the 1-ms tick generation section -of the GPTIMER blocks on some OMAP3530 chips. TOCR is sometimes -incremented when a a timer overflow event occurs and TPIR = TPNR = -TOWR = TOCR = 0, in contradiction of 34xx TRM 16.2.4.2.1. When TOCR -is incremented under these conditions, the timer will not generate any -further overflow interrupts. (The kernel currently relies on overflow -interrupts to generate ticks and drive the scheduler.) - -This patch works around the bug by clearing TOCR in the GPTIMER -overflow ISR and in the timer load functions. - -The precise sequence of hardware events needed to reproduce this bug -is still unknown. Without this patch, the bug is consistently -observable on several BeagleBoards (including mine and Koen's) within -a few minutes of boot. It's not clear whether this bug is present on -all OMAP3 revisions, or whether it is simply specific to certain -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. 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 | 9 ++++++++- - include/asm-arm/arch-omap/dmtimer.h | 2 ++ - 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 ---- a/arch/arm/mach-omap2/timer-gp.c -+++ b/arch/arm/mach-omap2/timer-gp.c -@@ -44,6 +44,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_clear_ovf_cnt(gpt); - omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW); - - evt->event_handler(evt); -diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c -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_clear_ovf_cnt(timer); -+ - omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); - } - -@@ -561,6 +563,7 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, - - 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_clear_ovf_cnt(timer); - omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); - } - -@@ -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) -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 -+++ b/include/asm-arm/arch-omap/dmtimer.h -@@ -73,6 +73,8 @@ 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_clear_ovf_cnt(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/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick new file mode 100644 index 0000000000..6eb6c9b477 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick @@ -0,0 +1,97 @@ +OMAP2/3 system tick GPTIMER: use match interrupts rather than overflow interrupts + +From: Paul Walmsley <paul@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); + 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 deleted file mode 100644 index 4b3d757bdc..0000000000 --- a/packages/linux/linux-omap2-git/beagleboard/03-gptimer_double_write_tocr +++ /dev/null @@ -1,25 +0,0 @@ -OMAP3 GPTIMER: TOCR clears sometimes require two writes - -From: Paul Walmsley <paul@pwsan.com> - -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/03-gptimer_match_plus_ovf b/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf new file mode 100644 index 0000000000..3de6e05042 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf @@ -0,0 +1,94 @@ +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); diff --git a/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug b/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q index 8ae6a6f22e..aa9f09811a 100644 --- a/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug +++ b/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q @@ -6,24 +6,24 @@ From: Paul Walmsley <paul@pwsan.com> --- arch/arm/mach-omap2/timer-gp.c | 3 ++- - arch/arm/plat-omap/dmtimer.c | 18 ++++++++++++++++++ + arch/arm/plat-omap/dmtimer.c | 20 ++++++++++++++++++++ include/asm-arm/arch-omap/dmtimer.h | 1 + - kernel/workqueue.c | 12 ++++++++++++ - 4 files changed, 33 insertions(+), 1 deletions(-) + 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 869fe14..4db3252 100644 +index ce5c2b4..e3ed368 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c -@@ -37,6 +37,7 @@ - #include <asm/arch/dmtimer.h> +@@ -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 irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) -@@ -114,7 +115,7 @@ static void __init omap2_gp_clockevent_init(void) + static u32 last_load; +@@ -111,7 +112,7 @@ static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; @@ -33,11 +33,11 @@ index 869fe14..4db3252 100644 #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 +index e38a11e..b10f8ac 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); +@@ -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) @@ -45,16 +45,18 @@ index 4a5ada7..3242495 100644 + 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); -+ 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); +} + + @@ -62,7 +64,7 @@ index 4a5ada7..3242495 100644 { 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 +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); @@ -70,36 +72,39 @@ index 7b1138b..db57015 100644 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 @@ + 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/debug_locks.h> - #include <linux/lockdep.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); - /* - * 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; ++ SEQ_printf(m, "\n"); ++ ++ omap_dm_timer_dump_int_enable(gptimer_pub); ++ + return 0; } + diff --git a/packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch b/packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch new file mode 100644 index 0000000000..3f6c930cc1 --- /dev/null +++ b/packages/linux/linux-omap2-git/beagleboard/read_die_ids.patch @@ -0,0 +1,23 @@ +OMAP2/3 TAP: enable debug messages + +From: Paul Walmsley <paul@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> diff --git a/packages/linux/linux-omap2_git.bb b/packages/linux/linux-omap2_git.bb index 22643987b4..61fb288135 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 = "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-harry-potter.diff;patch=1 \ 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.patch;patch=1 \ " SRC_URI_append_omap3evm = " file://no-harry-potter.diff;patch=1 \ |