From dc50eab76b709d68175a358d6e23a5a3890764d3 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 19:39:57 +0200 Subject: Merging upstream version 6.7.7. Signed-off-by: Daniel Baumann --- drivers/devfreq/devfreq.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'drivers/devfreq/devfreq.c') diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 81d9df89dd..7162d2bad4 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -88,7 +88,7 @@ static unsigned long find_available_min_freq(struct devfreq *devfreq) struct dev_pm_opp *opp; unsigned long min_freq = 0; - opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &min_freq); + opp = dev_pm_opp_find_freq_ceil_indexed(devfreq->dev.parent, &min_freq, 0); if (IS_ERR(opp)) min_freq = 0; else @@ -102,7 +102,7 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq) struct dev_pm_opp *opp; unsigned long max_freq = ULONG_MAX; - opp = dev_pm_opp_find_freq_floor(devfreq->dev.parent, &max_freq); + opp = dev_pm_opp_find_freq_floor_indexed(devfreq->dev.parent, &max_freq, 0); if (IS_ERR(opp)) max_freq = 0; else @@ -196,7 +196,7 @@ static int set_freq_table(struct devfreq *devfreq) return -ENOMEM; for (i = 0, freq = 0; i < devfreq->max_state; i++, freq++) { - opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq); + opp = dev_pm_opp_find_freq_ceil_indexed(devfreq->dev.parent, &freq, 0); if (IS_ERR(opp)) { devm_kfree(devfreq->dev.parent, devfreq->freq_table); return PTR_ERR(opp); @@ -461,10 +461,14 @@ static void devfreq_monitor(struct work_struct *work) if (err) dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + if (devfreq->stop_polling) + goto out; + queue_delayed_work(devfreq_wq, &devfreq->work, msecs_to_jiffies(devfreq->profile->polling_ms)); - mutex_unlock(&devfreq->lock); +out: + mutex_unlock(&devfreq->lock); trace_devfreq_monitor(devfreq); } @@ -483,6 +487,10 @@ void devfreq_monitor_start(struct devfreq *devfreq) if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) return; + mutex_lock(&devfreq->lock); + if (delayed_work_pending(&devfreq->work)) + goto out; + switch (devfreq->profile->timer) { case DEVFREQ_TIMER_DEFERRABLE: INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); @@ -491,12 +499,16 @@ void devfreq_monitor_start(struct devfreq *devfreq) INIT_DELAYED_WORK(&devfreq->work, devfreq_monitor); break; default: - return; + goto out; } if (devfreq->profile->polling_ms) queue_delayed_work(devfreq_wq, &devfreq->work, msecs_to_jiffies(devfreq->profile->polling_ms)); + +out: + devfreq->stop_polling = false; + mutex_unlock(&devfreq->lock); } EXPORT_SYMBOL(devfreq_monitor_start); @@ -513,6 +525,14 @@ void devfreq_monitor_stop(struct devfreq *devfreq) if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) return; + mutex_lock(&devfreq->lock); + if (devfreq->stop_polling) { + mutex_unlock(&devfreq->lock); + return; + } + + devfreq->stop_polling = true; + mutex_unlock(&devfreq->lock); cancel_delayed_work_sync(&devfreq->work); } EXPORT_SYMBOL(devfreq_monitor_stop); @@ -2057,18 +2077,18 @@ struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { /* The freq is an upper bound. opp should be lower */ - opp = dev_pm_opp_find_freq_floor(dev, freq); + opp = dev_pm_opp_find_freq_floor_indexed(dev, freq, 0); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ERANGE)) - opp = dev_pm_opp_find_freq_ceil(dev, freq); + opp = dev_pm_opp_find_freq_ceil_indexed(dev, freq, 0); } else { /* The freq is an lower bound. opp should be higher */ - opp = dev_pm_opp_find_freq_ceil(dev, freq); + opp = dev_pm_opp_find_freq_ceil_indexed(dev, freq, 0); /* If not available, use the closest opp */ if (opp == ERR_PTR(-ERANGE)) - opp = dev_pm_opp_find_freq_floor(dev, freq); + opp = dev_pm_opp_find_freq_floor_indexed(dev, freq, 0); } return opp; -- cgit v1.2.3