/*
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * This file contains utility functions to be used by platform specific CPR3
 * regulator drivers.
 */

#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/cpumask.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>

#include "cpr3-regulator.h"

#define BYTES_PER_FUSE_ROW		8
#define MAX_FUSE_ROW_BIT		63

#define CPR3_CONSECUTIVE_UP_DOWN_MIN	0
#define CPR3_CONSECUTIVE_UP_DOWN_MAX	15
#define CPR3_UP_DOWN_THRESHOLD_MIN	0
#define CPR3_UP_DOWN_THRESHOLD_MAX	31
#define CPR3_STEP_QUOT_MIN		0
#define CPR3_STEP_QUOT_MAX		63
#define CPR3_IDLE_CLOCKS_MIN		0
#define CPR3_IDLE_CLOCKS_MAX		31

/* This constant has units of uV/mV so 1000 corresponds to 100%. */
#define CPR3_AGING_DERATE_UNITY		1000

/**
 * cpr3_allocate_regulators() - allocate and initialize CPR3 regulators for a
 *		given thread based upon device tree data
 * @thread:		Pointer to the CPR3 thread
 *
 * This function allocates the thread->vreg array based upon the number of
 * device tree regulator subnodes.  It also initializes generic elements of each
 * regulator struct such as name, of_node, and thread.
 *
 * Return: 0 on success, errno on failure
 */
static int cpr3_allocate_regulators(struct cpr3_thread *thread)
{
	struct device_node *node;
	int i, rc;

	thread->vreg_count = 0;

	for_each_available_child_of_node(thread->of_node, node) {
		thread->vreg_count++;
	}

	thread->vreg = devm_kcalloc(thread->ctrl->dev, thread->vreg_count,
			sizeof(*thread->vreg), GFP_KERNEL);
	if (!thread->vreg)
		return -ENOMEM;

	i = 0;
	for_each_available_child_of_node(thread->of_node, node) {
		thread->vreg[i].of_node = node;
		thread->vreg[i].thread = thread;

		rc = of_property_read_string(node, "regulator-name",
						&thread->vreg[i].name);
		if (rc) {
			dev_err(thread->ctrl->dev, "could not find regulator name, rc=%d\n",
				rc);
			return rc;
		}

		i++;
	}

	return 0;
}

/**
 * cpr3_allocate_threads() - allocate and initialize CPR3 threads for a given
 *			     controller based upon device tree data
 * @ctrl:		Pointer to the CPR3 controller
 * @min_thread_id:	Minimum allowed hardware thread ID for this controller
 * @max_thread_id:	Maximum allowed hardware thread ID for this controller
 *
 * This function allocates the ctrl->thread array based upon the number of
 * device tree thread subnodes.  It also initializes generic elements of each
 * thread struct such as thread_id, of_node, ctrl, and vreg array.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_allocate_threads(struct cpr3_controller *ctrl, u32 min_thread_id,
			u32 max_thread_id)
{
	struct device *dev = ctrl->dev;
	struct device_node *thread_node;
	int i, j, rc;

	ctrl->thread_count = 0;

	for_each_available_child_of_node(dev->of_node, thread_node) {
		ctrl->thread_count++;
	}

	ctrl->thread = devm_kcalloc(dev, ctrl->thread_count,
			sizeof(*ctrl->thread), GFP_KERNEL);
	if (!ctrl->thread)
		return -ENOMEM;

	i = 0;
	for_each_available_child_of_node(dev->of_node, thread_node) {
		ctrl->thread[i].of_node = thread_node;
		ctrl->thread[i].ctrl = ctrl;

		rc = of_property_read_u32(thread_node, "qcom,cpr-thread-id",
					  &ctrl->thread[i].thread_id);
		if (rc) {
			dev_err(dev, "could not read DT property qcom,cpr-thread-id, rc=%d\n",
				rc);
			return rc;
		}

		if (ctrl->thread[i].thread_id < min_thread_id ||
				ctrl->thread[i].thread_id > max_thread_id) {
			dev_err(dev, "invalid thread id = %u; not within [%u, %u]\n",
				ctrl->thread[i].thread_id, min_thread_id,
				max_thread_id);
			return -EINVAL;
		}

		/* Verify that the thread ID is unique for all child nodes. */
		for (j = 0; j < i; j++) {
			if (ctrl->thread[j].thread_id
					== ctrl->thread[i].thread_id) {
				dev_err(dev, "duplicate thread id = %u found\n",
					ctrl->thread[i].thread_id);
				return -EINVAL;
			}
		}

		rc = cpr3_allocate_regulators(&ctrl->thread[i]);
		if (rc)
			return rc;

		i++;
	}

	return 0;
}

/**
 * cpr3_map_fuse_base() - ioremap the base address of the fuse region
 * @ctrl:	Pointer to the CPR3 controller
 * @pdev:	Platform device pointer for the CPR3 controller
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_map_fuse_base(struct cpr3_controller *ctrl,
			struct platform_device *pdev)
{
	struct resource *res;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fuse_base");
	if (!res || !res->start) {
		dev_err(&pdev->dev, "fuse base address is missing\n");
		return -ENXIO;
	}

	ctrl->fuse_base = devm_ioremap(&pdev->dev, res->start,
						resource_size(res));

	return 0;
}

/**
 * cpr3_read_fuse_param() - reads a CPR3 fuse parameter out of eFuses
 * @fuse_base_addr:	Virtual memory address of the eFuse base address
 * @param:		Null terminated array of fuse param segments to read
 *			from
 * @param_value:	Output with value read from the eFuses
 *
 * This function reads from each of the parameter segments listed in the param
 * array and concatenates their values together.  Reading stops when an element
 * is reached which has all 0 struct values.  The total number of bits specified
 * for the fuse parameter across all segments must be less than or equal to 64.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_read_fuse_param(void __iomem *fuse_base_addr,
		const struct cpr3_fuse_param *param, u64 *param_value)
{
	u64 fuse_val, val;
	int bits;
	int bits_total = 0;

	*param_value = 0;

	while (param->row || param->bit_start || param->bit_end) {
		if (param->bit_start > param->bit_end
		    || param->bit_end > MAX_FUSE_ROW_BIT) {
			pr_err("Invalid fuse parameter segment: row=%u, start=%u, end=%u\n",
				param->row, param->bit_start, param->bit_end);
			return -EINVAL;
		}

		bits = param->bit_end - param->bit_start + 1;
		if (bits_total + bits > 64) {
			pr_err("Invalid fuse parameter segments; total bits = %d\n",
				bits_total + bits);
			return -EINVAL;
		}

		fuse_val = readq_relaxed(fuse_base_addr
					 + param->row * BYTES_PER_FUSE_ROW);
		val = (fuse_val >> param->bit_start) & ((1ULL << bits) - 1);
		*param_value |= val << bits_total;
		bits_total += bits;

		param++;
	}

	return 0;
}

/**
 * cpr3_convert_open_loop_voltage_fuse() - converts an open loop voltage fuse
 *		value into an absolute voltage with units of microvolts
 * @ref_volt:		Reference voltage in microvolts
 * @step_volt:		The step size in microvolts of the fuse LSB
 * @fuse:		Open loop voltage fuse value
 * @fuse_len:		The bit length of the fuse value
 *
 * The MSB of the fuse parameter corresponds to a sign bit.  If it is set, then
 * the lower bits correspond to the number of steps to go down from the
 * reference voltage.  If it is not set, then the lower bits correspond to the
 * number of steps to go up from the reference voltage.
 */
int cpr3_convert_open_loop_voltage_fuse(int ref_volt, int step_volt, u32 fuse,
					int fuse_len)
{
	int sign, steps;

	sign = (fuse & (1 << (fuse_len - 1))) ? -1 : 1;
	steps = fuse & ((1 << (fuse_len - 1)) - 1);

	return ref_volt + sign * steps * step_volt;
}

/**
 * cpr3_interpolate() - performs linear interpolation
 * @x1		Lower known x value
 * @y1		Lower known y value
 * @x2		Upper known x value
 * @y2		Upper known y value
 * @x		Intermediate x value
 *
 * Returns y where (x, y) falls on the line between (x1, y1) and (x2, y2).
 * It is required that x1 < x2, y1 <= y2, and x1 <= x <= x2.  If these
 * conditions are not met, then y2 will be returned.
 */
u64 cpr3_interpolate(u64 x1, u64 y1, u64 x2, u64 y2, u64 x)
{
	u64 temp;

	if (x1 >= x2 || y1 > y2 || x1 > x || x > x2)
		return y2;

	temp = (x2 - x) * (y2 - y1);
	do_div(temp, (u32)(x2 - x1));

	return y2 - temp;
}

