* [PATCH v2 0/3] MTU3 MFD improvements
@ 2026-10-04 17:40 Cosmin Tanislav
2026-10-04 17:40 ` [PATCH v2 1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev Cosmin Tanislav
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Cosmin Tanislav @ 2026-10-04 17:40 UTC (permalink / raw)
To: Lee Jones; +Cc: mfd, linux-kernel, Cosmin Tanislav
This series does some code quality improvements to the MTU3 MFD driver,
and enables runtime PM to allow simplifications in the sub-drivers by
relying on PM domains rather than open-coding clock handling.
V2:
* capitalize subject after prefix
* switch struct rz_mtu3_priv retrieval to a back-pointer stored in
struct rz_mtu3_channel::priv
* remove struct rz_mtu3::priv_data as it is unused now
Cosmin Tanislav (3):
mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev
mfd: rz-mtu3: Reuse shared_reg_update_bit() in start_stop_ch()
mfd: rz-mtu3: Enable runtime PM
drivers/mfd/rz-mtu3.c | 70 +++++++++++++------------------------
include/linux/mfd/rz-mtu3.h | 7 ++--
2 files changed, 29 insertions(+), 48 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v2 1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev 2026-10-04 17:40 [PATCH v2 0/3] MTU3 MFD improvements Cosmin Tanislav @ 2026-10-04 17:40 ` Cosmin Tanislav 2026-10-15 15:40 ` Lee Jones 2026-10-04 17:40 ` [PATCH v2 2/3] mfd: rz-mtu3: Reuse shared_reg_update_bit() in start_stop_ch() Cosmin Tanislav ` (2 subsequent siblings) 3 siblings, 1 reply; 6+ messages in thread From: Cosmin Tanislav @ 2026-10-04 17:40 UTC (permalink / raw) To: Lee Jones; +Cc: mfd, linux-kernel, Cosmin Tanislav Channels 1 and 2 are used by both the PWM and counter drivers. Both subdrivers assign struct rz_mtu3_channel::dev to their own device instance for those shared channels, so the value stored in it depends on which subdriver binds last. The MFD core helpers currently use ch->dev->parent to retrieve the parent driver data, which makes them depend on subdriver-populated state. This is fragile for shared channels and unnecessarily couples the core to child driver initialization. Add a priv pointer to struct rz_mtu3_channel, populated by the MFD driver at probe time, and use it directly in place of ch->dev->parent in every MFD core helper, so the core no longer depends on subdriver-assigned state. Remove struct rz_mtu3::priv_data, which becomes redundant now that every channel carries its own priv pointer. Keep struct rz_mtu3_channel::dev for now, as it is still used by the PWM and counter drivers. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * capitalize subject after prefix * switch struct rz_mtu3_priv retrieval to a back-pointer stored in struct rz_mtu3_channel::priv * remove struct rz_mtu3::priv_data as it is unused now drivers/mfd/rz-mtu3.c | 40 +++++++++++++------------------------ include/linux/mfd/rz-mtu3.h | 7 ++++--- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/drivers/mfd/rz-mtu3.c b/drivers/mfd/rz-mtu3.c index 0a254e61ec0a..0fca16aaa566 100644 --- a/drivers/mfd/rz-mtu3.c +++ b/drivers/mfd/rz-mtu3.c @@ -62,8 +62,7 @@ static bool rz_mtu3_is_16bit_shared_reg(u16 offset) u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 offset) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; if (rz_mtu3_is_16bit_shared_reg(offset)) return readw(priv->mmio + offset); @@ -74,8 +73,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_read); u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; u16 ch_offs; ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset]; @@ -86,8 +84,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_read); u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; u16 ch_offs; /* MTU8 doesn't have 16-bit registers */ @@ -102,8 +99,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_read); u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; u16 ch_offs; if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8) @@ -117,8 +113,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_read); void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u8 val) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; u16 ch_offs; ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset]; @@ -128,8 +123,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_write); void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u16 val) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; u16 ch_offs; /* MTU8 doesn't have 16-bit registers */ @@ -143,8 +137,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_write); void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u32 val) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; u16 ch_offs; if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8) @@ -157,8 +150,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_write); void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 offset, u16 value) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; if (rz_mtu3_is_16bit_shared_reg(offset)) writew(value, priv->mmio + offset); @@ -170,8 +162,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_write); void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 offset, u16 pos, u8 val) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; unsigned long tmdr, flags; spin_lock_irqsave(&priv->lock, flags); @@ -244,8 +235,7 @@ static u8 rz_mtu3_get_tstr_bit_pos(struct rz_mtu3_channel *ch) static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; unsigned long flags, tstr; u16 offset; u8 bitpos; @@ -265,8 +255,7 @@ static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start) bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch) { - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); - struct rz_mtu3_priv *priv = mtu->priv_data; + struct rz_mtu3_priv *priv = ch->priv; unsigned long flags, tstr; u16 offset; u8 bitpos; @@ -320,12 +309,10 @@ static int rz_mtu3_probe(struct platform_device *pdev) if (!ddata) return -ENOMEM; - ddata->priv_data = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!ddata->priv_data) + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - priv = ddata->priv_data; - priv->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->mmio)) return PTR_ERR(priv->mmio); @@ -344,6 +331,7 @@ static int rz_mtu3_probe(struct platform_device *pdev) for (i = 0; i < RZ_MTU_NUM_CHANNELS; i++) { ddata->channels[i].channel_number = i; ddata->channels[i].is_busy = false; + ddata->channels[i].priv = priv; mutex_init(&ddata->channels[i].lock); } diff --git a/include/linux/mfd/rz-mtu3.h b/include/linux/mfd/rz-mtu3.h index 8421d49500bf..3884ae5b008c 100644 --- a/include/linux/mfd/rz-mtu3.h +++ b/include/linux/mfd/rz-mtu3.h @@ -122,6 +122,8 @@ enum rz_mtu3_channels { RZ_MTU_NUM_CHANNELS }; +struct rz_mtu3_priv; + /** * struct rz_mtu3_channel - MTU3 channel private data * @@ -129,12 +131,14 @@ enum rz_mtu3_channels { * @channel_number: channel number * @lock: Lock to protect channel state * @is_busy: channel state + * @priv: MFD private data */ struct rz_mtu3_channel { struct device *dev; unsigned int channel_number; struct mutex lock; bool is_busy; + struct rz_mtu3_priv *priv; }; /** @@ -142,13 +146,10 @@ struct rz_mtu3_channel { * * @clk: MTU3 module clock * @rz_mtu3_channel: HW channels - * @priv_data: MTU3 core driver private data */ struct rz_mtu3 { struct clk *clk; struct rz_mtu3_channel channels[RZ_MTU_NUM_CHANNELS]; - - void *priv_data; }; static inline bool rz_mtu3_request_channel(struct rz_mtu3_channel *ch) -- 2.55.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev 2026-10-04 17:40 ` [PATCH v2 1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev Cosmin Tanislav @ 2026-10-15 15:40 ` Lee Jones 0 siblings, 0 replies; 6+ messages in thread From: Lee Jones @ 2026-10-15 15:40 UTC (permalink / raw) To: Cosmin Tanislav; +Cc: mfd, linux-kernel --- checkpatch.pl: clean (0 issues) --- On Sun, 04 Oct 2026, Cosmin Tanislav wrote: Please review, explain or fix the Sashiko review(s). > Channels 1 and 2 are used by both the PWM and counter drivers. Both > subdrivers assign struct rz_mtu3_channel::dev to their own device > instance for those shared channels, so the value stored in it depends on > which subdriver binds last. > > The MFD core helpers currently use ch->dev->parent to retrieve the > parent driver data, which makes them depend on subdriver-populated > state. > > This is fragile for shared channels and unnecessarily couples the core > to child driver initialization. > > Add a priv pointer to struct rz_mtu3_channel, populated by the MFD > driver at probe time, and use it directly in place of ch->dev->parent > in every MFD core helper, so the core no longer depends on > subdriver-assigned state. Remove struct rz_mtu3::priv_data, which > becomes redundant now that every channel carries its own priv pointer. > > Keep struct rz_mtu3_channel::dev for now, as it is still used by the PWM > and counter drivers. > > Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> > --- > > V2: > * capitalize subject after prefix > * switch struct rz_mtu3_priv retrieval to a back-pointer stored in > struct rz_mtu3_channel::priv > * remove struct rz_mtu3::priv_data as it is unused now > > drivers/mfd/rz-mtu3.c | 40 +++++++++++++------------------------ > include/linux/mfd/rz-mtu3.h | 7 ++++--- > 2 files changed, 18 insertions(+), 29 deletions(-) > > diff --git a/drivers/mfd/rz-mtu3.c b/drivers/mfd/rz-mtu3.c > index 0a254e61ec0a..0fca16aaa566 100644 > --- a/drivers/mfd/rz-mtu3.c > +++ b/drivers/mfd/rz-mtu3.c > @@ -62,8 +62,7 @@ static bool rz_mtu3_is_16bit_shared_reg(u16 offset) > > u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 offset) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > > if (rz_mtu3_is_16bit_shared_reg(offset)) > return readw(priv->mmio + offset); > @@ -74,8 +73,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_read); > > u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > u16 ch_offs; > > ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset]; > @@ -86,8 +84,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_read); > > u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > u16 ch_offs; > > /* MTU8 doesn't have 16-bit registers */ > @@ -102,8 +99,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_read); > > u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 offset) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > u16 ch_offs; > > if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8) > @@ -117,8 +113,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_read); > > void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u8 val) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > u16 ch_offs; > > ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset]; > @@ -128,8 +123,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_write); > > void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u16 val) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > u16 ch_offs; > > /* MTU8 doesn't have 16-bit registers */ > @@ -143,8 +137,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_write); > > void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u32 val) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > u16 ch_offs; > > if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8) > @@ -157,8 +150,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_write); > > void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 offset, u16 value) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > > if (rz_mtu3_is_16bit_shared_reg(offset)) > writew(value, priv->mmio + offset); > @@ -170,8 +162,7 @@ EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_write); > void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 offset, > u16 pos, u8 val) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > unsigned long tmdr, flags; > > spin_lock_irqsave(&priv->lock, flags); > @@ -244,8 +235,7 @@ static u8 rz_mtu3_get_tstr_bit_pos(struct rz_mtu3_channel *ch) > > static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > unsigned long flags, tstr; > u16 offset; > u8 bitpos; > @@ -265,8 +255,7 @@ static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start) > > bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch) > { > - struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent); > - struct rz_mtu3_priv *priv = mtu->priv_data; > + struct rz_mtu3_priv *priv = ch->priv; > unsigned long flags, tstr; > u16 offset; > u8 bitpos; > @@ -320,12 +309,10 @@ static int rz_mtu3_probe(struct platform_device *pdev) > if (!ddata) > return -ENOMEM; > > - ddata->priv_data = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > - if (!ddata->priv_data) > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > return -ENOMEM; > > - priv = ddata->priv_data; > - > priv->mmio = devm_platform_ioremap_resource(pdev, 0); > if (IS_ERR(priv->mmio)) > return PTR_ERR(priv->mmio); > @@ -344,6 +331,7 @@ static int rz_mtu3_probe(struct platform_device *pdev) > for (i = 0; i < RZ_MTU_NUM_CHANNELS; i++) { > ddata->channels[i].channel_number = i; > ddata->channels[i].is_busy = false; > + ddata->channels[i].priv = priv; > mutex_init(&ddata->channels[i].lock); > } > > diff --git a/include/linux/mfd/rz-mtu3.h b/include/linux/mfd/rz-mtu3.h > index 8421d49500bf..3884ae5b008c 100644 > --- a/include/linux/mfd/rz-mtu3.h > +++ b/include/linux/mfd/rz-mtu3.h > @@ -122,6 +122,8 @@ enum rz_mtu3_channels { > RZ_MTU_NUM_CHANNELS > }; > > +struct rz_mtu3_priv; > + > /** > * struct rz_mtu3_channel - MTU3 channel private data > * > @@ -129,12 +131,14 @@ enum rz_mtu3_channels { > * @channel_number: channel number > * @lock: Lock to protect channel state > * @is_busy: channel state > + * @priv: MFD private data > */ > struct rz_mtu3_channel { > struct device *dev; > unsigned int channel_number; > struct mutex lock; > bool is_busy; > + struct rz_mtu3_priv *priv; > }; > > /** > @@ -142,13 +146,10 @@ struct rz_mtu3_channel { > * > * @clk: MTU3 module clock > * @rz_mtu3_channel: HW channels > - * @priv_data: MTU3 core driver private data > */ > struct rz_mtu3 { > struct clk *clk; > struct rz_mtu3_channel channels[RZ_MTU_NUM_CHANNELS]; > - > - void *priv_data; > }; > > static inline bool rz_mtu3_request_channel(struct rz_mtu3_channel *ch) > -- > 2.55.0 -- Lee Jones ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/3] mfd: rz-mtu3: Reuse shared_reg_update_bit() in start_stop_ch() 2026-10-04 17:40 [PATCH v2 0/3] MTU3 MFD improvements Cosmin Tanislav 2026-10-04 17:40 ` [PATCH v2 1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev Cosmin Tanislav @ 2026-10-04 17:40 ` Cosmin Tanislav 2026-10-04 17:40 ` [PATCH v2 3/3] mfd: rz-mtu3: Enable runtime PM Cosmin Tanislav 2026-10-20 11:44 ` [PATCH v2 0/3] MTU3 MFD improvements Lee Jones 3 siblings, 0 replies; 6+ messages in thread From: Cosmin Tanislav @ 2026-10-04 17:40 UTC (permalink / raw) To: Lee Jones; +Cc: mfd, linux-kernel, Cosmin Tanislav rz_mtu3_start_stop_ch() performs the same shared register update sequence already implemented by rz_mtu3_shared_reg_update_bit(). Reuse the helper instead of open-coding the read-modify-write sequence. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * capitalize subject after prefix drivers/mfd/rz-mtu3.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/drivers/mfd/rz-mtu3.c b/drivers/mfd/rz-mtu3.c index 0fca16aaa566..5be1f5a4167e 100644 --- a/drivers/mfd/rz-mtu3.c +++ b/drivers/mfd/rz-mtu3.c @@ -163,12 +163,12 @@ void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 offset, u16 pos, u8 val) { struct rz_mtu3_priv *priv = ch->priv; - unsigned long tmdr, flags; + unsigned long reg_val, flags; spin_lock_irqsave(&priv->lock, flags); - tmdr = rz_mtu3_shared_reg_read(ch, offset); - __assign_bit(pos, &tmdr, !!val); - rz_mtu3_shared_reg_write(ch, offset, tmdr); + reg_val = rz_mtu3_shared_reg_read(ch, offset); + __assign_bit(pos, ®_val, !!val); + rz_mtu3_shared_reg_write(ch, offset, reg_val); spin_unlock_irqrestore(&priv->lock, flags); } EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_update_bit); @@ -235,22 +235,8 @@ static u8 rz_mtu3_get_tstr_bit_pos(struct rz_mtu3_channel *ch) static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start) { - struct rz_mtu3_priv *priv = ch->priv; - unsigned long flags, tstr; - u16 offset; - u8 bitpos; - - offset = rz_mtu3_get_tstr_offset(ch); - bitpos = rz_mtu3_get_tstr_bit_pos(ch); - - /* start stop register shared by multiple timer channels */ - spin_lock_irqsave(&priv->lock, flags); - - tstr = rz_mtu3_shared_reg_read(ch, offset); - __assign_bit(bitpos, &tstr, start); - rz_mtu3_shared_reg_write(ch, offset, tstr); - - spin_unlock_irqrestore(&priv->lock, flags); + rz_mtu3_shared_reg_update_bit(ch, rz_mtu3_get_tstr_offset(ch), + rz_mtu3_get_tstr_bit_pos(ch), start); } bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch) -- 2.55.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 3/3] mfd: rz-mtu3: Enable runtime PM 2026-10-04 17:40 [PATCH v2 0/3] MTU3 MFD improvements Cosmin Tanislav 2026-10-04 17:40 ` [PATCH v2 1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev Cosmin Tanislav 2026-10-04 17:40 ` [PATCH v2 2/3] mfd: rz-mtu3: Reuse shared_reg_update_bit() in start_stop_ch() Cosmin Tanislav @ 2026-10-04 17:40 ` Cosmin Tanislav 2026-10-20 11:44 ` [PATCH v2 0/3] MTU3 MFD improvements Lee Jones 3 siblings, 0 replies; 6+ messages in thread From: Cosmin Tanislav @ 2026-10-04 17:40 UTC (permalink / raw) To: Lee Jones; +Cc: mfd, linux-kernel, Cosmin Tanislav The MTU3 child devices use runtime PM, but the PM domain is attached to the parent MFD device rather than to the individual child devices, and the child devices open-code their own clock handling instead of using the PM domain logic. Enable runtime PM on the parent device so runtime PM usage by the child devices can propagate to the parent. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- V2: * capitalize subject after prefix drivers/mfd/rz-mtu3.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/mfd/rz-mtu3.c b/drivers/mfd/rz-mtu3.c index 5be1f5a4167e..558ed3fbe520 100644 --- a/drivers/mfd/rz-mtu3.c +++ b/drivers/mfd/rz-mtu3.c @@ -13,6 +13,7 @@ #include <linux/mfd/rz-mtu3.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/spinlock.h> @@ -290,6 +291,7 @@ static int rz_mtu3_probe(struct platform_device *pdev) struct rz_mtu3 *ddata; struct reset_control *rstc; unsigned int i; + int ret; ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) @@ -321,6 +323,10 @@ static int rz_mtu3_probe(struct platform_device *pdev) mutex_init(&ddata->channels[i].lock); } + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; + return devm_mfd_add_devices(dev, 0, rz_mtu3_devs, ARRAY_SIZE(rz_mtu3_devs), NULL, 0, NULL); } -- 2.55.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/3] MTU3 MFD improvements 2026-10-04 17:40 [PATCH v2 0/3] MTU3 MFD improvements Cosmin Tanislav ` (2 preceding siblings ...) 2026-10-04 17:40 ` [PATCH v2 3/3] mfd: rz-mtu3: Enable runtime PM Cosmin Tanislav @ 2026-10-20 11:44 ` Lee Jones 3 siblings, 0 replies; 6+ messages in thread From: Lee Jones @ 2026-10-20 11:44 UTC (permalink / raw) To: Lee Jones, Cosmin Tanislav; +Cc: mfd, linux-kernel On Sun, 04 Oct 2026 20:40:21 +0300, Cosmin Tanislav wrote: > This series does some code quality improvements to the MTU3 MFD driver, > and enables runtime PM to allow simplifications in the sub-drivers by > relying on PM domains rather than open-coding clock handling. > > V2: > * capitalize subject after prefix > * switch struct rz_mtu3_priv retrieval to a back-pointer stored in > struct rz_mtu3_channel::priv > * remove struct rz_mtu3::priv_data as it is unused now > > [...] Applied, thanks! [1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev commit: 2e51117f96cfc96f3b83403d2f8988246a9085b4 [2/3] mfd: rz-mtu3: Reuse shared_reg_update_bit() in start_stop_ch() commit: da456a1d4097e0f67d0beecc7b359508fe7a00cb [3/3] mfd: rz-mtu3: Enable runtime PM commit: b035c19121cd1163c3ea703ab603374b238a4742 -- Lee Jones [李琼斯] ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-20 11:44 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-10-04 17:40 [PATCH v2 0/3] MTU3 MFD improvements Cosmin Tanislav 2026-10-04 17:40 ` [PATCH v2 1/3] mfd: rz-mtu3: Do not use struct rz_mtu3_channel::dev Cosmin Tanislav 2026-10-15 15:40 ` Lee Jones 2026-10-04 17:40 ` [PATCH v2 2/3] mfd: rz-mtu3: Reuse shared_reg_update_bit() in start_stop_ch() Cosmin Tanislav 2026-10-04 17:40 ` [PATCH v2 3/3] mfd: rz-mtu3: Enable runtime PM Cosmin Tanislav 2026-10-20 11:44 ` [PATCH v2 0/3] MTU3 MFD improvements Lee Jones
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®