ARM: tegra11: dvfs: Dynamically allocate cl dvfs object
Alex Frid [Tue, 9 Oct 2012 07:44:14 +0000 (00:44 -0700)]
Dynamically allocated cl dvfs object by the cl-dvfs driver, and
hide cl_dvfs structure definition from clock framework.

Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/142851
(cherry picked from commit a2adb1710edc52c61b1fa336e5253aa5735ec717)

Change-Id: I6dd1af043d15aba143bdf02bb53dd1e796784626
Signed-off-by: Bharat Nihalani <bnihalani@nvidia.com>
Reviewed-on: http://git-master/r/146277
Reviewed-by: Automatic_Commit_Validation_User

arch/arm/mach-tegra/clock.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 0b15ec6..b08bfb2 100644 (file)
@@ -80,8 +80,6 @@ struct clk;
 #define PERIPH_ON_APB          (1 << 29)
 #define PERIPH_ON_CBUS         (1 << 30)
 
-struct tegra_cl_dvfs;
-
 struct clk_mux_sel {
        struct clk      *input;
        u32             value;
@@ -193,7 +191,7 @@ struct clk {
                        u32     (*round_p_to_pdiv)(u32 p, u32 *pdiv);
                } pll;
                struct {
-                       struct tegra_cl_dvfs            *cl_dvfs;
+                       void                            *cl_dvfs;
                } dfll;
                struct {
                        unsigned long                   default_rate;
index 8453d92..5be3757 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/syscore_ops.h>
+#include <linux/platform_device.h>
 
 #include <asm/clkdev.h>
 
@@ -41,6 +42,7 @@
 #include "dvfs.h"
 #include "pm.h"
 #include "sleep.h"
+#include "devices.h"
 #include "tegra11_emc.h"
 #include "tegra_cl_dvfs.h"
 
@@ -3214,6 +3216,7 @@ static void __init tegra11_dfll_cpu_late_init(struct clk *c)
        ret = tegra_init_cl_dvfs();
        if (!ret) {
                c->state = OFF;
+               c->u.dfll.cl_dvfs = platform_get_drvdata(&tegra_cl_dvfs_device);
                pr_info("Tegra CPU DFLL is initialized\n");
        }
 }
@@ -5415,17 +5418,12 @@ 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;
-
 static struct clk tegra_dfll_cpu = {
        .name      = "dfll_cpu",
        .flags     = DFLL,
        .ops       = &tegra_dfll_ops,
        .reg       = 0x2f4,
        .max_rate  = 2000000000,
-       .u.dfll = {
-               .cl_dvfs = &cpu_cl_dvfs,
-       },
 };
 
 static struct clk tegra_pll_re_vco = {
index f534305..dc906a8 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "tegra_cl_dvfs.h"
 #include "clock.h"
+#include "dvfs.h"
 
 #define OUT_MASK                       0x3f
 
 
 #define CL_DVFS_OUTPUT_PENDING_TIMEOUT 1000
 
+enum tegra_cl_dvfs_ctrl_mode {
+       TEGRA_CL_DVFS_UNINITIALIZED = 0,
+       TEGRA_CL_DVFS_DISABLED = 1,
+       TEGRA_CL_DVFS_OPEN_LOOP = 2,
+       TEGRA_CL_DVFS_CLOSED_LOOP = 3,
+};
+
+struct dfll_rate_req {
+       u8      freq;
+       u8      scale;
+       u8      output;
+};
+
+struct tegra_cl_dvfs {
+       u32                                     cl_base;
+       struct tegra_cl_dvfs_platform_data      *p_data;
+
+       struct dvfs                     *safe_dvfs;
+       struct clk                      *soc_clk;
+       struct clk                      *ref_clk;
+       struct clk                      *i2c_clk;
+       unsigned long                   ref_rate;
+       unsigned long                   i2c_rate;
+
+       /* output voltage mapping:
+        * legacy dvfs table index -to- cl_dvfs output LUT index
+        * cl_dvfs output LUT index -to- PMU value/voltage pair ptr
+        */
+       u8                              clk_dvfs_map[MAX_DVFS_FREQS];
+       struct voltage_reg_map          *out_map[MAX_CL_DVFS_VOLTAGES];
+       u8                              num_voltages;
+       u8                              safe_ouput;
+
+       struct dfll_rate_req            last_req;
+       unsigned long                   dfll_rate_min;
+       enum tegra_cl_dvfs_ctrl_mode    mode;
+};
+
 /* Conversion macros (different scales for frequency request, and monitored
    rate is not a typo)*/
 #define GET_REQUEST_FREQ(rate, ref_rate)       ((rate) / ((ref_rate) / 2))
@@ -490,10 +529,13 @@ void tegra_cl_dvfs_resume(struct tegra_cl_dvfs *cld)
 
 static int __init tegra_cl_dvfs_probe(struct platform_device *pdev)
 {
+       int ret;
        struct tegra_cl_dvfs_platform_data *p_data;
        struct resource *res;
-       struct clk *c, *ref_clk, *soc_clk, *i2c_clk, *safe_dvfs_clk;
+       struct tegra_cl_dvfs *cld;
+       struct clk *ref_clk, *soc_clk, *i2c_clk, *safe_dvfs_clk;
 
+       /* Get resources */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "missing register base\n");
@@ -519,19 +561,30 @@ static int __init tegra_cl_dvfs_probe(struct platform_device *pdev)
                return PTR_ERR(safe_dvfs_clk);
        }
 
-       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;
+
+       /* Allocate cl_dvfs object and populate resource accessors */
+       cld = kzalloc(sizeof(*cld), GFP_KERNEL);
+       if (!cld) {
+               dev_err(&pdev->dev, "failed to allocate cl_dvfs object\n");
+               return -ENOMEM;
+       }
+
+       cld->cl_base = (u32)IO_ADDRESS(res->start);
+       cld->p_data = p_data;
+       cld->ref_clk = ref_clk;
+       cld->soc_clk = soc_clk;
+       cld->i2c_clk = i2c_clk;
+       cld->safe_dvfs = safe_dvfs_clk->dvfs;
+
+       /* Initialize cl_dvfs */
+       ret = cl_dvfs_init(cld);
+       if (ret) {
+               kfree(cld);
+               return ret;
        }
 
-       c->u.dfll.cl_dvfs->cl_base = (u32)IO_ADDRESS(res->start);
-       c->u.dfll.cl_dvfs->p_data = p_data;
-       c->u.dfll.cl_dvfs->ref_clk = ref_clk;
-       c->u.dfll.cl_dvfs->soc_clk = soc_clk;
-       c->u.dfll.cl_dvfs->i2c_clk = i2c_clk;
-       c->u.dfll.cl_dvfs->safe_dvfs = safe_dvfs_clk->dvfs;
-       return cl_dvfs_init(c->u.dfll.cl_dvfs);
+       platform_set_drvdata(pdev, cld);
+       return 0;
 }
 
 static struct platform_driver tegra_cl_dvfs_driver = {
@@ -744,8 +797,8 @@ unsigned long tegra_cl_dvfs_request_get(struct tegra_cl_dvfs *cld)
 
 static int lock_get(void *data, u64 *val)
 {
-       struct clk *c = (struct clk *)data;
-       *val = c->u.dfll.cl_dvfs->mode == TEGRA_CL_DVFS_CLOSED_LOOP;
+       struct tegra_cl_dvfs *cld = ((struct clk *)data)->u.dfll.cl_dvfs;
+       *val = cld->mode == TEGRA_CL_DVFS_CLOSED_LOOP;
        return 0;
 }
 static int lock_set(void *data, u64 val)
index 36e8b31..b0d39bd 100644 (file)
 #ifndef _TEGRA_CL_DVFS_H_
 #define _TEGRA_CL_DVFS_H_
 
-#include "dvfs.h"
+struct tegra_cl_dvfs;
 
 #define MAX_CL_DVFS_VOLTAGES           33
 
-enum tegra_cl_dvfs_ctrl_mode {
-       TEGRA_CL_DVFS_UNINITIALIZED = 0,
-       TEGRA_CL_DVFS_DISABLED = 1,
-       TEGRA_CL_DVFS_OPEN_LOOP = 2,
-       TEGRA_CL_DVFS_CLOSED_LOOP = 3,
-};
-
 enum tegra_cl_dvfs_force_mode {
        TEGRA_CL_DVFS_FORCE_NONE = 0,
        TEGRA_CL_DVFS_FORCE_FIXED = 1,
@@ -84,37 +77,6 @@ struct tegra_cl_dvfs_platform_data {
        struct tegra_cl_dvfs_cfg_param          *cfg_param;
 };
 
-struct dfll_rate_req {
-       u8      freq;
-       u8      scale;
-       u8      output;
-};
-
-struct tegra_cl_dvfs {
-       u32                                     cl_base;
-       struct tegra_cl_dvfs_platform_data      *p_data;
-
-       struct dvfs                     *safe_dvfs;
-       struct clk                      *soc_clk;
-       struct clk                      *ref_clk;
-       struct clk                      *i2c_clk;
-       unsigned long                   ref_rate;
-       unsigned long                   i2c_rate;
-
-       /* output voltage mapping:
-        * legacy dvfs table index -to- cl_dvfs output LUT index
-        * cl_dvfs output LUT index -to- PMU value/voltage pair ptr
-        */
-       u8                              clk_dvfs_map[MAX_DVFS_FREQS];
-       struct voltage_reg_map          *out_map[MAX_CL_DVFS_VOLTAGES];
-       u8                              num_voltages;
-       u8                              safe_ouput;
-
-       struct dfll_rate_req            last_req;
-       unsigned long                   dfll_rate_min;
-       enum tegra_cl_dvfs_ctrl_mode    mode;
-};
-
 #ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
 int tegra_init_cl_dvfs(void);
 void tegra_cl_dvfs_resume(struct tegra_cl_dvfs *cld);