/**
 * cpr3_parse_array_property() - fill an array from a portion of the values
 *		specified for a device tree property
 * @vreg:		Pointer to the CPR3 regulator
 * @prop_name:		The name of the device tree property to read from
 * @tuple_size:		The number of elements in each tuple
 * @out:		Output data array which must be of size tuple_size
 *
 * cpr3_parse_common_corner_data() must be called for vreg before this function
 * is called so that fuse combo and speed bin size elements are initialized.
 *
 * Three formats are supported for the device tree property:
 * 1. Length == tuple_size
 *	(reading begins at index 0)
 * 2. Length == tuple_size * vreg->fuse_combos_supported
 *	(reading begins at index tuple_size * vreg->fuse_combo)
 * 3. Length == tuple_size * vreg->speed_bins_supported
 *	(reading begins at index tuple_size * vreg->speed_bin_fuse)
 *
 * All other property lengths are treated as errors.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_array_property(struct cpr3_regulator *vreg,
		const char *prop_name, int tuple_size, u32 *out)
{
	struct device_node *node = vreg->of_node;
	int len = 0;
	int i, offset, rc;

	if (!of_find_property(node, prop_name, &len)) {
		cpr3_err(vreg, "property %s is missing\n", prop_name);
		return -EINVAL;
	}

	if (len == tuple_size * sizeof(u32)) {
		offset = 0;
	} else if (len == tuple_size * vreg->fuse_combos_supported
				     * sizeof(u32)) {
		offset = tuple_size * vreg->fuse_combo;
	} else if (vreg->speed_bins_supported > 0 &&
		 len == tuple_size * vreg->speed_bins_supported * sizeof(u32)) {
		offset = tuple_size * vreg->speed_bin_fuse;
	} else {
		if (vreg->speed_bins_supported > 0)
			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
				prop_name, len,
				tuple_size * sizeof(u32),
				tuple_size * vreg->speed_bins_supported
					   * sizeof(u32),
				tuple_size * vreg->fuse_combos_supported
					   * sizeof(u32));
		else
			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
				prop_name, len,
				tuple_size * sizeof(u32),
				tuple_size * vreg->fuse_combos_supported
					   * sizeof(u32));
		return -EINVAL;
	}

	for (i = 0; i < tuple_size; i++) {
		rc = of_property_read_u32_index(node, prop_name, offset + i,
						&out[i]);
		if (rc) {
			cpr3_err(vreg, "error reading property %s, rc=%d\n",
				prop_name, rc);
			return rc;
		}
	}

	return 0;
}

/**
 * cpr3_parse_corner_array_property() - fill a per-corner array from a portion
 *		of the values specified for a device tree property
 * @vreg:		Pointer to the CPR3 regulator
 * @prop_name:		The name of the device tree property to read from
 * @tuple_size:		The number of elements in each per-corner tuple
 * @out:		Output data array which must be of size:
 *			tuple_size * vreg->corner_count
 *
 * cpr3_parse_common_corner_data() must be called for vreg before this function
 * is called so that fuse combo and speed bin size elements are initialized.
 *
 * Three formats are supported for the device tree property:
 * 1. Length == tuple_size * vreg->corner_count
 *	(reading begins at index 0)
 * 2. Length == tuple_size * vreg->fuse_combo_corner_sum
 *	(reading begins at index tuple_size * vreg->fuse_combo_offset)
 * 3. Length == tuple_size * vreg->speed_bin_corner_sum
 *	(reading begins at index tuple_size * vreg->speed_bin_offset)
 *
 * All other property lengths are treated as errors.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_corner_array_property(struct cpr3_regulator *vreg,
		const char *prop_name, int tuple_size, u32 *out)
{
	struct device_node *node = vreg->of_node;
	int len = 0;
	int i, offset, rc;

	if (!of_find_property(node, prop_name, &len)) {
		cpr3_err(vreg, "property %s is missing\n", prop_name);
		return -EINVAL;
	}

	if (len == tuple_size * vreg->corner_count * sizeof(u32)) {
		offset = 0;
	} else if (len == tuple_size * vreg->fuse_combo_corner_sum
				     * sizeof(u32)) {
		offset = tuple_size * vreg->fuse_combo_offset;
	} else if (vreg->speed_bin_corner_sum > 0 &&
		 len == tuple_size * vreg->speed_bin_corner_sum * sizeof(u32)) {
		offset = tuple_size * vreg->speed_bin_offset;
	} else {
		if (vreg->speed_bin_corner_sum > 0)
			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
				prop_name, len,
				tuple_size * vreg->corner_count * sizeof(u32),
				tuple_size * vreg->speed_bin_corner_sum
					   * sizeof(u32),
				tuple_size * vreg->fuse_combo_corner_sum
					   * sizeof(u32));
		else
			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
				prop_name, len,
				tuple_size * vreg->corner_count * sizeof(u32),
				tuple_size * vreg->fuse_combo_corner_sum
					   * sizeof(u32));
		return -EINVAL;
	}

	for (i = 0; i < tuple_size * vreg->corner_count; i++) {
		rc = of_property_read_u32_index(node, prop_name, offset + i,
						&out[i]);
		if (rc) {
			cpr3_err(vreg, "error reading property %s, rc=%d\n",
				prop_name, rc);
			return rc;
		}
	}

	return 0;
}

/**
 * cpr3_parse_corner_band_array_property() - fill a per-corner band array
 *		from a portion of the values specified for a device tree
 *		property
 * @vreg:		Pointer to the CPR3 regulator
 * @prop_name:		The name of the device tree property to read from
 * @tuple_size:		The number of elements in each per-corner band tuple
 * @out:		Output data array which must be of size:
 *			tuple_size * vreg->corner_band_count
 *
 * cpr3_parse_common_corner_data() must be called for vreg before this function
 * is called so that fuse combo and speed bin size elements are initialized.
 * In addition, corner band fuse combo and speed bin sum and offset elements
 * must be initialized prior to executing this function.
 *
 * Three formats are supported for the device tree property:
 * 1. Length == tuple_size * vreg->corner_band_count
 *	(reading begins at index 0)
 * 2. Length == tuple_size * vreg->fuse_combo_corner_band_sum
 *	(reading begins at index tuple_size *
 *		vreg->fuse_combo_corner_band_offset)
 * 3. Length == tuple_size * vreg->speed_bin_corner_band_sum
 *	(reading begins at index tuple_size *
 *		vreg->speed_bin_corner_band_offset)
 *
 * All other property lengths are treated as errors.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_corner_band_array_property(struct cpr3_regulator *vreg,
		const char *prop_name, int tuple_size, u32 *out)
{
	struct device_node *node = vreg->of_node;
	int len = 0;
	int i, offset, rc;

	if (!of_find_property(node, prop_name, &len)) {
		cpr3_err(vreg, "property %s is missing\n", prop_name);
		return -EINVAL;
	}

	if (len == tuple_size * vreg->corner_band_count * sizeof(u32)) {
		offset = 0;
	} else if (len == tuple_size * vreg->fuse_combo_corner_band_sum
				     * sizeof(u32)) {
		offset = tuple_size * vreg->fuse_combo_corner_band_offset;
	} else if (vreg->speed_bin_corner_band_sum > 0 &&
		 len == tuple_size * vreg->speed_bin_corner_band_sum *
		   sizeof(u32)) {
		offset = tuple_size * vreg->speed_bin_corner_band_offset;
	} else {
		if (vreg->speed_bin_corner_band_sum > 0)
			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
				prop_name, len,
				tuple_size * vreg->corner_band_count *
				 sizeof(u32),
				tuple_size * vreg->speed_bin_corner_band_sum
					   * sizeof(u32),
				tuple_size * vreg->fuse_combo_corner_band_sum
					   * sizeof(u32));
		else
			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
				prop_name, len,
				tuple_size * vreg->corner_band_count *
				 sizeof(u32),
				tuple_size * vreg->fuse_combo_corner_band_sum
					   * sizeof(u32));
		return -EINVAL;
	}

	for (i = 0; i < tuple_size * vreg->corner_band_count; i++) {
		rc = of_property_read_u32_index(node, prop_name, offset + i,
						&out[i]);
		if (rc) {
			cpr3_err(vreg, "error reading property %s, rc=%d\n",
				prop_name, rc);
			return rc;
		}
	}

	return 0;
}

/**
 * cpr3_parse_common_corner_data() - parse common CPR3 properties relating to
 *		the corners supported by a CPR3 regulator from device tree
 * @vreg:		Pointer to the CPR3 regulator
 *
 * This function reads, validates, and utilizes the following device tree
 * properties: qcom,cpr-fuse-corners, qcom,cpr-fuse-combos, qcom,cpr-speed-bins,
 * qcom,cpr-speed-bin-corners, qcom,cpr-corners, qcom,cpr-voltage-ceiling,
 * qcom,cpr-voltage-floor, qcom,corner-frequencies,
 * and qcom,cpr-corner-fmax-map.
 *
 * It initializes these CPR3 regulator elements: corner, corner_count,
 * fuse_combos_supported, fuse_corner_map, and speed_bins_supported.  It
 * initializes these elements for each corner: ceiling_volt, floor_volt,
 * proc_freq, and cpr_fuse_corner.
 *
 * It requires that the following CPR3 regulator elements be initialized before
 * being called: fuse_corner_count, fuse_combo, and speed_bin_fuse.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg)
{
	struct device_node *node = vreg->of_node;
	struct cpr3_controller *ctrl = vreg->thread->ctrl;
	u32 max_fuse_combos, fuse_corners, aging_allowed = 0;
	u32 max_speed_bins = 0;
	u32 *combo_corners;
	u32 *speed_bin_corners;
	u32 *temp;
	int i, j, rc;

	rc = of_property_read_u32(node, "qcom,cpr-fuse-corners", &fuse_corners);
	if (rc) {
		cpr3_err(vreg, "error reading property qcom,cpr-fuse-corners, rc=%d\n",
			rc);
		return rc;
	}

	if (vreg->fuse_corner_count != fuse_corners) {
		cpr3_err(vreg, "device tree config supports %d fuse corners but the hardware has %d fuse corners\n",
			fuse_corners, vreg->fuse_corner_count);
		return -EINVAL;
	}

	/*
	 * Check if CPR3 regulator's fuse_combos_supported element is already
	 * populated by fuse-combo-map logic. If not populated, then parse the
	 * qcom,cpr-fuse-combos property.
	 */
	if (vreg->fuse_combos_supported)
		max_fuse_combos = vreg->fuse_combos_supported;
	else {
		rc = of_property_read_u32(node, "qcom,cpr-fuse-combos",
					&max_fuse_combos);
		if (rc) {
			cpr3_err(vreg, "error reading property qcom,cpr-fuse-combos, rc=%d\n",
				rc);
			return rc;
		}

		/*
		 * Sanity check against arbitrarily large value to avoid
		 * excessive memory allocation.
		 */
		if (max_fuse_combos > 100 || max_fuse_combos == 0) {
			cpr3_err(vreg, "qcom,cpr-fuse-combos is invalid: %u\n",
				max_fuse_combos);
			return -EINVAL;
		}

		if (vreg->fuse_combo >= max_fuse_combos) {
			cpr3_err(vreg, "device tree config supports fuse combos 0-%u but the hardware has combo %d\n",
				max_fuse_combos - 1, vreg->fuse_combo);
			WARN_ON(1);
			return -EINVAL;
		}

		vreg->fuse_combos_supported = max_fuse_combos;
	}

	of_property_read_u32(node, "qcom,cpr-speed-bins", &max_speed_bins);

	/*
	 * Sanity check against arbitrarily large value to avoid excessive
	 * memory allocation.
	 */
	if (max_speed_bins > 100) {
		cpr3_err(vreg, "qcom,cpr-speed-bins is invalid: %u\n",
			max_speed_bins);
		return -EINVAL;
	}

	if (max_speed_bins && vreg->speed_bin_fuse >= max_speed_bins) {
		cpr3_err(vreg, "device tree config supports speed bins 0-%u but the hardware has speed bin %d\n",
			max_speed_bins - 1, vreg->speed_bin_fuse);
		BUG();
		return -EINVAL;
	}

	vreg->speed_bins_supported = max_speed_bins;

	combo_corners = kcalloc(vreg->fuse_combos_supported,
				sizeof(*combo_corners), GFP_KERNEL);
	if (!combo_corners)
		return -ENOMEM;

	rc = of_property_read_u32_array(node, "qcom,cpr-corners", combo_corners,
					vreg->fuse_combos_supported);
	if (rc == -EOVERFLOW) {
		/* Single value case */
		rc = of_property_read_u32(node, "qcom,cpr-corners",
					combo_corners);
		for (i = 1; i < vreg->fuse_combos_supported; i++)
			combo_corners[i] = combo_corners[0];
	}
	if (rc) {
		cpr3_err(vreg, "error reading property qcom,cpr-corners, rc=%d\n",
			rc);
		kfree(combo_corners);
		return rc;
	}

	vreg->fuse_combo_offset = 0;
	vreg->fuse_combo_corner_sum = 0;
	for (i = 0; i < vreg->fuse_combos_supported; i++) {
		vreg->fuse_combo_corner_sum += combo_corners[i];
		if (i < vreg->fuse_combo)
			vreg->fuse_combo_offset += combo_corners[i];
	}

	vreg->corner_count = combo_corners[vreg->fuse_combo];

	kfree(combo_corners);

	vreg->speed_bin_offset = 0;
	vreg->speed_bin_corner_sum = 0;
	if (vreg->speed_bins_supported > 0) {
		speed_bin_corners = kcalloc(vreg->speed_bins_supported,
					sizeof(*speed_bin_corners), GFP_KERNEL);
		if (!speed_bin_corners)
			return -ENOMEM;

		rc = of_property_read_u32_array(node,
				"qcom,cpr-speed-bin-corners", speed_bin_corners,
				vreg->speed_bins_supported);
		if (rc) {
			cpr3_err(vreg, "error reading property qcom,cpr-speed-bin-corners, rc=%d\n",
				rc);
			kfree(speed_bin_corners);
			return rc;
		}

		for (i = 0; i < vreg->speed_bins_supported; i++) {
			vreg->speed_bin_corner_sum += speed_bin_corners[i];
			if (i < vreg->speed_bin_fuse)
				vreg->speed_bin_offset += speed_bin_corners[i];
		}

		if (speed_bin_corners[vreg->speed_bin_fuse]
		    != vreg->corner_count) {
			cpr3_err(vreg, "qcom,cpr-corners and qcom,cpr-speed-bin-corners conflict on number of corners: %d vs %u\n",
				vreg->corner_count,
				speed_bin_corners[vreg->speed_bin_fuse]);
			kfree(speed_bin_corners);
			return -EINVAL;
		}

		kfree(speed_bin_corners);
	}

	/*
	 * For CPRh compliant controllers two additional corners are
	 * allocated to correspond to the APM crossover voltage and the MEM ACC
	 * crossover voltage.
	 */
	vreg->corner = devm_kcalloc(ctrl->dev, ctrl->ctrl_type ==
				    CPR_CTRL_TYPE_CPRH ?
				    vreg->corner_count + 2 :
				    vreg->corner_count,
				    sizeof(*vreg->corner), GFP_KERNEL);
	temp = kcalloc(vreg->corner_count, sizeof(*temp), GFP_KERNEL);
	if (!vreg->corner || !temp)
		return -ENOMEM;

	rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-ceiling",
			1, temp);
	if (rc)
		goto free_temp;
	for (i = 0; i < vreg->corner_count; i++) {
		vreg->corner[i].ceiling_volt
			= CPR3_ROUND(temp[i], ctrl->step_volt);
		vreg->corner[i].abs_ceiling_volt = vreg->corner[i].ceiling_volt;
	}

	rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-floor",
			1, temp);
	if (rc)
		goto free_temp;
	for (i = 0; i < vreg->corner_count; i++)
		vreg->corner[i].floor_volt
			= CPR3_ROUND(temp[i], ctrl->step_volt);

	/* Validate ceiling and floor values */
	for (i = 0; i < vreg->corner_count; i++) {
		if (vreg->corner[i].floor_volt
		    > vreg->corner[i].ceiling_volt) {
			cpr3_err(vreg, "CPR floor[%d]=%d > ceiling[%d]=%d uV\n",
				i, vreg->corner[i].floor_volt,
				i, vreg->corner[i].ceiling_volt);
			rc = -EINVAL;
			goto free_temp;
		}
	}

	/* Load optional system-supply voltages */
	if (of_find_property(vreg->of_node, "qcom,system-voltage", NULL)) {
		rc = cpr3_parse_corner_array_property(vreg,
			"qcom,system-voltage", 1, temp);
		if (rc)
			goto free_temp;
		for (i = 0; i < vreg->corner_count; i++)
			vreg->corner[i].system_volt = temp[i];
	}

	rc = cpr3_parse_corner_array_property(vreg, "qcom,corner-frequencies",
			1, temp);
	if (rc)
		goto free_temp;
	for (i = 0; i < vreg->corner_count; i++)
		vreg->corner[i].proc_freq = temp[i];

	/* Validate frequencies */
	for (i = 1; i < vreg->corner_count; i++) {
		if (vreg->corner[i].proc_freq
		    < vreg->corner[i - 1].proc_freq) {
			cpr3_err(vreg, "invalid frequency: freq[%d]=%u < freq[%d]=%u\n",
				i, vreg->corner[i].proc_freq, i - 1,
				vreg->corner[i - 1].proc_freq);
			rc = -EINVAL;
			goto free_temp;
		}
	}

	vreg->fuse_corner_map = devm_kcalloc(ctrl->dev, vreg->fuse_corner_count,
				    sizeof(*vreg->fuse_corner_map), GFP_KERNEL);
	if (!vreg->fuse_corner_map) {
		rc = -ENOMEM;
		goto free_temp;
	}

	rc = cpr3_parse_array_property(vreg, "qcom,cpr-corner-fmax-map",
		vreg->fuse_corner_count, temp);
	if (rc)
		goto free_temp;
	for (i = 0; i < vreg->fuse_corner_count; i++) {
		vreg->fuse_corner_map[i] = temp[i] - CPR3_CORNER_OFFSET;
		if (temp[i] < CPR3_CORNER_OFFSET
		    || temp[i] > vreg->corner_count + CPR3_CORNER_OFFSET) {
			cpr3_err(vreg, "invalid corner value specified in qcom,cpr-corner-fmax-map: %u\n",
				temp[i]);
			rc = -EINVAL;
			goto free_temp;
		} else if (i > 0 && temp[i - 1] >= temp[i]) {
			cpr3_err(vreg, "invalid corner %u less than or equal to previous corner %u\n",
				temp[i], temp[i - 1]);
			rc = -EINVAL;
			goto free_temp;
		}
	}
	if (temp[vreg->fuse_corner_count - 1] != vreg->corner_count)
		cpr3_debug(vreg, "Note: highest Fmax corner %u in qcom,cpr-corner-fmax-map does not match highest supported corner %d\n",
			temp[vreg->fuse_corner_count - 1],
			vreg->corner_count);

	for (i = 0; i < vreg->corner_count; i++) {
		for (j = 0; j < vreg->fuse_corner_count; j++) {
			if (i + CPR3_CORNER_OFFSET <= temp[j]) {
				vreg->corner[i].cpr_fuse_corner = j;
				break;
			}
		}
		if (j == vreg->fuse_corner_count) {
			/*
			 * Handle the case where the highest fuse corner maps
			 * to a corner below the highest corner.
			 */
			vreg->corner[i].cpr_fuse_corner
				= vreg->fuse_corner_count - 1;
		}
	}

	if (of_find_property(vreg->of_node,
				"qcom,allow-aging-voltage-adjustment", NULL)) {
		rc = cpr3_parse_array_property(vreg,
			"qcom,allow-aging-voltage-adjustment",
			1, &aging_allowed);
		if (rc)
			goto free_temp;

		vreg->aging_allowed = aging_allowed;
	}

	if (of_find_property(vreg->of_node,
		       "qcom,allow-aging-open-loop-voltage-adjustment", NULL)) {
		rc = cpr3_parse_array_property(vreg,
			"qcom,allow-aging-open-loop-voltage-adjustment",
			1, &aging_allowed);
		if (rc)
			goto free_temp;

		vreg->aging_allow_open_loop_adj = aging_allowed;
	}

	if (vreg->aging_allowed) {
		if (ctrl->aging_ref_volt <= 0) {
			cpr3_err(ctrl, "qcom,cpr-aging-ref-voltage must be specified\n");
			rc = -EINVAL;
			goto free_temp;
		}

		rc = cpr3_parse_array_property(vreg,
			"qcom,cpr-aging-max-voltage-adjustment",
			1, &vreg->aging_max_adjust_volt);
		if (rc)
			goto free_temp;

		rc = cpr3_parse_array_property(vreg,
			"qcom,cpr-aging-ref-corner", 1, &vreg->aging_corner);
		if (rc) {
			goto free_temp;
		} else if (vreg->aging_corner < CPR3_CORNER_OFFSET
			   || vreg->aging_corner > vreg->corner_count - 1
							+ CPR3_CORNER_OFFSET) {
			cpr3_err(vreg, "aging reference corner=%d not in range [%d, %d]\n",
				vreg->aging_corner, CPR3_CORNER_OFFSET,
				vreg->corner_count - 1 + CPR3_CORNER_OFFSET);
			rc = -EINVAL;
			goto free_temp;
		}
		vreg->aging_corner -= CPR3_CORNER_OFFSET;

		if (of_find_property(vreg->of_node, "qcom,cpr-aging-derate",
					NULL)) {
			rc = cpr3_parse_corner_array_property(vreg,
				"qcom,cpr-aging-derate", 1, temp);
			if (rc)
				goto free_temp;

			for (i = 0; i < vreg->corner_count; i++)
				vreg->corner[i].aging_derate = temp[i];
		} else {
			for (i = 0; i < vreg->corner_count; i++)
				vreg->corner[i].aging_derate
					= CPR3_AGING_DERATE_UNITY;
		}
	}

