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
Reviewed-by: Mrutyunjay Sawant <msawant@nvidia.com>
Tested-by: Mrutyunjay Sawant <msawant@nvidia.com>

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

index 730c0dc..9bd2408 100644 (file)
@@ -615,7 +615,7 @@ EXPORT_SYMBOL(tegra_dvfs_set_rate);
 #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;
@@ -675,12 +675,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. */
@@ -1378,7 +1387,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 bcce817..89ac22d 100644 (file)
@@ -40,7 +40,7 @@ void tegra_periph_reset_deassert(struct clk *c);
 void tegra_periph_reset_assert(struct clk *c);
 
 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);
 
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
index a79de81..70295b8 100644 (file)
@@ -2073,7 +2073,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;
 
@@ -2089,7 +2089,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);