ARM: tegra11: dvfs: Add CL-DVFS platform device
Alex Frid [Sun, 7 Oct 2012 05:10:00 +0000 (22:10 -0700)]
Added CL-DVFS platform device. Converted CL-DVFS module to platform
device driver, used driver registration to get CL_DVFS platform data
instead of calling board level API.

Change-Id: I5283e80c5d43f0259743b55bd3ad6783c639b090
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/142169
Signed-off-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-on: http://git-master/r/146270
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

Rebase-Id: Ra08e3c067e3555b5c40d65e6cd6fd74f6e31bc44

arch/arm/mach-tegra/board-curacao-power.c
arch/arm/mach-tegra/board-dalmore-power.c
arch/arm/mach-tegra/board-pluto-power.c
arch/arm/mach-tegra/devices.c
arch/arm/mach-tegra/devices.h
arch/arm/mach-tegra/tegra11_clocks.c
arch/arm/mach-tegra/tegra_cl_dvfs.c
arch/arm/mach-tegra/tegra_cl_dvfs.h

index c1088fd..6ce7273 100644 (file)
@@ -39,6 +39,7 @@
 #include "tegra_cl_dvfs.h"
 #include "gpio-names.h"
 #include "tegra11_soctherm.h"
+#include "devices.h"
 
 #define PMC_CTRL                0x0
 #define PMC_CTRL_INTR_LOW       (1 << 17)
@@ -451,6 +452,15 @@ static struct tegra_cl_dvfs_platform_data curacao_cl_dvfs_data = {
        .cfg_param = &curacao_cl_dvfs_param,
 };
 
+static int __init curacao_cl_dvfs_init(void)
+{
+       fill_reg_map();
+       tegra_cl_dvfs_device.dev.platform_data = &curacao_cl_dvfs_data;
+       platform_device_register(&tegra_cl_dvfs_device);
+
+       return 0;
+}
+
 int __init curacao_regulator_init(void)
 {
        int ret;
@@ -460,8 +470,7 @@ int __init curacao_regulator_init(void)
        if (ret < 0)
                return ret;
 
-       fill_reg_map();
-       tegra_cl_dvfs_set_platform_data(&curacao_cl_dvfs_data);
+       curacao_cl_dvfs_init();
 
        return platform_add_devices(gpio_regs_devices,
                        ARRAY_SIZE(gpio_regs_devices));
index bfceeff..8235889 100644 (file)
@@ -46,6 +46,7 @@
 #include "gpio-names.h"
 #include "board-dalmore.h"
 #include "tegra_cl_dvfs.h"
+#include "devices.h"
 
 #define PMC_CTRL               0x0
 #define PMC_CTRL_INTR_LOW      (1 << 17)
@@ -1025,7 +1026,7 @@ static inline void fill_reg_map(void)
        }
 }
 
