| Message ID | 20260929061417.20733-6-jszhang@kernel.org |
|---|---|
| State | New |
| Headers | show |
| Series | arm64: add Synaptics SL261X SoCs and RDK boards | expand |
On Tue, Sep 29, 2026 at 02:14:02PM +0800, Jisheng Zhang wrote: > The Synopsys DesignWare I3C master controller can have multiple reset > lines, such as a core reset and APB reset. > > Refactor the driver to use devm_reset_control_array_get_exclusive() > instead of a single named reset handle. This automatically manages all > resets allocated to the device node sequentially. > > Signed-off-by: Jisheng Zhang <jszhang@kernel.org> > --- Reviewed-by: Frank Li <Frank.Li@nxp.com> > drivers/i3c/master/dw-i3c-master.c | 24 ++++++++++++++++++------ > drivers/i3c/master/dw-i3c-master.h | 2 +- > 2 files changed, 19 insertions(+), 7 deletions(-) > > diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c > index 4563d8761ba0..1c6c870f5bb3 100644 > --- a/drivers/i3c/master/dw-i3c-master.c > +++ b/drivers/i3c/master/dw-i3c-master.c > @@ -1657,6 +1657,11 @@ static const struct dw_i3c_platform_ops dw_i3c_platform_ops_default = { > .set_dat_ibi = dw_i3c_platform_set_dat_ibi_nop, > }; > > +static void dw_i3c_resets_assert(void *data) > +{ > + reset_control_assert(data); > +} > + > int dw_i3c_common_probe(struct dw_i3c_master *master, > struct platform_device *pdev) > { > @@ -1696,10 +1701,17 @@ int dw_i3c_common_probe(struct dw_i3c_master *master, > if (IS_ERR(master->pclk)) > return PTR_ERR(master->pclk); > > - master->core_rst = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, > - NULL); > - if (IS_ERR(master->core_rst)) > - return PTR_ERR(master->core_rst); > + master->resets = devm_reset_control_array_get_optional_exclusive(&pdev->dev); > + if (IS_ERR(master->resets)) > + return PTR_ERR(master->resets); > + > + ret = reset_control_deassert(master->resets); > + if (ret) > + return ret; > + > + ret = devm_add_action_or_reset(&pdev->dev, dw_i3c_resets_assert, master->resets); > + if (ret) > + return ret; > > spin_lock_init(&master->xferqueue.lock); > INIT_LIST_HEAD(&master->xferqueue.list); > @@ -1873,7 +1885,7 @@ static int __maybe_unused dw_i3c_master_runtime_suspend(struct device *dev) > > dw_i3c_master_disable(master); > > - reset_control_assert(master->core_rst); > + reset_control_assert(master->resets); > dw_i3c_master_disable_clks(master); > pinctrl_pm_select_sleep_state(dev); > return 0; > @@ -1885,7 +1897,7 @@ static int __maybe_unused dw_i3c_master_runtime_resume(struct device *dev) > > pinctrl_pm_select_default_state(dev); > dw_i3c_master_enable_clks(master); > - reset_control_deassert(master->core_rst); > + reset_control_deassert(master->resets); > > dw_i3c_master_set_intr_regs(master); > dw_i3c_master_restore_timing_regs(master); > diff --git a/drivers/i3c/master/dw-i3c-master.h b/drivers/i3c/master/dw-i3c-master.h > index 17ad817d1f8e..f5b4491b247a 100644 > --- a/drivers/i3c/master/dw-i3c-master.h > +++ b/drivers/i3c/master/dw-i3c-master.h > @@ -36,7 +36,7 @@ struct dw_i3c_master { > } xferqueue; > struct dw_i3c_master_caps caps; > void __iomem *regs; > - struct reset_control *core_rst; > + struct reset_control *resets; > struct clk *core_clk; > struct clk *pclk; > char version[5]; > -- > 2.53.0 >
diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index 4563d8761ba0..1c6c870f5bb3 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -1657,6 +1657,11 @@ static const struct dw_i3c_platform_ops dw_i3c_platform_ops_default = { .set_dat_ibi = dw_i3c_platform_set_dat_ibi_nop, }; +static void dw_i3c_resets_assert(void *data) +{ + reset_control_assert(data); +} + int dw_i3c_common_probe(struct dw_i3c_master *master, struct platform_device *pdev) { @@ -1696,10 +1701,17 @@ int dw_i3c_common_probe(struct dw_i3c_master *master, if (IS_ERR(master->pclk)) return PTR_ERR(master->pclk); - master->core_rst = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, - NULL); - if (IS_ERR(master->core_rst)) - return PTR_ERR(master->core_rst); + master->resets = devm_reset_control_array_get_optional_exclusive(&pdev->dev); + if (IS_ERR(master->resets)) + return PTR_ERR(master->resets); + + ret = reset_control_deassert(master->resets); + if (ret) + return ret; + + ret = devm_add_action_or_reset(&pdev->dev, dw_i3c_resets_assert, master->resets); + if (ret) + return ret; spin_lock_init(&master->xferqueue.lock); INIT_LIST_HEAD(&master->xferqueue.list); @@ -1873,7 +1885,7 @@ static int __maybe_unused dw_i3c_master_runtime_suspend(struct device *dev) dw_i3c_master_disable(master); - reset_control_assert(master->core_rst); + reset_control_assert(master->resets); dw_i3c_master_disable_clks(master); pinctrl_pm_select_sleep_state(dev); return 0; @@ -1885,7 +1897,7 @@ static int __maybe_unused dw_i3c_master_runtime_resume(struct device *dev) pinctrl_pm_select_default_state(dev); dw_i3c_master_enable_clks(master); - reset_control_deassert(master->core_rst); + reset_control_deassert(master->resets); dw_i3c_master_set_intr_regs(master); dw_i3c_master_restore_timing_regs(master); diff --git a/drivers/i3c/master/dw-i3c-master.h b/drivers/i3c/master/dw-i3c-master.h index 17ad817d1f8e..f5b4491b247a 100644 --- a/drivers/i3c/master/dw-i3c-master.h +++ b/drivers/i3c/master/dw-i3c-master.h @@ -36,7 +36,7 @@ struct dw_i3c_master { } xferqueue; struct dw_i3c_master_caps caps; void __iomem *regs; - struct reset_control *core_rst; + struct reset_control *resets; struct clk *core_clk; struct clk *pclk; char version[5];
The Synopsys DesignWare I3C master controller can have multiple reset lines, such as a core reset and APB reset. Refactor the driver to use devm_reset_control_array_get_exclusive() instead of a single named reset handle. This automatically manages all resets allocated to the device node sequentially. Signed-off-by: Jisheng Zhang <jszhang@kernel.org> --- drivers/i3c/master/dw-i3c-master.c | 24 ++++++++++++++++++------ drivers/i3c/master/dw-i3c-master.h | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-)