From 2c3c1048746a4622d8c89a29670120dc8fab93c4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:49:45 +0200 Subject: Adding upstream version 6.1.76. Signed-off-by: Daniel Baumann --- drivers/clk/sunxi-ng/ccu_reset.c | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu_reset.c (limited to 'drivers/clk/sunxi-ng/ccu_reset.c') diff --git a/drivers/clk/sunxi-ng/ccu_reset.c b/drivers/clk/sunxi-ng/ccu_reset.c new file mode 100644 index 000000000..6577aa18c --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu_reset.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2016 Maxime Ripard + * Maxime Ripard + */ + +#include +#include +#include + +#include "ccu_reset.h" + +static int ccu_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev); + const struct ccu_reset_map *map = &ccu->reset_map[id]; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(ccu->lock, flags); + + reg = readl(ccu->base + map->reg); + writel(reg & ~map->bit, ccu->base + map->reg); + + spin_unlock_irqrestore(ccu->lock, flags); + + return 0; +} + +static int ccu_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev); + const struct ccu_reset_map *map = &ccu->reset_map[id]; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(ccu->lock, flags); + + reg = readl(ccu->base + map->reg); + writel(reg | map->bit, ccu->base + map->reg); + + spin_unlock_irqrestore(ccu->lock, flags); + + return 0; +} + +static int ccu_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + ccu_reset_assert(rcdev, id); + udelay(10); + ccu_reset_deassert(rcdev, id); + + return 0; +} + +static int ccu_reset_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev); + const struct ccu_reset_map *map = &ccu->reset_map[id]; + + /* + * The reset control API expects 0 if reset is not asserted, + * which is the opposite of what our hardware uses. + */ + return !(map->bit & readl(ccu->base + map->reg)); +} + +const struct reset_control_ops ccu_reset_ops = { + .assert = ccu_reset_assert, + .deassert = ccu_reset_deassert, + .reset = ccu_reset_reset, + .status = ccu_reset_status, +}; +EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, SUNXI_CCU); -- cgit v1.2.3