cpufreq: exynos: Fix driver compilation with ARCH_MULTIPLATFORM
authorTomasz Figa <t.figa@samsung.com>
Sun, 25 May 2014 21:26:03 +0000 (06:26 +0900)
committerKukjin Kim <kgene.kim@samsung.com>
Fri, 30 May 2014 18:00:25 +0000 (03:00 +0900)
Currently Exynos cpufreq drivers rely on globally mapped
clock controller registers to configure frequency of CPU
cores. This is obviously wrong and will be removed in near
future, but to enable support for multi-platform builds
without introducing a regression it needs to be worked
around.

This patch hacks the code to look for clock controller node
in device tree and map its registers using of_iomap(),
instead of relying on global mapping, so dependencies on
platform headers are removed and the driver can compile
again with multiplatform support.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/exynos-cpufreq.c
drivers/cpufreq/exynos-cpufreq.h
drivers/cpufreq/exynos4210-cpufreq.c
drivers/cpufreq/exynos4x12-cpufreq.c
drivers/cpufreq/exynos5250-cpufreq.c

index 580503513f0f10687d46e666e19f253d7fbbfb51..d2c7b4b8ffd5ae76aa594074a1506796edf870d4 100644 (file)
@@ -30,7 +30,7 @@ config ARM_EXYNOS_CPUFREQ
 
 config ARM_EXYNOS4210_CPUFREQ
        bool "SAMSUNG EXYNOS4210"
-       depends on CPU_EXYNOS4210 && !ARCH_MULTIPLATFORM
+       depends on CPU_EXYNOS4210
        default y
        select ARM_EXYNOS_CPUFREQ
        help
@@ -41,7 +41,7 @@ config ARM_EXYNOS4210_CPUFREQ
 
 config ARM_EXYNOS4X12_CPUFREQ
        bool "SAMSUNG EXYNOS4x12"
-       depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
+       depends on SOC_EXYNOS4212 || SOC_EXYNOS4412
        default y
        select ARM_EXYNOS_CPUFREQ
        help
@@ -52,7 +52,7 @@ config ARM_EXYNOS4X12_CPUFREQ
 
 config ARM_EXYNOS5250_CPUFREQ
        bool "SAMSUNG EXYNOS5250"
-       depends on SOC_EXYNOS5250 && !ARCH_MULTIPLATFORM
+       depends on SOC_EXYNOS5250
        default y
        select ARM_EXYNOS_CPUFREQ
        help
index e8a4a7ed38c165f7a785f6539c6f1b06d39fa7dd..348c8bafe436247d8368989af5e9a35e3bb33057 100644 (file)
@@ -19,8 +19,6 @@
 #include <linux/platform_device.h>
 #include <linux/of.h>
 
-#include <plat/cpu.h>
-
 #include "exynos-cpufreq.h"
 
 static struct exynos_dvfs_info *exynos_info;
index f189547bb4479f53717d209466768f76a7cbfc26..51af42e1b7feb6eb2f9499bb63f28ca9944741cf 100644 (file)
@@ -49,6 +49,7 @@ struct exynos_dvfs_info {
        struct cpufreq_frequency_table  *freq_table;
        void (*set_freq)(unsigned int, unsigned int);
        bool (*need_apll_change)(unsigned int, unsigned int);
+       void __iomem    *cmu_regs;
 };
 
 #ifdef CONFIG_ARM_EXYNOS4210_CPUFREQ
@@ -76,24 +77,21 @@ static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
 }
 #endif
 
-#include <plat/cpu.h>
-#include <mach/map.h>
+#define EXYNOS4_CLKSRC_CPU                     0x14200
+#define EXYNOS4_CLKMUX_STATCPU                 0x14400
 
-#define EXYNOS4_CLKSRC_CPU                     (S5P_VA_CMU + 0x14200)
-#define EXYNOS4_CLKMUX_STATCPU                 (S5P_VA_CMU + 0x14400)
-
-#define EXYNOS4_CLKDIV_CPU                     (S5P_VA_CMU + 0x14500)
-#define EXYNOS4_CLKDIV_CPU1                    (S5P_VA_CMU + 0x14504)
-#define EXYNOS4_CLKDIV_STATCPU                 (S5P_VA_CMU + 0x14600)
-#define EXYNOS4_CLKDIV_STATCPU1                        (S5P_VA_CMU + 0x14604)
+#define EXYNOS4_CLKDIV_CPU                     0x14500
+#define EXYNOS4_CLKDIV_CPU1                    0x14504
+#define EXYNOS4_CLKDIV_STATCPU                 0x14600
+#define EXYNOS4_CLKDIV_STATCPU1                        0x14604
 
 #define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT       (16)
 #define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK    (0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)
 
