1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2014 MediaTek Inc.
6 #include <linux/mfd/syscon.h>
7 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/regmap.h>
11 #include <linux/reset-controller.h>
12 #include <linux/slab.h>
17 struct regmap *regmap;
19 struct reset_controller_dev rcdev;
22 static int mtk_reset_assert(struct reset_controller_dev *rcdev,
25 struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
27 return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
31 static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
34 struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
36 return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
40 static int mtk_reset(struct reset_controller_dev *rcdev,
45 ret = mtk_reset_assert(rcdev, id);
49 return mtk_reset_deassert(rcdev, id);
52 static const struct reset_control_ops mtk_reset_ops = {
53 .assert = mtk_reset_assert,
54 .deassert = mtk_reset_deassert,
58 void mtk_register_reset_controller(struct device_node *np,
59 unsigned int num_regs, int regofs)
61 struct mtk_reset *data;
63 struct regmap *regmap;
65 regmap = syscon_node_to_regmap(np);
67 pr_err("Cannot find regmap for %pOF: %ld\n", np,
72 data = kzalloc(sizeof(*data), GFP_KERNEL);
76 data->regmap = regmap;
77 data->regofs = regofs;
78 data->rcdev.owner = THIS_MODULE;
79 data->rcdev.nr_resets = num_regs * 32;
80 data->rcdev.ops = &mtk_reset_ops;
81 data->rcdev.of_node = np;
83 ret = reset_controller_register(&data->rcdev);
85 pr_err("could not register reset controller: %d\n", ret);