diff mbox series

[v4,5/6] pwm: meson: don't carry internal clock elements around

Message ID 20231222111658.832167-6-jbrunet@baylibre.com (mailing list archive)
State New, archived
Headers show
Series pwm: meson: dt-bindings fixup | expand

Commit Message

Jerome Brunet Dec. 22, 2023, 11:16 a.m. UTC
Pointers to the internal clock elements of the PWM are useless
after probe. There is no need to carry this around in the device
data. Just let devres deal with it.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
 drivers/pwm/pwm-meson.c | 67 ++++++++++++++++++++++++-----------------
 1 file changed, 39 insertions(+), 28 deletions(-)

Comments

Uwe Kleine-König Jan. 24, 2024, 9:02 a.m. UTC | #1
On Fri, Dec 22, 2023 at 12:16:53PM +0100, Jerome Brunet wrote:
> Pointers to the internal clock elements of the PWM are useless
> after probe. There is no need to carry this around in the device
> data. Just let devres deal with it.
> 
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
> ---
>  drivers/pwm/pwm-meson.c | 67 ++++++++++++++++++++++++-----------------
>  1 file changed, 39 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
> index 15c44185d784..fb113bc8da29 100644
> --- a/drivers/pwm/pwm-meson.c
> +++ b/drivers/pwm/pwm-meson.c
> @@ -90,9 +90,6 @@ struct meson_pwm_channel {
>  	unsigned int hi;
>  	unsigned int lo;
>  
> -	struct clk_mux mux;
> -	struct clk_divider div;
> -	struct clk_gate gate;
>  	struct clk *clk;
>  };
>  
> @@ -442,6 +439,13 @@ static int meson_pwm_init_channels(struct device *dev)
>  		struct meson_pwm_channel *channel = &meson->channels[i];
>  		struct clk_parent_data div_parent = {}, gate_parent = {};
>  		struct clk_init_data init = {};
> +		struct clk_divider *div;
> +		struct clk_gate *gate;
> +		struct clk_mux *mux;
> +
> +		mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
> +		if (!mux)
> +			return -ENOMEM;

I don't like this change. While it doesn't increase the memory used, it
fragments the used memory and increases the overhead of memory
management and the number of devm allocations.

Are these members of meson_pwm_channel in the way for anything later?

Best regards
Uwe
Jerome Brunet Jan. 24, 2024, 9:16 a.m. UTC | #2
On Wed 24 Jan 2024 at 10:02, Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:

> [[PGP Signed Part:Undecided]]
> On Fri, Dec 22, 2023 at 12:16:53PM +0100, Jerome Brunet wrote:
>> Pointers to the internal clock elements of the PWM are useless
>> after probe. There is no need to carry this around in the device
>> data. Just let devres deal with it.
>> 
>> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
>> ---
>>  drivers/pwm/pwm-meson.c | 67 ++++++++++++++++++++++++-----------------
>>  1 file changed, 39 insertions(+), 28 deletions(-)
>> 
>> diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
>> index 15c44185d784..fb113bc8da29 100644
>> --- a/drivers/pwm/pwm-meson.c
>> +++ b/drivers/pwm/pwm-meson.c
>> @@ -90,9 +90,6 @@ struct meson_pwm_channel {
>>  	unsigned int hi;
>>  	unsigned int lo;
>>  
>> -	struct clk_mux mux;
>> -	struct clk_divider div;
>> -	struct clk_gate gate;
>>  	struct clk *clk;
>>  };
>>  
>> @@ -442,6 +439,13 @@ static int meson_pwm_init_channels(struct device *dev)
>>  		struct meson_pwm_channel *channel = &meson->channels[i];
>>  		struct clk_parent_data div_parent = {}, gate_parent = {};
>>  		struct clk_init_data init = {};
>> +		struct clk_divider *div;
>> +		struct clk_gate *gate;
>> +		struct clk_mux *mux;
>> +
>> +		mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
>> +		if (!mux)
>> +			return -ENOMEM;
>
> I don't like this change. While it doesn't increase the memory used, it
> fragments the used memory and increases the overhead of memory
> management and the number of devm allocations.
>
> Are these members of meson_pwm_channel in the way for anything later?

