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/slab.h> 12 13 #include "reset.h" 14 15 static inline struct mtk_clk_rst_data *to_mtk_clk_rst_data(struct reset_controller_dev *rcdev) 16 { 17 return container_of(rcdev, struct mtk_clk_rst_data, rcdev); 18 } 19 20 static int mtk_reset_update(struct reset_controller_dev *rcdev, 21 unsigned long id, bool deassert) 22 { 23 struct mtk_clk_rst_data *data = to_mtk_clk_rst_data(rcdev); 24 unsigned int val = deassert ? 0 : ~0; 25 26 return regmap_update_bits(data->regmap, 27 data->desc->rst_bank_ofs[id / RST_NR_PER_BANK], 28 BIT(id % RST_NR_PER_BANK), val); 29 } 30 31 static int mtk_reset_assert(struct reset_controller_dev *rcdev, 32 unsigned long id) 33 { 34 return mtk_reset_update(rcdev, id, false); 35 } 36 37 static int mtk_reset_deassert(struct reset_controller_dev *rcdev, 38 unsigned long id) 39 { 40 return mtk_reset_update(rcdev, id, true); 41 } 42 43 static int mtk_reset(struct reset_controller_dev *rcdev, unsigned long id) 44 { 45 int ret; 46 47 ret = mtk_reset_assert(rcdev, id); 48 if (ret) 49 return ret; 50 51 return mtk_reset_deassert(rcdev, id); 52 } 53 54 static int mtk_reset_update_set_clr(struct reset_controller_dev *rcdev, 55 unsigned long id, bool deassert) 56 { 57 struct mtk_clk_rst_data *data = to_mtk_clk_rst_data(rcdev); 58 unsigned int deassert_ofs = deassert ? 0x4 : 0; 59 60 return regmap_write(data->regmap, 61 data->desc->rst_bank_ofs[id / RST_NR_PER_BANK] + 62 deassert_ofs, 63 BIT(id % RST_NR_PER_BANK)); 64 } 65 66 static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev, 67 unsigned long id) 68 { 69 return mtk_reset_update_set_clr(rcdev, id, false); 70 } 71 72 static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev, 73 unsigned long id) 74 { 75 return mtk_reset_update_set_clr(rcdev, id, true); 76 } 77 78 static int mtk_reset_set_clr(struct reset_controller_dev *rcdev, 79 unsigned long id) 80 { 81 int ret; 82 83 ret = mtk_reset_assert_set_clr(rcdev, id); 84 if (ret) 85 return ret; 86 return mtk_reset_deassert_set_clr(rcdev, id); 87 } 88 89 static const struct reset_control_ops mtk_reset_ops = { 90 .assert = mtk_reset_assert, 91 .deassert = mtk_reset_deassert, 92 .reset = mtk_reset, 93 }; 94 95 static const struct reset_control_ops mtk_reset_ops_set_clr = { 96 .assert = mtk_reset_assert_set_clr, 97 .deassert = mtk_reset_deassert_set_clr, 98 .reset = mtk_reset_set_clr, 99 }; 100 101 static int reset_xlate(struct reset_controller_dev *rcdev, 102 const struct of_phandle_args *reset_spec) 103 { 104 struct mtk_clk_rst_data *data = to_mtk_clk_rst_data(rcdev); 105 106 if (reset_spec->args[0] >= rcdev->nr_resets || 107 reset_spec->args[0] >= data->desc->rst_idx_map_nr) 108 return -EINVAL; 109 110 return data->desc->rst_idx_map[reset_spec->args[0]]; 111 } 112 113 int mtk_register_reset_controller(struct device_node *np, 114 const struct mtk_clk_rst_desc *desc) 115 { 116 struct regmap *regmap; 117 const struct reset_control_ops *rcops = NULL; 118 struct mtk_clk_rst_data *data; 119 int ret; 120 121 if (!desc) { 122 pr_err("mtk clock reset desc is NULL\n"); 123 return -EINVAL; 124 } 125 126 switch (desc->version) { 127 case MTK_RST_SIMPLE: 128 rcops = &mtk_reset_ops; 129 break; 130 case MTK_RST_SET_CLR: 131 rcops = &mtk_reset_ops_set_clr; 132 break; 133 default: 134 pr_err("Unknown reset version %d\n", desc->version); 135 return -EINVAL; 136 } 137 138 regmap = device_node_to_regmap(np); 139 if (IS_ERR(regmap)) { 140 pr_err("Cannot find regmap for %pOF: %pe\n", np, regmap); 141 return -EINVAL; 142 } 143 144 data = kzalloc(sizeof(*data), GFP_KERNEL); 145 if (!data) 146 return -ENOMEM; 147 148 data->desc = desc; 149 data->regmap = regmap; 150 data->rcdev.owner = THIS_MODULE; 151 data->rcdev.ops = rcops; 152 data->rcdev.of_node = np; 153 154 if (data->desc->rst_idx_map_nr > 0) { 155 data->rcdev.of_reset_n_cells = 1; 156 data->rcdev.nr_resets = desc->rst_idx_map_nr; 157 data->rcdev.of_xlate = reset_xlate; 158 } else { 159 data->rcdev.nr_resets = desc->rst_bank_nr * RST_NR_PER_BANK; 160 } 161 162 ret = reset_controller_register(&data->rcdev); 163 if (ret) { 164 pr_err("could not register reset controller: %d\n", ret); 165 kfree(data); 166 return ret; 167 } 168 169 return 0; 170 } 171 172 int mtk_register_reset_controller_with_dev(struct device *dev, 173 const struct mtk_clk_rst_desc *desc) 174 { 175 struct device_node *np = dev->of_node; 176 struct regmap *regmap; 177 const struct reset_control_ops *rcops = NULL; 178 struct mtk_clk_rst_data *data; 179 int ret; 180 181 if (!desc) { 182 dev_err(dev, "mtk clock reset desc is NULL\n"); 183 return -EINVAL; 184 } 185 186 switch (desc->version) { 187 case MTK_RST_SIMPLE: 188 rcops = &mtk_reset_ops; 189 break; 190 case MTK_RST_SET_CLR: 191 rcops = &mtk_reset_ops_set_clr; 192 break; 193 default: 194 dev_err(dev, "Unknown reset version %d\n", desc->version); 195 return -EINVAL; 196 } 197 198 regmap = device_node_to_regmap(np); 199 if (IS_ERR(regmap)) { 200 dev_err(dev, "Cannot find regmap %pe\n", regmap); 201 return -EINVAL; 202 } 203 204 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 205 if (!data) 206 return -ENOMEM; 207 208 data->desc = desc; 209 data->regmap = regmap; 210 data->rcdev.owner = THIS_MODULE; 211 data->rcdev.ops = rcops; 212 data->rcdev.of_node = np; 213 data->rcdev.dev = dev; 214 215 if (data->desc->rst_idx_map_nr > 0) { 216 data->rcdev.of_reset_n_cells = 1; 217 data->rcdev.nr_resets = desc->rst_idx_map_nr; 218 data->rcdev.of_xlate = reset_xlate; 219 } else { 220 data->rcdev.nr_resets = desc->rst_bank_nr * RST_NR_PER_BANK; 221 } 222 223 ret = devm_reset_controller_register(dev, &data->rcdev); 224 if (ret) { 225 dev_err(dev, "could not register reset controller: %d\n", ret); 226 return ret; 227 } 228 229 return 0; 230 } 231 EXPORT_SYMBOL_GPL(mtk_register_reset_controller_with_dev); 232 233 MODULE_LICENSE("GPL"); 234