FILE
clk-regmap-divider.c
File preview with syntax highlighting.
linux-6.19.14/drivers/clk/qcom/clk-regmap-divider.c
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2014, The Linux Foundation. All rights reserved. 4 */ 5 6#include <linux/kernel.h> 7#include <linux/bitops.h> 8#include <linux/regmap.h> 9#include <linux/export.h> 10 11#include "clk-regmap-divider.h" 12 13static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw) 14{ 15 return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr); 16} 17 18static int div_ro_determine_rate(struct clk_hw *hw, 19 struct clk_rate_request *req) 20{ 21 struct clk_regmap_div *divider = to_clk_regmap_div(hw); 22 struct clk_regmap *clkr = ÷r->clkr; 23 u32 val; 24 25 regmap_read(clkr->regmap, divider->reg, &val); 26 val >>= divider->shift; 27 val &= BIT(divider->width) - 1; 28 29 return divider_ro_determine_rate(hw, req, NULL, divider->width, 30 CLK_DIVIDER_ROUND_CLOSEST, val); 31} 32 33static int div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) 34{ 35 struct clk_regmap_div *divider = to_clk_regmap_div(hw); 36 37 return divider_determine_rate(hw, req, NULL, divider->width, 38 CLK_DIVIDER_ROUND_CLOSEST); 39} 40 41static int div_set_rate(struct clk_hw *hw, unsigned long rate, 42 unsigned long parent_rate) 43{ 44 struct clk_regmap_div *divider = to_clk_regmap_div(hw); 45 struct clk_regmap *clkr = ÷r->clkr; 46 u32 div; 47 48 div = divider_get_val(rate, parent_rate, NULL, divider->width, 49 CLK_DIVIDER_ROUND_CLOSEST); 50 51 return regmap_update_bits(clkr->regmap, divider->reg, 52 (BIT(divider->width) - 1) << divider->shift, 53 div << divider->shift); 54} 55 56static unsigned long div_recalc_rate(struct clk_hw *hw, 57 unsigned long parent_rate) 58{ 59 struct clk_regmap_div *divider = to_clk_regmap_div(hw); 60 struct clk_regmap *clkr = ÷r->clkr; 61 u32 div; 62 63 regmap_read(clkr->regmap, divider->reg, &div); 64 div >>= divider->shift; 65 div &= BIT(divider->width) - 1; 66 67 return divider_recalc_rate(hw, parent_rate, div, NULL, 68 CLK_DIVIDER_ROUND_CLOSEST, divider->width); 69} 70 71const struct clk_ops clk_regmap_div_ops = { 72 .determine_rate = div_determine_rate, 73 .set_rate = div_set_rate, 74 .recalc_rate = div_recalc_rate, 75}; 76EXPORT_SYMBOL_GPL(clk_regmap_div_ops); 77 78const struct clk_ops clk_regmap_div_ro_ops = { 79 .determine_rate = div_ro_determine_rate, 80 .recalc_rate = div_recalc_rate, 81}; 82EXPORT_SYMBOL_GPL(clk_regmap_div_ro_ops);
~/
Read-only file preview.