[PATCH v6 1/6] clk: bcm: rpi: Manage clock rate in prepare/unprepare callbacks

Maíra Canal mcanal at igalia.com
Thu Mar 5 04:37:28 PST 2026


Hi Maxime,

On 05/03/26 05:53, Maxime Ripard wrote:
> On Wed, Feb 25, 2026 at 10:57:11AM -0300, Maíra Canal wrote:
>> Hi Maxime,
>>
>> On 24/02/26 11:11, Maxime Ripard wrote:
>>> Hi Maira,
>>>
>>

[...]

>>>> @@ -306,10 +313,19 @@ static int raspberrypi_fw_prepare(struct clk_hw *hw)
>>>>    static void raspberrypi_fw_unprepare(struct clk_hw *hw)
>>>>    {
>>>>    	const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
>>>> +	struct raspberrypi_clk_variant *variant = data->variant;
>>>>    	struct raspberrypi_clk *rpi = data->rpi;
>>>>    	u32 state = 0;
>>>>    	int ret;
>>>> +	/*
>>>> +	 * On current firmware versions, RPI_FIRMWARE_SET_CLOCK_STATE doesn't
>>>> +	 * actually power off the clock. To achieve meaningful power consumption
>>>> +	 * reduction, the driver needs to set the clock rate to minimum before
>>>> +	 * disabling it.
>>>> +	 */
>>>> +	raspberrypi_fw_set_rate(hw, variant->min_rate, 0);
>>>
>>> I'm not sure setting it to variant->min_rate would work directly either,
>>> since it would break consumers expectations. Also, can we guard it with
>>
>> The clock is being unprepared, which means that any consumer that wants
>> to use it again must call clk_prepare() first, at which point the rate
>> gets restored (for maximize clocks) or re-established by the consumer
>> via clk_set_rate(). Considering that no consumer should be relying on
>> the rate of an unprepared clock, I understand that there are no
>> expectations to break here.
> 
> For both of those, I still feel like it's a pretty strong deviation from
> the general expected behaviour of the CCF API. From what you're saying,
> we shouldn't notice it too much, but at the very least we should
> document it explicitly, both what the deviation is, and why we think
> it's ok.
> 

I'll make sure to add such comment in the next version.

>>> a version check if we know that there's some good and bad firmwares?
>>
>> So far, all firmware versions have this issue. For future firmware
>> releases, it might change, but so far, all firmware versions have this
>> issue.
> 
> ack :)
> 
>>>
>>>>    	ret = raspberrypi_clock_property(rpi->firmware, data,
>>>>    					 RPI_FIRMWARE_SET_CLOCK_STATE, &state);
>>>>    	if (ret)
>>>> @@ -334,7 +350,7 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
>>>>    {
>>>>    	struct raspberrypi_clk_data *data;
>>>>    	struct clk_init_data init = {};
>>>> -	u32 min_rate, max_rate;
>>>> +	unsigned long rate;
>>>>    	int ret;
>>>>    	data = devm_kzalloc(rpi->dev, sizeof(*data), GFP_KERNEL);
>>>> @@ -354,18 +370,20 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
>>>>    	data->hw.init = &init;
>>>> -	ret = raspberrypi_clock_property(rpi->firmware, data,
>>>> -					 RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
>>>> -					 &min_rate);
>>>> -	if (ret) {
>>>> -		dev_err(rpi->dev, "Failed to get clock %d min freq: %d\n",
>>>> -			id, ret);
>>>> -		return ERR_PTR(ret);
>>>> +	if (!variant->min_rate) {
>>>> +		ret = raspberrypi_clock_property(rpi->firmware, data,
>>>> +						 RPI_FIRMWARE_GET_MIN_CLOCK_RATE,
>>>> +						 &variant->min_rate);
>>>> +		if (ret) {
>>>> +			dev_err(rpi->dev, "Failed to get clock %d min freq: %d\n",
>>>> +				id, ret);
>>>> +			return ERR_PTR(ret);
>>>> +		}
>>>>    	}
>>>
>>> It feels to me like it would need to be a separate patch. Why do you
>>> need to override the minimum clock rate reported by the firmware?
>>
>> This change is needed because the prepare/unprepare callbacks need
>> access to the min/max rates. In the current code, these are local
>> variables in raspberrypi_clk_register(). Storing them in the variant
>> struct makes them available to the callbacks. The `if (!variant-
>>> min_rate)` guard only preserves the existing behavior for clocks like
>> M2MC that have a hard-coded minimum rate.
> 
> min_rate itself is indeed available only in raspberrypi_clk_register(),
> but its main use is to call clk_hw_set_rate_range to use it as the
> minimum clock rate.
 > > In prepare/unprepare, you should be able to use clk_hw_get_rate_range()
> to retrieve it, or am I missing something?

Okay, I got now, I didn't know about the function
clk_hw_get_rate_range(). Thanks for your feedback! I'd address it in the
next version.

Best regards,
- Maíra

> 
> Maxime




More information about the linux-arm-kernel mailing list