2 * Copyright (c) 2014 MundoReader S.L.
3 * Author: Heiko Stuebner <heiko@sntech.de>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/slab.h>
18 #include <linux/reset-controller.h>
19 #include <linux/spinlock.h>
22 struct rockchip_softrst
{
23 struct reset_controller_dev rcdev
;
24 void __iomem
*reg_base
;
31 static int rockchip_softrst_assert(struct reset_controller_dev
*rcdev
,
34 struct rockchip_softrst
*softrst
= container_of(rcdev
,
35 struct rockchip_softrst
,
37 int bank
= id
/ softrst
->num_per_reg
;
38 int offset
= id
% softrst
->num_per_reg
;
40 if (softrst
->flags
& ROCKCHIP_SOFTRST_HIWORD_MASK
) {
41 writel(BIT(offset
) | (BIT(offset
) << 16),
42 softrst
->reg_base
+ (bank
* 4));
47 spin_lock_irqsave(&softrst
->lock
, flags
);
49 reg
= readl(softrst
->reg_base
+ (bank
* 4));
50 writel(reg
| BIT(offset
), softrst
->reg_base
+ (bank
* 4));
52 spin_unlock_irqrestore(&softrst
->lock
, flags
);
58 static int rockchip_softrst_deassert(struct reset_controller_dev
*rcdev
,
61 struct rockchip_softrst
*softrst
= container_of(rcdev
,
62 struct rockchip_softrst
,
64 int bank
= id
/ softrst
->num_per_reg
;
65 int offset
= id
% softrst
->num_per_reg
;
67 if (softrst
->flags
& ROCKCHIP_SOFTRST_HIWORD_MASK
) {
68 writel((BIT(offset
) << 16), softrst
->reg_base
+ (bank
* 4));
73 spin_lock_irqsave(&softrst
->lock
, flags
);
75 reg
= readl(softrst
->reg_base
+ (bank
* 4));
76 writel(reg
& ~BIT(offset
), softrst
->reg_base
+ (bank
* 4));
78 spin_unlock_irqrestore(&softrst
->lock
, flags
);
84 static const struct reset_control_ops rockchip_softrst_ops
= {
85 .assert = rockchip_softrst_assert
,
86 .deassert
= rockchip_softrst_deassert
,
89 void __init
rockchip_register_softrst(struct device_node
*np
,
90 unsigned int num_regs
,
91 void __iomem
*base
, u8 flags
)
93 struct rockchip_softrst
*softrst
;
96 softrst
= kzalloc(sizeof(*softrst
), GFP_KERNEL
);
100 spin_lock_init(&softrst
->lock
);
102 softrst
->reg_base
= base
;
103 softrst
->flags
= flags
;
104 softrst
->num_regs
= num_regs
;
105 softrst
->num_per_reg
= (flags
& ROCKCHIP_SOFTRST_HIWORD_MASK
) ? 16
108 softrst
->rcdev
.owner
= THIS_MODULE
;
109 softrst
->rcdev
.nr_resets
= num_regs
* softrst
->num_per_reg
;
110 softrst
->rcdev
.ops
= &rockchip_softrst_ops
;
111 softrst
->rcdev
.of_node
= np
;
112 ret
= reset_controller_register(&softrst
->rcdev
);
114 pr_err("%s: could not register reset controller, %d\n",