On Tue, 2 Jul 2024 at 12:17, Tomer Maimon <tmaimon77@xxxxxxxxx> wrote: > > Add NPCM8xx clock controller auxiliary bus device registration. > > The NPCM8xx clock controller is registered as an aux device because the > reset and the clock controller share the same register region. > > Signed-off-by: Tomer Maimon <tmaimon77@xxxxxxxxx> I booted a kernel with this driver and verified that basic functionality works fine. Tested-by: Benjamin Fair <benjaminfair@xxxxxxxxxx> > --- > drivers/reset/Kconfig | 1 + > drivers/reset/reset-npcm.c | 74 ++++++++++++++++++++++++++++- > include/soc/nuvoton/clock-npcm8xx.h | 16 +++++++ > 3 files changed, 90 insertions(+), 1 deletion(-) > create mode 100644 include/soc/nuvoton/clock-npcm8xx.h > > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig > index 7112f5932609..31ec8795c105 100644 > --- a/drivers/reset/Kconfig > +++ b/drivers/reset/Kconfig > @@ -148,6 +148,7 @@ config RESET_MESON_AUDIO_ARB > config RESET_NPCM > bool "NPCM BMC Reset Driver" if COMPILE_TEST > default ARCH_NPCM > + select AUXILIARY_BUS > help > This enables the reset controller driver for Nuvoton NPCM > BMC SoCs. > diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c > index 8935ef95a2d1..aa68b947226a 100644 > --- a/drivers/reset/reset-npcm.c > +++ b/drivers/reset/reset-npcm.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0 > // Copyright (c) 2019 Nuvoton Technology corporation. > > +#include <linux/auxiliary_bus.h> > #include <linux/delay.h> > #include <linux/err.h> > #include <linux/io.h> > @@ -10,11 +11,14 @@ > #include <linux/property.h> > #include <linux/reboot.h> > #include <linux/reset-controller.h> > +#include <linux/slab.h> > #include <linux/spinlock.h> > #include <linux/mfd/syscon.h> > #include <linux/regmap.h> > #include <linux/of_address.h> > > +#include <soc/nuvoton/clock-npcm8xx.h> > + > /* NPCM7xx GCR registers */ > #define NPCM_MDLR_OFFSET 0x7C > #define NPCM7XX_MDLR_USBD0 BIT(9) > @@ -89,6 +93,7 @@ struct npcm_rc_data { > const struct npcm_reset_info *info; > struct regmap *gcr_regmap; > u32 sw_reset_number; > + struct device *dev; > void __iomem *base; > spinlock_t lock; > }; > @@ -372,6 +377,67 @@ static const struct reset_control_ops npcm_rc_ops = { > .status = npcm_rc_status, > }; > > +static void npcm_clock_unregister_adev(void *_adev) > +{ > + struct auxiliary_device *adev = _adev; > + > + auxiliary_device_delete(adev); > + auxiliary_device_uninit(adev); > +} > + > +static void npcm_clock_adev_release(struct device *dev) > +{ > + struct auxiliary_device *adev = to_auxiliary_dev(dev); > + struct npcm_clock_adev *rdev = to_npcm_clock_adev(adev); > + > + kfree(rdev); > +} > + > +static struct auxiliary_device *npcm_clock_adev_alloc(struct npcm_rc_data *rst_data, char *clk_name) > +{ > + struct npcm_clock_adev *rdev; > + struct auxiliary_device *adev; > + int ret; > + > + rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); > + if (!rdev) > + return ERR_PTR(-ENOMEM); > + > + rdev->base = rst_data->base; > + > + adev = &rdev->adev; > + adev->name = clk_name; > + adev->dev.parent = rst_data->dev; > + adev->dev.release = npcm_clock_adev_release; > + adev->id = 555u; > + > + ret = auxiliary_device_init(adev); > + if (ret) { > + kfree(rdev); > + return ERR_PTR(ret); > + } > + > + return adev; > +} > + > +static int npcm8xx_clock_controller_register(struct npcm_rc_data *rst_data, char *clk_name) > +{ > + struct auxiliary_device *adev; > + int ret; > + > + adev = npcm_clock_adev_alloc(rst_data, clk_name); > + if (IS_ERR(adev)) > + return PTR_ERR(adev); > + > + ret = auxiliary_device_add(adev); > + if (ret) { > + auxiliary_device_uninit(adev); > + return ret; > + } > + > + return devm_add_action_or_reset(rst_data->dev, npcm_clock_unregister_adev, adev); > +} > + > static int npcm_rc_probe(struct platform_device *pdev) > { > struct npcm_rc_data *rc; > @@ -392,6 +458,7 @@ static int npcm_rc_probe(struct platform_device *pdev) > rc->rcdev.of_node = pdev->dev.of_node; > rc->rcdev.of_reset_n_cells = 2; > rc->rcdev.of_xlate = npcm_reset_xlate; > + rc->dev = &pdev->dev; > > ret = devm_reset_controller_register(&pdev->dev, &rc->rcdev); > if (ret) { > @@ -413,7 +480,12 @@ static int npcm_rc_probe(struct platform_device *pdev) > } > } > > - return ret; > + switch (rc->info->bmc_id) { > + case BMC_NPCM8XX: > + return npcm8xx_clock_controller_register(rc, "clk-npcm8xx"); > + default: > + return ret; > + } > } > > static struct platform_driver npcm_rc_driver = { > diff --git a/include/soc/nuvoton/clock-npcm8xx.h b/include/soc/nuvoton/clock-npcm8xx.h > new file mode 100644 > index 000000000000..139130e98c51 > --- /dev/null > +++ b/include/soc/nuvoton/clock-npcm8xx.h > @@ -0,0 +1,16 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __SOC_NPCM8XX_CLOCK_H > +#define __SOC_NPCM8XX_CLOCK_H > + > +#include <linux/auxiliary_bus.h> > +#include <linux/container_of.h> > + > +struct npcm_clock_adev { > + void __iomem *base; > + struct auxiliary_device adev; > +}; > + > +#define to_npcm_clock_adev(_adev) \ > + container_of((_adev), struct npcm_clock_adev, adev) > + > +#endif > -- > 2.34.1 >