From: Stephen Boyd Date: Sat, 27 Jan 2018 00:42:03 +0000 (-0800) Subject: Merge branch 'clk-divider-container' into clk-next X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=716d9b1d4a88493ec3e52957cc1026d32534ee67;p=linux.git Merge branch 'clk-divider-container' into clk-next * clk-divider-container: clk: divider: fix incorrect usage of container_of Plus fixup sprd/div.c to pass the width too. --- 716d9b1d4a88493ec3e52957cc1026d32534ee67 diff --cc drivers/clk/sprd/div.c index 887a8633fdc99,0000000000000..7621a1d1ab9c1 mode 100644,000000..100644 --- a/drivers/clk/sprd/div.c +++ b/drivers/clk/sprd/div.c @@@ -1,90 -1,0 +1,91 @@@ +// SPDX-License-Identifier: GPL-2.0 +// +// Spreadtrum divider clock driver +// +// Copyright (C) 2017 Spreadtrum, Inc. +// Author: Chunyan Zhang + +#include + +#include "div.h" + +long sprd_div_helper_round_rate(struct sprd_clk_common *common, + const struct sprd_div_internal *div, + unsigned long rate, + unsigned long *parent_rate) +{ + return divider_round_rate(&common->hw, rate, parent_rate, + NULL, div->width, 0); +} +EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate); + +static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct sprd_div *cd = hw_to_sprd_div(hw); + + return sprd_div_helper_round_rate(&cd->common, &cd->div, + rate, parent_rate); +} + +unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, + const struct sprd_div_internal *div, + unsigned long parent_rate) +{ + unsigned long val; + unsigned int reg; + + regmap_read(common->regmap, common->reg, ®); + val = reg >> div->shift; + val &= (1 << div->width) - 1; + - return divider_recalc_rate(&common->hw, parent_rate, val, NULL, 0); ++ return divider_recalc_rate(&common->hw, parent_rate, val, NULL, 0, ++ div->width); +} +EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate); + +static unsigned long sprd_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sprd_div *cd = hw_to_sprd_div(hw); + + return sprd_div_helper_recalc_rate(&cd->common, &cd->div, parent_rate); +} + +int sprd_div_helper_set_rate(const struct sprd_clk_common *common, + const struct sprd_div_internal *div, + unsigned long rate, + unsigned long parent_rate) +{ + unsigned long val; + unsigned int reg; + + val = divider_get_val(rate, parent_rate, NULL, + div->width, 0); + + regmap_read(common->regmap, common->reg, ®); + reg &= ~GENMASK(div->width + div->shift - 1, div->shift); + + regmap_write(common->regmap, common->reg, + reg | (val << div->shift)); + + return 0; + +} +EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate); + +static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sprd_div *cd = hw_to_sprd_div(hw); + + return sprd_div_helper_set_rate(&cd->common, &cd->div, + rate, parent_rate); +} + +const struct clk_ops sprd_div_ops = { + .recalc_rate = sprd_div_recalc_rate, + .round_rate = sprd_div_round_rate, + .set_rate = sprd_div_set_rate, +}; +EXPORT_SYMBOL_GPL(sprd_div_ops);