On 2018년 11월 22일 03:01, Lukasz Luba wrote: > The patch adds support for handling suspend/resume process. > It uses atomic variables to make sure no race condition > affects the process. > > The patch draws on Tobias Jakobi's work posted ~2 years ago, who tried to > solve issue with devfreq device's frequency during suspend/resume. > During the discussion on LKML some corner cases and comments appeared > related to the design. This patch address them keeping in mind suggestions > from Chanwoo Choi. Please remove the duplicate information about patch history. > > Suggested-by: Tobias Jakobi <tjakobi@xxxxxxxxxxxxxxxxxxxxx> > Suggested-by: Chanwoo Choi <cw00.choi@xxxxxxxxxxx> > Signed-off-by: Lukasz Luba <l.luba@xxxxxxxxxxxxxxxxxxx> > --- > drivers/devfreq/devfreq.c | 45 +++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 39 insertions(+), 6 deletions(-) > > diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c > index cf9c643..7e09de8 100644 > --- a/drivers/devfreq/devfreq.c > +++ b/drivers/devfreq/devfreq.c > @@ -872,14 +872,33 @@ EXPORT_SYMBOL(devm_devfreq_remove_device); > */ > int devfreq_suspend_device(struct devfreq *devfreq) > { > - if (!devfreq) > - return -EINVAL; > + int ret; Move 'ret' definition under 'if (devfreq->suspend_freq) {' because 'ret' is used if suspend_freq isn't zero. > + unsigned long prev_freq; > + u32 flags = 0; > + > + if (!devfreq) > + return -EINVAL; > + > + if (devfreq->governor) { > + ret = devfreq->governor->event_handler(devfreq, > + DEVFREQ_GOV_SUSPEND, NULL); > + if (ret) > + return ret; > + } > > - if (!devfreq->governor) > - return 0; > + if (devfreq->suspend_freq) { > + if (atomic_inc_return(&devfreq->suspend_count) > 1) > + return 0; > > - return devfreq->governor->event_handler(devfreq, > - DEVFREQ_GOV_SUSPEND, NULL); > + ret = devfreq_set_target(devfreq, devfreq->suspend_freq, > + &prev_freq, flags); Remove the 'prev_freq' parameter. > + if (ret) > + return ret; > + > + devfreq->resume_freq = prev_freq; As I commented on patch2, if devfreq_set_taget save the current frequency to 'devfreq->resume_freq', this line is not needed. > + } > + > + return 0; > } > EXPORT_SYMBOL(devfreq_suspend_device); > > @@ -893,9 +912,23 @@ EXPORT_SYMBOL(devfreq_suspend_device); > */ > int devfreq_resume_device(struct devfreq *devfreq) > { > + int ret; Move 'ret' definition under 'if (devfreq->suspend_freq) {' because 'ret' is used if suspend_freq isn't zero. > + unsigned long prev_freq; Remove prev_freq variable which is not used on this function. After calling devfreq_set_target, prev_freq is not used. > + u32 flags = 0; > + > if (!devfreq) > return -EINVAL; > > + if (devfreq->suspend_freq) { > + if (atomic_dec_return(&devfreq->suspend_count) >= 1) > + return 0; > + > + ret = devfreq_set_target(devfreq, devfreq->resume_freq, > + &prev_freq, flags); Remove the 'prev_freq' parameter. > + if (ret) > + return ret; > + } > + > if (!devfreq->governor) > return 0; > > -- Best Regards, Chanwoo Choi Samsung Electronics