-#define EXYNOS5_APLL_LOCK                      (S5P_VA_CMU + 0x00000)
-#define EXYNOS5_APLL_CON0                      (S5P_VA_CMU + 0x00100)
-#define EXYNOS5_CLKMUX_STATCPU                 (S5P_VA_CMU + 0x00400)
-#define EXYNOS5_CLKDIV_CPU0                    (S5P_VA_CMU + 0x00500)
-#define EXYNOS5_CLKDIV_CPU1                    (S5P_VA_CMU + 0x00504)
-#define EXYNOS5_CLKDIV_STATCPU0                        (S5P_VA_CMU + 0x00600)
-#define EXYNOS5_CLKDIV_STATCPU1                        (S5P_VA_CMU + 0x00604)
+#define EXYNOS5_APLL_LOCK                      0x00000
+#define EXYNOS5_APLL_CON0                      0x00100
+#define EXYNOS5_CLKMUX_STATCPU                 0x00400
+#define EXYNOS5_CLKDIV_CPU0                    0x00500
+#define EXYNOS5_CLKDIV_CPU1                    0x00504
+#define EXYNOS5_CLKDIV_STATCPU0                        0x00600
+#define EXYNOS5_CLKDIV_STATCPU1                        0x00604
index 6384e5b9a347dab5fefdcb5aa2ad40c0924f5230..61a54310a1b9df6923a1fbfbb3ab6e1872c914eb 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include "exynos-cpufreq.h"
 
@@ -23,6 +25,7 @@ static struct clk *cpu_clk;
 static struct clk *moutcore;
 static struct clk *mout_mpll;
 static struct clk *mout_apll;
+static struct exynos_dvfs_info *cpufreq;
 
 static unsigned int exynos4210_volt_table[] = {
        1250000, 1150000, 1050000, 975000, 950000,
@@ -60,20 +63,20 @@ static void exynos4210_set_clkdiv(unsigned int div_index)
 
        tmp = apll_freq_4210[div_index].clk_div_cpu0;
 
-       __raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
+       __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU);
 
        do {
-               tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU);
+               tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU);
        } while (tmp & 0x1111111);
 
        /* Change Divider - CPU1 */
 
        tmp = apll_freq_4210[div_index].clk_div_cpu1;
 
-       __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
+       __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU1);
 
        do {
-               tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU1);
+               tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU1);
        } while (tmp & 0x11);
 }
 
@@ -85,7 +88,7 @@ static void exynos4210_set_apll(unsigned int index)
        clk_set_parent(moutcore, mout_mpll);
 
        do {
-               tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU)
+               tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU)
                        >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
                tmp &= 0x7;
        } while (tmp != 0x2);
@@ -96,7 +99,7 @@ static void exynos4210_set_apll(unsigned int index)
        clk_set_parent(moutcore, mout_apll);
 
        do {
-               tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU);
+               tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU);
                tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
        } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
 }
@@ -115,8 +118,30 @@ static void exynos4210_set_frequency(unsigned int old_index,
 
 int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
 {
+       struct device_node *np;
        unsigned long rate;
 
+       /*
+        * HACK: This is a temporary workaround to get access to clock
+        * controller registers directly and remove static mappings and
+        * dependencies on platform headers. It is necessary to enable
+        * Exynos multi-platform support and will be removed together with
+        * this whole driver as soon as Exynos gets migrated to use
+        * cpufreq-cpu0 driver.
+        */
+       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-clock");
+       if (!np) {
+               pr_err("%s: failed to find clock controller DT node\n",
+                       __func__);
+               return -ENODEV;
+       }
+
+       info->cmu_regs = of_iomap(np, 0);
+       if (!info->cmu_regs) {
+               pr_err("%s: failed to map CMU registers\n", __func__);
+               return -EFAULT;
+       }
+
        cpu_clk = clk_get(NULL, "armclk");
        if (IS_ERR(cpu_clk))
                return PTR_ERR(cpu_clk);
@@ -143,6 +168,8 @@ int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
        info->freq_table = exynos4210_freq_table;
        info->set_freq = exynos4210_set_frequency;
 
+       cpufreq = info;
+
        return 0;
 
 err_mout_apll:
index 63a3907ce5782d45860fff01fb35cb14f837ffba..351a2074cfea784c8a522b3fa6080a67c59e7180 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include "exynos-cpufreq.h"
 
@@ -23,6 +25,7 @@ static struct clk *cpu_clk;
 static struct clk *moutcore;
 static struct clk *mout_mpll;
 static struct clk *mout_apll;
+static struct exynos_dvfs_info *cpufreq;
 
 static unsigned int exynos4x12_volt_table[] = {
        1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500,
@@ -105,19 +108,20 @@ static void exynos4x12_set_clkdiv(unsigned int div_index)
 
        tmp = apll_freq_4x12[div_index].clk_div_cpu0;
 
-       __raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
+       __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU);
 
-       while (__raw_readl(EXYNOS4_CLKDIV_STATCPU) & 0x11111111)
+       while (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU)
+              & 0x11111111)
                cpu_relax();
 
        /* Change Divider - CPU1 */
        tmp = apll_freq_4x12[div_index].clk_div_cpu1;
 
-       __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
+       __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU1);
 
        do {
                cpu_relax();
-               tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU1);
+               tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU1);
        } while (tmp != 0x0);
 }
 
