From 7961f20c09af4524266a808fed3695c4dcc98e59 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sat, 16 Jun 2007 07:17:42 +1000 Subject: [POWERPC] PS3: Rename IPI symbols Rename the PS3 static symbol virqs to ps3_ipi_virqs to aid in debugging. Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/ps3/smp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/powerpc/platforms/ps3/smp.c') diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index 53416ec5198..2134ef1360a 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c @@ -39,11 +39,11 @@ static irqreturn_t ipi_function_handler(int irq, void *msg) } /** - * virqs - a per cpu array of virqs for ipi use + * ps3_ipi_virqs - a per cpu array of virqs for ipi use */ #define MSG_COUNT 4 -static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]); +static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]); static const char *names[MSG_COUNT] = { "ipi call", @@ -62,7 +62,7 @@ static void do_message_pass(int target, int msg) return; } - virq = per_cpu(virqs, target)[msg]; + virq = per_cpu(ps3_ipi_virqs, target)[msg]; result = ps3_send_event_locally(virq); if (result) @@ -94,13 +94,13 @@ static int ps3_smp_probe(void) static void __init ps3_smp_setup_cpu(int cpu) { int result; - unsigned int *virqs = per_cpu(virqs, cpu); + unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu); int i; DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); /* - * Check assumptions on virqs[] indexing. If this + * Check assumptions on ps3_ipi_virqs[] indexing. If this * check fails, then a different mapping of PPC_MSG_ * to index needs to be setup. */ @@ -132,7 +132,7 @@ static void __init ps3_smp_setup_cpu(int cpu) void ps3_smp_cleanup_cpu(int cpu) { - unsigned int *virqs = per_cpu(virqs, cpu); + unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu); int i; DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); -- cgit v1.2.3-70-g09d2 From 83bb643d0714b0006ab99dbd195ec51b55a97f4e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 16 Jun 2007 07:19:23 +1000 Subject: [POWERPC] PS3: Simplify definition of DBG Simplify the PS3 definition of DBG. Signed-off-by: Geert Uytterhoeven Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/ps3/htab.c | 4 ++-- arch/powerpc/platforms/ps3/interrupt.c | 4 ++-- arch/powerpc/platforms/ps3/mm.c | 4 ++-- arch/powerpc/platforms/ps3/setup.c | 4 ++-- arch/powerpc/platforms/ps3/smp.c | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/powerpc/platforms/ps3/smp.c') diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index 0f4eb1251d7..d741edd96a2 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c @@ -29,9 +29,9 @@ #include "platform.h" #if defined(DEBUG) -#define DBG(fmt...) udbg_printf(fmt) +#define DBG udbg_printf #else -#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#define DBG pr_debug #endif static struct hash_pte *htab; diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index c9fd4ed66e8..2a0a422cea1 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -30,9 +30,9 @@ #include "platform.h" #if defined(DEBUG) -#define DBG(fmt...) udbg_printf(fmt) +#define DBG udbg_printf #else -#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#define DBG pr_debug #endif /** diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index f8a3e206c58..39c200b3498 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -30,9 +30,9 @@ #include "platform.h" #if defined(DEBUG) -#define DBG(fmt...) udbg_printf(fmt) +#define DBG udbg_printf #else -#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#define DBG pr_debug #endif enum { diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index b79d62b68df..8854af184dd 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -37,9 +37,9 @@ #include "platform.h" #if defined(DEBUG) -#define DBG(fmt...) udbg_printf(fmt) +#define DBG udbg_printf #else -#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#define DBG pr_debug #endif #if !defined(CONFIG_SMP) diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index 2134ef1360a..d8437138203 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c @@ -27,9 +27,9 @@ #include "platform.h" #if defined(DEBUG) -#define DBG(fmt...) udbg_printf(fmt) +#define DBG udbg_printf #else -#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#define DBG pr_debug #endif static irqreturn_t ipi_function_handler(int irq, void *msg) -- cgit v1.2.3-70-g09d2 From 9263e85aa9e9d341ef238fffc040f586674d1709 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sat, 16 Jun 2007 07:19:32 +1000 Subject: [POWERPC] PS3: Kexec support Fixup the core platform parts needed for kexec to work on the PS3. - Setup ps3_hpte_clear correctly. - Mask interrupts on irq removal. - Release all hypervisor resources. - Create new routine ps3_shutdown_IRQ() Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/ps3/htab.c | 13 +++++-- arch/powerpc/platforms/ps3/interrupt.c | 68 ++++++++++++++++++++++++++-------- arch/powerpc/platforms/ps3/platform.h | 1 + arch/powerpc/platforms/ps3/setup.c | 29 +++------------ arch/powerpc/platforms/ps3/smp.c | 2 +- 5 files changed, 70 insertions(+), 43 deletions(-) (limited to 'arch/powerpc/platforms/ps3/smp.c') diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index d741edd96a2..5d2e176a1b1 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c @@ -234,10 +234,17 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va, static void ps3_hpte_clear(void) { - /* Make sure to clean up the frame buffer device first */ - ps3fb_cleanup(); + int result; - lv1_unmap_htab(htab_addr); + DBG(" -> %s:%d\n", __func__, __LINE__); + + result = lv1_unmap_htab(htab_addr); + BUG_ON(result); + + ps3_mm_shutdown(); + ps3_mm_vas_destroy(); + + DBG(" <- %s:%d\n", __func__, __LINE__); } void __init ps3_hpte_init(unsigned long htab_size) diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 2a0a422cea1..462eacc55c9 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -220,6 +220,8 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, goto fail_set; } + ps3_chip_mask(*virq); + return result; fail_set: @@ -311,6 +313,8 @@ int ps3_irq_plug_destroy(unsigned int virq) pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, pd->node, pd->cpu, virq); + ps3_chip_mask(virq); + result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); if (result) @@ -368,7 +372,9 @@ int ps3_event_receive_port_destroy(unsigned int virq) { int result; - pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); + pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq); + + ps3_chip_mask(virq); result = lv1_destruct_event_receive_port(virq_to_hw(virq)); @@ -376,17 +382,14 @@ int ps3_event_receive_port_destroy(unsigned int virq) pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", __func__, __LINE__, ps3_result(result)); - /* lv1_destruct_event_receive_port() destroys the IRQ plug, - * so don't call ps3_irq_plug_destroy() here. + /* + * Don't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu() + * calls from interrupt context (smp_call_function) when kexecing. */ - result = ps3_virq_destroy(virq); - BUG_ON(result); - pr_debug(" <- %s:%d\n", __func__, __LINE__); return result; } -EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy); int ps3_send_event_locally(unsigned int virq) { @@ -458,6 +461,14 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, result = ps3_event_receive_port_destroy(virq); BUG_ON(result); + /* + * ps3_event_receive_port_destroy() destroys the IRQ plug, + * so don't call ps3_irq_plug_destroy() here. + */ + + result = ps3_virq_destroy(virq); + BUG_ON(result); + pr_debug(" <- %s:%d\n", __func__, __LINE__); return result; } @@ -498,16 +509,24 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup); int ps3_io_irq_destroy(unsigned int virq) { int result; + unsigned long outlet = virq_to_hw(virq); - result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); + ps3_chip_mask(virq); - if (result) - pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", - __func__, __LINE__, ps3_result(result)); + /* + * lv1_destruct_io_irq_outlet() will destroy the IRQ plug, + * so call ps3_irq_plug_destroy() first. + */ result = ps3_irq_plug_destroy(virq); BUG_ON(result); + result = lv1_destruct_io_irq_outlet(outlet); + + if (result) + pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", + __func__, __LINE__, ps3_result(result)); + return result; } EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); @@ -552,6 +571,7 @@ int ps3_vuart_irq_destroy(unsigned int virq) { int result; + ps3_chip_mask(virq); result = lv1_deconfigure_virtual_uart_irq(); if (result) { @@ -600,9 +620,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, int ps3_spe_irq_destroy(unsigned int virq) { - int result = ps3_irq_plug_destroy(virq); + int result; + + ps3_chip_mask(virq); + + result = ps3_irq_plug_destroy(virq); BUG_ON(result); - return 0; + + return result; } @@ -662,7 +687,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq, pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq, virq); - set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); + set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq); return 0; } @@ -682,7 +707,7 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) cpu, virq, pd->bmp.ipi_debug_brk_mask); } -unsigned int ps3_get_irq(void) +static unsigned int ps3_get_irq(void) { struct ps3_private *pd = &__get_cpu_var(ps3_private); u64 x = (pd->bmp.status & pd->bmp.mask); @@ -747,3 +772,16 @@ void __init ps3_init_IRQ(void) ppc_md.get_irq = ps3_get_irq; } + +void ps3_shutdown_IRQ(int cpu) +{ + int result; + u64 ppe_id; + u64 thread_id = get_hard_smp_processor_id(cpu); + + lv1_get_logical_ppe_id(&ppe_id); + result = lv1_configure_irq_state_bitmap(ppe_id, thread_id, 0); + + DBG("%s:%d: lv1_configure_irq_state_bitmap (%lu:%lu/%d) %s\n", __func__, + __LINE__, ppe_id, thread_id, cpu, ps3_result(result)); +} diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index ca04f03305c..0b93665829d 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h @@ -41,6 +41,7 @@ void ps3_mm_shutdown(void); /* irq */ void ps3_init_IRQ(void); +void ps3_shutdown_IRQ(int cpu); void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); /* smp */ diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 8854af184dd..96ad4263bd2 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -209,31 +209,12 @@ static int __init ps3_probe(void) #if defined(CONFIG_KEXEC) static void ps3_kexec_cpu_down(int crash_shutdown, int secondary) { - DBG(" -> %s:%d\n", __func__, __LINE__); - - if (secondary) { - int cpu; - for_each_online_cpu(cpu) - if (cpu) - ps3_smp_cleanup_cpu(cpu); - } else - ps3_smp_cleanup_cpu(0); - - DBG(" <- %s:%d\n", __func__, __LINE__); -} - -static void ps3_machine_kexec(struct kimage *image) -{ - unsigned long ppe_id; - - DBG(" -> %s:%d\n", __func__, __LINE__); + int cpu = smp_processor_id(); - lv1_get_logical_ppe_id(&ppe_id); - lv1_configure_irq_state_bitmap(ppe_id, 0, 0); - ps3_mm_shutdown(); - ps3_mm_vas_destroy(); + DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); - default_machine_kexec(image); + ps3_smp_cleanup_cpu(cpu); + ps3_shutdown_IRQ(cpu); DBG(" <- %s:%d\n", __func__, __LINE__); } @@ -255,7 +236,7 @@ define_machine(ps3) { .power_off = ps3_power_off, #if defined(CONFIG_KEXEC) .kexec_cpu_down = ps3_kexec_cpu_down, - .machine_kexec = ps3_machine_kexec, + .machine_kexec = default_machine_kexec, .machine_kexec_prepare = default_machine_kexec_prepare, .machine_crash_shutdown = default_machine_crash_shutdown, #endif diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index d8437138203..f0b12f21236 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c @@ -138,7 +138,7 @@ void ps3_smp_cleanup_cpu(int cpu) DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); for (i = 0; i < MSG_COUNT; i++) { - free_irq(virqs[i], (void*)(long)i); + /* Can't call free_irq from interrupt context. */ ps3_event_receive_port_destroy(virqs[i]); virqs[i] = NO_IRQ; } -- cgit v1.2.3-70-g09d2