xref: /openbmc/linux/drivers/clk/sunxi-ng/ccu_reset.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21d80c142SMaxime Ripard /*
31d80c142SMaxime Ripard  * Copyright (C) 2016 Maxime Ripard
41d80c142SMaxime Ripard  * Maxime Ripard <maxime.ripard@free-electrons.com>
51d80c142SMaxime Ripard  */
61d80c142SMaxime Ripard 
7734d21ccSMaxime Ripard #include <linux/delay.h>
81d80c142SMaxime Ripard #include <linux/io.h>
91d80c142SMaxime Ripard #include <linux/reset-controller.h>
101d80c142SMaxime Ripard 
111d80c142SMaxime Ripard #include "ccu_reset.h"
121d80c142SMaxime Ripard 
ccu_reset_assert(struct reset_controller_dev * rcdev,unsigned long id)131d80c142SMaxime Ripard static int ccu_reset_assert(struct reset_controller_dev *rcdev,
141d80c142SMaxime Ripard 			    unsigned long id)
151d80c142SMaxime Ripard {
161d80c142SMaxime Ripard 	struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
171d80c142SMaxime Ripard 	const struct ccu_reset_map *map = &ccu->reset_map[id];
181d80c142SMaxime Ripard 	unsigned long flags;
191d80c142SMaxime Ripard 	u32 reg;
201d80c142SMaxime Ripard 
211d80c142SMaxime Ripard 	spin_lock_irqsave(ccu->lock, flags);
221d80c142SMaxime Ripard 
231d80c142SMaxime Ripard 	reg = readl(ccu->base + map->reg);
241d80c142SMaxime Ripard 	writel(reg & ~map->bit, ccu->base + map->reg);
251d80c142SMaxime Ripard 
261d80c142SMaxime Ripard 	spin_unlock_irqrestore(ccu->lock, flags);
271d80c142SMaxime Ripard 
281d80c142SMaxime Ripard 	return 0;
291d80c142SMaxime Ripard }
301d80c142SMaxime Ripard 
ccu_reset_deassert(struct reset_controller_dev * rcdev,unsigned long id)311d80c142SMaxime Ripard static int ccu_reset_deassert(struct reset_controller_dev *rcdev,
321d80c142SMaxime Ripard 			      unsigned long id)
331d80c142SMaxime Ripard {
341d80c142SMaxime Ripard 	struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
351d80c142SMaxime Ripard 	const struct ccu_reset_map *map = &ccu->reset_map[id];
361d80c142SMaxime Ripard 	unsigned long flags;
371d80c142SMaxime Ripard 	u32 reg;
381d80c142SMaxime Ripard 
391d80c142SMaxime Ripard 	spin_lock_irqsave(ccu->lock, flags);
401d80c142SMaxime Ripard 
411d80c142SMaxime Ripard 	reg = readl(ccu->base + map->reg);
421d80c142SMaxime Ripard 	writel(reg | map->bit, ccu->base + map->reg);
431d80c142SMaxime Ripard 
441d80c142SMaxime Ripard 	spin_unlock_irqrestore(ccu->lock, flags);
451d80c142SMaxime Ripard 
461d80c142SMaxime Ripard 	return 0;
471d80c142SMaxime Ripard }
481d80c142SMaxime Ripard 
ccu_reset_reset(struct reset_controller_dev * rcdev,unsigned long id)49734d21ccSMaxime Ripard static int ccu_reset_reset(struct reset_controller_dev *rcdev,
50734d21ccSMaxime Ripard 			   unsigned long id)
51734d21ccSMaxime Ripard {
52734d21ccSMaxime Ripard 	ccu_reset_assert(rcdev, id);
53734d21ccSMaxime Ripard 	udelay(10);
54734d21ccSMaxime Ripard 	ccu_reset_deassert(rcdev, id);
55734d21ccSMaxime Ripard 
56734d21ccSMaxime Ripard 	return 0;
57734d21ccSMaxime Ripard }
58734d21ccSMaxime Ripard 
ccu_reset_status(struct reset_controller_dev * rcdev,unsigned long id)595da672cfSChen-Yu Tsai static int ccu_reset_status(struct reset_controller_dev *rcdev,
605da672cfSChen-Yu Tsai 			    unsigned long id)
615da672cfSChen-Yu Tsai {
625da672cfSChen-Yu Tsai 	struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
635da672cfSChen-Yu Tsai 	const struct ccu_reset_map *map = &ccu->reset_map[id];
645da672cfSChen-Yu Tsai 
655da672cfSChen-Yu Tsai 	/*
665da672cfSChen-Yu Tsai 	 * The reset control API expects 0 if reset is not asserted,
675da672cfSChen-Yu Tsai 	 * which is the opposite of what our hardware uses.
685da672cfSChen-Yu Tsai 	 */
695da672cfSChen-Yu Tsai 	return !(map->bit & readl(ccu->base + map->reg));
705da672cfSChen-Yu Tsai }
715da672cfSChen-Yu Tsai 
721d80c142SMaxime Ripard const struct reset_control_ops ccu_reset_ops = {
731d80c142SMaxime Ripard 	.assert		= ccu_reset_assert,
741d80c142SMaxime Ripard 	.deassert	= ccu_reset_deassert,
75734d21ccSMaxime Ripard 	.reset		= ccu_reset_reset,
765da672cfSChen-Yu Tsai 	.status		= ccu_reset_status,
771d80c142SMaxime Ripard };
78*551b62b1SSamuel Holland EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, SUNXI_CCU);
79