From: Chanwoo Choi <cw00.choi@samsung.com>
To: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>,
linux-samsung-soc@vger.kernel.org
Cc: linux-pm@vger.kernel.org, m.reichl@fivetechno.de, myungjoo.ham@gmail.com
Subject: Re: [RFC 1/4] PM / devfreq: Add DevFreq subsystem suspend/resume
Date: Thu, 24 Nov 2016 17:20:55 +0900 [thread overview]
Message-ID: <5836A2E7.5080504@samsung.com> (raw)
In-Reply-To: <583643A7.6020502@samsung.com>
Hi Tobias,
On 2016년 11월 24일 10:34, Chanwoo Choi wrote:
> Hi Tobias,
>
> I like your suggestion. But I have some comment on below.
>
> On 2016년 11월 23일 22:51, Tobias Jakobi wrote:
>> This suspend/resume operations works analogous to the
>> cpufreq_{suspend,resume}() calls in the CPUFreq subsystem.
>>
>> Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
>> ---
>> drivers/devfreq/devfreq.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
>> include/linux/devfreq.h | 10 +++++++
>> 2 files changed, 85 insertions(+)
>>
>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
>> index bf3ea76..2f1aa83 100644
>> --- a/drivers/devfreq/devfreq.c
>> +++ b/drivers/devfreq/devfreq.c
>> @@ -785,6 +785,81 @@ int devfreq_resume_device(struct devfreq *devfreq)
>> EXPORT_SYMBOL(devfreq_resume_device);
>>
>> /**
>> + * devfreq_suspend() - Suspend DevFreq governors
>> + *
>> + * Called during system wide Suspend/Hibernate cycles for suspending governors
>> + * in the same fashion as cpufreq_suspend().
>> + */
>> +void devfreq_suspend(void)
>> +{
>> + struct devfreq *devfreq;
>> + unsigned long freq;
>> + int ret;
>> +
>> + mutex_lock(&devfreq_list_lock);
>> +
>> + list_for_each_entry(devfreq, &devfreq_list, node) {
>> + if (!devfreq->suspend_freq)
>> + continue;
>> +
>> + ret = devfreq_suspend_device(devfreq);
The devfreq_suspend_device() stop the monitoring of governors.
But, this function is exported. It means that each devfreq device.
can call the devfreq_suspend/resume_device() (e.g., int drivers/scsi/ufs/ufshcd.c)
So, you should consider following case:
- case :Before calling the devfreq_suspend() and specific devfreq already call
the devfreq_suspend_device(), how to support it?
In this case, the specific devfreq device don't want to call
the devfreq_resume_device() in the devfreq_resume().
>> + if (ret < 0) {
>> + dev_warn(&devfreq->dev, "%s: governor suspend failed\n", __func__);
>> + continue;
>> + }
>> +
>> + devfreq->resume_freq = 0;
>> + if (devfreq->profile->get_cur_freq) {
>> + ret = devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq);
>> + if (ret >= 0)
>> + devfreq->resume_freq = freq;
>> + }
>> +
>> + freq = devfreq->suspend_freq;
>> + ret = devfreq->profile->target(devfreq->dev.parent, &freq, 0);
>
>
> DEVFREQ subsystem has the passive governor[2] and devfreq device using passive[1]
> governor depends on the parent devfreq device. The passive governor uses
> 'DEVFREQ_TRANSITION_NOTIFIER' notifier to track the changed state of
> parent devfreq device.
>
> When changing the clock/voltage of parent devfreq device,
> DEVFREQ subsystem have to notify the changed frequency
> to the passive devfreq device.
>
> So, you should call the devfreq_notifiy_transition()
> before/after 'devfreq->profile->target' as following:
> You can refer the update_devfreq() function
> that is how to use devfreq_notifiy_transition().
>
> For example,
> struct devfreq_freq freqs;
>
> if (devfreq->profile->get_cur_freq) {
> ret = devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq);
> if (ret >= 0)
> devfreq->resume_freq = freq;
> } else {
> devfreq->resume_freq = devfreq_previous_freq;
> }
>
> freqs.old = devfreq->resume_freq;
> freqs.new = devfreq->suspend_freq;
> devfreq_notify_transition(devfreq, &freqs, DEVFREQ_PRECHANGE);
>
> freq = devfreq->suspend_freq;
> ret = devfreq->profile->target(devfreq->dev.parent, &freq, 0);
>
> freqs.new = freq;
> devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE);
>
> if (ret < 0)
> dev_warn(&devfreq->dev, "%s: setting suspend frequency failed\n", __func__);
> }
>
> [1] DEVFREQ_TRANSITION_NOTIFIER notifier
> - https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0fe3a66410a3ba96679be903f1e287d7a0a264a9
> [2] DEVFREQ passive governor
> - https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=996133119f57334c38b020dbfaaac5b5eb127e29
>
>> +
>> + if (ret < 0)
>> + dev_warn(&devfreq->dev, "%s: setting suspend frequency failed\n", __func__);
>> + }
>> +
>> + mutex_unlock(&devfreq_list_lock);
>> +}
>> +
>> +/**
>> + * devfreq_resume() - Resume DevFreq governors
>> + *
>> + * Called during system wide Suspend/Hibernate cycle for resuming governors that
>> + * are suspended with devfreq_suspend().
>> + */
>> +void devfreq_resume(void)
>> +{
>> + struct devfreq *devfreq;
>> + unsigned long freq;
>> + int ret;
>> +
>> + mutex_lock(&devfreq_list_lock);
>> +
>> + list_for_each_entry(devfreq, &devfreq_list, node) {
>> + if (!devfreq->suspend_freq)
>> + continue;
>> +
>> + freq = devfreq->resume_freq;
>> + ret = devfreq->profile->target(devfreq->dev.parent, &freq, 0);
>
> ditto.
>
>> +
>> + if (ret < 0) {
>> + dev_warn(&devfreq->dev, "%s: setting resume frequency failed\n", __func__);
>> + continue;
>> + }
>> +
>> + ret = devfreq_resume_device(devfreq);
>> + if (ret < 0)
>> + dev_warn(&devfreq->dev, "%s: governor resume failed\n", __func__);
>> + }
>> +
>> + mutex_unlock(&devfreq_list_lock);
>> +}
>> +
>> +/**
>> * devfreq_add_governor() - Add devfreq governor
>> * @governor: the devfreq governor to be added
>> */
>> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
>> index 2de4e2e..555d024 100644
>> --- a/include/linux/devfreq.h
>> +++ b/include/linux/devfreq.h
>> @@ -171,6 +171,9 @@ struct devfreq {
>> struct notifier_block nb;
>> struct delayed_work work;
>>
>> + unsigned long suspend_freq; /* freq during devfreq suspend */
>> + unsigned long resume_freq; /* freq restored after suspend cycle */
>> +
>> unsigned long previous_freq;
>> struct devfreq_dev_status last_status;
>>
>> @@ -211,6 +214,10 @@ extern void devm_devfreq_remove_device(struct device *dev,
>> extern int devfreq_suspend_device(struct devfreq *devfreq);
>> extern int devfreq_resume_device(struct devfreq *devfreq);
>>
>> +/* Suspend/resume the entire Devfreq subsystem. */
>> +void devfreq_suspend(void);
>> +void devfreq_resume(void);
>> +
>> /* Helper functions for devfreq user device driver with OPP. */
>> extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
>> unsigned long *freq, u32 flags);
>> @@ -410,6 +417,9 @@ static inline int devfreq_update_stats(struct devfreq *df)
>> {
>> return -EINVAL;
>> }
>> +
>> +static inline void devfreq_suspend(void) {}
>> +static inline void devfreq_resume(void) {}
>> #endif /* CONFIG_PM_DEVFREQ */
>>
>> #endif /* __LINUX_DEVFREQ_H__ */
>>
>
>
Best Regards,
Chanwoo Choi
next prev parent reply other threads:[~2016-11-24 8:20 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-23 13:51 [RFC 0/4] PM / devfreq: draft for OPP suspend impl Tobias Jakobi
2016-11-23 13:51 ` [RFC 1/4] PM / devfreq: Add DevFreq subsystem suspend/resume Tobias Jakobi
2016-11-24 1:34 ` Chanwoo Choi
2016-11-24 8:20 ` Chanwoo Choi [this message]
2016-11-24 14:20 ` Tobias Jakobi
2016-11-23 13:51 ` [RFC 2/4] PM / devfreq: suspend subsystem on system suspend/hibernate Tobias Jakobi
2016-11-24 1:35 ` Chanwoo Choi
2016-11-23 13:51 ` [RFC 3/4] PM / devfreq: exynos-bus: add support for suspend OPP Tobias Jakobi
2016-11-24 1:38 ` Chanwoo Choi
2016-11-24 14:22 ` Tobias Jakobi
2016-11-23 13:51 ` [RFC 4/4] ARM: dts: exynos4x12: add suspend OPP for DMC and leftbus Tobias Jakobi
2016-11-24 1:41 ` Chanwoo Choi
2016-11-24 14:27 ` Tobias Jakobi
2016-11-24 23:44 ` Chanwoo Choi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5836A2E7.5080504@samsung.com \
--to=cw00.choi@samsung.com \
--cc=linux-pm@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=m.reichl@fivetechno.de \
--cc=myungjoo.ham@gmail.com \
--cc=tjakobi@math.uni-bielefeld.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.