/*
 * Copyright (c) 2017, 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.
 */

#include <linux/cpu.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,cpu-a7.h>

#include "clk-alpha-pll.h"
#include "clk-debug.h"
#include "clk-rcg.h"
#include "clk-regmap-mux-div.h"
#include "common.h"
#include "vdd-level-sdm845.h"

#define SYS_APC0_AUX_CLK_SRC	1

#define PLL_MODE_REG		0x0
#define PLL_OPMODE_RUN		0x1
#define PLL_OPMODE_REG		0x38
#define PLL_MODE_OUTCTRL	BIT(0)

#define to_clk_regmap_mux_div(_hw) \
	container_of(to_clk_regmap(_hw), struct clk_regmap_mux_div, clkr)

static DEFINE_VDD_REGULATORS(vdd_cx, VDD_CX_NUM, 1, vdd_corner);
static DEFINE_VDD_REGS_INIT(vdd_cpu, 1);

enum apcs_clk_parent_index {
	XO_AO_INDEX,
	SYS_APC0_AUX_CLK_INDEX,
	APCS_CPU_PLL_INDEX,
};

enum {
	P_SYS_APC0_AUX_CLK,
	P_APCS_CPU_PLL,
	P_BI_TCXO_AO,
};

static const struct parent_map apcs_clk_parent_map[] = {
	[XO_AO_INDEX] = { P_BI_TCXO_AO, 0 },
	[SYS_APC0_AUX_CLK_INDEX] = { P_SYS_APC0_AUX_CLK, 1 },
	[APCS_CPU_PLL_INDEX] = { P_APCS_CPU_PLL, 5 },
};

static const char *const apcs_clk_parent_name[] = {
	[XO_AO_INDEX] = "bi_tcxo_ao",
	[SYS_APC0_AUX_CLK_INDEX] = "sys_apc0_aux_clk",
	[APCS_CPU_PLL_INDEX] = "apcs_cpu_pll",
};

static int a7cc_clk_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
						unsigned long prate, u8 index)
{
	struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw);

	return __mux_div_set_src_div(cpuclk, cpuclk->parent_map[index].cfg,
					cpuclk->div);
}

static int a7cc_clk_set_parent(struct clk_hw *hw, u8 index)
{
	/*
	 * Since a7cc_clk_set_rate_and_parent() is defined and set_parent()
	 * will never gets called from clk_change_rate() so return 0.
	 */
	return 0;
}

static int a7cc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
						unsigned long prate)
{
	struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw);

	/*
	 * Parent is same as the last rate.
	 * Here just configure new div.
	 */
	return __mux_div_set_src_div(cpuclk, cpuclk->src, cpuclk->div);
}

static int a7cc_clk_determine_rate(struct clk_hw *hw,
					struct clk_rate_request *req)
{
	int ret;
	u32 div = 1;
	struct clk_hw *xo, *apc0_auxclk_hw, *apcs_cpu_pll_hw;
	unsigned long apc0_auxclk_rate, rate = req->rate;
	struct clk_rate_request parent_req = { };
	struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw);
	unsigned long mask = BIT(cpuclk->hid_width) - 1;

	xo = clk_hw_get_parent_by_index(hw, XO_AO_INDEX);
	if (rate == clk_hw_get_rate(xo)) {
		req->best_parent_hw = xo;
		req->best_parent_rate = rate;
		cpuclk->div = div;
		cpuclk->src = cpuclk->parent_map[XO_AO_INDEX].cfg;
		return 0;
	}

	apc0_auxclk_hw = clk_hw_get_parent_by_index(hw, SYS_APC0_AUX_CLK_INDEX);
	apcs_cpu_pll_hw = clk_hw_get_parent_by_index(hw, APCS_CPU_PLL_INDEX);

	apc0_auxclk_rate = clk_hw_get_rate(apc0_auxclk_hw);
	if (rate <= apc0_auxclk_rate) {
		req->best_parent_hw = apc0_auxclk_hw;
		req->best_parent_rate = apc0_auxclk_rate;

		div = DIV_ROUND_UP((2 * req->best_parent_rate), rate) - 1;
		div = min_t(unsigned long, div, mask);

		req->rate = clk_rcg2_calc_rate(req->best_parent_rate, 0,
							0, 0, div);
		cpuclk->src = cpuclk->parent_map[SYS_APC0_AUX_CLK_INDEX].cfg;
	} else {
		parent_req.rate = rate;
		parent_req.best_parent_hw = apcs_cpu_pll_hw;

		req->best_parent_hw = apcs_cpu_pll_hw;
		ret = __clk_determine_rate(req->best_parent_hw, &parent_req);
		if (ret)
			return ret;

		req->best_parent_rate = parent_req.rate;
		cpuclk->src = cpuclk->parent_map[APCS_CPU_PLL_INDEX].cfg;
	}
	cpuclk->div = div;

	return 0;
}

