Loading drivers/devfreq/devfreq.c +38 −4 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ int update_devfreq(struct devfreq *devfreq) { unsigned long freq; int err = 0; u32 flags = 0; if (!mutex_is_locked(&devfreq->lock)) { WARN(true, "devfreq->lock must be locked by the caller.\n"); Loading @@ -94,7 +95,24 @@ int update_devfreq(struct devfreq *devfreq) if (err) return err; err = devfreq->profile->target(devfreq->dev.parent, &freq); /* * Adjust the freuqency with user freq and QoS. * * List from the highest proiority * max_freq (probably called by thermal when it's too hot) * min_freq */ if (devfreq->min_freq && freq < devfreq->min_freq) { freq = devfreq->min_freq; flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */ } if (devfreq->max_freq && freq > devfreq->max_freq) { freq = devfreq->max_freq; flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ } err = devfreq->profile->target(devfreq->dev.parent, &freq, flags); if (err) return err; Loading Loading @@ -625,14 +643,30 @@ module_exit(devfreq_exit); * freq value given to target callback. * @dev The devfreq user device. (parent of devfreq) * @freq The frequency given to target function * @flags Flags handed from devfreq framework. * */ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq) struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { struct opp *opp = opp_find_freq_ceil(dev, freq); struct opp *opp; if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { /* The freq is an upper bound. opp should be lower */ opp = opp_find_freq_floor(dev, freq); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ENODEV)) opp = opp_find_freq_ceil(dev, freq); } else { /* The freq is an lower bound. opp should be higher */ opp = opp_find_freq_ceil(dev, freq); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ENODEV)) opp = opp_find_freq_floor(dev, freq); } return opp; } Loading drivers/devfreq/exynos4_bus.c +10 −4 Original line number Diff line number Diff line Loading @@ -619,13 +619,19 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, return err; } static int exynos4_bus_target(struct device *dev, unsigned long *_freq) static int exynos4_bus_target(struct device *dev, unsigned long *_freq, u32 flags) { int err = 0; struct busfreq_data *data = dev_get_drvdata(dev); struct opp *opp = devfreq_recommended_opp(dev, _freq); unsigned long old_freq = opp_get_freq(data->curr_opp); struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct busfreq_data *data = platform_get_drvdata(pdev); struct opp *opp = devfreq_recommended_opp(dev, _freq, flags); unsigned long freq = opp_get_freq(opp); unsigned long old_freq = opp_get_freq(data->curr_opp); if (IS_ERR(opp)) return PTR_ERR(opp); if (old_freq == freq) return 0; Loading include/linux/devfreq.h +13 −3 Original line number Diff line number Diff line Loading @@ -44,6 +44,14 @@ struct devfreq_dev_status { void *private_data; }; /* * The resulting frequency should be at most this. (this bound is the * least upper bound; thus, the resulting freq should be lower or same) * If the flag is not set, the resulting frequency should be at most the * bound (greatest lower bound) */ #define DEVFREQ_FLAG_LEAST_UPPER_BOUND 0x1 /** * struct devfreq_dev_profile - Devfreq's user device profile * @initial_freq The operating frequency when devfreq_add_device() is Loading @@ -54,6 +62,8 @@ struct devfreq_dev_status { * higher than any operable frequency, set maximum. * Before returning, target function should set * freq at the current frequency. * The "flags" parameter's possible values are * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. * @exit An optional callback that is called when devfreq Loading @@ -66,7 +76,7 @@ struct devfreq_dev_profile { unsigned long initial_freq; unsigned int polling_ms; int (*target)(struct device *dev, unsigned long *freq); int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); void (*exit)(struct device *dev); Loading Loading @@ -165,7 +175,7 @@ extern int devfreq_remove_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq); unsigned long *freq, u32 flags); extern int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq); extern int devfreq_unregister_opp_notifier(struct device *dev, Loading Loading @@ -216,7 +226,7 @@ static int devfreq_remove_device(struct devfreq *devfreq) } static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq) unsigned long *freq, u32 flags) { return -EINVAL; } Loading Loading
drivers/devfreq/devfreq.c +38 −4 Original line number Diff line number Diff line Loading @@ -83,6 +83,7 @@ int update_devfreq(struct devfreq *devfreq) { unsigned long freq; int err = 0; u32 flags = 0; if (!mutex_is_locked(&devfreq->lock)) { WARN(true, "devfreq->lock must be locked by the caller.\n"); Loading @@ -94,7 +95,24 @@ int update_devfreq(struct devfreq *devfreq) if (err) return err; err = devfreq->profile->target(devfreq->dev.parent, &freq); /* * Adjust the freuqency with user freq and QoS. * * List from the highest proiority * max_freq (probably called by thermal when it's too hot) * min_freq */ if (devfreq->min_freq && freq < devfreq->min_freq) { freq = devfreq->min_freq; flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */ } if (devfreq->max_freq && freq > devfreq->max_freq) { freq = devfreq->max_freq; flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ } err = devfreq->profile->target(devfreq->dev.parent, &freq, flags); if (err) return err; Loading Loading @@ -625,14 +643,30 @@ module_exit(devfreq_exit); * freq value given to target callback. * @dev The devfreq user device. (parent of devfreq) * @freq The frequency given to target function * @flags Flags handed from devfreq framework. * */ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq) struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { struct opp *opp = opp_find_freq_ceil(dev, freq); struct opp *opp; if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { /* The freq is an upper bound. opp should be lower */ opp = opp_find_freq_floor(dev, freq); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ENODEV)) opp = opp_find_freq_ceil(dev, freq); } else { /* The freq is an lower bound. opp should be higher */ opp = opp_find_freq_ceil(dev, freq); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ENODEV)) opp = opp_find_freq_floor(dev, freq); } return opp; } Loading
drivers/devfreq/exynos4_bus.c +10 −4 Original line number Diff line number Diff line Loading @@ -619,13 +619,19 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, return err; } static int exynos4_bus_target(struct device *dev, unsigned long *_freq) static int exynos4_bus_target(struct device *dev, unsigned long *_freq, u32 flags) { int err = 0; struct busfreq_data *data = dev_get_drvdata(dev); struct opp *opp = devfreq_recommended_opp(dev, _freq); unsigned long old_freq = opp_get_freq(data->curr_opp); struct platform_device *pdev = container_of(dev, struct platform_device, dev); struct busfreq_data *data = platform_get_drvdata(pdev); struct opp *opp = devfreq_recommended_opp(dev, _freq, flags); unsigned long freq = opp_get_freq(opp); unsigned long old_freq = opp_get_freq(data->curr_opp); if (IS_ERR(opp)) return PTR_ERR(opp); if (old_freq == freq) return 0; Loading
include/linux/devfreq.h +13 −3 Original line number Diff line number Diff line Loading @@ -44,6 +44,14 @@ struct devfreq_dev_status { void *private_data; }; /* * The resulting frequency should be at most this. (this bound is the * least upper bound; thus, the resulting freq should be lower or same) * If the flag is not set, the resulting frequency should be at most the * bound (greatest lower bound) */ #define DEVFREQ_FLAG_LEAST_UPPER_BOUND 0x1 /** * struct devfreq_dev_profile - Devfreq's user device profile * @initial_freq The operating frequency when devfreq_add_device() is Loading @@ -54,6 +62,8 @@ struct devfreq_dev_status { * higher than any operable frequency, set maximum. * Before returning, target function should set * freq at the current frequency. * The "flags" parameter's possible values are * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. * @exit An optional callback that is called when devfreq Loading @@ -66,7 +76,7 @@ struct devfreq_dev_profile { unsigned long initial_freq; unsigned int polling_ms; int (*target)(struct device *dev, unsigned long *freq); int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); void (*exit)(struct device *dev); Loading Loading @@ -165,7 +175,7 @@ extern int devfreq_remove_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq); unsigned long *freq, u32 flags); extern int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq); extern int devfreq_unregister_opp_notifier(struct device *dev, Loading Loading @@ -216,7 +226,7 @@ static int devfreq_remove_device(struct devfreq *devfreq) } static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq) unsigned long *freq, u32 flags) { return -EINVAL; } Loading