aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/mediatek/reset.c
diff options
context:
space:
mode:
authorRex-BC Chen <rex-bc.chen@mediatek.com>2022-05-23 17:33:35 +0800
committerStephen Boyd <sboyd@kernel.org>2022-06-15 17:24:12 -0700
commit322989ddf7c478a9cbbb51da0d4b51825a47735d (patch)
tree3a4b7764809914e19aa05632a140a0ab6f564a47 /drivers/clk/mediatek/reset.c
parentclk: mediatek: reset: Support nonsequence base offsets of reset registers (diff)
downloadlinux-dev-322989ddf7c478a9cbbb51da0d4b51825a47735d.tar.xz
linux-dev-322989ddf7c478a9cbbb51da0d4b51825a47735d.zip
clk: mediatek: reset: Support inuput argument index mode
There is a large number of mediatek infra reset bits, but we do not use all of them. In addition, the proper input argement of reset controller soulde be index. Therefore, to be compatible with previous drivers and usage, we add description variables to store the ids which can mapping to index. To use this mode, we need to put the id in rst_idx_map to map from index to ids. For example, if we want to input index 1 (this index is used to set bank 1 bit 14) for svs, we need to declare the reset controller like this: In drivers: static u16 rst_ofs[] = { 0x120, 0x130, 0x140, 0x150, 0x730, }; static u16 rst_idx_map[] = { 0 * 32 + 0, 1 * 32 + 14, .... }; static const struct mtk_clk_rst_desc clk_rst_desc = { .version = MTK_RST_SET_CLR, .rst_bank_ofs = rst_ofs, .rst_bank_nr = ARRAY_SIZE(rst_ofs), .rst_idx_map = rst_idx_map, .rst_idx_map_nr = ARRAY_SIZE(rst_idx_map), }; In dts: svs: { ... resets = <&infra 1>; ... }; Signed-off-by: Rex-BC Chen <rex-bc.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: NĂ­colas F. R. A. Prado <nfraprado@collabora.com> Tested-by: NĂ­colas F. R. A. Prado <nfraprado@collabora.com> Link: https://lore.kernel.org/r/20220523093346.28493-9-rex-bc.chen@mediatek.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/mediatek/reset.c')
-rw-r--r--drivers/clk/mediatek/reset.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index 11b2f74f121d..89e617ea6393 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -98,6 +98,18 @@ static const struct reset_control_ops mtk_reset_ops_set_clr = {
.reset = mtk_reset_set_clr,
};
+static int reset_xlate(struct reset_controller_dev *rcdev,
+ const struct of_phandle_args *reset_spec)
+{
+ struct mtk_clk_rst_data *data = to_mtk_clk_rst_data(rcdev);
+
+ if (reset_spec->args[0] >= rcdev->nr_resets ||
+ reset_spec->args[0] >= data->desc->rst_idx_map_nr)
+ return -EINVAL;
+
+ return data->desc->rst_idx_map[reset_spec->args[0]];
+}
+
void mtk_register_reset_controller(struct device_node *np,
const struct mtk_clk_rst_desc *desc)
{
@@ -136,10 +148,17 @@ void mtk_register_reset_controller(struct device_node *np,
data->desc = desc;
data->regmap = regmap;
data->rcdev.owner = THIS_MODULE;
- data->rcdev.nr_resets = desc->rst_bank_nr * RST_NR_PER_BANK;
data->rcdev.ops = rcops;
data->rcdev.of_node = np;
+ if (data->desc->rst_idx_map_nr > 0) {
+ data->rcdev.of_reset_n_cells = 1;
+ data->rcdev.nr_resets = desc->rst_idx_map_nr;
+ data->rcdev.of_xlate = reset_xlate;
+ } else {
+ data->rcdev.nr_resets = desc->rst_bank_nr * RST_NR_PER_BANK;
+ }
+
ret = reset_controller_register(&data->rcdev);
if (ret) {
pr_err("could not register reset controller: %d\n", ret);