Not really. It is just not useful on the SoCs which do use it and not
used at all starting from s4/a1.

What about a dedicated struct for the 3 clock elements and a single
devm_kzalloc() instead of 3 ? 

>
> Best regards
> Uwe
Uwe Kleine-König Jan. 24, 2024, 9:48 a.m. UTC | #3
Hello Jerome,

On Wed, Jan 24, 2024 at 10:16:17AM +0100, Jerome Brunet wrote:
> On Wed 24 Jan 2024 at 10:02, Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:
> > On Fri, Dec 22, 2023 at 12:16:53PM +0100, Jerome Brunet wrote:
> >> @@ -442,6 +439,13 @@ static int meson_pwm_init_channels(struct device *dev)
> >>  		struct meson_pwm_channel *channel = &meson->channels[i];
> >>  		struct clk_parent_data div_parent = {}, gate_parent = {};
> >>  		struct clk_init_data init = {};
> >> +		struct clk_divider *div;
> >> +		struct clk_gate *gate;
> >> +		struct clk_mux *mux;
> >> +
> >> +		mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
> >> +		if (!mux)
> >> +			return -ENOMEM;
> >
> > I don't like this change. While it doesn't increase the memory used, it
> > fragments the used memory and increases the overhead of memory
> > management and the number of devm allocations.
> >
> > Are these members of meson_pwm_channel in the way for anything later?
> 
> Not really. It is just not useful on the SoCs which do use it and not
> used at all starting from s4/a1.

This remembers me about the old pwm-imx driver. This was essentially a
single file containing two drivers just because both types appeared on
imx machines. Later it was split into imx1 and imx27.

I didn't look at the relevant differences between the existing driver
and the changes needed for s4, but please don't repeat this issue for
meson. Not sure this fear is justified, just saying ...

Best regards
Uwe
Jerome Brunet Jan. 24, 2024, 9:59 a.m. UTC | #4
On Wed 24 Jan 2024 at 10:48, Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:

> [[PGP Signed Part:Undecided]]
> Hello Jerome,
>
> On Wed, Jan 24, 2024 at 10:16:17AM +0100, Jerome Brunet wrote:
>> On Wed 24 Jan 2024 at 10:02, Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:
>> > On Fri, Dec 22, 2023 at 12:16:53PM +0100, Jerome Brunet wrote:
>> >> @@ -442,6 +439,13 @@ static int meson_pwm_init_channels(struct device *dev)
>> >>  		struct meson_pwm_channel *channel = &meson->channels[i];
>> >>  		struct clk_parent_data div_parent = {}, gate_parent = {};
>> >>  		struct clk_init_data init = {};
>> >> +		struct clk_divider *div;
>> >> +		struct clk_gate *gate;
>> >> +		struct clk_mux *mux;
>> >> +
>> >> +		mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
>> >> +		if (!mux)
>> >> +			return -ENOMEM;
>> >
>> > I don't like this change. While it doesn't increase the memory used, it
>> > fragments the used memory and increases the overhead of memory
>> > management and the number of devm allocations.
>> >
>> > Are these members of meson_pwm_channel in the way for anything later?
>> 
>> Not really. It is just not useful on the SoCs which do use it and not
>> used at all starting from s4/a1.
>
> This remembers me about the old pwm-imx driver. This was essentially a
> single file containing two drivers just because both types appeared on
> imx machines. Later it was split into imx1 and imx27.
>
> I didn't look at the relevant differences between the existing driver
> and the changes needed for s4, but please don't repeat this issue for
> meson. Not sure this fear is justified, just saying ...

Noted. Don't worry. s4 is indeed the same PWM block as before, just
mux/div/gate migrated from the pwm IP to the main clk controller.
That's all ... I know ;)

