This patch adds omap_device_set_rate and omap_device_get_rate API's which can be used to generic device rate scaling. Signed-off-by: Thara Gopinath <thara@xxxxxx> --- arch/arm/plat-omap/include/plat/omap_device.h | 2 + arch/arm/plat-omap/omap_device.c | 87 +++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index 3694b62..e0d06bb 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -114,6 +114,8 @@ int omap_device_enable_hwmods(struct omap_device *od); int omap_device_disable_clocks(struct omap_device *od); int omap_device_enable_clocks(struct omap_device *od); +int omap_device_set_rate(struct device *dev, unsigned long rate); +unsigned long omap_device_get_rate(struct device *dev); /* * Entries should be kept in latency order ascending diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 6614cba..900bb5d 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -85,6 +85,8 @@ #include <plat/omap_device.h> #include <plat/omap_hwmod.h> +#include <plat/opp.h> +#include <plat/voltage.h> /* These parameters are passed to _omap_device_{de,}activate() */ #define USE_WAKEUP_LAT 0 @@ -734,3 +736,88 @@ int omap_device_enable_clocks(struct omap_device *od) /* XXX pass along return value here? */ return 0; } + +/** + * omap_device_set_rate - Set a new rate at which the device is to operate + * @dev : the device pointer + * @rate : the rnew rate for the device. + * + * This API gets the device opp table associated with this device and + * tries putting the device to the requested rate and the voltage domain + * associated with the device to the voltage corresponding to the + * requested rate. Since multiple devices can be assocciated with a + * voltage domain this API finds out the possible voltage the + * voltage domain can enter and then decides on the final device + * rate. Return 0 on success else the error value + */ +int omap_device_set_rate(struct device *dev, unsigned long rate) +{ + struct device_opp *dev_opp; + struct omap_opp *opp; + unsigned long volt, freq; + int ret; + + dev_opp = opp_find_dev_opp(dev); + if (IS_ERR(dev_opp)) { + dev_warn(dev, "%s: Unable to find device opp table\n", + __func__); + return -ENODEV; + } + + /* Get the possible rate from the opp layer */ + freq = rate; + opp = opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) { + dev_err(dev, "%s: Unable to find OPP for freq%ld\n", + __func__, rate); + return -ENODEV; + } + if (unlikely(freq != rate)) + dev_warn(dev, "%s: Available freq %ld != dpll freq %ld.\n", + __func__, freq, rate); + + /* Get the voltage corresponding to the requested frequency */ + volt = opp_get_voltage(opp); + + /* + * Call into the voltage layer to get the final voltage possible + * for the voltage domain associated with the device. + */ + + ret = omap_volt_get_final(dev_opp->volt_domain, dev, &volt); + if (ret) { + dev_err(dev, "%s: Unable to get the final volt for scaling\n", + __func__); + return ret; + } + + /* Do the actual scaling */ + return omap_voltage_scale(dev_opp->volt_domain, volt); +} + +/** + * omap_device_get_rate - Gets the current operating rate of the device + * @dev - the device pointer + * + * This API returns the current operating rate of the device on success. + * Else returns the error value. + */ +unsigned long omap_device_get_rate(struct device *dev) +{ + struct device_opp *dev_opp; + + dev_opp = opp_find_dev_opp(dev); + + if (IS_ERR(dev_opp)) { + dev_warn(dev, "%s: Unable to find device opp table\n", + __func__); + return -ENODEV; + } + + if (!dev_opp->get_rate) { + dev_warn(dev, "%s: No get_rate API\n", __func__); + return -EINVAL; + } + + return dev_opp->get_rate(dev); +} -- 1.7.0.rc1.33.g07cf0f -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html