// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PowerPC64 LPAR Configuration Information Driver
 *
 * Dave Engebretsen engebret@us.ibm.com
 *    Copyright (c) 2003 Dave Engebretsen
 * Will Schmidt willschm@us.ibm.com
 *    SPLPAR updates, Copyright (c) 2003 Will Schmidt IBM Corporation.
 *    seq_file updates, Copyright (c) 2004 Will Schmidt IBM Corporation.
 * Nathan Lynch nathanl@austin.ibm.com
 *    Added lparcfg_write, Copyright (C) 2004 Nathan Lynch IBM Corporation.
 *
 * This driver creates a proc file at /proc/ppc64/lparcfg which contains
 * keyword - value pairs that specify the configuration of the partition.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/hugetlb.h>
#include <asm/lppaca.h>
#include <asm/hvcall.h>
#include <asm/firmware.h>
#include <asm/rtas.h>
#include <asm/time.h>
#include <asm/vdso_datapage.h>
#include <asm/vio.h>
#include <asm/mmu.h>
#include <asm/machdep.h>
#include <asm/drmem.h>

#include "pseries.h"

/*
 * This isn't a module but we expose that to userspace
 * via /proc so leave the definitions here
 */
#define MODULE_VERS "1.9"
#define MODULE_NAME "lparcfg"

/* #define LPARCFG_DEBUG */

/*
 * Track sum of all purrs across all processors. This is used to further
 * calculate usage values by different applications
 */
static void cpu_get_purr(void *arg)
{
	atomic64_t *sum = arg;

	atomic64_add(mfspr(SPRN_PURR), sum);
}

static unsigned long get_purr(void)
{
	atomic64_t purr = ATOMIC64_INIT(0);

	on_each_cpu(cpu_get_purr, &purr, 1);

	return atomic64_read(&purr);
}

/*
 * Methods used to fetch LPAR data when running on a pSeries platform.
 */

struct hvcall_ppp_data {
	u64	entitlement;
	u64	unallocated_entitlement;
	u16	group_num;
	u16	pool_num;
	u8	capped;
	u8	weight;
	u8	unallocated_weight;
	u16	active_procs_in_pool;
	u16	active_system_procs;
	u16	phys_platform_procs;
	u32	max_proc_cap_avail;
	u32	entitled_proc_cap_avail;
};

/*
 * H_GET_PPP hcall returns info in 4 parms.
 *  entitled_capacity,unallocated_capacity,
 *  aggregation, resource_capability).
 *
 *  R4 = Entitled Processor Capacity Percentage.
 *  R5 = Unallocated Processor Capacity Percentage.
 *  R6 (AABBCCDDEEFFGGHH).
 *      XXXX - reserved (0)
 *          XXXX - reserved (0)
 *              XXXX - Group Number
 *                  XXXX - Pool Number.
 *  R7 (IIJJKKLLMMNNOOPP).
 *      XX - reserved. (0)
 *        XX - bit 0-6 reserved (0).   bit 7 is Capped indicator.
 *          XX - variable processor Capacity Weight
 *            XX - Unallocated Variable Processor Capacity Weight.
 *              XXXX - Active processors in Physical Processor Pool.
 *                  XXXX  - Processors active on platform.
 *  R8 (QQQQRRRRRRSSSSSS). if ibm,partition-performance-parameters-level >= 1
 *	XXXX - Physical platform procs allocated to virtualization.
 *	    XXXXXX - Max procs capacity % available to the partitions pool.
 *	          XXXXXX - Entitled procs capacity % available to the
 *			   partitions pool.
 */
