1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2014 MundoReader S.L.
4 * Author: Heiko Stuebner <heiko@sntech.de>
7 #include <linux/slab.h>
9 #include <linux/reset-controller.h>
10 #include <linux/spinlock.h>
13 struct rockchip_softrst
{
14 struct reset_controller_dev rcdev
;
15 void __iomem
*reg_base
;
22 static int rockchip_softrst_assert(struct reset_controller_dev
*rcdev
,
25 struct rockchip_softrst
*softrst
= container_of(rcdev
,
26 struct rockchip_softrst
,
28 int bank
= id
/ softrst
->num_per_reg
;
29 int offset
= id
% softrst
->num_per_reg
;
31 if (softrst
->flags
& ROCKCHIP_SOFTRST_HIWORD_MASK
) {
32 writel(BIT(offset
) | (BIT(offset
) << 16),
33 softrst
->reg_base
+ (bank
* 4));
38 spin_lock_irqsave(&softrst
->lock
, flags
);
40 reg
= readl(softrst
->reg_base
+ (bank
* 4));
41 writel(reg
| BIT(offset
), softrst
->reg_base
+ (bank
* 4));
43 spin_unlock_irqrestore(&softrst
->lock
, flags
);
49 static int rockchip_softrst_deassert(struct reset_controller_dev
*rcdev
,
52 struct rockchip_softrst
*softrst
= container_of(rcdev
,
53 struct rockchip_softrst
,
55 int bank
= id
/ softrst
->num_per_reg
;
56 int offset
= id
% softrst
->num_per_reg
;
58 if (softrst
->flags
& ROCKCHIP_SOFTRST_HIWORD_MASK
) {
59 writel((BIT(offset
) << 16), softrst
->reg_base
+ (bank
* 4));
64 spin_lock_irqsave(&softrst
->lock
, flags
);
66 reg
= readl(softrst
->reg_base
+ (bank
* 4));
67 writel(reg
& ~BIT(offset
), softrst
->reg_base
+ (bank
* 4));
69 spin_unlock_irqrestore(&softrst
->lock
, flags
);
75 static const struct reset_control_ops rockchip_softrst_ops
= {
76 .assert = rockchip_softrst_assert
,
77 .deassert
= rockchip_softrst_deassert
,
80 void rockchip_register_softrst(struct device_node
*np
,
81 unsigned int num_regs
,
82 void __iomem
*base
, u8 flags
)
84 struct rockchip_softrst
*softrst
;
87 softrst
= kzalloc(sizeof(*softrst
), GFP_KERNEL
);
91 spin_lock_init(&softrst
->lock
);
93 softrst
->reg_base
= base
;
94 softrst
->flags
= flags
;
95 softrst
->num_regs
= num_regs
;
96 softrst
->num_per_reg
= (flags
& ROCKCHIP_SOFTRST_HIWORD_MASK
) ? 16
99 softrst
->rcdev
.owner
= THIS_MODULE
;
100 softrst
->rcdev
.nr_resets
= num_regs
* softrst
->num_per_reg
;
101 softrst
->rcdev
.ops
= &rockchip_softrst_ops
;
102 softrst
->rcdev
.of_node
= np
;
103 ret
= reset_controller_register(&softrst
->rcdev
);
105 pr_err("%s: could not register reset controller, %d\n",
110 EXPORT_SYMBOL_GPL(rockchip_register_softrst
);