From faa9650cdc5440fe65215e129baa3c6404e8c305 Mon Sep 17 00:00:00 2001 From: Vivek Aknurwar Date: Wed, 26 Feb 2020 15:50:10 -0800 Subject: [PATCH 1/2] clk: qcom: Maintain qcom_regmap_list of qcom clks Providers adds ops for list rate and print reg debug nodes to print necessary debug information, these nodes can not be added to clk framework and is moved down to provider level. Since provider does not have complete knowledge on clks owned at clk framework, providers can not blindly typecast clks owned by clk framework to call its list/print ops. A separate qcom_regmap_list is maintained during qcom clk registration with clk framework. So as when debug list/print calls are called, provider have knowledge of qcom clks and only call respective ops on qcom clks maintained in clk_regmap_list. Providers can use this API to know if clk is qcom regmaped clk. Change-Id: I3e4d8280c8fa0c692f855c0d6659dd14f95008df Signed-off-by: Vivek Aknurwar --- drivers/clk/qcom/clk-regmap.c | 35 ++++++++++++++++++++++++++++++++++- drivers/clk/qcom/clk-regmap.h | 5 ++++- 2 files changed, 38 insertions(+), 2 deletions(-) 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; From 1e2d93e14489687e838b3b2348084f76d686295b Mon Sep 17 00:00:00 2001 From: Vivek Aknurwar Date: Thu, 27 Feb 2020 11:53:14 -0800 Subject: [PATCH 2/2] clk: qcom: clk-debug: List regs only if respective clk is qcom-regmap clk List register ops is provider supported hence can not be called on clk framework clks. For example: xo-board,sleep-clk are fixed clock. List/print only those clocks who are qcom-regmap clks. Cast member structure only if clk_hw is valid clk_regmap clk. Change-Id: Id66856f45166a32e37ea7e477f80360ab020ab25 Signed-off-by: Vivek Aknurwar --- drivers/clk/qcom/clk-debug.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) 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)