static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
{
	unsigned long rc;
	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];

	rc = plpar_hcall9(H_GET_PPP, retbuf);

	ppp_data->entitlement = retbuf[0];
	ppp_data->unallocated_entitlement = retbuf[1];

	ppp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
	ppp_data->pool_num = retbuf[2] & 0xffff;

	ppp_data->capped = (retbuf[3] >> 6 * 8) & 0x01;
	ppp_data->weight = (retbuf[3] >> 5 * 8) & 0xff;
	ppp_data->unallocated_weight = (retbuf[3] >> 4 * 8) & 0xff;
	ppp_data->active_procs_in_pool = (retbuf[3] >> 2 * 8) & 0xffff;
	ppp_data->active_system_procs = retbuf[3] & 0xffff;

	ppp_data->phys_platform_procs = retbuf[4] >> 6 * 8;
	ppp_data->max_proc_cap_avail = (retbuf[4] >> 3 * 8) & 0xffffff;
	ppp_data->entitled_proc_cap_avail = retbuf[4] & 0xffffff;

	return rc;
}

static void show_gpci_data(struct seq_file *m)
{
	struct hv_gpci_request_buffer *buf;
	unsigned int affinity_score;
	long ret;

	buf = kmalloc(sizeof(*buf), GFP_KERNEL);
	if (buf == NULL)
		return;

	/*
	 * Show the local LPAR's affinity score.
	 *
	 * 0xB1 selects the Affinity_Domain_Info_By_Partition subcall.
	 * The score is at byte 0xB in the output buffer.
	 */
	memset(&buf->params, 0, sizeof(buf->params));
	buf->params.counter_request = cpu_to_be32(0xB1);
	buf->params.starting_index = cpu_to_be32(-1);	/* local LPAR */
	buf->params.counter_info_version_in = 0x5;	/* v5+ for score */
	ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, virt_to_phys(buf),
				 sizeof(*buf));
	if (ret != H_SUCCESS) {
		pr_debug("hcall failed: H_GET_PERF_COUNTER_INFO: %ld, %x\n",
			 ret, be32_to_cpu(buf->params.detail_rc));
		goto out;
	}
	affinity_score = buf->bytes[0xB];
	seq_printf(m, "partition_affinity_score=%u\n", affinity_score);
out:
	kfree(buf);
}

static unsigned h_pic(unsigned long *pool_idle_time,
		      unsigned long *num_procs)
{
	unsigned long rc;
	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];

	rc = plpar_hcall(H_PIC, retbuf);

	*pool_idle_time = retbuf[0];
	*num_procs = retbuf[1];

	return rc;
}

/*
 * parse_ppp_data
 * Parse out the data returned from h_get_ppp and h_pic
 */
static void parse_ppp_data(struct seq_file *m)
{
	struct hvcall_ppp_data ppp_data;
	struct device_node *root;
	const __be32 *perf_level;
	int rc;

	rc = h_get_ppp(&ppp_data);
	if (rc)
		return;

	seq_printf(m, "partition_entitled_capacity=%lld\n",
	           ppp_data.entitlement);
	seq_printf(m, "group=%d\n", ppp_data.group_num);
	seq_printf(m, "system_active_processors=%d\n",
	           ppp_data.active_system_procs);

	/* pool related entries are appropriate for shared configs */
	if (lppaca_shared_proc(get_lppaca())) {
		unsigned long pool_idle_time, pool_procs;

		seq_printf(m, "pool=%d\n", ppp_data.pool_num);

		/* report pool_capacity in percentage */
		seq_printf(m, "pool_capacity=%d\n",
			   ppp_data.active_procs_in_pool * 100);

		h_pic(&pool_idle_time, &pool_procs);
		seq_printf(m, "pool_idle_time=%ld\n", pool_idle_time);
		seq_printf(m, "pool_num_procs=%ld\n", pool_procs);
	}

	seq_printf(m, "unallocated_capacity_weight=%d\n",
		   ppp_data.unallocated_weight);
	seq_printf(m, "capacity_weight=%d\n", ppp_data.weight);
	seq_printf(m, "capped=%d\n", ppp_data.capped);
	seq_printf(m, "unallocated_capacity=%lld\n",
		   ppp_data.unallocated_entitlement);

	/* The last bits of information returned from h_get_ppp are only
	 * valid if the ibm,partition-performance-parameters-level
	 * property is >= 1.
	 */
	root = of_find_node_by_path("/");
	if (root) {
		perf_level = of_get_property(root,
				"ibm,partition-performance-parameters-level",
					     NULL);
		if (perf_level && (be32_to_cpup(perf_level) >= 1)) {
			seq_printf(m,
			    "physical_procs_allocated_to_virtualization=%d\n",
				   ppp_data.phys_platform_procs);
			seq_printf(m, "max_proc_capacity_available=%d\n",
				   ppp_data.max_proc_cap_avail);
			seq_printf(m, "entitled_proc_capacity_available=%d\n",
				   ppp_data.entitled_proc_cap_avail);
		}

		of_node_put(root);
	}
}