free_temp:
	kfree(temp);
	return rc;
}

/**
 * cpr3_parse_thread_u32() - parse the specified property from the CPR3 thread's
 *		device tree node and verify that it is within the allowed limits
 * @thread:		Pointer to the CPR3 thread
 * @propname:		The name of the device tree property to read
 * @out_value:		The output pointer to fill with the value read
 * @value_min:		The minimum allowed property value
 * @value_max:		The maximum allowed property value
 *
 * This function prints a verbose error message if the property is missing or
 * has a value which is not within the specified range.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_thread_u32(struct cpr3_thread *thread, const char *propname,
		       u32 *out_value, u32 value_min, u32 value_max)
{
	int rc;

	rc = of_property_read_u32(thread->of_node, propname, out_value);
	if (rc) {
		cpr3_err(thread->ctrl, "thread %u error reading property %s, rc=%d\n",
			thread->thread_id, propname, rc);
		return rc;
	}

	if (*out_value < value_min || *out_value > value_max) {
		cpr3_err(thread->ctrl, "thread %u %s=%u is invalid; allowed range: [%u, %u]\n",
			thread->thread_id, propname, *out_value, value_min,
			value_max);
		return -EINVAL;
	}

	return 0;
}

/**
 * cpr3_parse_ctrl_u32() - parse the specified property from the CPR3
 *		controller's device tree node and verify that it is within the
 *		allowed limits
 * @ctrl:		Pointer to the CPR3 controller
 * @propname:		The name of the device tree property to read
 * @out_value:		The output pointer to fill with the value read
 * @value_min:		The minimum allowed property value
 * @value_max:		The maximum allowed property value
 *
 * This function prints a verbose error message if the property is missing or
 * has a value which is not within the specified range.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_ctrl_u32(struct cpr3_controller *ctrl, const char *propname,
		       u32 *out_value, u32 value_min, u32 value_max)
{
	int rc;

	rc = of_property_read_u32(ctrl->dev->of_node, propname, out_value);
	if (rc) {
		cpr3_err(ctrl, "error reading property %s, rc=%d\n",
			propname, rc);
		return rc;
	}

	if (*out_value < value_min || *out_value > value_max) {
		cpr3_err(ctrl, "%s=%u is invalid; allowed range: [%u, %u]\n",
			propname, *out_value, value_min, value_max);
		return -EINVAL;
	}

	return 0;
}

/**
 * cpr3_parse_common_thread_data() - parse common CPR3 thread properties from
 *		device tree
 * @thread:		Pointer to the CPR3 thread
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_common_thread_data(struct cpr3_thread *thread)
{
	int rc;

	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-consecutive-up",
			&thread->consecutive_up, CPR3_CONSECUTIVE_UP_DOWN_MIN,
			CPR3_CONSECUTIVE_UP_DOWN_MAX);
	if (rc)
		return rc;

	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-consecutive-down",
			&thread->consecutive_down, CPR3_CONSECUTIVE_UP_DOWN_MIN,
			CPR3_CONSECUTIVE_UP_DOWN_MAX);
	if (rc)
		return rc;

	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-up-threshold",
			&thread->up_threshold, CPR3_UP_DOWN_THRESHOLD_MIN,
			CPR3_UP_DOWN_THRESHOLD_MAX);
	if (rc)
		return rc;

	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-down-threshold",
			&thread->down_threshold, CPR3_UP_DOWN_THRESHOLD_MIN,
			CPR3_UP_DOWN_THRESHOLD_MAX);
	if (rc)
		return rc;

	return rc;
}

/**
 * cpr3_parse_irq_affinity() - parse CPR IRQ affinity information
 * @ctrl:		Pointer to the CPR3 controller
 *
 * Return: 0 on success, errno on failure
 */
