From 1629bc37b05420bbfd0918d96f86697bf6d94160 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 8 Oct 2013 11:57:13 +0200 Subject: ARM: cpufreq: Parse CPUFREQ's voltage table passed as device tree node Now it is possible to parse cpufreq's voltage table information passed as device tree node. This is handy for various different PMICs. It is also possible to override this device tree node by defining empty "volt_table" node. Then default exynos4x12_volt_table[] is used. Signed-off-by: Lukasz Majewski --- drivers/cpufreq/exynos-cpufreq.c | 45 ++++++++++++++++++++++++++++++++++++ drivers/cpufreq/exynos-cpufreq.h | 2 ++ drivers/cpufreq/exynos4x12-cpufreq.c | 5 +++- 3 files changed, 51 insertions(+), 1 deletion(-) (limited to 'drivers/cpufreq') diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index d748ada5f39..aa869debe8e 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -350,6 +350,51 @@ struct cpufreq_frequency_table *exynos_of_parse_freq_table( return ret; } +unsigned int *exynos_of_parse_volt_table(struct exynos_dvfs_info *info, + const char *property_name) +{ + struct device_node *node = info->dev->of_node; + struct property *pp; + int len, num; + u32 *of_v_tab; + + if (!node) + return NULL; + + pp = of_find_property(node, property_name, &len); + if (!pp) { + pr_debug("%s: Property: %s not found\n", __func__, + property_name); + goto err; + } + + if (len == 0) { + pr_debug("%s: Length wrong value!\n", __func__); + goto err; + } + + of_v_tab = kzalloc(len, GFP_KERNEL); + if (!of_v_tab) { + pr_err("%s: Allocation failed\n", __func__); + goto err; + } + + num = len / sizeof(u32); + if (of_property_read_u32_array(node, pp->name, of_v_tab, num)) { + pr_err("%s: Property: %s cannot be read!\n", __func__, + pp->name); + goto err_of_v_tab; + } + + return of_v_tab; + + err_of_v_tab: + kfree(of_v_tab); + err: + return NULL; +} + + #ifdef CONFIG_OF static struct of_device_id exynos_cpufreq_of_match[] = { { .compatible = "samsung,exynos-cpufreq", }, diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h index 4e08ba768ac..8ad711ffda5 100644 --- a/drivers/cpufreq/exynos-cpufreq.h +++ b/drivers/cpufreq/exynos-cpufreq.h @@ -49,3 +49,5 @@ extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *); extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *); extern struct cpufreq_frequency_table *exynos_of_parse_freq_table( struct exynos_dvfs_info *info, const char *property_name); +unsigned int *exynos_of_parse_volt_table(struct exynos_dvfs_info *info, + const char *property_name); diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c index 1359fd91455..8b2749dfaaa 100644 --- a/drivers/cpufreq/exynos4x12-cpufreq.c +++ b/drivers/cpufreq/exynos4x12-cpufreq.c @@ -232,7 +232,10 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) /* 800Mhz */ info->pll_safe_idx = L7; info->cpu_clk = cpu_clk; - info->volt_table = exynos4x12_volt_table; + + info->volt_table = exynos_of_parse_volt_table(info, "volt_table"); + if (!info->volt_table) + info->volt_table = exynos4x12_volt_table; info->freq_table = exynos_of_parse_freq_table(info, "freq_table"); if (!info->freq_table) -- cgit v1.2.3