/**
 * parse_mpp_data
 * Parse out data returned from h_get_mpp
 */
static void parse_mpp_data(struct seq_file *m)
{
	struct hvcall_mpp_data mpp_data;
	int rc;

	rc = h_get_mpp(&mpp_data);
	if (rc)
		return;

	seq_printf(m, "entitled_memory=%ld\n", mpp_data.entitled_mem);

	if (mpp_data.mapped_mem != -1)
		seq_printf(m, "mapped_entitled_memory=%ld\n",
		           mpp_data.mapped_mem);

	seq_printf(m, "entitled_memory_group_number=%d\n", mpp_data.group_num);
	seq_printf(m, "entitled_memory_pool_number=%d\n", mpp_data.pool_num);

	seq_printf(m, "entitled_memory_weight=%d\n", mpp_data.mem_weight);
	seq_printf(m, "unallocated_entitled_memory_weight=%d\n",
	           mpp_data.unallocated_mem_weight);
	seq_printf(m, "unallocated_io_mapping_entitlement=%ld\n",
	           mpp_data.unallocated_entitlement);

	if (mpp_data.pool_size != -1)
		seq_printf(m, "entitled_memory_pool_size=%ld bytes\n",
		           mpp_data.pool_size);

	seq_printf(m, "entitled_memory_loan_request=%ld\n",
	           mpp_data.loan_request);

	seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem);
}

/**
 * parse_mpp_x_data
 * Parse out data returned from h_get_mpp_x
 */
static void parse_mpp_x_data(struct seq_file *m)
{
	struct hvcall_mpp_x_data mpp_x_data;

	if (!firmware_has_feature(FW_FEATURE_XCMO))
		return;
	if (h_get_mpp_x(&mpp_x_data))
		return;

	seq_printf(m, "coalesced_bytes=%ld\n", mpp_x_data.coalesced_bytes);

	if (mpp_x_data.pool_coalesced_bytes)
		seq_printf(m, "pool_coalesced_bytes=%ld\n",
			   mpp_x_data.pool_coalesced_bytes);
	if (mpp_x_data.pool_purr_cycles)
		seq_printf(m, "coalesce_pool_purr=%ld\n", mpp_x_data.pool_purr_cycles);
	if (mpp_x_data.pool_spurr_cycles)
		seq_printf(m, "coalesce_pool_spurr=%ld\n", mpp_x_data.pool_spurr_cycles);
}

/*
 * PAPR defines, in section "7.3.16 System Parameters Option", the token 55 to
 * read the LPAR name, and the largest output data to 4000 + 2 bytes length.
 */
#define SPLPAR_LPAR_NAME_TOKEN	55
#define GET_SYS_PARM_BUF_SIZE	4002
#if GET_SYS_PARM_BUF_SIZE > RTAS_DATA_BUF_SIZE
#error "GET_SYS_PARM_BUF_SIZE is larger than RTAS_DATA_BUF_SIZE"
#endif

/*
 * Read the lpar name using the RTAS ibm,get-system-parameter call.
 *
 * The name read through this call is updated if changes are made by the end
 * user on the hypervisor side.
 *
 * Some hypervisor (like Qemu) may not provide this value. In that case, a non
 * null value is returned.
 */