static int cpr3_parse_irq_affinity(struct cpr3_controller *ctrl)
{
	struct device_node *cpu_node;
	int i, cpu;
	int len = 0;

	if (!of_find_property(ctrl->dev->of_node, "qcom,cpr-interrupt-affinity",
				&len)) {
		/* No IRQ affinity required */
		return 0;
	}

	len /= sizeof(u32);

	for (i = 0; i < len; i++) {
		cpu_node = of_parse_phandle(ctrl->dev->of_node,
					    "qcom,cpr-interrupt-affinity", i);
		if (!cpu_node) {
			cpr3_err(ctrl, "could not find CPU node %d\n", i);
			return -EINVAL;
		}

		for_each_possible_cpu(cpu) {
			if (of_get_cpu_node(cpu, NULL) == cpu_node) {
				cpumask_set_cpu(cpu, &ctrl->irq_affinity_mask);
				break;
			}
		}
		of_node_put(cpu_node);
	}

	return 0;
}

static int cpr3_panic_notifier_init(struct cpr3_controller *ctrl)
{
	struct device_node *node = ctrl->dev->of_node;
	struct cpr3_panic_regs_info *panic_regs_info;
	struct cpr3_reg_info *regs;
	int i, reg_count, len, rc = 0;

	if (!of_find_property(node, "qcom,cpr-panic-reg-addr-list", &len)) {
		/* panic register address list not specified */
		return rc;
	}

	reg_count = len / sizeof(u32);
	if (!reg_count) {
		cpr3_err(ctrl, "qcom,cpr-panic-reg-addr-list has invalid len = %d\n",
			len);
		return -EINVAL;
	}

	if (!of_find_property(node, "qcom,cpr-panic-reg-name-list", NULL)) {
		cpr3_err(ctrl, "property qcom,cpr-panic-reg-name-list not specified\n");
		return -EINVAL;
	}

	len = of_property_count_strings(node, "qcom,cpr-panic-reg-name-list");
	if (reg_count != len) {
		cpr3_err(ctrl, "qcom,cpr-panic-reg-name-list should have %d strings\n",
			reg_count);
		return -EINVAL;
	}

	panic_regs_info = devm_kzalloc(ctrl->dev, sizeof(*panic_regs_info),
					GFP_KERNEL);
	if (!panic_regs_info)
		return -ENOMEM;

	regs = devm_kcalloc(ctrl->dev, reg_count, sizeof(*regs), GFP_KERNEL);
	if (!regs)
		return -ENOMEM;

	for (i = 0; i < reg_count; i++) {
		rc = of_property_read_string_index(node,
				"qcom,cpr-panic-reg-name-list", i,
				&(regs[i].name));
		if (rc) {
			cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-name-list, rc=%d\n",
				rc);
			return rc;
		}

		rc = of_property_read_u32_index(node,
				"qcom,cpr-panic-reg-addr-list", i,
				&(regs[i].addr));
		if (rc) {
			cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-addr-list, rc=%d\n",
				rc);
			return rc;
		}
		regs[i].virt_addr = devm_ioremap(ctrl->dev, regs[i].addr, 0x4);
		if (!regs[i].virt_addr) {
			pr_err("Unable to map panic register addr 0x%08x\n",
				regs[i].addr);
			return -EINVAL;
		}
		regs[i].value = 0xFFFFFFFF;
	}

	panic_regs_info->reg_count = reg_count;
	panic_regs_info->regs = regs;
	ctrl->panic_regs_info = panic_regs_info;

	return rc;
}

/**
 * cpr3_parse_common_ctrl_data() - parse common CPR3 controller properties from
 *		device tree
 * @ctrl:		Pointer to the CPR3 controller
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl)
{
	int rc;

	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-sensor-time",
			&ctrl->sensor_time, 0, UINT_MAX);
	if (rc)
		return rc;

	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-loop-time",
			&ctrl->loop_time, 0, UINT_MAX);
	if (rc)
		return rc;

	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-idle-cycles",
			&ctrl->idle_clocks, CPR3_IDLE_CLOCKS_MIN,
			CPR3_IDLE_CLOCKS_MAX);
	if (rc)
		return rc;

	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-step-quot-init-min",
			&ctrl->step_quot_init_min, CPR3_STEP_QUOT_MIN,
			CPR3_STEP_QUOT_MAX);
	if (rc)
		return rc;

	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-step-quot-init-max",
			&ctrl->step_quot_init_max, CPR3_STEP_QUOT_MIN,
			CPR3_STEP_QUOT_MAX);
	if (rc)
		return rc;

	rc = of_property_read_u32(ctrl->dev->of_node, "qcom,voltage-step",
				&ctrl->step_volt);
	if (rc) {
		cpr3_err(ctrl, "error reading property qcom,voltage-step, rc=%d\n",
			rc);
		return rc;
	}
	if (ctrl->step_volt <= 0) {
		cpr3_err(ctrl, "qcom,voltage-step=%d is invalid\n",
			ctrl->step_volt);
		return -EINVAL;
	}

	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-count-mode",
			&ctrl->count_mode, CPR3_COUNT_MODE_ALL_AT_ONCE_MIN,
			CPR3_COUNT_MODE_STAGGERED);
	if (rc)
		return rc;

	/* Count repeat is optional */
	ctrl->count_repeat = 0;
	of_property_read_u32(ctrl->dev->of_node, "qcom,cpr-count-repeat",
			&ctrl->count_repeat);

	ctrl->cpr_allowed_sw = of_property_read_bool(ctrl->dev->of_node,
			"qcom,cpr-enable");

	rc = cpr3_parse_irq_affinity(ctrl);
	if (rc)
		return rc;

	ctrl->ignore_invalid_fuses = of_property_read_bool(ctrl->dev->of_node,
				"qcom,cpr-ignore-invalid-fuses");

	/* Aging reference voltage is optional */
	ctrl->aging_ref_volt = 0;
	of_property_read_u32(ctrl->dev->of_node, "qcom,cpr-aging-ref-voltage",
			&ctrl->aging_ref_volt);

	/* Aging possible bitmask is optional */
	ctrl->aging_possible_mask = 0;
	of_property_read_u32(ctrl->dev->of_node,
			"qcom,cpr-aging-allowed-reg-mask",
			&ctrl->aging_possible_mask);

	if (ctrl->aging_possible_mask) {
		/*
		 * Aging possible register value required if bitmask is
		 * specified
		 */
		rc = cpr3_parse_ctrl_u32(ctrl,
				"qcom,cpr-aging-allowed-reg-value",
				&ctrl->aging_possible_val, 0, UINT_MAX);
		if (rc)
			return rc;
	}

	if (of_find_property(ctrl->dev->of_node, "clock-names", NULL)) {
		ctrl->core_clk = devm_clk_get(ctrl->dev, "core_clk");
		if (IS_ERR(ctrl->core_clk)) {
			rc = PTR_ERR(ctrl->core_clk);
			if (rc != -EPROBE_DEFER)
				cpr3_err(ctrl, "unable request core clock, rc=%d\n",
				rc);
			return rc;
		}
	}

	rc = cpr3_panic_notifier_init(ctrl);
	if (rc)
		return rc;

	if (of_find_property(ctrl->dev->of_node, "vdd-supply", NULL)) {
		ctrl->vdd_regulator = devm_regulator_get(ctrl->dev, "vdd");
		if (IS_ERR(ctrl->vdd_regulator)) {
			rc = PTR_ERR(ctrl->vdd_regulator);
			if (rc != -EPROBE_DEFER)
				cpr3_err(ctrl, "unable to request vdd regulator, rc=%d\n",
					 rc);
			return rc;
		}
	} else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPRH) {
		/* vdd-supply is optional for CPRh controllers. */
		ctrl->vdd_regulator = NULL;
	} else {
		cpr3_err(ctrl, "vdd supply is not defined\n");
		return -ENODEV;
	}

	/*
	 * Reset step_quot to default on each loop_en = 0 transition is
	 * optional.
	 */
	ctrl->reset_step_quot_loop_en
		= of_property_read_bool(ctrl->dev->of_node,
					"qcom,cpr-reset-step-quot-loop-en");

	/*
	 * Configure CPR controller to not consider MID/DN recommendations
	 * from other thread when all sensors mapped to a thread collapsed
	 * in a multi-thread configuration.
	 */
	if (ctrl->thread_count > 1)
		ctrl->thread_has_always_vote_en
			= of_property_read_bool(ctrl->dev->of_node,
					"qcom,cpr-thread-has-always-vote-en");

	/*
	 * Regulator device handles are not necessary for CPRh controllers
	 * since communication with the regulators is completely managed
	 * in hardware.
	 */
	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPRH)
		return rc;

	ctrl->system_regulator = devm_regulator_get_optional(ctrl->dev,
								"system");
	if (IS_ERR(ctrl->system_regulator)) {
		rc = PTR_ERR(ctrl->system_regulator);
		if (rc != -EPROBE_DEFER) {
			rc = 0;
			ctrl->system_regulator = NULL;
		} else {
			return rc;
		}
	}

	ctrl->mem_acc_regulator = devm_regulator_get_optional(ctrl->dev,
							      "mem-acc");
	if (IS_ERR(ctrl->mem_acc_regulator)) {
		rc = PTR_ERR(ctrl->mem_acc_regulator);
		if (rc != -EPROBE_DEFER) {
			rc = 0;
			ctrl->mem_acc_regulator = NULL;
		} else {
			return rc;
		}
	}

	return rc;
}

