summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/dlpar.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/dlpar.c')
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c197
1 files changed, 7 insertions, 190 deletions
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index f244dcb4f2cf..2b93ae8d557a 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -20,7 +20,6 @@
#include <linux/of.h>
#include "of_helpers.h"
-#include "offline_states.h"
#include "pseries.h"
#include <asm/prom.h>
@@ -338,185 +337,6 @@ int dlpar_release_drc(u32 drc_index)
return 0;
}
-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
-
-static int dlpar_online_cpu(struct device_node *dn)
-{
- int rc = 0;
- unsigned int cpu;
- int len, nthreads, i;
- const __be32 *intserv;
- u32 thread;
-
- intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return -EINVAL;
-
- nthreads = len / sizeof(u32);
-
- cpu_maps_update_begin();
- for (i = 0; i < nthreads; i++) {
- thread = be32_to_cpu(intserv[i]);
- for_each_present_cpu(cpu) {
- if (get_hard_smp_processor_id(cpu) != thread)
- continue;
- BUG_ON(get_cpu_current_state(cpu)
- != CPU_STATE_OFFLINE);
- cpu_maps_update_done();
- rc = device_online(get_cpu_device(cpu));
- if (rc)
- goto out;
- cpu_maps_update_begin();
-
- break;
- }
- if (cpu == num_possible_cpus())
- printk(KERN_WARNING "Could not find cpu to online "
- "with physical id 0x%x\n", thread);
- }
- cpu_maps_update_done();
-
-out:
- return rc;
-
-}
-
-static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
-{
- struct device_node *dn, *parent;
- u32 drc_index;
- int rc;
-
- rc = kstrtou32(buf, 0, &drc_index);
- if (rc)
- return -EINVAL;
-
- rc = dlpar_acquire_drc(drc_index);
- if (rc)
- return -EINVAL;
-
- parent = of_find_node_by_path("/cpus");
- if (!parent)
- return -ENODEV;
-
- dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
- of_node_put(parent);
- if (!dn) {
- dlpar_release_drc(drc_index);
- return -EINVAL;
- }
-
- rc = dlpar_attach_node(dn);
- if (rc) {
- dlpar_release_drc(drc_index);
- dlpar_free_cc_nodes(dn);
- return rc;
- }
-
- rc = dlpar_online_cpu(dn);
- if (rc)
- return rc;
-
- return count;
-}
-
-static int dlpar_offline_cpu(struct device_node *dn)
-{
- int rc = 0;
- unsigned int cpu;
- int len, nthreads, i;
- const __be32 *intserv;
- u32 thread;
-
- intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return -EINVAL;
-
- nthreads = len / sizeof(u32);
-
- cpu_maps_update_begin();
- for (i = 0; i < nthreads; i++) {
- thread = be32_to_cpu(intserv[i]);
- for_each_present_cpu(cpu) {
- if (get_hard_smp_processor_id(cpu) != thread)
- continue;
-
- if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
- break;
-
- if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
- set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
- cpu_maps_update_done();
- rc = device_offline(get_cpu_device(cpu));
- if (rc)
- goto out;
- cpu_maps_update_begin();
- break;
-
- }
-
- /*
- * The cpu is in CPU_STATE_INACTIVE.
- * Upgrade it's state to CPU_STATE_OFFLINE.
- */
- set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
- BUG_ON(plpar_hcall_norets(H_PROD, thread)
- != H_SUCCESS);
- __cpu_die(cpu);
- break;
- }
- if (cpu == num_possible_cpus())
- printk(KERN_WARNING "Could not find cpu to offline "
- "with physical id 0x%x\n", thread);
- }
- cpu_maps_update_done();
-
-out:
- return rc;
-
-}
-
-static ssize_t dlpar_cpu_release(const char *buf, size_t count)
-{
- struct device_node *dn;
- u32 drc_index;
- int rc;
-
- dn = of_find_node_by_path(buf);
- if (!dn)
- return -EINVAL;
-
- rc = of_property_read_u32(dn, "ibm,my-drc-index", &drc_index);
- if (rc) {
- of_node_put(dn);
- return -EINVAL;
- }
-
- rc = dlpar_offline_cpu(dn);
- if (rc) {
- of_node_put(dn);
- return -EINVAL;
- }
-
- rc = dlpar_release_drc(drc_index);
- if (rc) {
- of_node_put(dn);
- return rc;
- }
-
- rc = dlpar_detach_node(dn);
- if (rc) {
- dlpar_acquire_drc(drc_index);
- return rc;
- }
-
- of_node_put(dn);
-
- return count;
-}
-
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-
static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
{
int rc;
@@ -536,6 +356,9 @@ static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
case PSERIES_HP_ELOG_RESOURCE_MEM:
rc = dlpar_memory(hp_elog);
break;
+ case PSERIES_HP_ELOG_RESOURCE_CPU:
+ rc = dlpar_cpu(hp_elog);
+ break;
default:
pr_warn_ratelimited("Invalid resource (%d) specified\n",
hp_elog->resource);
@@ -565,6 +388,9 @@ static ssize_t dlpar_store(struct class *class, struct class_attribute *attr,
if (!strncmp(arg, "memory", 6)) {
hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM;
arg += strlen("memory ");
+ } else if (!strncmp(arg, "cpu", 3)) {
+ hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_CPU;
+ arg += strlen("cpu ");
} else {
pr_err("Invalid resource specified: \"%s\"\n", buf);
rc = -EINVAL;
@@ -624,16 +450,7 @@ static CLASS_ATTR(dlpar, S_IWUSR, NULL, dlpar_store);
static int __init pseries_dlpar_init(void)
{
- int rc;
-
-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
- ppc_md.cpu_probe = dlpar_cpu_probe;
- ppc_md.cpu_release = dlpar_cpu_release;
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-
- rc = sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
-
- return rc;
+ return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr);
}
machine_device_initcall(pseries, pseries_dlpar_init);