-static struct tegra_cl_dvfs_platform_data dalmore_dfll_cpu_data = {
+static struct tegra_cl_dvfs_platform_data dalmore_cl_dvfs_data = {
        .dfll_clk_name = "dfll_cpu",
        .pmu_if = TEGRA_CL_DVFS_PMU_I2C,
        .u.pmu_i2c = {
@@ -1039,6 +1040,15 @@ static struct tegra_cl_dvfs_platform_data dalmore_dfll_cpu_data = {
        .cfg_param = &dalmore_cl_dvfs_param,
 };
 
+static int __init dalmore_cl_dvfs_init(void)
+{
+       fill_reg_map();
+       tegra_cl_dvfs_device.dev.platform_data = &dalmore_cl_dvfs_data;
+       platform_device_register(&tegra_cl_dvfs_device);
+
+       return 0;
+}
+
 static int __init dalmore_max77663_regulator_init(void)
 {
        void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
@@ -1101,8 +1111,7 @@ int __init dalmore_regulator_init(void)
        i2c_register_board_info(4, tps65090_regulators,
                        ARRAY_SIZE(tps65090_regulators));
 
-       fill_reg_map();
-       tegra_cl_dvfs_set_platform_data(&dalmore_dfll_cpu_data);
+       dalmore_cl_dvfs_init();
 
        tegra_get_board_info(&board_info);
        if (board_info.board_id == BOARD_E1611)
index 1af82ac..340621f 100644 (file)
@@ -35,6 +35,7 @@
 #include "board.h"
 #include "board-pluto.h"
 #include "tegra_cl_dvfs.h"
+#include "devices.h"
 
 #define PMC_CTRL               0x0
 #define PMC_CTRL_INTR_LOW      (1 << 17)
@@ -555,7 +556,7 @@ static inline void fill_reg_map(void)
        }
 }
 
-static struct tegra_cl_dvfs_platform_data pluto_dfll_cpu_data = {
+static struct tegra_cl_dvfs_platform_data pluto_cl_dvfs_data = {
        .dfll_clk_name = "dfll_cpu",
        .pmu_if = TEGRA_CL_DVFS_PMU_I2C,
        .u.pmu_i2c = {
@@ -569,6 +570,15 @@ static struct tegra_cl_dvfs_platform_data pluto_dfll_cpu_data = {
        .cfg_param = &pluto_cl_dvfs_param,
 };
 
+static int __init pluto_cl_dvfs_init(void)
+{
+       fill_reg_map();
+       tegra_cl_dvfs_device.dev.platform_data = &pluto_cl_dvfs_data;
+       platform_device_register(&tegra_cl_dvfs_device);
+
+       return 0;
+}
+
 static struct palmas_pmic_platform_data pmic_platform = {
        .enable_ldo8_tracking = true,
 };
@@ -609,8 +619,7 @@ int __init pluto_regulator_init(void)
        u32 pmc_ctrl;
        int i;
 
-       fill_reg_map();
-       tegra_cl_dvfs_set_platform_data(&pluto_dfll_cpu_data);
+       pluto_cl_dvfs_init();
 
        /* TPS65913: Normal state of INT request line is LOW.
         * configure the power management controller to trigger PMU
index 29b58de..0a58f88 100644 (file)
@@ -2083,6 +2083,23 @@ struct platform_device tegra_cec_device = {
 };
 #endif
 
+#ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
+static struct resource cl_dvfs_resource[] = {
+       [0] = {
+               .start  = TEGRA_CL_DVFS_BASE,
+               .end    = TEGRA_CL_DVFS_BASE + TEGRA_CL_DVFS_SIZE-1,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+struct platform_device tegra_cl_dvfs_device = {
+       .name           = "tegra_cl_dvfs",
+       .id             = 0,
+       .resource       = cl_dvfs_resource,
+       .num_resources  = ARRAY_SIZE(cl_dvfs_resource),
+};
+#endif
+
 void __init tegra_init_debug_uart_rate(void)
 {
        unsigned int uartclk;
index 6e434b9..022d88b 100644 (file)
@@ -159,6 +159,9 @@ extern struct platform_device tegra_nvmap_device;
 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
 extern struct platform_device tegra_cec_device;
 #endif
+#ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
+extern struct platform_device tegra_cl_dvfs_device;
+#endif
 
 void __init tegra_init_debug_uart_rate(void);
 
index 88f8bc9..1de45d5 100644 (file)
@@ -3215,7 +3215,7 @@ static void __init tegra11_dfll_cpu_late_init(struct clk *c)
        /* release dfll clock source reset, init cl_dvfs control logic, and
           move dfll to initialized state, so it can be used as CPU source */
        tegra_periph_reset_deassert(c);
-       ret = tegra_init_cl_dvfs(cld);
+       ret = tegra_init_cl_dvfs();
        if (!ret) {
                c->state = OFF;
                pr_info("Tegra CPU DFLL is initialized\n");
@@ -5419,9 +5419,7 @@ static struct clk tegra_pll_x_out0 = {
 /* FIXME: remove; for now, should be always checked-in as "0" */
 #define USE_LP_CPU_TO_TEST_DFLL                0
 
-static struct tegra_cl_dvfs cpu_cl_dvfs = {
-       .cl_base = (u32)IO_ADDRESS(TEGRA_CL_DVFS_BASE),
-};
+static struct tegra_cl_dvfs cpu_cl_dvfs;
 
 static struct clk tegra_dfll_cpu = {
        .name      = "dfll_cpu",
index 51a8610..fe054ea 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include <mach/iomap.h>
 #include <mach/irqs.h>
@@ -410,7 +411,7 @@ static void cl_dvfs_disable_clocks(struct tegra_cl_dvfs *cld)
        clk_disable(cld->soc_clk);
 }
 
-int __init tegra_init_cl_dvfs(struct tegra_cl_dvfs *cld)
+static int cl_dvfs_init(struct tegra_cl_dvfs *cld)
 {
        int ret;
 
@@ -487,11 +488,45 @@ void tegra_cl_dvfs_resume(struct tegra_cl_dvfs *cld)
        }
 }
 
-void tegra_cl_dvfs_set_platform_data(struct tegra_cl_dvfs_platform_data *data)
+static int __init tegra_cl_dvfs_probe(struct platform_device *pdev)
 {
-       struct clk *c = tegra_get_clock_by_name(data->dfll_clk_name);
-       if (c && c->u.dfll.cl_dvfs)
-               c->u.dfll.cl_dvfs->p_data = data;
+       struct tegra_cl_dvfs_platform_data *p_data;
+       struct resource *res;
+       struct clk *c;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "missing register base\n");
+               return -ENOMEM;
+       }
+
+       p_data = pdev->dev.platform_data;
+       if (!p_data) {
+               dev_err(&pdev->dev, "missing platform data\n");
+               return -ENODATA;
+       }
+       c = tegra_get_clock_by_name(p_data->dfll_clk_name);
+       if (!c || !c->u.dfll.cl_dvfs) {
+               dev_err(&pdev->dev, "missing target dfll\n");
+               return -ENODATA;
+       }
+
+       c->u.dfll.cl_dvfs->cl_base = IO_ADDRESS(res->start);
+       c->u.dfll.cl_dvfs->p_data = p_data;
+       return cl_dvfs_init(c->u.dfll.cl_dvfs);
+}
+
+static struct platform_driver tegra_cl_dvfs_driver = {
+       .driver         = {
+               .name   = "tegra_cl_dvfs",
+               .owner  = THIS_MODULE,
+       },
+};
+
+int __init tegra_init_cl_dvfs(void)
+{
+       return platform_driver_probe(&tegra_cl_dvfs_driver,
+                                    tegra_cl_dvfs_probe);
 }
 
 /*
index 745497b..36e8b31 100644 (file)
@@ -116,8 +116,7 @@ struct tegra_cl_dvfs {
 };
 
 #ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
-void tegra_cl_dvfs_set_platform_data(struct tegra_cl_dvfs_platform_data *data);
-int tegra_init_cl_dvfs(struct tegra_cl_dvfs *cld);
+int tegra_init_cl_dvfs(void);
 void tegra_cl_dvfs_resume(struct tegra_cl_dvfs *cld);
 
 void tegra_cl_dvfs_disable(struct tegra_cl_dvfs *cld);
@@ -127,10 +126,7 @@ int tegra_cl_dvfs_unlock(struct tegra_cl_dvfs *cld);
 int tegra_cl_dvfs_request_rate(struct tegra_cl_dvfs *cld, unsigned long rate);
 unsigned long tegra_cl_dvfs_request_get(struct tegra_cl_dvfs *cld);
 #else
-static inline void tegra_cl_dvfs_set_platform_data(
-               struct tegra_cl_dvfs_platform_data *data)
-{}
-static inline int tegra_init_cl_dvfs(struct tegra_cl_dvfs *cld)
+static inline int tegra_init_cl_dvfs(void)
 { return -ENOSYS; }
 static inline void tegra_cl_dvfs_resume(struct tegra_cl_dvfs *cld)
 {}