/**
 * cpr3_limit_open_loop_voltages() - modify the open-loop voltage of each corner
 *				so that it fits within the floor to ceiling
 *				voltage range of the corner
 * @vreg:		Pointer to the CPR3 regulator
 *
 * This function clips the open-loop voltage for each corner so that it is
 * limited to the floor to ceiling range.  It also rounds each open-loop voltage
 * so that it corresponds to a set point available to the underlying regulator.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg)
{
	int i, volt;

	cpr3_debug(vreg, "open-loop voltages after trimming and rounding:\n");
	for (i = 0; i < vreg->corner_count; i++) {
		volt = CPR3_ROUND(vreg->corner[i].open_loop_volt,
					vreg->thread->ctrl->step_volt);
		if (volt < vreg->corner[i].floor_volt)
			volt = vreg->corner[i].floor_volt;
		else if (volt > vreg->corner[i].ceiling_volt)
			volt = vreg->corner[i].ceiling_volt;
		vreg->corner[i].open_loop_volt = volt;
		cpr3_debug(vreg, "corner[%2d]: open-loop=%d uV\n", i, volt);
	}

	return 0;
}

/**
 * cpr3_open_loop_voltage_as_ceiling() - configures the ceiling voltage for each
 *		corner to equal the open-loop voltage if the relevant device
 *		tree property is found for the CPR3 regulator
 * @vreg:		Pointer to the CPR3 regulator
 *
 * This function assumes that the the open-loop voltage for each corner has
 * already been rounded to the nearest allowed set point and that it falls
 * within the floor to ceiling range.
 *
 * Return: none
 */
void cpr3_open_loop_voltage_as_ceiling(struct cpr3_regulator *vreg)
{
	int i;

	if (!of_property_read_bool(vreg->of_node,
				"qcom,cpr-scaled-open-loop-voltage-as-ceiling"))
		return;

	for (i = 0; i < vreg->corner_count; i++)
		vreg->corner[i].ceiling_volt
			= vreg->corner[i].open_loop_volt;
}

/**
 * cpr3_limit_floor_voltages() - raise the floor voltage of each corner so that
 *		the optional maximum floor to ceiling voltage range specified in
 *		device tree is satisfied
 * @vreg:		Pointer to the CPR3 regulator
 *
 * This function also ensures that the open-loop voltage for each corner falls
 * within the final floor to ceiling voltage range and that floor voltages
 * increase monotonically.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg)
{
	char *prop = "qcom,cpr-floor-to-ceiling-max-range";
	int i, floor_new;
	u32 *floor_range;
	int rc = 0;

	if (!of_find_property(vreg->of_node, prop, NULL))
		goto enforce_monotonicity;

	floor_range = kcalloc(vreg->corner_count, sizeof(*floor_range),
				GFP_KERNEL);
	if (!floor_range)
		return -ENOMEM;

	rc = cpr3_parse_corner_array_property(vreg, prop, 1, floor_range);
	if (rc)
		goto free_floor_adjust;

	for (i = 0; i < vreg->corner_count; i++) {
		if ((s32)floor_range[i] >= 0) {
			floor_new = CPR3_ROUND(vreg->corner[i].ceiling_volt
							- floor_range[i],
						vreg->thread->ctrl->step_volt);

			vreg->corner[i].floor_volt = max(floor_new,
						vreg->corner[i].floor_volt);
			if (vreg->corner[i].open_loop_volt
			    < vreg->corner[i].floor_volt)
				vreg->corner[i].open_loop_volt
					= vreg->corner[i].floor_volt;
		}
	}

free_floor_adjust:
	kfree(floor_range);

enforce_monotonicity:
	/* Ensure that floor voltages increase monotonically. */
	for (i = 1; i < vreg->corner_count; i++) {
		if (vreg->corner[i].floor_volt
		    < vreg->corner[i - 1].floor_volt) {
			cpr3_debug(vreg, "corner %d floor voltage=%d uV < corner %d voltage=%d uV; overriding: corner %d voltage=%d\n",
				i, vreg->corner[i].floor_volt,
				i - 1, vreg->corner[i - 1].floor_volt,
				i, vreg->corner[i - 1].floor_volt);
			vreg->corner[i].floor_volt
				= vreg->corner[i - 1].floor_volt;

			if (vreg->corner[i].open_loop_volt
			    < vreg->corner[i].floor_volt)
				vreg->corner[i].open_loop_volt
					= vreg->corner[i].floor_volt;
			if (vreg->corner[i].ceiling_volt
			    < vreg->corner[i].floor_volt)
				vreg->corner[i].ceiling_volt
					= vreg->corner[i].floor_volt;
		}
	}

	return rc;
}

/**
 * cpr3_print_quots() - print CPR target quotients into the kernel log for
 *		debugging purposes
 * @vreg:		Pointer to the CPR3 regulator
 *
 * Return: none
 */
void cpr3_print_quots(struct cpr3_regulator *vreg)
{
	int i, j, pos;
	size_t buflen;
	char *buf;

	buflen = sizeof(*buf) * CPR3_RO_COUNT * (MAX_CHARS_PER_INT + 2);
	buf = kzalloc(buflen, GFP_KERNEL);
	if (!buf)
		return;

	for (i = 0; i < vreg->corner_count; i++) {
		for (j = 0, pos = 0; j < CPR3_RO_COUNT; j++)
			pos += scnprintf(buf + pos, buflen - pos, " %u",
				vreg->corner[i].target_quot[j]);
		cpr3_debug(vreg, "target quots[%2d]:%s\n", i, buf);
	}

	kfree(buf);
}

/**
 * cpr3_adjust_fused_open_loop_voltages() - adjust the fused open-loop voltages
 *		for each fuse corner according to device tree values
 * @vreg:		Pointer to the CPR3 regulator
 * @fuse_volt:		Pointer to an array of the fused open-loop voltage
 *			values
 *
 * Voltage values in fuse_volt are modified in place.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_adjust_fused_open_loop_voltages(struct cpr3_regulator *vreg,
		int *fuse_volt)
{
	int i, rc, prev_volt;
	int *volt_adjust;

	if (!of_find_property(vreg->of_node,
			"qcom,cpr-open-loop-voltage-fuse-adjustment", NULL)) {
		/* No adjustment required. */
		return 0;
	}

	volt_adjust = kcalloc(vreg->fuse_corner_count, sizeof(*volt_adjust),
				GFP_KERNEL);
	if (!volt_adjust)
		return -ENOMEM;

	rc = cpr3_parse_array_property(vreg,
		"qcom,cpr-open-loop-voltage-fuse-adjustment",
		vreg->fuse_corner_count, volt_adjust);
	if (rc) {
		cpr3_err(vreg, "could not load open-loop fused voltage adjustments, rc=%d\n",
			rc);
		goto done;
	}

	for (i = 0; i < vreg->fuse_corner_count; i++) {
		if (volt_adjust[i]) {
			prev_volt = fuse_volt[i];
			fuse_volt[i] += volt_adjust[i];
			cpr3_debug(vreg, "adjusted fuse corner %d open-loop voltage: %d --> %d uV\n",
				i, prev_volt, fuse_volt[i]);
		}
	}

done:
	kfree(volt_adjust);
	return rc;
}

/**
 * cpr3_adjust_open_loop_voltages() - adjust the open-loop voltages for each
 *		corner according to device tree values
 * @vreg:		Pointer to the CPR3 regulator
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg)
{
	int i, rc, prev_volt, min_volt;
	int *volt_adjust, *volt_diff;

	if (!of_find_property(vreg->of_node,
			"qcom,cpr-open-loop-voltage-adjustment", NULL)) {
		/* No adjustment required. */
		return 0;
	}

	volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
				GFP_KERNEL);
	volt_diff = kcalloc(vreg->corner_count, sizeof(*volt_diff), GFP_KERNEL);
	if (!volt_adjust || !volt_diff) {
		rc = -ENOMEM;
		goto done;
	}

	rc = cpr3_parse_corner_array_property(vreg,
		"qcom,cpr-open-loop-voltage-adjustment", 1, volt_adjust);
	if (rc) {
		cpr3_err(vreg, "could not load open-loop voltage adjustments, rc=%d\n",
			rc);
		goto done;
	}

	for (i = 0; i < vreg->corner_count; i++) {
		if (volt_adjust[i]) {
			prev_volt = vreg->corner[i].open_loop_volt;
			vreg->corner[i].open_loop_volt += volt_adjust[i];
			cpr3_debug(vreg, "adjusted corner %d open-loop voltage: %d --> %d uV\n",
				i, prev_volt, vreg->corner[i].open_loop_volt);
		}
	}

	if (of_find_property(vreg->of_node,
			"qcom,cpr-open-loop-voltage-min-diff", NULL)) {
		rc = cpr3_parse_corner_array_property(vreg,
			"qcom,cpr-open-loop-voltage-min-diff", 1, volt_diff);
		if (rc) {
			cpr3_err(vreg, "could not load minimum open-loop voltage differences, rc=%d\n",
				rc);
			goto done;
		}
	}

	/*
	 * Ensure that open-loop voltages increase monotonically with respect
	 * to configurable minimum allowed differences.
	 */
	for (i = 1; i < vreg->corner_count; i++) {
		min_volt = vreg->corner[i - 1].open_loop_volt + volt_diff[i];
		if (vreg->corner[i].open_loop_volt < min_volt) {
			cpr3_debug(vreg, "adjusted corner %d open-loop voltage=%d uV < corner %d voltage=%d uV + min diff=%d uV; overriding: corner %d voltage=%d\n",
				i, vreg->corner[i].open_loop_volt,
				i - 1, vreg->corner[i - 1].open_loop_volt,
				volt_diff[i], i, min_volt);
			vreg->corner[i].open_loop_volt = min_volt;
		}
	}

done:
	kfree(volt_diff);
	kfree(volt_adjust);
	return rc;
}

/**
 * cpr3_quot_adjustment() - returns the quotient adjustment value resulting from
 *		the specified voltage adjustment and RO scaling factor
 * @ro_scale:		The CPR ring oscillator (RO) scaling factor with units
 *			of QUOT/V
 * @volt_adjust:	The amount to adjust the voltage by in units of
 *			microvolts.  This value may be positive or negative.
 */
int cpr3_quot_adjustment(int ro_scale, int volt_adjust)
{
	unsigned long long temp;
	int quot_adjust;
	int sign = 1;

	if (ro_scale < 0) {
		sign = -sign;
		ro_scale = -ro_scale;
	}

	if (volt_adjust < 0) {
		sign = -sign;
		volt_adjust = -volt_adjust;
	}

	temp = (unsigned long long)ro_scale * (unsigned long long)volt_adjust;
	do_div(temp, 1000000);

	quot_adjust = temp;
	quot_adjust *= sign;

	return quot_adjust;
}

/**
 * cpr3_voltage_adjustment() - returns the voltage adjustment value resulting
 *		from the specified quotient adjustment and RO scaling factor
 * @ro_scale:		The CPR ring oscillator (RO) scaling factor with units
 *			of QUOT/V
 * @quot_adjust:	The amount to adjust the quotient by in units of
 *			QUOT.  This value may be positive or negative.
 */
int cpr3_voltage_adjustment(int ro_scale, int quot_adjust)
{
	unsigned long long temp;
	int volt_adjust;
	int sign = 1;

	if (ro_scale < 0) {
		sign = -sign;
		ro_scale = -ro_scale;
	}

	if (quot_adjust < 0) {
		sign = -sign;
		quot_adjust = -quot_adjust;
	}

	if (ro_scale == 0)
		return 0;

	temp = (unsigned long long)quot_adjust * 1000000;
	do_div(temp, ro_scale);

	volt_adjust = temp;
	volt_adjust *= sign;

	return volt_adjust;
}

/**
 * cpr3_parse_closed_loop_voltage_adjustments() - load per-fuse-corner and
 *		per-corner closed-loop adjustment values from device tree
 * @vreg:		Pointer to the CPR3 regulator
 * @ro_sel:		Array of ring oscillator values selected for each
 *			fuse corner
 * @volt_adjust:	Pointer to array which will be filled with the
 *			per-corner closed-loop adjustment voltages
 * @volt_adjust_fuse:	Pointer to array which will be filled with the
 *			per-fuse-corner closed-loop adjustment voltages
 * @ro_scale:		Pointer to array which will be filled with the
 *			per-fuse-corner RO scaling factor values with units of
 *			QUOT/V
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_parse_closed_loop_voltage_adjustments(
			struct cpr3_regulator *vreg, u64 *ro_sel,
			int *volt_adjust, int *volt_adjust_fuse, int *ro_scale)
{
	int i, rc;
	u32 *ro_all_scale;

	if (!of_find_property(vreg->of_node,
			"qcom,cpr-closed-loop-voltage-adjustment", NULL)
	    && !of_find_property(vreg->of_node,
			"qcom,cpr-closed-loop-voltage-fuse-adjustment", NULL)
	    && !vreg->aging_allowed) {
		/* No adjustment required. */
		return 0;
	} else if (!of_find_property(vreg->of_node,
			"qcom,cpr-ro-scaling-factor", NULL)) {
		cpr3_err(vreg, "qcom,cpr-ro-scaling-factor is required for closed-loop voltage adjustment, but is missing\n");
		return -EINVAL;
	}

	ro_all_scale = kcalloc(vreg->fuse_corner_count * CPR3_RO_COUNT,
				sizeof(*ro_all_scale), GFP_KERNEL);
	if (!ro_all_scale)
		return -ENOMEM;

	rc = cpr3_parse_array_property(vreg, "qcom,cpr-ro-scaling-factor",
		vreg->fuse_corner_count * CPR3_RO_COUNT, ro_all_scale);
	if (rc) {
		cpr3_err(vreg, "could not load RO scaling factors, rc=%d\n",
			rc);
		goto done;
	}

	for (i = 0; i < vreg->fuse_corner_count; i++)
		ro_scale[i] = ro_all_scale[i * CPR3_RO_COUNT + ro_sel[i]];

	for (i = 0; i < vreg->corner_count; i++)
		memcpy(vreg->corner[i].ro_scale,
		 &ro_all_scale[vreg->corner[i].cpr_fuse_corner * CPR3_RO_COUNT],
		 sizeof(*ro_all_scale) * CPR3_RO_COUNT);

	if (of_find_property(vreg->of_node,
			"qcom,cpr-closed-loop-voltage-fuse-adjustment", NULL)) {
		rc = cpr3_parse_array_property(vreg,
			"qcom,cpr-closed-loop-voltage-fuse-adjustment",
			vreg->fuse_corner_count, volt_adjust_fuse);
		if (rc) {
			cpr3_err(vreg, "could not load closed-loop fused voltage adjustments, rc=%d\n",
				rc);
			goto done;
		}
	}

	if (of_find_property(vreg->of_node,
			"qcom,cpr-closed-loop-voltage-adjustment", NULL)) {
		rc = cpr3_parse_corner_array_property(vreg,
			"qcom,cpr-closed-loop-voltage-adjustment",
			1, volt_adjust);
		if (rc) {
			cpr3_err(vreg, "could not load closed-loop voltage adjustments, rc=%d\n",
				rc);
			goto done;
		}
	}

done:
	kfree(ro_all_scale);
	return rc;
}

/**
 * cpr3_apm_init() - initialize APM data for a CPR3 controller
 * @ctrl:		Pointer to the CPR3 controller
 *
 * This function loads memory array power mux (APM) data from device tree
 * if it is present and requests a handle to the appropriate APM controller
 * device.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_apm_init(struct cpr3_controller *ctrl)
{
	struct device_node *node = ctrl->dev->of_node;
	int rc;

	if (!of_find_property(node, "qcom,apm-ctrl", NULL)) {
		/* No APM used */
		return 0;
	}

	ctrl->apm = msm_apm_ctrl_dev_get(ctrl->dev);
	if (IS_ERR(ctrl->apm)) {
		rc = PTR_ERR(ctrl->apm);
		if (rc != -EPROBE_DEFER)
			cpr3_err(ctrl, "APM get failed, rc=%d\n", rc);
		return rc;
	}

	rc = of_property_read_u32(node, "qcom,apm-threshold-voltage",
				&ctrl->apm_threshold_volt);
	if (rc) {
		cpr3_err(ctrl, "error reading qcom,apm-threshold-voltage, rc=%d\n",
			rc);
		return rc;
	}
	ctrl->apm_threshold_volt
		= CPR3_ROUND(ctrl->apm_threshold_volt, ctrl->step_volt);

	/* No error check since this is an optional property. */
	of_property_read_u32(node, "qcom,apm-hysteresis-voltage",
				&ctrl->apm_adj_volt);
	ctrl->apm_adj_volt = CPR3_ROUND(ctrl->apm_adj_volt, ctrl->step_volt);

	ctrl->apm_high_supply = MSM_APM_SUPPLY_APCC;
	ctrl->apm_low_supply = MSM_APM_SUPPLY_MX;

	return 0;
}

/**
 * cpr3_mem_acc_init() - initialize mem-acc regulator data for
 *		a CPR3 regulator
 * @ctrl:		Pointer to the CPR3 controller
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_mem_acc_init(struct cpr3_regulator *vreg)
{
	struct cpr3_controller *ctrl = vreg->thread->ctrl;
	u32 *temp;
	int i, rc;

	if (!ctrl->mem_acc_regulator) {
		cpr3_info(ctrl, "not using memory accelerator regulator\n");
		return 0;
	}

	temp = kcalloc(vreg->corner_count, sizeof(*temp), GFP_KERNEL);
	if (!temp)
		return -ENOMEM;

	rc = cpr3_parse_corner_array_property(vreg, "qcom,mem-acc-voltage",
					      1, temp);
	if (rc) {
		cpr3_err(ctrl, "could not load mem-acc corners, rc=%d\n", rc);
	} else {
		for (i = 0; i < vreg->corner_count; i++)
			vreg->corner[i].mem_acc_volt = temp[i];
	}

	kfree(temp);
	return rc;
}

/**
 * cpr4_load_core_and_temp_adj() - parse amount of voltage adjustment for
 *		per-online-core and per-temperature voltage adjustment for a
 *		given corner or corner band from device tree.
 * @vreg:	Pointer to the CPR3 regulator
 * @num:	Corner number or corner band number
 * @use_corner_band:	Boolean indicating if the CPR3 regulator supports
 *			adjustments per corner band
 *
 * Return: 0 on success, errno on failure
 */
static int cpr4_load_core_and_temp_adj(struct cpr3_regulator *vreg,
					int num, bool use_corner_band)
{
	struct cpr3_controller *ctrl = vreg->thread->ctrl;
	struct cpr4_sdelta *sdelta;
	int sdelta_size, i, j, pos, rc = 0;
	char str[75];
	size_t buflen;
	char *buf;

	sdelta = use_corner_band ? vreg->corner_band[num].sdelta :
		vreg->corner[num].sdelta;

	if (!sdelta->allow_core_count_adj && !sdelta->allow_temp_adj) {
		/* corner doesn't need sdelta table */
		sdelta->max_core_count = 0;
		sdelta->temp_band_count = 0;
		return rc;
	}

	sdelta_size = sdelta->max_core_count * sdelta->temp_band_count;
	snprintf(str, sizeof(str), use_corner_band ?
	 "corner_band=%d core_config_count=%d temp_band_count=%d sdelta_size=%d\n"
	 : "corner=%d core_config_count=%d temp_band_count=%d sdelta_size=%d\n",
		 num, sdelta->max_core_count,
		 sdelta->temp_band_count, sdelta_size);

	cpr3_debug(vreg, "%s", str);

	sdelta->table = devm_kcalloc(ctrl->dev, sdelta_size,
				sizeof(*sdelta->table), GFP_KERNEL);
	if (!sdelta->table)
		return -ENOMEM;

	snprintf(str, sizeof(str), use_corner_band ?
		 "qcom,cpr-corner-band%d-temp-core-voltage-adjustment" :
		 "qcom,cpr-corner%d-temp-core-voltage-adjustment",
		 num + CPR3_CORNER_OFFSET);

	rc = cpr3_parse_array_property(vreg, str, sdelta_size,
				sdelta->table);
	if (rc) {
		cpr3_err(vreg, "could not load %s, rc=%d\n", str, rc);
		return rc;
	}

	/*
	 * Convert sdelta margins from uV to PMIC steps and apply negation to
	 * follow the SDELTA register semantics.
	 */
	for (i = 0; i < sdelta_size; i++)
		sdelta->table[i] = -(sdelta->table[i] / ctrl->step_volt);

	buflen = sizeof(*buf) * sdelta_size * (MAX_CHARS_PER_INT + 2);
	buf = kzalloc(buflen, GFP_KERNEL);
	if (!buf)
		return rc;

	for (i = 0; i < sdelta->max_core_count; i++) {
		for (j = 0, pos = 0; j < sdelta->temp_band_count; j++)
			pos += scnprintf(buf + pos, buflen - pos, " %u",
			 sdelta->table[i * sdelta->temp_band_count + j]);
		cpr3_debug(vreg, "sdelta[%d]:%s\n", i, buf);
	}

	kfree(buf);
	return rc;
}

/**
 * cpr4_parse_core_count_temp_voltage_adj() - parse configuration data for
 *		per-online-core and per-temperature voltage adjustment for
 *		a CPR3 regulator from device tree.
 * @vreg:	Pointer to the CPR3 regulator
 * @use_corner_band:	Boolean indicating if the CPR3 regulator supports
 *			adjustments per corner band
 *
 * This function supports parsing of per-online-core and per-temperature
 * adjustments per corner or per corner band. CPR controllers which support
 * corner bands apply the same adjustments to all corners within a corner band.
 *
 * Return: 0 on success, errno on failure
 */