static int read_rtas_lpar_name(struct seq_file *m)
{
	int rc, len, token;
	union {
		char raw_buffer[GET_SYS_PARM_BUF_SIZE];
		struct {
			__be16 len;
			char name[GET_SYS_PARM_BUF_SIZE-2];
		};
	} *local_buffer;

	token = rtas_token("ibm,get-system-parameter");
	if (token == RTAS_UNKNOWN_SERVICE)
		return -EINVAL;

	local_buffer = kmalloc(sizeof(*local_buffer), GFP_KERNEL);
	if (!local_buffer)
		return -ENOMEM;

	do {
		spin_lock(&rtas_data_buf_lock);
		memset(rtas_data_buf, 0, sizeof(*local_buffer));
		rc = rtas_call(token, 3, 1, NULL, SPLPAR_LPAR_NAME_TOKEN,
			       __pa(rtas_data_buf), sizeof(*local_buffer));
		if (!rc)
			memcpy(local_buffer->raw_buffer, rtas_data_buf,
			       sizeof(local_buffer->raw_buffer));
		spin_unlock(&rtas_data_buf_lock);
	} while (rtas_busy_delay(rc));

	if (!rc) {
		/* Force end of string */
		len = min((int) be16_to_cpu(local_buffer->len),
			  (int) sizeof(local_buffer->name)-1);
		local_buffer->name[len] = '\0';

		seq_printf(m, "partition_name=%s\n", local_buffer->name);
	} else
		rc = -ENODATA;

	kfree(local_buffer);
	return rc;
}

/*
 * Read the LPAR name from the Device Tree.
 *
 * The value read in the DT is not updated if the end-user is touching the LPAR
 * name on the hypervisor side.
 */
static int read_dt_lpar_name(struct seq_file *m)
{
	const char *name;

	if (of_property_read_string(of_root, "ibm,partition-name", &name))
		return -ENOENT;

	seq_printf(m, "partition_name=%s\n", name);
	return 0;
}

static void read_lpar_name(struct seq_file *m)
{
	if (read_rtas_lpar_name(m) && read_dt_lpar_name(m))
		pr_err_once("Error can't get the LPAR name");
}

#define SPLPAR_CHARACTERISTICS_TOKEN 20
#define SPLPAR_MAXLENGTH 1026*(sizeof(char))

/*
 * parse_system_parameter_string()
 * Retrieve the potential_processors, max_entitled_capacity and friends
 * through the get-system-parameter rtas call.  Replace keyword strings as
 * necessary.
 */
static void parse_system_parameter_string(struct seq_file *m)
{
	int call_status;

	unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
	if (!local_buffer) {
		printk(KERN_ERR "%s %s kmalloc failure at line %d\n",
		       __FILE__, __func__, __LINE__);
		return;
	}

	spin_lock(&rtas_data_buf_lock);
	memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH);
	call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
				NULL,
				SPLPAR_CHARACTERISTICS_TOKEN,
				__pa(rtas_data_buf),
				RTAS_DATA_BUF_SIZE);
	memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH);
	local_buffer[SPLPAR_MAXLENGTH - 1] = '\0';
	spin_unlock(&rtas_data_buf_lock);

	if (call_status != 0) {
		printk(KERN_INFO
		       "%s %s Error calling get-system-parameter (0x%x)\n",
		       __FILE__, __func__, call_status);
	} else {
		int splpar_strlen;
		int idx, w_idx;
		char *workbuffer = kzalloc(SPLPAR_MAXLENGTH, GFP_KERNEL);
		if (!workbuffer) {
			printk(KERN_ERR "%s %s kmalloc failure at line %d\n",
			       __FILE__, __func__, __LINE__);
			kfree(local_buffer);
			return;
		}
#ifdef LPARCFG_DEBUG
		printk(KERN_INFO "success calling get-system-parameter\n");
#endif
		splpar_strlen = local_buffer[0] * 256 + local_buffer[1];
		local_buffer += 2;	/* step over strlen value */

		w_idx = 0;
		idx = 0;
		while ((*local_buffer) && (idx < splpar_strlen)) {
			workbuffer[w_idx++] = local_buffer[idx++];
			if ((local_buffer[idx] == ',')
			    || (local_buffer[idx] == '\0')) {
				workbuffer[w_idx] = '\0';
				if (w_idx) {
					/* avoid the empty string */
					seq_printf(m, "%s\n", workbuffer);
				}
				memset(workbuffer, 0, SPLPAR_MAXLENGTH);
				idx++;	/* skip the comma */
				w_idx = 0;
			} else if (local_buffer[idx] == '=') {
				/* code here to replace workbuffer contents
				   with different keyword strings */
				if (0 == strcmp(workbuffer, "MaxEntCap")) {
					strcpy(workbuffer,
					       "partition_max_entitled_capacity");
					w_idx = strlen(workbuffer);
				}
				if (0 == strcmp(workbuffer, "MaxPlatProcs")) {
					strcpy(workbuffer,
					       "system_potential_processors");
					w_idx = strlen(workbuffer);
				}
			}
		}
		kfree(workbuffer);
		local_buffer -= 2;	/* back up over strlen value */
	}
	kfree(local_buffer);
}