static void a7cc_clk_list_registers(struct seq_file *f, struct clk_hw *hw)
{
	struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw);
	int i = 0, size = 0, val;

	static struct clk_register_data data[] = {
		{"CMD_RCGR", 0x0},
		{"CFG_RCGR", 0x4},
	};

	size = ARRAY_SIZE(data);
	for (i = 0; i < size; i++) {
		regmap_read(cpuclk->clkr.regmap,
				cpuclk->reg_offset + data[i].offset, &val);
		seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
	}
}

static unsigned long a7cc_clk_recalc_rate(struct clk_hw *hw,
					unsigned long prate)
{
	struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw);
	const char *name = clk_hw_get_name(hw);
	struct clk_hw *parent;
	int ret = 0;
	unsigned long parent_rate;
	u32 i, div, src = 0;
	u32 num_parents = clk_hw_get_num_parents(hw);

	ret = mux_div_get_src_div(cpuclk, &src, &div);
	if (ret)
		return ret;

	for (i = 0; i < num_parents; i++) {
		if (src == cpuclk->parent_map[i].cfg) {
			parent = clk_hw_get_parent_by_index(hw, i);
			parent_rate = clk_hw_get_rate(parent);
			return clk_rcg2_calc_rate(parent_rate, 0, 0, 0, div);
		}
	}
	pr_err("%s: Can't find parent %d\n", name, src);
	return ret;
}

static int a7cc_clk_enable(struct clk_hw *hw)
{
	return clk_regmap_mux_div_ops.enable(hw);
}

static void a7cc_clk_disable(struct clk_hw *hw)
{
	clk_regmap_mux_div_ops.disable(hw);
}

static u8 a7cc_clk_get_parent(struct clk_hw *hw)
{
	return clk_regmap_mux_div_ops.get_parent(hw);
}

/*
 * We use the notifier function for switching to a temporary safe configuration
 * (mux and divider), while the APSS pll is reconfigured.
 */
static int a7cc_notifier_cb(struct notifier_block *nb, unsigned long event,
			     void *data)
{
	int ret = 0;
	struct clk_regmap_mux_div *cpuclk = container_of(nb,
					struct clk_regmap_mux_div, clk_nb);

	if (event == PRE_RATE_CHANGE)
		/* set the mux to safe source(sys_apc0_aux_clk) & div */
		ret = __mux_div_set_src_div(cpuclk, SYS_APC0_AUX_CLK_SRC, 1);

	if (event == ABORT_RATE_CHANGE)
		pr_err("Error in configuring PLL - stay at safe src only\n");

	return notifier_from_errno(ret);
}

static const struct clk_ops a7cc_clk_ops = {
	.enable = a7cc_clk_enable,
	.disable = a7cc_clk_disable,
	.get_parent = a7cc_clk_get_parent,
	.set_rate = a7cc_clk_set_rate,
	.set_parent = a7cc_clk_set_parent,
	.set_rate_and_parent = a7cc_clk_set_rate_and_parent,
	.determine_rate = a7cc_clk_determine_rate,
	.recalc_rate = a7cc_clk_recalc_rate,
	.debug_init = clk_debug_measure_add,
	.list_registers = a7cc_clk_list_registers,
};

/*
 * As per HW, sys_apc0_aux_clk runs at 300MHz and configured by BOOT
 * So adding it as dummy clock.
 */

