1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2014 MediaTek Inc. 4 */ 5 6 #include <linux/mfd/syscon.h> 7 #include <linux/module.h> 8 #include <linux/of.h> 9 #include <linux/platform_device.h> 10 #include <linux/regmap.h> 11 #include <linux/reset-controller.h> 12 #include <linux/slab.h> 13 14 #include "clk-mtk.h" 15 16 struct mtk_reset { 17 struct regmap *regmap; 18 int regofs; 19 struct reset_controller_dev rcdev; 20 }; 21 22 static int mtk_reset_assert(struct reset_controller_dev *rcdev, 23 unsigned long id) 24 { 25 struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); 26 27 return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2), 28 BIT(id % 32), ~0); 29 } 30 31 static int mtk_reset_deassert(struct reset_controller_dev *rcdev, 32 unsigned long id) 33 { 34 struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); 35 36 return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2), 37 BIT(id % 32), 0); 38 } 39 40 static int mtk_reset(struct reset_controller_dev *rcdev, 41 unsigned long id) 42 { 43 int ret; 44 45 ret = mtk_reset_assert(rcdev, id); 46 if (ret) 47 return ret; 48 49 return mtk_reset_deassert(rcdev, id); 50 } 51 52 static const struct reset_control_ops mtk_reset_ops = { 53 .assert = mtk_reset_assert, 54 .deassert = mtk_reset_deassert, 55 .reset = mtk_reset, 56 }; 57 58 void mtk_register_reset_controller(struct device_node *np, 59 unsigned int num_regs, int regofs) 60 { 61 struct mtk_reset *data; 62 int ret; 63 struct regmap *regmap; 64 65 regmap = syscon_node_to_regmap(np); 66 if (IS_ERR(regmap)) { 67 pr_err("Cannot find regmap for %pOF: %ld\n", np, 68 PTR_ERR(regmap)); 69 return; 70 } 71 72 data = kzalloc(sizeof(*data), GFP_KERNEL); 73 if (!data) 74 return; 75 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; 82 83 ret = reset_controller_register(&data->rcdev); 84 if (ret) { 85 pr_err("could not register reset controller: %d\n", ret); 86 kfree(data); 87 return; 88 } 89 } 90