/* Return the number of processors in the system.
 * This function reads through the device tree and counts
 * the virtual processors, this does not include threads.
 */
static int lparcfg_count_active_processors(void)
{
	struct device_node *cpus_dn;
	int count = 0;

	for_each_node_by_type(cpus_dn, "cpu") {
#ifdef LPARCFG_DEBUG
		printk(KERN_ERR "cpus_dn %p\n", cpus_dn);
#endif
		count++;
	}
	return count;
}

static void pseries_cmo_data(struct seq_file *m)
{
	int cpu;
	unsigned long cmo_faults = 0;
	unsigned long cmo_fault_time = 0;

	seq_printf(m, "cmo_enabled=%d\n", firmware_has_feature(FW_FEATURE_CMO));

	if (!firmware_has_feature(FW_FEATURE_CMO))
		return;

	for_each_possible_cpu(cpu) {
		cmo_faults += be64_to_cpu(lppaca_of(cpu).cmo_faults);
		cmo_fault_time += be64_to_cpu(lppaca_of(cpu).cmo_fault_time);
	}

	seq_printf(m, "cmo_faults=%lu\n", cmo_faults);
	seq_printf(m, "cmo_fault_time_usec=%lu\n",
		   cmo_fault_time / tb_ticks_per_usec);
	seq_printf(m, "cmo_primary_psp=%d\n", cmo_get_primary_psp());
	seq_printf(m, "cmo_secondary_psp=%d\n", cmo_get_secondary_psp());
	seq_printf(m, "cmo_page_size=%lu\n", cmo_get_page_size());
}

static void splpar_dispatch_data(struct seq_file *m)
{
	int cpu;
	unsigned long dispatches = 0;
	unsigned long dispatch_dispersions = 0;

	for_each_possible_cpu(cpu) {
		dispatches += be32_to_cpu(lppaca_of(cpu).yield_count);
		dispatch_dispersions +=
			be32_to_cpu(lppaca_of(cpu).dispersion_count);
	}

	seq_printf(m, "dispatches=%lu\n", dispatches);
	seq_printf(m, "dispatch_dispersions=%lu\n", dispatch_dispersions);
}

static void parse_em_data(struct seq_file *m)
{
	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];

	if (firmware_has_feature(FW_FEATURE_LPAR) &&
	    plpar_hcall(H_GET_EM_PARMS, retbuf) == H_SUCCESS)
		seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
}

static void maxmem_data(struct seq_file *m)
{
	unsigned long maxmem = 0;

	maxmem += (unsigned long)drmem_info->n_lmbs * drmem_info->lmb_size;
	maxmem += hugetlb_total_pages() * PAGE_SIZE;

	seq_printf(m, "MaxMem=%lu\n", maxmem);
}

