aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c42
-rw-r--r--arch/powerpc/platforms/pseries/offline_states.h23
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h4
-rw-r--r--arch/powerpc/platforms/pseries/xics.c7
4 files changed, 43 insertions, 33 deletions
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index d1b124e44d7..a8e1d5d17a2 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -122,44 +122,32 @@ static void pseries_mach_cpu_die(void)
if (!get_lppaca()->shared_proc)
get_lppaca()->donate_dedicated_cpu = 1;
- printk(KERN_INFO
- "cpu %u (hwid %u) ceding for offline with hint %d\n",
- cpu, hwcpu, cede_latency_hint);
while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
extended_cede_processor(cede_latency_hint);
- printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n",
- cpu, hwcpu);
- printk(KERN_INFO
- "Decrementer value = %x Timebase value = %llx\n",
- get_dec(), get_tb());
}
- printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n",
- cpu, hwcpu);
-
if (!get_lppaca()->shared_proc)
get_lppaca()->donate_dedicated_cpu = 0;
get_lppaca()->idle = 0;
- }
- if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
- unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+ if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
+ unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
- /*
- * NOTE: Calling start_secondary() here for now to
- * start new context.
- * However, need to do it cleanly by resetting the
- * stack pointer.
- */
- start_secondary();
+ /*
+ * Call to start_secondary_resume() will not return.
+ * Kernel stack will be reset and start_secondary()
+ * will be called to continue the online operation.
+ */
+ start_secondary_resume();
+ }
+ }
- } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+ /* Requested state is CPU_STATE_OFFLINE at this point */
+ WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
- set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
- unregister_slb_shadow(hard_smp_processor_id(),
- __pa(get_slb_shadow()));
- rtas_stop_self();
- }
+ set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
+ unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+ rtas_stop_self();
/* Should never get here... */
BUG();
diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h
index 22574e0d9d9..75a6f480d93 100644
--- a/arch/powerpc/platforms/pseries/offline_states.h
+++ b/arch/powerpc/platforms/pseries/offline_states.h
@@ -9,10 +9,31 @@ enum cpu_state_vals {
CPU_MAX_OFFLINE_STATES
};
+#ifdef CONFIG_HOTPLUG_CPU
extern enum cpu_state_vals get_cpu_current_state(int cpu);
extern void set_cpu_current_state(int cpu, enum cpu_state_vals state);
-extern enum cpu_state_vals get_preferred_offline_state(int cpu);
extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state);
extern void set_default_offline_state(int cpu);
+#else
+static inline enum cpu_state_vals get_cpu_current_state(int cpu)
+{
+ return CPU_STATE_ONLINE;
+}
+
+static inline void set_cpu_current_state(int cpu, enum cpu_state_vals state)
+{
+}
+
+static inline void set_preferred_offline_state(int cpu, enum cpu_state_vals state)
+{
+}
+
+static inline void set_default_offline_state(int cpu)
+{
+}
+#endif
+
+extern enum cpu_state_vals get_preferred_offline_state(int cpu);
extern int start_secondary(void);
+extern void start_secondary_resume(void);
#endif
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index 0603c91538a..a05f8d42785 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -259,12 +259,12 @@ static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
return plpar_hcall_norets(H_IPI, servernum, mfrr);
}
-static inline long plpar_xirr(unsigned long *xirr_ret)
+static inline long plpar_xirr(unsigned long *xirr_ret, unsigned char cppr)
{
long rc;
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
- rc = plpar_hcall(H_XIRR, retbuf);
+ rc = plpar_hcall(H_XIRR, retbuf, cppr);
*xirr_ret = retbuf[0];
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 4ca641042ec..1bcedd8b461 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -120,12 +120,12 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
/* LPAR low level accessors */
-static inline unsigned int lpar_xirr_info_get(void)
+static inline unsigned int lpar_xirr_info_get(unsigned char cppr)
{
unsigned long lpar_rc;
unsigned long return_value;
- lpar_rc = plpar_xirr(&return_value);
+ lpar_rc = plpar_xirr(&return_value, cppr);
if (lpar_rc != H_SUCCESS)
panic(" bad return code xirr - rc = %lx\n", lpar_rc);
return (unsigned int)return_value;
@@ -331,7 +331,8 @@ static unsigned int xics_get_irq_direct(void)
static unsigned int xics_get_irq_lpar(void)
{
- unsigned int xirr = lpar_xirr_info_get();
+ struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+ unsigned int xirr = lpar_xirr_info_get(os_cppr->stack[os_cppr->index]);
unsigned int vec = xics_xirr_vector(xirr);
unsigned int irq;