Skip to content

Commit

Permalink
reset: npcm: register npcm8xx clock auxiliary bus device
Browse files Browse the repository at this point in the history
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@gmail.com>
Tested-by: Benjamin Fair <benjaminfair@google.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Link: https://lore.kernel.org/r/20240912191038.981105-3-tmaimon77@gmail.com
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
  • Loading branch information
tmaimon authored and bebarino committed Oct 17, 2024
1 parent d62f45b commit 2282315
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/reset/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
78 changes: 76 additions & 2 deletions drivers/reset/reset-npcm.c
Original file line number Diff line number Diff line change
@@ -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>
Expand All @@ -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)
Expand Down Expand Up @@ -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;
};
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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 = {
Expand Down
18 changes: 18 additions & 0 deletions include/soc/nuvoton/clock-npcm8xx.h
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2282315

Please sign in to comment.