Only the clock registration should change and simplify.

>
> Best regards
> Uwe
Junyi Zhao Jan. 25, 2024, 6:53 a.m. UTC | #5
On 2024/1/24 17:59, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> On Wed 24 Jan 2024 at 10:48, Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:
> 
>> [[PGP Signed Part:Undecided]]
>> Hello Jerome,
>>
>> On Wed, Jan 24, 2024 at 10:16:17AM +0100, Jerome Brunet wrote:
>>> On Wed 24 Jan 2024 at 10:02, Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:
>>>> On Fri, Dec 22, 2023 at 12:16:53PM +0100, Jerome Brunet wrote:
>>>>> @@ -442,6 +439,13 @@ static int meson_pwm_init_channels(struct device *dev)
>>>>>            struct meson_pwm_channel *channel = &meson->channels[i];
>>>>>            struct clk_parent_data div_parent = {}, gate_parent = {};
>>>>>            struct clk_init_data init = {};
>>>>> +         struct clk_divider *div;
>>>>> +         struct clk_gate *gate;
>>>>> +         struct clk_mux *mux;
>>>>> +
>>>>> +         mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
>>>>> +         if (!mux)
>>>>> +                 return -ENOMEM;
>>>>
>>>> I don't like this change. While it doesn't increase the memory used, it
>>>> fragments the used memory and increases the overhead of memory
>>>> management and the number of devm allocations.
>>>>
>>>> Are these members of meson_pwm_channel in the way for anything later?
>>>
>>> Not really. It is just not useful on the SoCs which do use it and not
>>> used at all starting from s4/a1.
>>
>> This remembers me about the old pwm-imx driver. This was essentially a
>> single file containing two drivers just because both types appeared on
>> imx machines. Later it was split into imx1 and imx27.
>>
>> I didn't look at the relevant differences between the existing driver
>> and the changes needed for s4, but please don't repeat this issue for
>> meson. Not sure this fear is justified, just saying ...
> 
> Noted. Don't worry. s4 is indeed the same PWM block as before, just
> mux/div/gate migrated from the pwm IP to the main clk controller.
> That's all ... I know ;)
> 
> Only the clock registration should change and simplify.
> 
>>
>> Best regards
>> Uwe
> 
> 
> --
> Jerome
Hi ,Uwe and Jerom.
Compared with m8b g12a and sm1, s4 and A1 are new pwm ip that moved 
MUX/DIV/GATE from pwm chip to clock tree module and the pwm block are same.
About new s7,compared with s4,one pwmchip corresponds one pwm channel. 
Like,we separate PWMAB into PWMA and PWMB.
Here is a version from Amlogic. We will start the following work of pwm 
driver. Welcom to give comments.

Best regards
--
Junyi
diff mbox series

Patch

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 15c44185d784..fb113bc8da29 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -90,9 +90,6 @@  struct meson_pwm_channel {
 	unsigned int hi;
 	unsigned int lo;
 
-	struct clk_mux mux;
-	struct clk_divider div;
-	struct clk_gate gate;
 	struct clk *clk;
 };
 
@@ -442,6 +439,13 @@  static int meson_pwm_init_channels(struct device *dev)
 		struct meson_pwm_channel *channel = &meson->channels[i];
 		struct clk_parent_data div_parent = {}, gate_parent = {};
 		struct clk_init_data init = {};
+		struct clk_divider *div;
+		struct clk_gate *gate;
+		struct clk_mux *mux;
+
+		mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
+		if (!mux)
+			return -ENOMEM;
 
 		snprintf(name, sizeof(name), "%s#mux%u", dev_name(dev), i);
 
@@ -451,63 +455,70 @@  static int meson_pwm_init_channels(struct device *dev)
 		init.parent_data = mux_parent_data;
 		init.num_parents = MESON_NUM_MUX_PARENTS;
 