static struct clk_dummy sys_apc0_aux_clk = {
	.rrate = 300000000,
	.hw.init = &(struct clk_init_data){
		.name = "sys_apc0_aux_clk",
		.ops = &clk_dummy_ops,
	},
};

/* Initial configuration for 1497.6MHz(Turbo) */
static const struct pll_config apcs_cpu_pll_config = {
	.l = 0x4E,
};

static struct pll_vco trion_vco[] = {
	{ 249600000, 2000000000, 0 },
};

static struct clk_alpha_pll apcs_cpu_pll = {
	.type = TRION_PLL,
	.vco_table = trion_vco,
	.num_vco = ARRAY_SIZE(trion_vco),
	.clkr.hw.init = &(struct clk_init_data){
		.name = "apcs_cpu_pll",
		.parent_names = (const char *[]){ "bi_tcxo_ao" },
		.num_parents = 1,
		.ops = &clk_trion_pll_ops,
		VDD_CX_FMAX_MAP4(LOWER, 345600000,
				LOW, 576000000,
				NOMINAL, 1094400000,
				HIGH, 1497600000),
	},
};

static struct clk_regmap_mux_div apcs_clk = {
	.hid_width  = 5,
	.hid_shift  = 0,
	.src_width  = 3,
	.src_shift  = 8,
	.safe_src = 1,
	.safe_div = 1,
	.parent_map = apcs_clk_parent_map,
	.clk_nb.notifier_call = a7cc_notifier_cb,
	.clkr.hw.init = &(struct clk_init_data) {
		.name = "apcs_clk",
		.parent_names = apcs_clk_parent_name,
		.num_parents = 3,
		.vdd_class = &vdd_cpu,
		.flags = CLK_SET_RATE_PARENT,
		.ops = &a7cc_clk_ops,
	},
};

static const struct of_device_id match_table[] = {
	{ .compatible = "qcom,cpu-sdxpoorwills" },
	{}
};

static const struct regmap_config cpu_regmap_config = {
	.reg_bits               = 32,
	.reg_stride             = 4,
	.val_bits               = 32,
	.max_register           = 0x7F10,
	.fast_io                = true,
};

static struct clk_hw *cpu_clks_hws[] = {
	[SYS_APC0_AUX_CLK] = &sys_apc0_aux_clk.hw,
	[APCS_CPU_PLL] = &apcs_cpu_pll.clkr.hw,
	[APCS_CLK] = &apcs_clk.clkr.hw,
};

static void a7cc_clk_get_speed_bin(struct platform_device *pdev, int *bin,
							int *version)
{
	struct resource *res;
	void __iomem *base;
	u32 pte_efuse, valid;

	*bin = 0;
	*version = 0;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse");
	if (!res) {
		dev_info(&pdev->dev,
			"No speed/PVS binning available. Defaulting to 0!\n");
		return;
	}

	base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!base) {
		dev_info(&pdev->dev,
			"Unable to read efuse data. Defaulting to 0!\n");
		return;
	}

	pte_efuse = readl_relaxed(base);
	devm_iounmap(&pdev->dev, base);

	*bin = pte_efuse & 0x7;
	valid = (pte_efuse >> 3) & 0x1;
	*version = (pte_efuse >> 4) & 0x3;

	if (!valid) {
		dev_info(&pdev->dev, "Speed bin not set. Defaulting to 0!\n");
		*bin = 0;
	} else {
		dev_info(&pdev->dev, "Speed bin: %d\n", *bin);
	}

	dev_info(&pdev->dev, "PVS version: %d\n", *version);
}

static int a7cc_clk_get_fmax_vdd_class(struct platform_device *pdev,
			struct clk_init_data *clk_intd, char *prop_name)
{
	struct device_node *of = pdev->dev.of_node;
	int prop_len, i, j;
	struct clk_vdd_class *vdd = clk_intd->vdd_class;
	int num = vdd->num_regulators + 1;
	u32 *array;

	if (!of_find_property(of, prop_name, &prop_len)) {
		dev_err(&pdev->dev, "missing %s\n", prop_name);
		return -EINVAL;
	}

