Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: qcom: Add support for regmap divider clocks

Add support for dividers that use regmap instead of readl/writel.

Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
[sboyd@codeaurora.org: Switch to using generic divider code, drop
enable/disable, reword commit text]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Tested-by: Kenneth Westfield <kwestfie@codeaurora.org>
Signed-off-by: Michael Turquette <mturquette@linaro.org>

authored by

Josh Cartwright and committed by
Michael Turquette
4116076e bca9690b

+100
+1
drivers/clk/qcom/Makefile
··· 6 6 clk-qcom-y += clk-rcg.o 7 7 clk-qcom-y += clk-rcg2.o 8 8 clk-qcom-y += clk-branch.o 9 + clk-qcom-y += clk-regmap-divider.o 9 10 clk-qcom-y += reset.o 10 11 11 12 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
+70
drivers/clk/qcom/clk-regmap-divider.c
··· 1 + /* 2 + * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/kernel.h> 15 + #include <linux/bitops.h> 16 + #include <linux/regmap.h> 17 + #include <linux/export.h> 18 + 19 + #include "clk-regmap-divider.h" 20 + 21 + static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw) 22 + { 23 + return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr); 24 + } 25 + 26 + static long div_round_rate(struct clk_hw *hw, unsigned long rate, 27 + unsigned long *prate) 28 + { 29 + struct clk_regmap_div *divider = to_clk_regmap_div(hw); 30 + 31 + return divider_round_rate(hw, rate, prate, NULL, divider->width, 32 + CLK_DIVIDER_ROUND_CLOSEST); 33 + } 34 + 35 + static int div_set_rate(struct clk_hw *hw, unsigned long rate, 36 + unsigned long parent_rate) 37 + { 38 + struct clk_regmap_div *divider = to_clk_regmap_div(hw); 39 + struct clk_regmap *clkr = &divider->clkr; 40 + u32 div; 41 + 42 + div = divider_get_val(rate, parent_rate, NULL, divider->width, 43 + CLK_DIVIDER_ROUND_CLOSEST); 44 + 45 + return regmap_update_bits(clkr->regmap, divider->reg, 46 + (BIT(divider->width) - 1) << divider->shift, 47 + div << divider->shift); 48 + } 49 + 50 + static unsigned long div_recalc_rate(struct clk_hw *hw, 51 + unsigned long parent_rate) 52 + { 53 + struct clk_regmap_div *divider = to_clk_regmap_div(hw); 54 + struct clk_regmap *clkr = &divider->clkr; 55 + u32 div; 56 + 57 + regmap_read(clkr->regmap, divider->reg, &div); 58 + div >>= divider->shift; 59 + div &= BIT(divider->width) - 1; 60 + 61 + return divider_recalc_rate(hw, parent_rate, div, NULL, 62 + CLK_DIVIDER_ROUND_CLOSEST); 63 + } 64 + 65 + const struct clk_ops clk_regmap_div_ops = { 66 + .round_rate = div_round_rate, 67 + .set_rate = div_set_rate, 68 + .recalc_rate = div_recalc_rate, 69 + }; 70 + EXPORT_SYMBOL_GPL(clk_regmap_div_ops);
+29
drivers/clk/qcom/clk-regmap-divider.h
··· 1 + /* 2 + * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #ifndef __QCOM_CLK_REGMAP_DIVIDER_H__ 15 + #define __QCOM_CLK_REGMAP_DIVIDER_H__ 16 + 17 + #include <linux/clk-provider.h> 18 + #include "clk-regmap.h" 19 + 20 + struct clk_regmap_div { 21 + u32 reg; 22 + u32 shift; 23 + u32 width; 24 + struct clk_regmap clkr; 25 + }; 26 + 27 + extern const struct clk_ops clk_regmap_div_ops; 28 + 29 + #endif