diff --git a/drivers/clk/qcom/clk-debug.c b/drivers/clk/qcom/clk-debug.c index d87b78c9a59b..70afd99ed217 100644 --- a/drivers/clk/qcom/clk-debug.c +++ b/drivers/clk/qcom/clk-debug.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016, 2019, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2016, 2019-2020, The Linux Foundation. All rights reserved. */ #include #include @@ -512,17 +512,19 @@ static const struct file_operations list_rates_fops = { static void clk_debug_print_hw(struct clk_hw *hw, struct seq_file *f) { - struct clk_regmap *rclk = to_clk_regmap(hw); + struct clk_regmap *rclk; if (IS_ERR_OR_NULL(hw)) return; clk_debug_print_hw(clk_hw_get_parent(hw), f); - seq_printf(f, "%s\n", clk_hw_get_name(hw)); - if (rclk->ops && rclk->ops->list_registers) - rclk->ops->list_registers(f, hw); + if (clk_is_regmap_clk(hw)) { + rclk = to_clk_regmap(hw); + if (rclk->ops && rclk->ops->list_registers) + rclk->ops->list_registers(f, hw); + } } static int print_hw_show(struct seq_file *m, void *unused) diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c index bd92f4390107..54d8ee1b33fb 100644 --- a/drivers/clk/qcom/clk-regmap.c +++ b/drivers/clk/qcom/clk-regmap.c @@ -10,6 +10,8 @@ #include "clk-regmap.h" +static LIST_HEAD(clk_regmap_list); + /** * clk_is_enabled_regmap - standard is_enabled() for regmap users * @@ -230,6 +232,30 @@ void clk_unprepare_regmap(struct clk_hw *hw) } EXPORT_SYMBOL(clk_unprepare_regmap); +/** + * clk_is_regmap_clk - Checks if clk is a regmap clk + * + * @hw: clk to check on + * + * Iterate over maintained clk regmap list to know + * if concern clk is regmap + * + * Returns true on success, false otherwise. + */ +bool clk_is_regmap_clk(struct clk_hw *hw) +{ + struct clk_regmap *rclk; + + if (hw) { + list_for_each_entry(rclk, &clk_regmap_list, list_node) + if (&rclk->hw == hw) + return true; + } + + return false; +} +EXPORT_SYMBOL(clk_is_regmap_clk); + /** * devm_clk_register_regmap - register a clk_regmap clock * @@ -238,14 +264,21 @@ EXPORT_SYMBOL(clk_unprepare_regmap); * Clocks that use regmap for their register I/O should register their * clk_regmap struct via this function so that the regmap is initialized * and so that the clock is registered with the common clock framework. + * Also maintain clk-regmap clks list for providers use. */ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk) { + int ret; + if (dev && dev_get_regmap(dev, NULL)) rclk->regmap = dev_get_regmap(dev, NULL); else if (dev && dev->parent) rclk->regmap = dev_get_regmap(dev->parent, NULL); - return devm_clk_hw_register(dev, &rclk->hw); + ret = devm_clk_hw_register(dev, &rclk->hw); + if (!ret) + list_add(&rclk->list_node, &clk_regmap_list); + + return ret; } EXPORT_SYMBOL_GPL(devm_clk_register_regmap); diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h index 30f1ae366f9e..0060f6b7504d 100644 --- a/drivers/clk/qcom/clk-regmap.h +++ b/drivers/clk/qcom/clk-regmap.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2014, 2016-2019, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2014, 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_REGMAP_H__ #define __QCOM_CLK_REGMAP_H__ @@ -49,6 +49,7 @@ struct clk_regmap { bool enable_is_inverted; struct clk_vdd_class_data vdd_data; struct clk_regmap_ops *ops; + struct list_head list_node; }; #define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw) @@ -63,6 +64,8 @@ int clk_post_change_regmap(struct clk_hw *hw, unsigned long old_rate, unsigned long cur_rate); int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk); +bool clk_is_regmap_clk(struct clk_hw *hw); + struct clk_register_data { char *name; u32 offset;