	prop_len /= sizeof(u32);
	if (prop_len % num) {
		dev_err(&pdev->dev, "bad length %d\n", prop_len);
		return -EINVAL;
	}

	prop_len /= num;
	vdd->level_votes = devm_kzalloc(&pdev->dev, prop_len * sizeof(int),
					GFP_KERNEL);
	if (!vdd->level_votes)
		return -ENOMEM;

	vdd->vdd_uv = devm_kzalloc(&pdev->dev,
				prop_len * sizeof(int) * (num - 1), GFP_KERNEL);
	if (!vdd->vdd_uv)
		return -ENOMEM;

	clk_intd->rate_max = devm_kzalloc(&pdev->dev,
				prop_len * sizeof(unsigned long), GFP_KERNEL);
	if (!clk_intd->rate_max)
		return -ENOMEM;

	array = devm_kzalloc(&pdev->dev,
			prop_len * sizeof(u32) * num, GFP_KERNEL);
	if (!array)
		return -ENOMEM;

	of_property_read_u32_array(of, prop_name, array, prop_len * num);
	for (i = 0; i < prop_len; i++) {
		clk_intd->rate_max[i] = array[num * i];
		for (j = 1; j < num; j++) {
			vdd->vdd_uv[(num - 1) * i + (j - 1)] =
					array[num * i + j];
		}
	}

	devm_kfree(&pdev->dev, array);
	vdd->num_levels = prop_len;
	vdd->cur_level = prop_len;
	clk_intd->num_rate_max = prop_len;

	return 0;
}

/*
 *  Find the voltage level required for a given clock rate.
 */
static int find_vdd_level(struct clk_init_data *clk_intd, unsigned long rate)
{
	int level;

	for (level = 0; level < clk_intd->num_rate_max; level++)
		if (rate <= clk_intd->rate_max[level])
			break;

	if (level == clk_intd->num_rate_max) {
		pr_err("Rate %lu for %s is greater than highest Fmax\n", rate,
				clk_intd->name);
		return -EINVAL;
	}

	return level;
}

static int
a7cc_clk_add_opp(struct clk_hw *hw, struct device *dev, unsigned long max_rate)
{
	unsigned long rate = 0;
	int level, uv, j = 1;
	long ret;
	struct clk_init_data *clk_intd =  (struct clk_init_data *)hw->init;
	struct clk_vdd_class *vdd = clk_intd->vdd_class;

	if (IS_ERR_OR_NULL(dev)) {
		pr_err("%s: Invalid parameters\n", __func__);
		return -EINVAL;
	}

	while (1) {
		rate = clk_intd->rate_max[j++];
		level = find_vdd_level(clk_intd, rate);
		if (level <= 0) {
			pr_warn("clock-cpu: no corner for %lu.\n", rate);
			return -EINVAL;
		}

		uv = vdd->vdd_uv[level];
		if (uv < 0) {
			pr_warn("clock-cpu: no uv for %lu.\n", rate);
			return -EINVAL;
		}

		ret = dev_pm_opp_add(dev, rate, uv);
		if (ret) {
			pr_warn("clock-cpu: failed to add OPP for %lu\n", rate);
			return rate;
		}

		if (rate >= max_rate)
			break;
	}

	return 0;
}

static void a7cc_clk_print_opp_table(int a7_cpu)
{
	struct dev_pm_opp *oppfmax, *oppfmin;
	unsigned long apc_fmax, apc_fmin;
	u32 max_a7ss_index = apcs_clk.clkr.hw.init->num_rate_max;

	apc_fmax = apcs_clk.clkr.hw.init->rate_max[max_a7ss_index - 1];
	apc_fmin = apcs_clk.clkr.hw.init->rate_max[1];

	rcu_read_lock();

	oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a7_cpu),
					apc_fmax, true);
	oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a7_cpu),
					apc_fmin, true);
	pr_info("Clock_cpu: OPP voltage for %lu: %ld\n", apc_fmin,
		dev_pm_opp_get_voltage(oppfmin));
	pr_info("Clock_cpu: OPP voltage for %lu: %ld\n", apc_fmax,
		dev_pm_opp_get_voltage(oppfmax));

	rcu_read_unlock();
}

