2 * Copyright (c) 2014 MediaTek Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/mfd/syscon.h>
15 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/regmap.h>
19 #include <linux/reset-controller.h>
20 #include <linux/slab.h>
25 struct regmap
*regmap
;
27 struct reset_controller_dev rcdev
;
30 static int mtk_reset_assert(struct reset_controller_dev
*rcdev
,
33 struct mtk_reset
*data
= container_of(rcdev
, struct mtk_reset
, rcdev
);
35 return regmap_update_bits(data
->regmap
, data
->regofs
+ ((id
/ 32) << 2),
39 static int mtk_reset_deassert(struct reset_controller_dev
*rcdev
,
42 struct mtk_reset
*data
= container_of(rcdev
, struct mtk_reset
, rcdev
);
44 return regmap_update_bits(data
->regmap
, data
->regofs
+ ((id
/ 32) << 2),
48 static int mtk_reset(struct reset_controller_dev
*rcdev
,
53 ret
= mtk_reset_assert(rcdev
, id
);
57 return mtk_reset_deassert(rcdev
, id
);
60 static const struct reset_control_ops mtk_reset_ops
= {
61 .assert = mtk_reset_assert
,
62 .deassert
= mtk_reset_deassert
,
66 void mtk_register_reset_controller(struct device_node
*np
,
67 unsigned int num_regs
, int regofs
)
69 struct mtk_reset
*data
;
71 struct regmap
*regmap
;
73 regmap
= syscon_node_to_regmap(np
);
75 pr_err("Cannot find regmap for %pOF: %ld\n", np
,
80 data
= kzalloc(sizeof(*data
), GFP_KERNEL
);
84 data
->regmap
= regmap
;
85 data
->regofs
= regofs
;
86 data
->rcdev
.owner
= THIS_MODULE
;
87 data
->rcdev
.nr_resets
= num_regs
* 32;
88 data
->rcdev
.ops
= &mtk_reset_ops
;
89 data
->rcdev
.of_node
= np
;
91 ret
= reset_controller_register(&data
->rcdev
);
93 pr_err("could not register reset controller: %d\n", ret
);