static int pseries_lparcfg_data(struct seq_file *m, void *v)
{
	int partition_potential_processors;
	int partition_active_processors;
	struct device_node *rtas_node;
	const __be32 *lrdrp = NULL;

	rtas_node = of_find_node_by_path("/rtas");
	if (rtas_node)
		lrdrp = of_get_property(rtas_node, "ibm,lrdr-capacity", NULL);

	if (lrdrp == NULL) {
		partition_potential_processors = vdso_data->processorCount;
	} else {
		partition_potential_processors = be32_to_cpup(lrdrp + 4);
	}
	of_node_put(rtas_node);

	partition_active_processors = lparcfg_count_active_processors();

	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
		/* this call handles the ibm,get-system-parameter contents */
		read_lpar_name(m);
		parse_system_parameter_string(m);
		parse_ppp_data(m);
		parse_mpp_data(m);
		parse_mpp_x_data(m);
		pseries_cmo_data(m);
		splpar_dispatch_data(m);

		seq_printf(m, "purr=%ld\n", get_purr());
		seq_printf(m, "tbr=%ld\n", mftb());
	} else {		/* non SPLPAR case */

		seq_printf(m, "system_active_processors=%d\n",
			   partition_potential_processors);

		seq_printf(m, "system_potential_processors=%d\n",
			   partition_potential_processors);

		seq_printf(m, "partition_max_entitled_capacity=%d\n",
			   partition_potential_processors * 100);

		seq_printf(m, "partition_entitled_capacity=%d\n",
			   partition_active_processors * 100);
	}

	show_gpci_data(m);

	seq_printf(m, "partition_active_processors=%d\n",
		   partition_active_processors);

	seq_printf(m, "partition_potential_processors=%d\n",
		   partition_potential_processors);

	seq_printf(m, "shared_processor_mode=%d\n",
		   lppaca_shared_proc(get_lppaca()));

#ifdef CONFIG_PPC_64S_HASH_MMU
	if (!radix_enabled())
		seq_printf(m, "slb_size=%d\n", mmu_slb_size);
#endif
	parse_em_data(m);
	maxmem_data(m);

	seq_printf(m, "security_flavor=%u\n", pseries_security_flavor);

	return 0;
}

static ssize_t update_ppp(u64 *entitlement, u8 *weight)
{
	struct hvcall_ppp_data ppp_data;
	u8 new_weight;
	u64 new_entitled;
	ssize_t retval;

	/* Get our current parameters */
	retval = h_get_ppp(&ppp_data);
	if (retval)
		return retval;

	if (entitlement) {
		new_weight = ppp_data.weight;
		new_entitled = *entitlement;
	} else if (weight) {
		new_weight = *weight;
		new_entitled = ppp_data.entitlement;
	} else
		return -EINVAL;

	pr_debug("%s: current_entitled = %llu, current_weight = %u\n",
		 __func__, ppp_data.entitlement, ppp_data.weight);

	pr_debug("%s: new_entitled = %llu, new_weight = %u\n",
		 __func__, new_entitled, new_weight);

	retval = plpar_hcall_norets(H_SET_PPP, new_entitled, new_weight);
	return retval;
}

/**
 * update_mpp
 *
 * Update the memory entitlement and weight for the partition.  Caller must
 * specify either a new entitlement or weight, not both, to be updated
 * since the h_set_mpp call takes both entitlement and weight as parameters.
 */
static ssize_t update_mpp(u64 *entitlement, u8 *weight)
{
	struct hvcall_mpp_data mpp_data;
	u64 new_entitled;
	u8 new_weight;
	ssize_t rc;

	if (entitlement) {
		/* Check with vio to ensure the new memory entitlement
		 * can be handled.
		 */
		rc = vio_cmo_entitlement_update(*entitlement);
		if (rc)
			return rc;
	}

	rc = h_get_mpp(&mpp_data);
	if (rc)
		return rc;

	if (entitlement) {
		new_weight = mpp_data.mem_weight;
		new_entitled = *entitlement;
	} else if (weight) {
		new_weight = *weight;
		new_entitled = mpp_data.entitled_mem;
	} else
		return -EINVAL;

	pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
	         __func__, mpp_data.entitled_mem, mpp_data.mem_weight);

	pr_debug("%s: new_entitled = %llu, new_weight = %u\n",
		 __func__, new_entitled, new_weight);

	rc = plpar_hcall_norets(H_SET_MPP, new_entitled, new_weight);
	return rc;
}

/*
 * Interface for changing system parameters (variable capacity weight
 * and entitled capacity).  Format of input is "param_name=value";
 * anything after value is ignored.  Valid parameters at this time are
 * "partition_entitled_capacity" and "capacity_weight".  We use
 * H_SET_PPP to alter parameters.
 *
 * This function should be invoked only on systems with
 * FW_FEATURE_SPLPAR.
 */
