diff options
| -rw-r--r-- | drivers/reset/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/reset/reset-npcm.c | 78 | ||||
| -rw-r--r-- | include/soc/nuvoton/clock-npcm8xx.h | 18 | 
3 files changed, 95 insertions, 2 deletions
| diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 5484a65f66b9..ace9c842d7bb 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -170,6 +170,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..4f3b9fc58de0 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) { @@ -408,12 +475,19 @@ static int npcm_rc_probe(struct platform_device *pdev)  			rc->restart_nb.priority = 192,  			rc->restart_nb.notifier_call = npcm_rc_restart,  			ret = register_restart_handler(&rc->restart_nb); -			if (ret) +			if (ret) {  				dev_warn(&pdev->dev, "failed to register restart handler\n"); +				return ret; +			}  		}  	} -	return ret; +	switch (rc->info->bmc_id) { +	case BMC_NPCM8XX: +		return npcm8xx_clock_controller_register(rc, "clk-npcm8xx"); +	default: +		return 0; +	}  }  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..1d974e89d8a8 --- /dev/null +++ b/include/soc/nuvoton/clock-npcm8xx.h @@ -0,0 +1,18 @@ +/* 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; +}; + +static inline struct npcm_clock_adev *to_npcm_clock_adev(struct auxiliary_device *_adev) +{ +	return container_of(_adev, struct npcm_clock_adev, adev); +} + +#endif | 