int cpr4_parse_core_count_temp_voltage_adj(
			struct cpr3_regulator *vreg, bool use_corner_band)
{
	struct cpr3_controller *ctrl = vreg->thread->ctrl;
	struct device_node *node = vreg->of_node;
	struct cpr3_corner *corner;
	struct cpr4_sdelta *sdelta;
	int i, sdelta_table_count, rc = 0;
	int *allow_core_count_adj = NULL, *allow_temp_adj = NULL;
	char prop_str[75];

	if (of_find_property(node, use_corner_band ?
			     "qcom,corner-band-allow-temp-adjustment"
			     : "qcom,corner-allow-temp-adjustment", NULL)) {
		if (!ctrl->allow_temp_adj) {
			cpr3_err(ctrl, "Temperature adjustment configurations missing\n");
			return -EINVAL;
		}

		vreg->allow_temp_adj = true;
	}

	if (of_find_property(node, use_corner_band ?
			     "qcom,corner-band-allow-core-count-adjustment"
			     : "qcom,corner-allow-core-count-adjustment",
			     NULL)) {
		rc = of_property_read_u32(node, "qcom,max-core-count",
				&vreg->max_core_count);
		if (rc) {
			cpr3_err(vreg, "error reading qcom,max-core-count, rc=%d\n",
				rc);
			return -EINVAL;
		}

		vreg->allow_core_count_adj = true;
		ctrl->allow_core_count_adj = true;
	}

	if (!vreg->allow_temp_adj && !vreg->allow_core_count_adj) {
		/*
		 * Both per-online-core and temperature based adjustments are
		 * disabled for this regulator.
		 */
		return 0;
	} else if (!vreg->allow_core_count_adj) {
		/*
		 * Only per-temperature voltage adjusments are allowed.
		 * Keep max core count value as 1 to allocate SDELTA.
		 */
		vreg->max_core_count = 1;
	}

	if (vreg->allow_core_count_adj) {
		allow_core_count_adj = kcalloc(vreg->corner_count,
					sizeof(*allow_core_count_adj),
					GFP_KERNEL);
		if (!allow_core_count_adj)
			return -ENOMEM;

		snprintf(prop_str, sizeof(prop_str), use_corner_band ?
			 "qcom,corner-band-allow-core-count-adjustment" :
			 "qcom,corner-allow-core-count-adjustment");

		rc = use_corner_band ?
			cpr3_parse_corner_band_array_property(vreg, prop_str,
					      1, allow_core_count_adj) :
			cpr3_parse_corner_array_property(vreg, prop_str,
						 1, allow_core_count_adj);
		if (rc) {
			cpr3_err(vreg, "error reading %s, rc=%d\n", prop_str,
				 rc);
			goto done;
		}
	}

	if (vreg->allow_temp_adj) {
		allow_temp_adj = kcalloc(vreg->corner_count,
					sizeof(*allow_temp_adj), GFP_KERNEL);
		if (!allow_temp_adj) {
			rc = -ENOMEM;
			goto done;
		}

		snprintf(prop_str, sizeof(prop_str), use_corner_band ?
			 "qcom,corner-band-allow-temp-adjustment" :
			 "qcom,corner-allow-temp-adjustment");

		rc = use_corner_band ?
			cpr3_parse_corner_band_array_property(vreg, prop_str,
						      1, allow_temp_adj) :
			cpr3_parse_corner_array_property(vreg, prop_str,
						 1, allow_temp_adj);
		if (rc) {
			cpr3_err(vreg, "error reading %s, rc=%d\n", prop_str,
				 rc);
			goto done;
		}
	}

	sdelta_table_count = use_corner_band ? vreg->corner_band_count :
		vreg->corner_count;

	for (i = 0; i < sdelta_table_count; i++) {
		sdelta = devm_kzalloc(ctrl->dev, sizeof(*corner->sdelta),
				      GFP_KERNEL);
		if (!sdelta) {
			rc = -ENOMEM;
			goto done;
		}

		if (allow_core_count_adj)
			sdelta->allow_core_count_adj = allow_core_count_adj[i];
		if (allow_temp_adj)
			sdelta->allow_temp_adj = allow_temp_adj[i];
		sdelta->max_core_count = vreg->max_core_count;
		sdelta->temp_band_count = ctrl->temp_band_count;

		if (use_corner_band)
			vreg->corner_band[i].sdelta = sdelta;
		else
			vreg->corner[i].sdelta = sdelta;

		rc = cpr4_load_core_and_temp_adj(vreg, i, use_corner_band);
		if (rc) {
			cpr3_err(vreg, "corner/band %d core and temp adjustment loading failed, rc=%d\n",
				 i, rc);
			goto done;
		}
	}

done:
	kfree(allow_core_count_adj);
	kfree(allow_temp_adj);

	return rc;
}

/**
 * cprh_adjust_voltages_for_apm() - adjust per-corner floor and ceiling voltages
 *		so that they do not overlap the APM threshold voltage.
 * @vreg:		Pointer to the CPR3 regulator
 *
 * The memory array power mux (APM) must be configured for a specific supply
 * based upon where the VDD voltage lies with respect to the APM threshold
 * voltage.  When using CPR hardware closed-loop, the voltage may vary anywhere
 * between the floor and ceiling voltage without software notification.
 * Therefore, it is required that the floor to ceiling range for every corner
 * not intersect the APM threshold voltage.  This function adjusts the floor to
 * ceiling range for each corner which violates this requirement.
 *
 * The following algorithm is applied:
 *	if floor < threshold <= ceiling:
 *		if open_loop >= threshold, then floor = threshold - adj
 *		else ceiling = threshold - step
 * where:
 *	adj = APM hysteresis voltage established to minimize the number of
 *	      corners with artificially increased floor voltages
 *	step = voltage in microvolts of a single step of the VDD supply
 *
 * The open-loop voltage is also bounded by the new floor or ceiling value as
 * needed.
 *
 * Return: none
 */
void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg)
{
	struct cpr3_controller *ctrl = vreg->thread->ctrl;
	struct cpr3_corner *corner;
	int i, adj, threshold, prev_ceiling, prev_floor, prev_open_loop;

	if (!ctrl->apm_threshold_volt) {
		/* APM not being used. */
		return;
	}

	ctrl->apm_threshold_volt = CPR3_ROUND(ctrl->apm_threshold_volt,
						ctrl->step_volt);
	ctrl->apm_adj_volt = CPR3_ROUND(ctrl->apm_adj_volt, ctrl->step_volt);

	threshold = ctrl->apm_threshold_volt;
	adj = ctrl->apm_adj_volt;

	for (i = 0; i < vreg->corner_count; i++) {
		corner = &vreg->corner[i];

		if (threshold <= corner->floor_volt
		    || threshold > corner->ceiling_volt)
			continue;

		prev_floor = corner->floor_volt;
		prev_ceiling = corner->ceiling_volt;
		prev_open_loop = corner->open_loop_volt;

		if (corner->open_loop_volt >= threshold) {
			corner->floor_volt = max(corner->floor_volt,
						 threshold - adj);
			if (corner->open_loop_volt < corner->floor_volt)
				corner->open_loop_volt = corner->floor_volt;
		} else {
			corner->ceiling_volt = threshold - ctrl->step_volt;
		}

		if (corner->floor_volt != prev_floor
		    || corner->ceiling_volt != prev_ceiling
		    || corner->open_loop_volt != prev_open_loop)
			cpr3_debug(vreg, "APM threshold=%d, APM adj=%d changed corner %d voltages; prev: floor=%d, ceiling=%d, open-loop=%d; new: floor=%d, ceiling=%d, open-loop=%d\n",
				threshold, adj, i, prev_floor, prev_ceiling,
				prev_open_loop, corner->floor_volt,
				corner->ceiling_volt, corner->open_loop_volt);
	}
}

/**
 * cprh_adjust_voltages_for_mem_acc() - adjust per-corner floor and ceiling
 *		voltages so that they do not intersect the MEM ACC threshold
 *		voltage
 * @vreg:		Pointer to the CPR3 regulator
 *
 * The following algorithm is applied:
 *	if floor < threshold <= ceiling:
 *		if open_loop >= threshold, then floor = threshold
 *		else ceiling = threshold - step
 * where:
 *	step = voltage in microvolts of a single step of the VDD supply
 *
 * The open-loop voltage is also bounded by the new floor or ceiling value as
 * needed.
 *
 * Return: none
 */
void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg)
{
	struct cpr3_controller *ctrl = vreg->thread->ctrl;
	struct cpr3_corner *corner;
	int i, threshold, prev_ceiling, prev_floor, prev_open_loop;

	if (!ctrl->mem_acc_threshold_volt) {
		/* MEM ACC not being used. */
		return;
	}

	ctrl->mem_acc_threshold_volt = CPR3_ROUND(ctrl->mem_acc_threshold_volt,
						ctrl->step_volt);

	threshold = ctrl->mem_acc_threshold_volt;

	for (i = 0; i < vreg->corner_count; i++) {
		corner = &vreg->corner[i];

		if (threshold <= corner->floor_volt
		    || threshold > corner->ceiling_volt)
			continue;

		prev_floor = corner->floor_volt;
		prev_ceiling = corner->ceiling_volt;
		prev_open_loop = corner->open_loop_volt;

		if (corner->open_loop_volt >= threshold) {
			corner->floor_volt = max(corner->floor_volt, threshold);
			if (corner->open_loop_volt < corner->floor_volt)
				corner->open_loop_volt = corner->floor_volt;
		} else {
			corner->ceiling_volt = threshold - ctrl->step_volt;
		}

		if (corner->floor_volt != prev_floor
		    || corner->ceiling_volt != prev_ceiling
		    || corner->open_loop_volt != prev_open_loop)
			cpr3_debug(vreg, "MEM ACC threshold=%d changed corner %d voltages; prev: floor=%d, ceiling=%d, open-loop=%d; new: floor=%d, ceiling=%d, open-loop=%d\n",
				threshold, i, prev_floor, prev_ceiling,
				prev_open_loop, corner->floor_volt,
				corner->ceiling_volt, corner->open_loop_volt);
	}
}

/**
 * cpr3_apply_closed_loop_offset_voltages() - modify the closed-loop voltage
 *		adjustments by the amounts that are needed for this
 *		fuse combo
 * @vreg:		Pointer to the CPR3 regulator
 * @volt_adjust:	Array of closed-loop voltage adjustment values of length
 *			vreg->corner_count which is further adjusted based upon
 *			offset voltage fuse values.
 * @fuse_volt_adjust:	Fused closed-loop voltage adjustment values of length
 *			vreg->fuse_corner_count.
 *
 * Return: 0 on success, errno on failure
 */