@@ -130,7 +134,7 @@ static void exynos4x12_set_apll(unsigned int index)
 
        do {
                cpu_relax();
-               tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU)
+               tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU)
                        >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
                tmp &= 0x7;
        } while (tmp != 0x2);
@@ -142,7 +146,7 @@ static void exynos4x12_set_apll(unsigned int index)
 
        do {
                cpu_relax();
-               tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU);
+               tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU);
                tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
        } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
 }
@@ -161,8 +165,30 @@ static void exynos4x12_set_frequency(unsigned int old_index,
 
 int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
 {
+       struct device_node *np;
        unsigned long rate;
 
+       /*
+        * HACK: This is a temporary workaround to get access to clock
+        * controller registers directly and remove static mappings and
+        * dependencies on platform headers. It is necessary to enable
+        * Exynos multi-platform support and will be removed together with
+        * this whole driver as soon as Exynos gets migrated to use
+        * cpufreq-cpu0 driver.
+        */
+       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4412-clock");
+       if (!np) {
+               pr_err("%s: failed to find clock controller DT node\n",
+                       __func__);
+               return -ENODEV;
+       }
+
+       info->cmu_regs = of_iomap(np, 0);
+       if (!info->cmu_regs) {
+               pr_err("%s: failed to map CMU registers\n", __func__);
+               return -EFAULT;
+       }
+
        cpu_clk = clk_get(NULL, "armclk");
        if (IS_ERR(cpu_clk))
                return PTR_ERR(cpu_clk);
@@ -194,6 +220,8 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
        info->freq_table = exynos4x12_freq_table;
        info->set_freq = exynos4x12_set_frequency;
 
+       cpufreq = info;
+
        return 0;
 
 err_mout_apll:
index 363a0b3fe1b109a7d746c15626155cabf2a03089..c91ce69dc63101d3a1f866b906acaf780c20070a 100644 (file)
@@ -16,8 +16,8 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
-
-#include <mach/map.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include "exynos-cpufreq.h"
 
@@ -25,6 +25,7 @@ static struct clk *cpu_clk;
 static struct clk *moutcore;
 static struct clk *mout_mpll;
 static struct clk *mout_apll;
+static struct exynos_dvfs_info *cpufreq;
 
 static unsigned int exynos5250_volt_table[] = {
        1300000, 1250000, 1225000, 1200000, 1150000,
@@ -87,17 +88,18 @@ static void set_clkdiv(unsigned int div_index)
 
        tmp = apll_freq_5250[div_index].clk_div_cpu0;
 
-       __raw_writel(tmp, EXYNOS5_CLKDIV_CPU0);
+       __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS5_CLKDIV_CPU0);
 
-       while (__raw_readl(EXYNOS5_CLKDIV_STATCPU0) & 0x11111111)
+       while (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKDIV_STATCPU0)
+              & 0x11111111)
                cpu_relax();
 
        /* Change Divider - CPU1 */
        tmp = apll_freq_5250[div_index].clk_div_cpu1;
 
-       __raw_writel(tmp, EXYNOS5_CLKDIV_CPU1);
+       __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS5_CLKDIV_CPU1);
 
-       while (__raw_readl(EXYNOS5_CLKDIV_STATCPU1) & 0x11)
+       while (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKDIV_STATCPU1) & 0x11)
                cpu_relax();
 }
 
@@ -111,7 +113,8 @@ static void set_apll(unsigned int index)
 
        do {
                cpu_relax();
-               tmp = (__raw_readl(EXYNOS5_CLKMUX_STATCPU) >> 16);
+               tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKMUX_STATCPU)
+                       >> 16);
                tmp &= 0x7;
        } while (tmp != 0x2);
 
@@ -122,7 +125,7 @@ static void set_apll(unsigned int index)
 
        do {
                cpu_relax();
-               tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU);
+               tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKMUX_STATCPU);
                tmp &= (0x7 << 16);
        } while (tmp != (0x1 << 16));
 }
@@ -141,8 +144,30 @@ static void exynos5250_set_frequency(unsigned int old_index,
 
 int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
 {
+       struct device_node *np;
        unsigned long rate;
 
+       /*
+        * HACK: This is a temporary workaround to get access to clock
+        * controller registers directly and remove static mappings and
+        * dependencies on platform headers. It is necessary to enable
+        * Exynos multi-platform support and will be removed together with
+        * this whole driver as soon as Exynos gets migrated to use
+        * cpufreq-cpu0 driver.
+        */
+       np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-clock");
+       if (!np) {
+               pr_err("%s: failed to find clock controller DT node\n",
+                       __func__);
+               return -ENODEV;
+       }
+
+       info->cmu_regs = of_iomap(np, 0);
+       if (!info->cmu_regs) {
+               pr_err("%s: failed to map CMU registers\n", __func__);
+               return -EFAULT;
+       }
+
        cpu_clk = clk_get(NULL, "armclk");
        if (IS_ERR(cpu_clk))
                return PTR_ERR(cpu_clk);
@@ -169,6 +194,8 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
        info->freq_table = exynos5250_freq_table;
        info->set_freq = exynos5250_set_frequency;
 
+       cpufreq = info;
+
        return 0;
 
 err_mout_apll: