#include <asm/vdso_datapage.h>
#include <asm/pSeries_reconfig.h>
#include "xics.h"
+#include "plpar_wrappers.h"
/* This version can't take the spinlock, because it never returns */
static struct rtas_args rtas_stop_self_args = {
panic("Alas, I survived.\n");
}
-static void pSeries_mach_cpu_die(void)
+static void pseries_mach_cpu_die(void)
{
local_irq_disable();
idle_task_exit();
- xics_teardown_cpu(0);
+ xics_teardown_cpu();
+ unregister_slb_shadow(hard_smp_processor_id(), __pa(get_slb_shadow()));
rtas_stop_self();
/* Should never get here... */
BUG();
return cpu_status;
}
-static int pSeries_cpu_disable(void)
+static int pseries_cpu_disable(void)
{
int cpu = smp_processor_id();
return 0;
}
-static void pSeries_cpu_die(unsigned int cpu)
+static void pseries_cpu_die(unsigned int cpu)
{
int tries;
int cpu_status;
cpu_status = query_cpu_stopped(pcpu);
if (cpu_status == 0 || cpu_status == -1)
break;
- msleep(200);
+ cpu_relax();
}
if (cpu_status != 0) {
printk("Querying DEAD? cpu %i (%i) shows %i\n",
* the logical ids for sibling SMT threads x and y are adjacent, such
* that x^1 == y and y^1 == x.
*/
-static int pSeries_add_processor(struct device_node *np)
+static int pseries_add_processor(struct device_node *np)
{
unsigned int cpu;
cpumask_t candidate_map, tmp = CPU_MASK_NONE;
int err = -ENOSPC, len, nthreads, i;
const u32 *intserv;
- intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
+ intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
if (!intserv)
return 0;
for (i = 0; i < nthreads; i++)
cpu_set(i, tmp);
- lock_cpu_hotplug();
+ cpu_maps_update_begin();
BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
}
err = 0;
out_unlock:
- unlock_cpu_hotplug();
+ cpu_maps_update_done();
return err;
}
* the hard id in the paca(s) to -1 to be consistent with boot time
* convention for non-present cpus.
*/
-static void pSeries_remove_processor(struct device_node *np)
+static void pseries_remove_processor(struct device_node *np)
{
unsigned int cpu;
int len, nthreads, i;
const u32 *intserv;
- intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
+ intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len);
if (!intserv)
return;
nthreads = len / sizeof(u32);
- lock_cpu_hotplug();
+ cpu_maps_update_begin();
for (i = 0; i < nthreads; i++) {
for_each_present_cpu(cpu) {
if (get_hard_smp_processor_id(cpu) != intserv[i])
printk(KERN_WARNING "Could not find cpu to remove "
"with physical id 0x%x\n", intserv[i]);
}
- unlock_cpu_hotplug();
+ cpu_maps_update_done();
}
-static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node)
+static int pseries_smp_notifier(struct notifier_block *nb,
+ unsigned long action, void *node)
{
int err = NOTIFY_OK;
switch (action) {
case PSERIES_RECONFIG_ADD:
- if (pSeries_add_processor(node))
+ if (pseries_add_processor(node))
err = NOTIFY_BAD;
break;
case PSERIES_RECONFIG_REMOVE:
- pSeries_remove_processor(node);
+ pseries_remove_processor(node);
break;
default:
err = NOTIFY_DONE;
return err;
}
-static struct notifier_block pSeries_smp_nb = {
- .notifier_call = pSeries_smp_notifier,
+static struct notifier_block pseries_smp_nb = {
+ .notifier_call = pseries_smp_notifier,
};
static int __init pseries_cpu_hotplug_init(void)
{
+ struct device_node *np;
+ const char *typep;
+
+ for_each_node_by_name(np, "interrupt-controller") {
+ typep = of_get_property(np, "compatible", NULL);
+ if (strstr(typep, "open-pic")) {
+ of_node_put(np);
+
+ printk(KERN_INFO "CPU Hotplug not supported on "
+ "systems using MPIC\n");
+ return 0;
+ }
+ }
+
rtas_stop_self_args.token = rtas_token("stop-self");
qcss_tok = rtas_token("query-cpu-stopped-state");
return 0;
}
- ppc_md.cpu_die = pSeries_mach_cpu_die;
- smp_ops->cpu_disable = pSeries_cpu_disable;
- smp_ops->cpu_die = pSeries_cpu_die;
+ ppc_md.cpu_die = pseries_mach_cpu_die;
+ smp_ops->cpu_disable = pseries_cpu_disable;
+ smp_ops->cpu_die = pseries_cpu_die;
/* Processors can be added/removed only on LPAR */
if (firmware_has_feature(FW_FEATURE_LPAR))
- pSeries_reconfig_notifier_register(&pSeries_smp_nb);
+ pSeries_reconfig_notifier_register(&pseries_smp_nb);
return 0;
}