From b7f90a406ff72d6698b619210c205e3375dd099a Mon Sep 17 00:00:00 2001 From: Masato Noguchi Date: Fri, 7 Sep 2007 18:28:27 +1000 Subject: [POWERPC] cell/PS3: Fix a bug that causes the PS3 to hang on the SPU Class 0 interrupt. The Cell BE Architecture spec states that the SPU MFC Class 0 interrupt is edge-triggered. The current spu interrupt handler assumes this behavior and does not clear the interrupt status. The PS3 hypervisor visualizes all SPU interrupts as level, and on return from the interrupt handler the hypervisor will deliver a new virtual interrupt for any unmasked interrupts which for which the status has not been cleared. This fix clears the interrupt status in the interrupt handler. Signed-off-by: Masato Noguchi Signed-off-by: Geoff Levand Signed-off-by: Jeremy Kerr Acked-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- include/asm-powerpc/spu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-powerpc') diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index 8836c0f1f2f..5bde3980bf4 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h @@ -130,6 +130,7 @@ struct spu { u64 flags; u64 dar; u64 dsisr; + u64 class_0_pending; size_t ls_size; unsigned int slb_replace; struct mm_struct *mm; @@ -138,7 +139,6 @@ struct spu { unsigned long long timestamp; pid_t pid; pid_t tgid; - int class_0_pending; spinlock_t register_lock; void (* wbox_callback)(struct spu *spu); -- cgit v1.2.3-70-g09d2 From c27da339698145a9383e052c1070a950d30da478 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 19 Sep 2007 14:21:56 +1000 Subject: [POWERPC] Fix timekeeping on PowerPC 601 Recent changes to the timekeeping code broke support for the PowerPC 601 processor which doesn't have the usual timebase facility but a slightly different thing called (yuck) the RTC. This fixes it, boot tested on an old 601 based PowerMac 7200. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 8 +++++--- include/asm-powerpc/time.h | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'include/asm-powerpc') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 727a6699f2f..c627cf86d1e 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -239,7 +239,7 @@ static void snapshot_tb_and_purr(void *data) struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data); local_irq_save(flags); - p->tb = mftb(); + p->tb = get_tb_or_rtc(); p->purr = mfspr(SPRN_PURR); wmb(); p->initialized = 1; @@ -317,7 +317,7 @@ static void snapshot_purr(void) */ void snapshot_timebase(void) { - __get_cpu_var(last_jiffy) = get_tb(); + __get_cpu_var(last_jiffy) = get_tb_or_rtc(); snapshot_purr(); } @@ -684,6 +684,8 @@ void timer_interrupt(struct pt_regs * regs) write_seqlock(&xtime_lock); tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy; + if (__USE_RTC() && tb_next_jiffy >= 1000000000) + tb_next_jiffy -= 1000000000; if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) { tb_last_jiffy = tb_next_jiffy; do_timer(1); @@ -977,7 +979,7 @@ void __init time_init(void) tb_to_ns_scale = scale; tb_to_ns_shift = shift; /* Save the current timebase to pretty up CONFIG_PRINTK_TIME */ - boot_tb = get_tb(); + boot_tb = get_tb_or_rtc(); tm = get_boot_time(); diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h index d7f5ddfbaac..c104c15c662 100644 --- a/include/asm-powerpc/time.h +++ b/include/asm-powerpc/time.h @@ -149,6 +149,11 @@ static inline u64 get_tb(void) } #endif /* !CONFIG_PPC64 */ +static inline u64 get_tb_or_rtc(void) +{ + return __USE_RTC() ? get_rtc() : get_tb(); +} + static inline void set_tb(unsigned int upper, unsigned int lower) { mtspr(SPRN_TBWL, 0); -- cgit v1.2.3-70-g09d2