-		channel->mux.reg = meson->base + REG_MISC_AB;
-		channel->mux.shift =
-				meson_pwm_per_channel_data[i].clk_sel_shift;
-		channel->mux.mask = MISC_CLK_SEL_MASK;
-		channel->mux.flags = 0;
-		channel->mux.lock = &meson->lock;
-		channel->mux.table = NULL;
-		channel->mux.hw.init = &init;
+		mux->reg = meson->base + REG_MISC_AB;
+		mux->shift = meson_pwm_per_channel_data[i].clk_sel_shift;
+		mux->mask = MISC_CLK_SEL_MASK;
+		mux->flags = 0;
+		mux->lock = &meson->lock;
+		mux->table = NULL;
+		mux->hw.init = &init;
 
-		err = devm_clk_hw_register(dev, &channel->mux.hw);
+		err = devm_clk_hw_register(dev, &mux->hw);
 		if (err)
 			return dev_err_probe(dev, err,
 					     "failed to register %s\n", name);
 
+		div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
+		if (!div)
+			return -ENOMEM;
+
 		snprintf(name, sizeof(name), "%s#div%u", dev_name(dev), i);
 
 		init.name = name;
 		init.ops = &clk_divider_ops;
 		init.flags = CLK_SET_RATE_PARENT;
 		div_parent.index = -1;
-		div_parent.hw = &channel->mux.hw;
+		div_parent.hw = &mux->hw;
 		init.parent_data = &div_parent;
 		init.num_parents = 1;
 
-		channel->div.reg = meson->base + REG_MISC_AB;
-		channel->div.shift = meson_pwm_per_channel_data[i].clk_div_shift;
-		channel->div.width = MISC_CLK_DIV_WIDTH;
-		channel->div.hw.init = &init;
-		channel->div.flags = 0;
-		channel->div.lock = &meson->lock;
+		div->reg = meson->base + REG_MISC_AB;
+		div->shift = meson_pwm_per_channel_data[i].clk_div_shift;
+		div->width = MISC_CLK_DIV_WIDTH;
+		div->hw.init = &init;
+		div->flags = 0;
+		div->lock = &meson->lock;
 
-		err = devm_clk_hw_register(dev, &channel->div.hw);
+		err = devm_clk_hw_register(dev, &div->hw);
 		if (err)
 			return dev_err_probe(dev, err,
 					     "failed to register %s\n", name);
 
+		gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
+		if (!gate)
+			return -ENOMEM;
+
 		snprintf(name, sizeof(name), "%s#gate%u", dev_name(dev), i);
 
 		init.name = name;
 		init.ops = &clk_gate_ops;
 		init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
 		gate_parent.index = -1;
-		gate_parent.hw = &channel->div.hw;
+		gate_parent.hw = &div->hw;
 		init.parent_data = &gate_parent;
 		init.num_parents = 1;
 
-		channel->gate.reg = meson->base + REG_MISC_AB;
-		channel->gate.bit_idx = meson_pwm_per_channel_data[i].clk_en_shift;
-		channel->gate.hw.init = &init;
-		channel->gate.flags = 0;
-		channel->gate.lock = &meson->lock;
+		gate->reg = meson->base + REG_MISC_AB;
+		gate->bit_idx = meson_pwm_per_channel_data[i].clk_en_shift;
+		gate->hw.init = &init;
+		gate->flags = 0;
+		gate->lock = &meson->lock;
 
-		err = devm_clk_hw_register(dev, &channel->gate.hw);
+		err = devm_clk_hw_register(dev, &gate->hw);
 		if (err)
 			return dev_err_probe(dev, err, "failed to register %s\n", name);
 
-		channel->clk = devm_clk_hw_get_clk(dev, &channel->gate.hw, NULL);
+		channel->clk = devm_clk_hw_get_clk(dev, &gate->hw, NULL);
 		if (IS_ERR(channel->clk))
 			return dev_err_probe(dev, PTR_ERR(channel->clk),
 					     "failed to register %s\n", name);