ARM: tegra: dvfs: Restrict vdd core override
Alex Frid [Sun, 21 Jul 2013 03:06:24 +0000 (20:06 -0700)]
Restricted vdd core override to clocks with dvfs override property.

Bug 1307369

Change-Id: Idaf20ac8ab6016b0ca306190ac7e1327354f99b3
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/251664
(cherry picked from commit dbce70c975587128c7c420b62e3ad0dc5737fbae)
Reviewed-on: http://git-master/r/277515
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>

arch/arm/mach-tegra/dvfs.c
drivers/mmc/host/sdhci-tegra.c
include/linux/clk/tegra.h

index 4fc26f9..91ddef4 100644 (file)
@@ -732,7 +732,7 @@ EXPORT_SYMBOL(tegra_dvfs_get_freqs);
 #ifdef CONFIG_TEGRA_VDD_CORE_OVERRIDE
 static DEFINE_MUTEX(rail_override_lock);
 
-int tegra_dvfs_override_core_voltage(int override_mv)
+static int dvfs_override_core_voltage(int override_mv)
 {
        int ret, floor, ceiling;
        struct dvfs_rail *rail = tegra_core_rail;
@@ -795,12 +795,21 @@ out:
        return ret;
 }
 #else
-int tegra_dvfs_override_core_voltage(int override_mv)
+static int dvfs_override_core_voltage(int override_mv)
 {
        pr_err("%s: vdd core override is not supported\n", __func__);
        return -ENOSYS;
 }
 #endif
+
+int tegra_dvfs_override_core_voltage(struct clk *c, int override_mv)
+{
+       if (!c->dvfs || !c->dvfs->can_override) {
+               pr_err("%s: %s cannot override vdd core\n", __func__, c->name);
+               return -EPERM;
+       }
+       return dvfs_override_core_voltage(override_mv);
+}
 EXPORT_SYMBOL(tegra_dvfs_override_core_voltage);
 
 /* May only be called during clock init, does not take any locks on clock c. */
@@ -1691,7 +1700,7 @@ static int core_override_get(void *data, u64 *val)
 }
 static int core_override_set(void *data, u64 val)
 {
-       return tegra_dvfs_override_core_voltage((int)val);
+       return dvfs_override_core_voltage((int)val);
 }
 DEFINE_SIMPLE_ATTRIBUTE(core_override_fops,
                        core_override_get, core_override_set, "%llu\n");
index 3662b59..fb194ee 100644 (file)
@@ -2127,7 +2127,7 @@ static int sdhci_tegra_set_tuning_voltage(struct sdhci_host *sdhci,
        SDHCI_TEGRA_DBG("%s: Setting vcore override %d\n",
                mmc_hostname(sdhci->mmc), voltage);
        /* First clear any previous dvfs override settings */
-       err = tegra_dvfs_override_core_voltage(0);
+       err = tegra_dvfs_override_core_voltage(pltfm_host->clk, 0);
        if (!voltage)
                return err;
 
@@ -2144,7 +2144,7 @@ static int sdhci_tegra_set_tuning_voltage(struct sdhci_host *sdhci,
                        nom_emc_freq_set = true;
        }
 
-       err = tegra_dvfs_override_core_voltage(voltage);
+       err = tegra_dvfs_override_core_voltage(pltfm_host->clk, voltage);
        if (err)
                dev_err(mmc_dev(sdhci->mmc),
                        "failed to set vcore override %dmv\n", voltage);
index ace4ad1..519dc84 100644 (file)
@@ -139,7 +139,7 @@ void tegra_periph_reset_assert(struct clk *c);
 void tegra_clocks_init(void);
 void tegra_clocks_apply_init_table(void);
 
-static inline int tegra_dvfs_override_core_voltage(int override_mv)
+static inline int tegra_dvfs_override_core_voltage(struct clk *c, int override_mv)
 {
        return -EINVAL;
 }
@@ -158,7 +158,7 @@ struct notifier_block;
 
 int tegra_dvfs_get_freqs(struct clk *c, unsigned long **freqs, int *num_freqs);
 int tegra_dvfs_set_rate(struct clk *c, unsigned long rate);
-int tegra_dvfs_override_core_voltage(int override_mv);
+int tegra_dvfs_override_core_voltage(struct clk *c, int override_mv);
 unsigned long clk_get_rate_all_locked(struct clk *c);
 int tegra_dvfs_rail_disable_by_name(const char *reg_id);
 int tegra_register_clk_rate_notifier(struct clk *c, struct notifier_block *nb);