From: Geoff Levand <geoffrey.levand@am•sony.com>
To: paulus@samba•org
Cc: linuxppc-dev@ozlabs•org
Subject: [patch 10/33] PS3: Kexec support
Date: Fri, 15 Jun 2007 14:19:32 -0700 [thread overview]
Message-ID: <46730264.2040208@am.sony.com> (raw)
In-Reply-To: <20070615204749.629571012@am.sony.com>>
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 <geoffrey.levand@am•sony.com>
---
o Fixed use of the ps3_kexec_cpu_down() 'secondary' arg.
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(-)
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -234,10 +234,17 @@ static void ps3_hpte_invalidate(unsigned
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)
--- 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
goto fail_set;
}
+ ps3_chip_mask(*virq);
+
return result;
fail_set:
@@ -311,6 +313,8 @@ int ps3_irq_plug_destroy(unsigned int vi
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(unsig
{
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(unsig
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(co
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 v
{
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_bindi
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
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(u
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));
+}
--- 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 */
--- 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__);
+ int cpu = smp_processor_id();
- 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: (%d)\n", __func__, __LINE__, cpu);
- DBG(" <- %s:%d\n", __func__, __LINE__);
-}
-
-static void ps3_machine_kexec(struct kimage *image)
-{
- unsigned long ppe_id;
-
- DBG(" -> %s:%d\n", __func__, __LINE__);
-
- lv1_get_logical_ppe_id(&ppe_id);
- lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
- ps3_mm_shutdown();
- ps3_mm_vas_destroy();
-
- 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
--- 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;
}
--
next prev parent reply other threads:[~2007-06-15 22:18 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20070615204749.629571012@am.sony.com>
2007-06-15 21:17 ` [patch 01/33] Cell: Add spu shutdown method Geoff Levand
2007-06-15 21:17 ` [patch 02/33] PS3: Rename IPI symbols Geoff Levand
2007-06-15 21:18 ` [patch 03/33] PS3: Use __maybe_unused Geoff Levand
2007-06-15 21:18 ` [patch 04/33] PS3: Compare firmware version Geoff Levand
2007-06-15 21:18 ` [patch 05/33] PS3: Use ioremap_flags Geoff Levand
2007-06-15 21:19 ` [patch 06/33] PS3: Fix sparse warnings Geoff Levand
2007-06-15 21:19 ` [patch 07/33] PS3: Add support for HDMI RGB Full Range mode Geoff Levand
2007-06-15 21:19 ` [patch 08/33] PS3: Move chip mask defs up Geoff Levand
2007-06-15 21:19 ` [patch 09/33] PS3: Simplify definition of DBG Geoff Levand
2007-06-15 21:19 ` Geoff Levand [this message]
2007-06-15 21:52 ` [patch 11/33] PS3: System-bus rework Geoff Levand
2007-06-15 21:55 ` [patch 12/33] PS3: System-bus uevent Geoff Levand
2007-06-15 21:55 ` [patch 13/33] PS3: System-bus modinfo attribute Geoff Levand
2007-06-15 21:55 ` [patch 14/33] PS3: Repository probe cleanups Geoff Levand
2007-06-15 22:01 ` [patch 15/33] PS3: Vuart rework Geoff Levand
2007-06-15 22:03 ` [patch 16/33] PS3: System manager re-work Geoff Levand
2007-06-15 22:05 ` [patch 17/33] PS3: Rework AV settings driver Geoff Levand
2007-06-15 22:05 ` [patch 18/33] PS3: Frame buffer system-bus rework Geoff Levand
2007-06-19 6:47 ` Paul Mackerras
2007-06-19 7:09 ` Geert Uytterhoeven
2007-06-21 22:18 ` Levand, Geoffrey
2007-06-15 22:05 ` [patch 19/33] PS3: Device registration routines Geoff Levand
2007-06-15 22:06 ` [patch 20/33] PS3: Rename processor id symbols Geoff Levand
2007-06-15 22:06 ` [patch 21/33] PS3: Use clear_bit Geoff Levand
2007-06-15 23:43 ` Benjamin Herrenschmidt
2007-06-15 22:06 ` [patch 22/33] powerpc: Output params value in early_init_devtree Geoff Levand
2007-06-15 22:06 ` [patch 23/33] powerpc: Localize mmu_off Geoff Levand
2007-06-18 14:08 ` Milton Miller
2007-06-18 22:47 ` Geoff Levand
2007-06-19 6:46 ` Paul Mackerras
2007-06-23 19:24 ` Geoff Levand
2007-06-15 22:06 ` [patch 24/33] powerpc: Correct __secondary_hold comment Geoff Levand
2007-06-18 14:08 ` Milton Miller
2007-06-18 16:56 ` Segher Boessenkool
2007-06-18 22:47 ` Geoff Levand
2007-06-15 22:06 ` [patch 25/33] Powerpc: Add signed types to bootwrapper Geoff Levand
2007-06-15 22:06 ` [patch 26/33] Powerpc: Add u64 printf " Geoff Levand
2007-06-15 22:06 ` [patch 27/33] Powerpc: Fix constantness of bootwrapper arg Geoff Levand
2007-06-15 22:06 ` [patch 28/33] powerpc: Bootwrapper global scope kernel_entry_t Geoff Levand
2007-06-15 22:06 ` [patch 29/33] PS3: Device tree source Geoff Levand
2007-06-15 23:48 ` Segher Boessenkool
2007-06-15 22:07 ` [patch 30/33] PS3: Bootwrapper support Geoff Levand
2007-06-18 14:20 ` Milton Miller
2007-06-18 22:47 ` Geoff Levand
2007-06-18 22:55 ` Mark A. Greer
2007-06-19 0:01 ` Geoff Levand
2007-06-19 5:58 ` Mark A. Greer
2007-06-19 6:44 ` Paul Mackerras
2007-06-21 22:24 ` Levand, Geoffrey
2007-06-18 22:47 ` [patch 30/33 v2] " Geoff Levand
2007-06-23 19:16 ` [patch 30/33 v3] " Geoff Levand
2007-07-03 23:07 ` [patch v4] " Geoff Levand
2007-06-15 22:07 ` [patch 31/33] PS3: Select MEMORY_HOTPLUG Geoff Levand
2007-06-15 22:07 ` [patch 32/33] PS3: Fix more sparse warnings Geoff Levand
2007-06-15 22:07 ` [patch 33/33] PS3: Update ps3_defconfig Geoff Levand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46730264.2040208@am.sony.com \
--to=geoffrey.levand@am$(echo .)sony.com \
--cc=linuxppc-dev@ozlabs$(echo .)org \
--cc=paulus@samba$(echo .)org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox