[PATCH v3 3/4] devfreq: Factor out devfreq_set_governor()

Jie Zhan zhanjie9 at hisilicon.com
Sun May 31 18:55:26 PDT 2026



On 5/21/2026 4:06 PM, zhenglifeng (A) wrote:
> On 5/19/2026 7:32 PM, Jie Zhan wrote:
>> governor_store() and devfreq_add_device() contain similar logic for setting
>> a governor when devfreq->governor is NULL.  Merge this into a common
>> function, devfreq_set_governor(), to reduce code duplication and unify the
>> entry of setting governors.
>>
>> This also prepares for further changes that get / put a module refcount of
>> the active governor and prevent the governor module from being unloaded
>> while it's in use.
>>
>> Signed-off-by: Jie Zhan <zhanjie9 at hisilicon.com>
>> ---
>>  drivers/devfreq/devfreq.c | 117 ++++++++++++++++++--------------------
>>  1 file changed, 56 insertions(+), 61 deletions(-)
>>
>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
>> index 53c40d795a13..9e3e6a7348f8 100644
>> --- a/drivers/devfreq/devfreq.c
>> +++ b/drivers/devfreq/devfreq.c
>> @@ -318,6 +318,59 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
>>  	return governor;
>>  }
>>  
>> +static int devfreq_set_governor(struct devfreq *df,
>> +				const struct devfreq_governor *new_gov)
>> +{
>> +	const struct devfreq_governor *old_gov;
>> +	struct device *dev;
>> +	int ret;
>> +
>> +	lockdep_assert_held(&devfreq_list_lock);
>> +
>> +	old_gov = df->governor;
>> +	dev = &df->dev;
>> +
>> +	if (old_gov) {
>> +		if (old_gov == new_gov)
>> +			return 0;
>> +
>> +		if (IS_SUPPORTED_FLAG(old_gov->flags, IMMUTABLE) ||
>> +		    IS_SUPPORTED_FLAG(new_gov->flags, IMMUTABLE))
>> +			return -EINVAL;
>> +
>> +		/* Stop the current governor */
>> +		ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
>> +		if (ret) {
>> +			dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
>> +				 __func__, df->governor->name, ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	/* Start the new governor */
>> +	df->governor = new_gov;
>> +	ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
>> +	if (ret) {
>> +		dev_warn(dev, "%s: Governor %s not started(%d)\n",
>> +			 __func__, df->governor->name, ret);
>> +
>> +		/* Restore previous governor */
>> +		df->governor = old_gov;
>> +		if (!df->governor)
>> +			return ret;
>> +
>> +		ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
>> +		if (ret) {
>> +			dev_err(dev, "%s: restore Governor %s failed (%d)\n",
>> +				__func__, df->governor->name, ret);
>> +			df->governor = NULL;
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	return sysfs_update_group(&df->dev.kobj, &gov_attr_group);
> 
> Here is a little problem which is not introduced by this patch. When
> starting new governor fails but restoring old governor succeeds, this
> function will return 0. This might lead users to believe that the governor
> has been successfully modified.
> 
Yes, good catch.  This suppresses the error code.

I think, from a quick glance, the path of restoring the old governor should
discard the return value of event_handler() and skip updating sysfs.



More information about the linux-arm-kernel mailing list