#include <linux/cpufreq.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_address.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#define PU_SOC_VOLTAGE_NORMAL 1250000
#define PU_SOC_VOLTAGE_HIGH 1275000
#define FREQ_1P2_GHZ 1200000000
static struct regulator *arm_reg;
static struct regulator *pu_reg;
static struct regulator *soc_reg;
#define IMX6Q_CPUFREQ_CLK_NUM 5
#define IMX6UL_CPUFREQ_CLK_NUM 7
static struct clk_bulk_data clks[] = {
{ .id = "pll2_pfd2_396m" },
{ .id = "secondary_sel" },
static struct device *cpu_dev;
static struct cpufreq_frequency_table *freq_table;
static unsigned int max_freq;
static unsigned int transition_latency;
static u32 *imx6_soc_volt;
static u32 soc_opp_count;
static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
unsigned long freq_hz, volt, volt_old;
unsigned int old_freq, new_freq;
bool pll1_sys_temp_enabled = false;
new_freq = freq_table[index].frequency;
freq_hz = new_freq * 1000;
old_freq = clk_get_rate(clks[ARM].clk) / 1000;
opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
volt = dev_pm_opp_get_voltage(opp);
volt_old = regulator_get_voltage(arm_reg);
dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
old_freq / 1000, volt_old / 1000,
new_freq / 1000, volt / 1000);
if (new_freq > old_freq) {
ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);