static ssize_t lparcfg_write(struct file *file, const char __user * buf,
			     size_t count, loff_t * off)
{
	char kbuf[64];
	char *tmp;
	u64 new_entitled, *new_entitled_ptr = &new_entitled;
	u8 new_weight, *new_weight_ptr = &new_weight;
	ssize_t retval;

	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
		return -EINVAL;

	if (count > sizeof(kbuf))
		return -EINVAL;

	if (copy_from_user(kbuf, buf, count))
		return -EFAULT;

	kbuf[count - 1] = '\0';
	tmp = strchr(kbuf, '=');
	if (!tmp)
		return -EINVAL;

	*tmp++ = '\0';

	if (!strcmp(kbuf, "partition_entitled_capacity")) {
		char *endp;
		*new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
		if (endp == tmp)
			return -EINVAL;

		retval = update_ppp(new_entitled_ptr, NULL);
	} else if (!strcmp(kbuf, "capacity_weight")) {
		char *endp;
		*new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
		if (endp == tmp)
			return -EINVAL;

		retval = update_ppp(NULL, new_weight_ptr);
	} else if (!strcmp(kbuf, "entitled_memory")) {
		char *endp;
		*new_entitled_ptr = (u64) simple_strtoul(tmp, &endp, 10);
		if (endp == tmp)
			return -EINVAL;

		retval = update_mpp(new_entitled_ptr, NULL);
	} else if (!strcmp(kbuf, "entitled_memory_weight")) {
		char *endp;
		*new_weight_ptr = (u8) simple_strtoul(tmp, &endp, 10);
		if (endp == tmp)
			return -EINVAL;

		retval = update_mpp(NULL, new_weight_ptr);
	} else
		return -EINVAL;

	if (retval == H_SUCCESS || retval == H_CONSTRAINED) {
		retval = count;
	} else if (retval == H_BUSY) {
		retval = -EBUSY;
	} else if (retval == H_HARDWARE) {
		retval = -EIO;
	} else if (retval == H_PARAMETER) {
		retval = -EINVAL;
	}

	return retval;
}

static int lparcfg_data(struct seq_file *m, void *v)
{
	struct device_node *rootdn;
	const char *model = "";
	const char *system_id = "";
	const char *tmp;
	const __be32 *lp_index_ptr;
	unsigned int lp_index = 0;

	seq_printf(m, "%s %s\n", MODULE_NAME, MODULE_VERS);

	rootdn = of_find_node_by_path("/");
	if (rootdn) {
		tmp = of_get_property(rootdn, "model", NULL);
		if (tmp)
			model = tmp;
		tmp = of_get_property(rootdn, "system-id", NULL);
		if (tmp)
			system_id = tmp;
		lp_index_ptr = of_get_property(rootdn, "ibm,partition-no",
					NULL);
		if (lp_index_ptr)
			lp_index = be32_to_cpup(lp_index_ptr);
		of_node_put(rootdn);
	}
	seq_printf(m, "serial_number=%s\n", system_id);
	seq_printf(m, "system_type=%s\n", model);
	seq_printf(m, "partition_id=%d\n", (int)lp_index);

	return pseries_lparcfg_data(m, v);
}

static int lparcfg_open(struct inode *inode, struct file *file)
{
	return single_open(file, lparcfg_data, NULL);
}

static const struct proc_ops lparcfg_proc_ops = {
	.proc_read	= seq_read,
	.proc_write	= lparcfg_write,
	.proc_open	= lparcfg_open,
	.proc_release	= single_release,
	.proc_lseek	= seq_lseek,
};

static int __init lparcfg_init(void)
{
	umode_t mode = 0444;

	/* Allow writing if we have FW_FEATURE_SPLPAR */
	if (firmware_has_feature(FW_FEATURE_SPLPAR))
		mode |= 0200;

	if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_proc_ops)) {
		printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
		return -EIO;
	}
	return 0;
}
machine_device_initcall(pseries, lparcfg_init);
