Support BPMP_CLK_STATE_CHANGE_DENIED by not populating state changing operations when the flag is set. Support BPMP_CLK_RATE_PARENT_CHANGE_DENIED by not populating rate or parent changing operations when the flag is set. Changelog: v1: Initial version v2: Fix dev_warn() usage v3: Use dev_WARN() instead of dev_warn() and clarify error message Signed-off-by: Peter De Schrijver <pdeschrijver@xxxxxxxxxx> --- drivers/clk/tegra/clk-bpmp.c | 37 +++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index d82a71f10c2c..303ddf591efb 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2016-2020 NVIDIA Corporation + * Copyright (C) 2016-2022 NVIDIA Corporation */ #include <linux/clk-provider.h> @@ -310,6 +310,23 @@ static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = { .set_rate = tegra_bpmp_clk_set_rate, }; +static const struct clk_ops tegra_bpmp_clk_mux_read_only_ops = { + .get_parent = tegra_bpmp_clk_get_parent, + .recalc_rate = tegra_bpmp_clk_recalc_rate, +}; + +static const struct clk_ops tegra_bpmp_clk_read_only_ops = { + .recalc_rate = tegra_bpmp_clk_recalc_rate, +}; + +static const struct clk_ops tegra_bpmp_clk_gate_mux_read_only_ops = { + .prepare = tegra_bpmp_clk_prepare, + .unprepare = tegra_bpmp_clk_unprepare, + .is_prepared = tegra_bpmp_clk_is_prepared, + .recalc_rate = tegra_bpmp_clk_recalc_rate, + .get_parent = tegra_bpmp_clk_get_parent, +}; + static int tegra_bpmp_clk_get_max_id(struct tegra_bpmp *bpmp) { struct cmd_clk_get_max_clk_id_response response; @@ -510,8 +527,22 @@ tegra_bpmp_clk_register(struct tegra_bpmp *bpmp, memset(&init, 0, sizeof(init)); init.name = info->name; clk->hw.init = &init; - - if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { + if (info->flags & BPMP_CLK_STATE_CHANGE_DENIED) { + if ((info->flags & BPMP_CLK_RATE_PARENT_CHANGE_DENIED) == 0) { + dev_WARN(bpmp->dev, + "Firmware bug! Inconsistent permission bits for clock %s. State and parent/rate changes disabled." + init.name); + } + if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) + init.ops = &tegra_bpmp_clk_mux_read_only_ops; + else + init.ops = &tegra_bpmp_clk_read_only_ops; + } else if (info->flags & BPMP_CLK_RATE_PARENT_CHANGE_DENIED) { + if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) + init.ops = &tegra_bpmp_clk_gate_mux_read_only_ops; + else + init.ops = &tegra_bpmp_clk_gate_ops; + } else if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { if (info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) init.ops = &tegra_bpmp_clk_mux_rate_ops; else -- 2.34.1