From 50359819794b4a16ae35051cd80f2dab025f6019 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 21 Jan 2016 21:53:09 +0100 Subject: clk-divider: make sure read-only dividers do not write to their register Commit e6d5e7d90be9 ("clk-divider: Fix READ_ONLY when divider > 1") removed the special ops struct for read-only clocks and instead opted to handle them inside the regular ops. On the rk3368 this results in breakage as aclkm now gets set a value. While it is the same divider value, the A53 core still doesn't like it, which can result in the cpu ending up in a hang. The reason being that "ACLKENMasserts one clock cycle before the rising edge of ACLKM" and the clock should only be touched when STANDBYWFIL2 is asserted. To fix this, reintroduce the read-only ops but do include the round_rate callback. That way no writes that may be unsafe are done to the divider register in any case. The Rockchip use of the clk_divider_ops is adapted to this split again, as is the nxp, lpc18xx-ccu driver that was included since the original commit. On lpc18xx-ccu the divider seems to always be read-only so only uses the new ops now. Fixes: e6d5e7d90be9 ("clk-divider: Fix READ_ONLY when divider > 1") Reported-by: Zhang Qing Signed-off-by: Heiko Stuebner Signed-off-by: Stephen Boyd --- drivers/clk/nxp/clk-lpc18xx-ccu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clk/nxp/clk-lpc18xx-ccu.c') diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index 13aabbb3acbe..558da89555af 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c @@ -222,7 +222,7 @@ static void lpc18xx_ccu_register_branch_gate_div(struct lpc18xx_clk_branch *bran div->width = 1; div_hw = &div->hw; - div_ops = &clk_divider_ops; + div_ops = &clk_divider_ro_ops; } branch->gate.reg = branch->offset + reg_base; -- cgit v1.2.3 From 5fd9c05c846db98319e75496612da24435cee208 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Fri, 8 Jan 2016 23:51:46 +0800 Subject: clk: move the common clock's to_clk_*(_hw) macros to clk-provider.h to_clk_*(_hw) macros have been repeatedly defined in many places. This patch moves all the to_clk_*(_hw) definitions in the common clock framework to public header clk-provider.h, and drop the local definitions. Signed-off-by: Geliang Tang Signed-off-by: Stephen Boyd --- drivers/clk/clk-composite.c | 2 -- drivers/clk/clk-divider.c | 2 -- drivers/clk/clk-fixed-factor.c | 2 -- drivers/clk/clk-fixed-rate.c | 2 -- drivers/clk/clk-fractional-divider.c | 2 -- drivers/clk/clk-gate.c | 2 -- drivers/clk/clk-gpio.c | 2 -- drivers/clk/clk-multiplier.c | 2 -- drivers/clk/clk-mux.c | 2 -- drivers/clk/imx/clk-busy.c | 4 ++-- drivers/clk/imx/clk-fixup-div.c | 5 ++--- drivers/clk/imx/clk-fixup-mux.c | 2 -- drivers/clk/imx/clk-gate-exclusive.c | 2 +- drivers/clk/mediatek/clk-gate.c | 8 ++++---- drivers/clk/mediatek/clk-gate.h | 2 +- drivers/clk/mvebu/common.c | 2 -- drivers/clk/mvebu/kirkwood.c | 2 -- drivers/clk/mxs/clk-div.c | 2 +- drivers/clk/nxp/clk-lpc18xx-ccu.c | 2 -- drivers/clk/st/clkgen-mux.c | 9 ++++----- drivers/clk/ti/composite.c | 2 -- drivers/clk/ti/divider.c | 2 -- drivers/clk/ti/gate.c | 2 -- drivers/clk/ti/mux.c | 2 -- include/linux/clk-provider.h | 18 ++++++++++++++++++ 25 files changed, 33 insertions(+), 51 deletions(-) (limited to 'drivers/clk/nxp/clk-lpc18xx-ccu.c') diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 4735de0660cc..1f903e1f86a2 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -19,8 +19,6 @@ #include #include -#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) - static u8 clk_composite_get_parent(struct clk_hw *hw) { struct clk_composite *composite = to_clk_composite(hw); diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index aa1dacdaa39d..7d62dc30e969 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -28,8 +28,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #define div_mask(width) ((1 << (width)) - 1) static unsigned int _get_table_maxdiv(const struct clk_div_table *table, diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 83de57aeceea..f0ddf37d5e15 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -23,8 +23,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw) - static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index f85ec8d1711f..e156beb871f0 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -26,8 +26,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) - static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index 5c4955e33f7a..1abcd76b4993 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -16,8 +16,6 @@ #include #include -#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) - static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index de0b322f5f58..d0d8ec8e1f1b 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -26,8 +26,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - /* * It works on following logic: * diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 19fed65587e8..cbbea2985cc9 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -31,8 +31,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw) - static int clk_gpio_gate_enable(struct clk_hw *hw) { struct clk_gpio *clk = to_clk_gpio(hw); diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c index fe7806506bf3..9e449c7b751c 100644 --- a/drivers/clk/clk-multiplier.c +++ b/drivers/clk/clk-multiplier.c @@ -14,8 +14,6 @@ #include #include -#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw) - static unsigned long __get_mult(struct clk_multiplier *mult, unsigned long rate, unsigned long parent_rate) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 5ed03c8a8df9..252188fd8bcd 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -26,8 +26,6 @@ * parent - parent is adjustable through clk_set_parent */ -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static u8 clk_mux_get_parent(struct clk_hw *hw) { struct clk_mux *mux = to_clk_mux(hw); diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index 4bb1bc419b79..5cc99590f9a3 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c @@ -38,7 +38,7 @@ struct clk_busy_divider { static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw) { - struct clk_divider *div = container_of(hw, struct clk_divider, hw); + struct clk_divider *div = to_clk_divider(hw); return container_of(div, struct clk_busy_divider, div); } @@ -123,7 +123,7 @@ struct clk_busy_mux { static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw) { - struct clk_mux *mux = container_of(hw, struct clk_mux, hw); + struct clk_mux *mux = to_clk_mux(hw); return container_of(mux, struct clk_busy_mux, mux); } diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index 21db020b1f2d..ce5722732715 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -15,7 +15,6 @@ #include #include "clk.h" -#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw) #define div_mask(d) ((1 << (d->width)) - 1) /** @@ -35,7 +34,7 @@ struct clk_fixup_div { static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw) { - struct clk_divider *divider = to_clk_div(hw); + struct clk_divider *divider = to_clk_divider(hw); return container_of(divider, struct clk_fixup_div, divider); } @@ -60,7 +59,7 @@ static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); - struct clk_divider *div = to_clk_div(hw); + struct clk_divider *div = to_clk_divider(hw); unsigned int divider, value; unsigned long flags = 0; u32 val; diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index 0d40b35c557c..c9b327e0a8dd 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -15,8 +15,6 @@ #include #include "clk.h" -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - /** * struct clk_fixup_mux - imx integer fixup multiplexer clock * @mux: the parent class diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index c12f5f2e04dc..3bd9dee618b2 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c @@ -31,7 +31,7 @@ struct clk_gate_exclusive { static int clk_gate_exclusive_enable(struct clk_hw *hw) { - struct clk_gate *gate = container_of(hw, struct clk_gate, hw); + struct clk_gate *gate = to_clk_gate(hw); struct clk_gate_exclusive *exgate = container_of(gate, struct clk_gate_exclusive, gate); u32 val = readl(gate->reg); diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 576bdb7c98b8..2a76901bf04b 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -25,7 +25,7 @@ static int mtk_cg_bit_is_cleared(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; regmap_read(cg->regmap, cg->sta_ofs, &val); @@ -37,7 +37,7 @@ static int mtk_cg_bit_is_cleared(struct clk_hw *hw) static int mtk_cg_bit_is_set(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; regmap_read(cg->regmap, cg->sta_ofs, &val); @@ -49,14 +49,14 @@ static int mtk_cg_bit_is_set(struct clk_hw *hw) static void mtk_cg_set_bit(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit)); } static void mtk_cg_clr_bit(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit)); } diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h index 11e25c992948..b1821603b887 100644 --- a/drivers/clk/mediatek/clk-gate.h +++ b/drivers/clk/mediatek/clk-gate.h @@ -29,7 +29,7 @@ struct mtk_clk_gate { u8 bit; }; -static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw) +static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw) { return container_of(hw, struct mtk_clk_gate, hw); } diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 28aac67e7b92..daa6ebdac131 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -199,8 +199,6 @@ struct clk_gating_ctrl { u32 saved_reg; }; -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - static struct clk_gating_ctrl *ctrl; static struct clk *clk_gating_get_src( diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index 99550f25975e..a2a8d614039d 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c @@ -256,8 +256,6 @@ static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = { 11, 1, 0 }, }; -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static struct clk *clk_muxing_get_src( struct of_phandle_args *clkspec, void *data) { diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c index 049ee27d5a22..f75e989c578f 100644 --- a/drivers/clk/mxs/clk-div.c +++ b/drivers/clk/mxs/clk-div.c @@ -33,7 +33,7 @@ struct clk_div { static inline struct clk_div *to_clk_div(struct clk_hw *hw) { - struct clk_divider *divider = container_of(hw, struct clk_divider, hw); + struct clk_divider *divider = to_clk_divider(hw); return container_of(divider, struct clk_div, divider); } diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index 558da89555af..f7136b94fd0e 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c @@ -28,8 +28,6 @@ #define CCU_BRANCH_IS_BUS BIT(0) #define CCU_BRANCH_HAVE_DIV2 BIT(1) -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - struct lpc18xx_branch_clk_data { const char **name; int num; diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index 5dc5ce217960..0d9a74b66ea3 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c @@ -822,11 +822,10 @@ err: if (!clk_data->clks[i]) continue; - composite = container_of(__clk_get_hw(clk_data->clks[i]), - struct clk_composite, hw); - kfree(container_of(composite->gate_hw, struct clk_gate, hw)); - kfree(container_of(composite->rate_hw, struct clk_divider, hw)); - kfree(container_of(composite->mux_hw, struct clk_mux, hw)); + composite = to_clk_composite(__clk_get_hw(clk_data->clks[i])); + kfree(to_clk_gate(composite->gate_hw)); + kfree(to_clk_divider(composite->rate_hw)); + kfree(to_clk_mux(composite->mux_hw)); } kfree(clk_data->clks); diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index dbef218fe5ec..43345c417815 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -28,8 +28,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - static unsigned long ti_composite_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index df2558350fc1..b4e5de16e561 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -26,8 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #define div_mask(d) ((1 << ((d)->width)) - 1) static unsigned int _get_table_maxdiv(const struct clk_div_table *table) diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 5429d3534363..bc05f276f32b 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -24,8 +24,6 @@ #include "clock.h" -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index dab9ba88b9d6..618ded96ace3 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -26,8 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static u8 ti_clk_mux_get_parent(struct clk_hw *hw) { struct clk_mux *mux = to_clk_mux(hw); diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 408a60dca353..33dc814d0f43 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -276,6 +276,8 @@ struct clk_fixed_rate { u8 flags; }; +#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) + extern const struct clk_ops clk_fixed_rate_ops; struct clk *clk_register_fixed_rate(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -314,6 +316,8 @@ struct clk_gate { spinlock_t *lock; }; +#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) + #define CLK_GATE_SET_TO_DISABLE BIT(0) #define CLK_GATE_HIWORD_MASK BIT(1) @@ -376,6 +380,8 @@ struct clk_divider { spinlock_t *lock; }; +#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) + #define CLK_DIVIDER_ONE_BASED BIT(0) #define CLK_DIVIDER_POWER_OF_TWO BIT(1) #define CLK_DIVIDER_ALLOW_ZERO BIT(2) @@ -441,6 +447,8 @@ struct clk_mux { spinlock_t *lock; }; +#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) + #define CLK_MUX_INDEX_ONE BIT(0) #define CLK_MUX_INDEX_BIT BIT(1) #define CLK_MUX_HIWORD_MASK BIT(2) @@ -484,6 +492,8 @@ struct clk_fixed_factor { unsigned int div; }; +#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw) + extern const struct clk_ops clk_fixed_factor_ops; struct clk *clk_register_fixed_factor(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -515,6 +525,8 @@ struct clk_fractional_divider { spinlock_t *lock; }; +#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) + extern const struct clk_ops clk_fractional_divider_ops; struct clk *clk_register_fractional_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -551,6 +563,8 @@ struct clk_multiplier { spinlock_t *lock; }; +#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw) + #define CLK_MULTIPLIER_ZERO_BYPASS BIT(0) #define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1) @@ -580,6 +594,8 @@ struct clk_composite { const struct clk_ops *gate_ops; }; +#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) + struct clk *clk_register_composite(struct device *dev, const char *name, const char * const *parent_names, int num_parents, struct clk_hw *mux_hw, const struct clk_ops *mux_ops, @@ -602,6 +618,8 @@ struct clk_gpio { struct gpio_desc *gpiod; }; +#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw) + extern const struct clk_ops clk_gpio_gate_ops; struct clk *clk_register_gpio_gate(struct device *dev, const char *name, const char *parent_name, unsigned gpio, bool active_low, -- cgit v1.2.3