This patch adds the separate target function to set the freq/voltage because the devfreq have to handle the passive devfreq device using passive governor when chaning the freq/voltage of parent devfreq device.
Signed-off-by: Chanwoo Choi <cw00.c...@samsung.com> --- drivers/devfreq/devfreq.c | 65 ++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 4bd7a8f71b07..e386f14d91c3 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -216,6 +216,43 @@ static int devfreq_notify_transition(struct devfreq *devfreq, return 0; } +static int devfreq_set_target(struct devfreq *devfreq, unsigned long new_freq, + u32 flags) +{ + struct devfreq_freqs freqs; + unsigned long freq, cur_freq; + int ret; + + freq = new_freq; + if (devfreq->profile->get_cur_freq) + devfreq->profile->get_cur_freq(devfreq->dev.parent, &cur_freq); + else + cur_freq = devfreq->previous_freq; + + freqs.old = cur_freq; + freqs.new = freq; + devfreq_notify_transition(devfreq, &freqs, DEVFREQ_PRECHANGE); + + ret = devfreq->profile->target(devfreq->dev.parent, &freq, flags); + if (ret < 0) { + freqs.new = cur_freq; + devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE); + return ret; + } + + freqs.new = freq; + devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE); + + if (devfreq->profile->freq_table + && (devfreq_update_status(devfreq, freq))) + dev_err(&devfreq->dev, + "Couldn't update frequency transition information.\n"); + + devfreq->previous_freq = freq; + + return 0; +} + /* Load monitoring helper functions for governors use */ /** @@ -227,8 +264,7 @@ static int devfreq_notify_transition(struct devfreq *devfreq, */ int update_devfreq(struct devfreq *devfreq) { - struct devfreq_freqs freqs; - unsigned long freq, cur_freq; + unsigned long freq; int err = 0; u32 flags = 0; @@ -262,31 +298,12 @@ int update_devfreq(struct devfreq *devfreq) flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ } - if (devfreq->profile->get_cur_freq) - devfreq->profile->get_cur_freq(devfreq->dev.parent, &cur_freq); - else - cur_freq = devfreq->previous_freq; - - freqs.old = cur_freq; - freqs.new = freq; - devfreq_notify_transition(devfreq, &freqs, DEVFREQ_PRECHANGE); - - err = devfreq->profile->target(devfreq->dev.parent, &freq, flags); - if (err) { - freqs.new = cur_freq; - devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE); + err = devfreq_set_target(devfreq, freq, flags); + if (err < 0) { + dev_err(devfreq->dev.parent, "failed to set frequency\n"); return err; } - freqs.new = freq; - devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE); - - if (devfreq->profile->freq_table) - if (devfreq_update_status(devfreq, freq)) - dev_err(&devfreq->dev, - "Couldn't update frequency transition information.\n"); - - devfreq->previous_freq = freq; return err; } EXPORT_SYMBOL(update_devfreq); -- 1.9.1