static int cpr3_apply_closed_loop_offset_voltages(struct cpr3_regulator *vreg,
			int *volt_adjust, int *fuse_volt_adjust)
{
	u32 *corner_map;
	int rc = 0, i;

	if (!of_find_property(vreg->of_node,
		"qcom,cpr-fused-closed-loop-voltage-adjustment-map", NULL)) {
		/* No closed-loop offset required. */
		return 0;
	}

	corner_map = kcalloc(vreg->corner_count, sizeof(*corner_map),
				GFP_KERNEL);
	if (!corner_map)
		return -ENOMEM;

	rc = cpr3_parse_corner_array_property(vreg,
		"qcom,cpr-fused-closed-loop-voltage-adjustment-map",
		1, corner_map);
	if (rc)
		goto done;

	for (i = 0; i < vreg->corner_count; i++) {
		if (corner_map[i] == 0) {
			continue;
		} else if (corner_map[i] > vreg->fuse_corner_count) {
			cpr3_err(vreg, "corner %d mapped to invalid fuse corner: %u\n",
				i, corner_map[i]);
			rc = -EINVAL;
			goto done;
		}

		volt_adjust[i] += fuse_volt_adjust[corner_map[i] - 1];
	}

done:
	kfree(corner_map);
	return rc;
}

/**
 * cpr3_enforce_inc_quotient_monotonicity() - Ensure that target quotients
 *		increase monotonically from lower to higher corners
 * @vreg:		Pointer to the CPR3 regulator
 *
 * Return: 0 on success, errno on failure
 */
static void cpr3_enforce_inc_quotient_monotonicity(struct cpr3_regulator *vreg)
{
	int i, j;

	for (i = 1; i < vreg->corner_count; i++) {
		for (j = 0; j < CPR3_RO_COUNT; j++) {
			if (vreg->corner[i].target_quot[j]
			    && vreg->corner[i].target_quot[j]
					< vreg->corner[i - 1].target_quot[j]) {
				cpr3_debug(vreg, "corner %d RO%u target quot=%u < corner %d RO%u target quot=%u; overriding: corner %d RO%u target quot=%u\n",
					i, j,
					vreg->corner[i].target_quot[j],
					i - 1, j,
					vreg->corner[i - 1].target_quot[j],
					i, j,
					vreg->corner[i - 1].target_quot[j]);
				vreg->corner[i].target_quot[j]
					= vreg->corner[i - 1].target_quot[j];
			}
		}
	}
}

/**
 * cpr3_enforce_dec_quotient_monotonicity() - Ensure that target quotients
 *		decrease monotonically from higher to lower corners
 * @vreg:		Pointer to the CPR3 regulator
 *
 * Return: 0 on success, errno on failure
 */
static void cpr3_enforce_dec_quotient_monotonicity(struct cpr3_regulator *vreg)
{
	int i, j;

	for (i = vreg->corner_count - 2; i >= 0; i--) {
		for (j = 0; j < CPR3_RO_COUNT; j++) {
			if (vreg->corner[i + 1].target_quot[j]
			    && vreg->corner[i].target_quot[j]
					> vreg->corner[i + 1].target_quot[j]) {
				cpr3_debug(vreg, "corner %d RO%u target quot=%u > corner %d RO%u target quot=%u; overriding: corner %d RO%u target quot=%u\n",
					i, j,
					vreg->corner[i].target_quot[j],
					i + 1, j,
					vreg->corner[i + 1].target_quot[j],
					i, j,
					vreg->corner[i + 1].target_quot[j]);
				vreg->corner[i].target_quot[j]
					= vreg->corner[i + 1].target_quot[j];
			}
		}
	}
}

/**
 * _cpr3_adjust_target_quotients() - adjust the target quotients for each
 *		corner of the regulator according to input adjustment and
 *		scaling arrays
 * @vreg:		Pointer to the CPR3 regulator
 * @volt_adjust:	Pointer to an array of closed-loop voltage adjustments
 *			with units of microvolts.  The array must have
 *			vreg->corner_count number of elements.
 * @ro_scale:		Pointer to a flattened 2D array of RO scaling factors.
 *			The array must have an inner dimension of CPR3_RO_COUNT
 *			and an outer dimension of vreg->corner_count
 * @label:		Null terminated string providing a label for the type
 *			of adjustment.
 *
 * Return: true if any corners received a positive voltage adjustment (> 0),
 *	   else false
 */
static bool _cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
		const int *volt_adjust, const int *ro_scale, const char *label)
{
	int i, j, quot_adjust;
	bool is_increasing = false;
	u32 prev_quot;

	for (i = 0; i < vreg->corner_count; i++) {
		for (j = 0; j < CPR3_RO_COUNT; j++) {
			if (vreg->corner[i].target_quot[j]) {
				quot_adjust = cpr3_quot_adjustment(
					ro_scale[i * CPR3_RO_COUNT + j],
					volt_adjust[i]);
				if (quot_adjust) {
					prev_quot = vreg->corner[i].
							target_quot[j];
					vreg->corner[i].target_quot[j]
						+= quot_adjust;
					cpr3_debug(vreg, "adjusted corner %d RO%d target quot %s: %u --> %u (%d uV)\n",
						i, j, label, prev_quot,
						vreg->corner[i].target_quot[j],
						volt_adjust[i]);
				}
			}
		}
		if (volt_adjust[i] > 0)
			is_increasing = true;
	}

	return is_increasing;
}

/**
 * cpr3_adjust_target_quotients() - adjust the target quotients for each
 *			corner according to device tree values and fuse values
 * @vreg:		Pointer to the CPR3 regulator
 * @fuse_volt_adjust:	Fused closed-loop voltage adjustment values of length
 *			vreg->fuse_corner_count. This parameter could be null
 *			pointer when no fused adjustments are needed.
 *
 * Return: 0 on success, errno on failure
 */
int cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
			int *fuse_volt_adjust)
{
	int i, rc;
	int *volt_adjust, *ro_scale;
	bool explicit_adjustment, fused_adjustment, is_increasing;

	explicit_adjustment = of_find_property(vreg->of_node,
		"qcom,cpr-closed-loop-voltage-adjustment", NULL);
	fused_adjustment = of_find_property(vreg->of_node,
		"qcom,cpr-fused-closed-loop-voltage-adjustment-map", NULL);

	if (!explicit_adjustment && !fused_adjustment && !vreg->aging_allowed) {
		/* No adjustment required. */
		return 0;
	} else if (!of_find_property(vreg->of_node,
			"qcom,cpr-ro-scaling-factor", NULL)) {
		cpr3_err(vreg, "qcom,cpr-ro-scaling-factor is required for closed-loop voltage adjustment, but is missing\n");
		return -EINVAL;
	}

	volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
				GFP_KERNEL);
	ro_scale = kcalloc(vreg->corner_count * CPR3_RO_COUNT,
				sizeof(*ro_scale), GFP_KERNEL);
	if (!volt_adjust || !ro_scale) {
		rc = -ENOMEM;
		goto done;
	}

	rc = cpr3_parse_corner_array_property(vreg,
			"qcom,cpr-ro-scaling-factor", CPR3_RO_COUNT, ro_scale);
	if (rc) {
		cpr3_err(vreg, "could not load RO scaling factors, rc=%d\n",
			rc);
		goto done;
	}

	for (i = 0; i < vreg->corner_count; i++)
		memcpy(vreg->corner[i].ro_scale, &ro_scale[i * CPR3_RO_COUNT],
			sizeof(*ro_scale) * CPR3_RO_COUNT);

	if (explicit_adjustment) {
		rc = cpr3_parse_corner_array_property(vreg,
			"qcom,cpr-closed-loop-voltage-adjustment",
			1, volt_adjust);
		if (rc) {
			cpr3_err(vreg, "could not load closed-loop voltage adjustments, rc=%d\n",
				rc);
			goto done;
		}

		_cpr3_adjust_target_quotients(vreg, volt_adjust, ro_scale,
			"from DT");
		cpr3_enforce_inc_quotient_monotonicity(vreg);
	}

	if (fused_adjustment && fuse_volt_adjust) {
		memset(volt_adjust, 0,
			sizeof(*volt_adjust) * vreg->corner_count);

		rc = cpr3_apply_closed_loop_offset_voltages(vreg, volt_adjust,
				fuse_volt_adjust);
		if (rc) {
			cpr3_err(vreg, "could not apply fused closed-loop voltage reductions, rc=%d\n",
				rc);
			goto done;
		}

		is_increasing = _cpr3_adjust_target_quotients(vreg, volt_adjust,
					ro_scale, "from fuse");
		if (is_increasing)
			cpr3_enforce_inc_quotient_monotonicity(vreg);
		else
			cpr3_enforce_dec_quotient_monotonicity(vreg);
	}

done:
	kfree(volt_adjust);
	kfree(ro_scale);
	return rc;
}

/**
 * cpr3_parse_fuse_combo_map() - parse fuse combo map data for a CPR3 regulator
 *		from device tree.
 * @vreg:		Pointer to the CPR3 regulator
 * @fuse_val:		Array of selection fuse parameter values
 * @fuse_count:		Number of selection fuse parameters used in fuse combo
 *			map
 *
 * This function reads the qcom,cpr-fuse-combo-map device tree property and
 * populates the fuse_combo element of CPR3 regulator with the row number of
 * fuse combo map data that matches with the data in fuse_val input array.
 *
 * Return: 0 on success, -ENODEV if qcom,cpr-fuse-combo-map property is not
 *		specified in device node, other errno on failure
 */
int cpr3_parse_fuse_combo_map(struct cpr3_regulator *vreg, u64 *fuse_val,
			int fuse_count)
{
	struct device_node *node = vreg->of_node;
	int i, j, len, num_fuse_combos, row_size, rc = 0;
	u32 *tmp;

	if (!of_find_property(node, "qcom,cpr-fuse-combo-map", &len)) {
		/* property not specified */
		return -ENODEV;
	}

	row_size = fuse_count * 2;
	if (len == 0 || len % (sizeof(u32) * row_size)) {
		cpr3_err(vreg, "qcom,cpr-fuse-combo-map length=%d is invalid\n",
			len);
		return -EINVAL;
	}

	num_fuse_combos = len / (sizeof(u32) * row_size);
	vreg->fuse_combos_supported = num_fuse_combos;

	tmp = kzalloc(len, GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;

	rc = of_property_read_u32_array(node, "qcom,cpr-fuse-combo-map",
			tmp, num_fuse_combos * row_size);
	if (rc) {
		cpr3_err(vreg, "could not read qcom,cpr-fuse-combo-map, rc=%d\n",
			rc);
		goto done;
	}

	for (i = 0; i < num_fuse_combos; i++) {
		for (j = 0; j < fuse_count; j++) {
			if (tmp[i * row_size + j * 2] > fuse_val[j]
			      || tmp[i * row_size + j * 2 + 1] < fuse_val[j])
				break;
		}
		if (j == fuse_count) {
			vreg->fuse_combo = i;
			break;
		}
	}

	if (i >= num_fuse_combos) {
		cpr3_err(vreg, "No matching CPR fuse combo found!\n");
		WARN_ON(1);
		rc = -EINVAL;
		goto done;
	}

done:
	kfree(tmp);
	return rc;
}