static void a7cc_clk_populate_opp_table(struct platform_device *pdev)
{
	unsigned long apc_fmax;
	int cpu, a7_cpu = 0;
	u32 max_a7ss_index = apcs_clk.clkr.hw.init->num_rate_max;

	apc_fmax = apcs_clk.clkr.hw.init->rate_max[max_a7ss_index - 1];

	for_each_possible_cpu(cpu) {
		a7_cpu = cpu;
		WARN(a7cc_clk_add_opp(&apcs_clk.clkr.hw, get_cpu_device(cpu),
				apc_fmax),
				"Failed to add OPP levels for apcs_clk\n");
	}
	/* One time print during bootup */
	dev_info(&pdev->dev, "OPP tables populated (cpu %d)\n", a7_cpu);

	a7cc_clk_print_opp_table(a7_cpu);
}

static int a7cc_driver_probe(struct platform_device *pdev)
{
	struct clk *clk;
	void __iomem *base;
	u32 opmode_regval, mode_regval;
	struct resource *res;
	struct clk_onecell_data *data;
	struct device *dev = &pdev->dev;
	struct device_node *of = pdev->dev.of_node;
	int i, ret, speed_bin, version, cpu;
	int num_clks = ARRAY_SIZE(cpu_clks_hws);
	u32 a7cc_clk_init_rate = 0;
	char prop_name[] = "qcom,speedX-bin-vX";
	struct clk *ext_xo_clk;

	/* Require the RPMH-XO clock to be registered before */
	ext_xo_clk = devm_clk_get(dev, "xo_ao");
	if (IS_ERR(ext_xo_clk)) {
		if (PTR_ERR(ext_xo_clk) != -EPROBE_DEFER)
			dev_err(dev, "Unable to get xo clock\n");
		return PTR_ERR(ext_xo_clk);
	}

	/* Get speed bin information */
	a7cc_clk_get_speed_bin(pdev, &speed_bin, &version);

	/* Rail Regulator for apcs_pll */
	vdd_cx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_dig_ao");
	if (IS_ERR(vdd_cx.regulator[0])) {
		if (!(PTR_ERR(vdd_cx.regulator[0]) == -EPROBE_DEFER))
			dev_err(&pdev->dev,
				"Unable to get vdd_dig_ao regulator\n");
		return PTR_ERR(vdd_cx.regulator[0]);
	}

	/* Rail Regulator for APSS a7ss mux */
	vdd_cpu.regulator[0] = devm_regulator_get(&pdev->dev, "cpu-vdd");
	if (IS_ERR(vdd_cpu.regulator[0])) {
		if (!(PTR_ERR(vdd_cpu.regulator[0]) == -EPROBE_DEFER))
			dev_err(&pdev->dev,
				"Unable to get cpu-vdd regulator\n");
		return PTR_ERR(vdd_cpu.regulator[0]);
	}

	snprintf(prop_name, ARRAY_SIZE(prop_name),
			"qcom,speed%d-bin-v%d", speed_bin, version);

	ret = a7cc_clk_get_fmax_vdd_class(pdev,
		(struct clk_init_data *)apcs_clk.clkr.hw.init, prop_name);
	if (ret) {
		dev_err(&pdev->dev,
		"Can't get speed bin for apcs_clk. Falling back to zero\n");
		ret = a7cc_clk_get_fmax_vdd_class(pdev,
				(struct clk_init_data *)apcs_clk.clkr.hw.init,
				"qcom,speed0-bin-v0");
		if (ret) {
			dev_err(&pdev->dev,
			"Unable to get speed bin for apcs_clk freq-corner mapping info\n");
			return ret;
		}
	}

	ret = of_property_read_u32(of, "qcom,a7cc-init-rate",
						&a7cc_clk_init_rate);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to find qcom,a7cc_clk_init_rate property,ret=%d\n",
			ret);
		return -EINVAL;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs_pll");
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base)) {
		dev_err(&pdev->dev, "Failed to map apcs_cpu_pll register base\n");
		return PTR_ERR(base);
	}

	apcs_cpu_pll.clkr.regmap = devm_regmap_init_mmio(dev, base,
						&cpu_regmap_config);
	if (IS_ERR(apcs_cpu_pll.clkr.regmap)) {
		dev_err(&pdev->dev, "Couldn't get regmap for apcs_cpu_pll\n");
		return PTR_ERR(apcs_cpu_pll.clkr.regmap);
	}

	ret = of_property_read_u32(of, "qcom,rcg-reg-offset",
						&apcs_clk.reg_offset);
	if (ret) {
		dev_err(&pdev->dev,
			"unable to find qcom,rcg-reg-offset property,ret=%d\n",
			ret);
		return -EINVAL;
	}

	apcs_clk.clkr.regmap = apcs_cpu_pll.clkr.regmap;

	/* Read PLLs OPMODE and mode register */
	ret = regmap_read(apcs_cpu_pll.clkr.regmap, PLL_OPMODE_REG,
							&opmode_regval);
	if (ret)
		return ret;

	ret = regmap_read(apcs_cpu_pll.clkr.regmap, PLL_MODE_REG,
							&mode_regval);
	if (ret)
		return ret;

	/* Configure APSS PLL only if it is not enabled and running */
	if (!(opmode_regval & PLL_OPMODE_RUN) &&
				!(mode_regval & PLL_MODE_OUTCTRL))
		clk_trion_pll_configure(&apcs_cpu_pll,
			apcs_cpu_pll.clkr.regmap, &apcs_cpu_pll_config);

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->clk_num = num_clks;

	data->clks = devm_kzalloc(dev, num_clks * sizeof(struct clk *),
					GFP_KERNEL);
	if (!data->clks)
		return -ENOMEM;

	/* Register clocks with clock framework */
	for (i = 0; i < num_clks; i++) {
		clk = devm_clk_register(dev, cpu_clks_hws[i]);
		if (IS_ERR(clk))
			return PTR_ERR(clk);
		data->clks[i] = clk;
	}

	ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
	if (ret) {
		dev_err(&pdev->dev, "CPU clock driver registeration failed\n");
		return ret;
	}

	ret = clk_notifier_register(apcs_cpu_pll.clkr.hw.clk, &apcs_clk.clk_nb);
	if (ret) {
		dev_err(dev, "failed to register clock notifier: %d\n", ret);
		return ret;
	}

	/* Put proxy vote for APSS PLL */
	clk_prepare_enable(apcs_cpu_pll.clkr.hw.clk);

	/* Set to TURBO boot frequency */
	ret = clk_set_rate(apcs_clk.clkr.hw.clk, a7cc_clk_init_rate);
	if (ret)
		dev_err(&pdev->dev, "Unable to set init rate on apcs_clk\n");

	/*
	 * We don't want the CPU clocks to be turned off at late init
	 * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the
	 * refcount of these clocks. Any cpufreq/hotplug manager can assume
	 * that the clocks have already been prepared and enabled by the time
	 * they take over.
	 */

	get_online_cpus();
	for_each_online_cpu(cpu)
		WARN(clk_prepare_enable(apcs_clk.clkr.hw.clk),
			"Unable to turn on CPU clock\n");
	put_online_cpus();

	/* Remove proxy vote for APSS PLL */
	clk_disable_unprepare(apcs_cpu_pll.clkr.hw.clk);

	a7cc_clk_populate_opp_table(pdev);

	dev_info(dev, "CPU clock Driver probed successfully\n");

	return ret;
}

static struct platform_driver a7_clk_driver = {
	.probe = a7cc_driver_probe,
	.driver = {
		.name = "qcom-cpu-sdxpoorwills",
		.of_match_table = match_table,
	},
};

static int __init a7_clk_init(void)
{
	return platform_driver_register(&a7_clk_driver);
}
subsys_initcall(a7_clk_init);

static void __exit a7_clk_exit(void)
{
	platform_driver_unregister(&a7_clk_driver);
}
module_exit(a7_clk_exit);

MODULE_ALIAS("platform:cpu");
MODULE_DESCRIPTION("A7 CPU clock Driver");
MODULE_LICENSE("GPL v2");
