From d2e82ad9e0ef5243d45ab54dd04ee2a4d3191d1f Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Tue, 30 Aug 2022 16:41:38 +0200 Subject: [PATCH] clk: imx: gate2 support shared counter and relative clock functions Add shared counter in order to avoid to swich off clock that are already used. Signed-off-by: Michael Trimarchi Reviewed-by: Dario Binacchi Signed-off-by: Dario Binacchi --- drivers/clk/imx/clk-gate2.c | 15 ++++++++++++++- drivers/clk/imx/clk.h | 27 +++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index 40b2d4c..da27230 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include "clk.h" @@ -33,6 +34,7 @@ struct clk_gate2 { u8 bit_idx; u8 cgr_val; u8 flags; + unsigned int *share_count; }; #define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk) @@ -42,6 +44,9 @@ static int clk_gate2_enable(struct clk *clk) struct clk_gate2 *gate = to_clk_gate2(clk); u32 reg; + if (gate->share_count && (*gate->share_count)++ > 0) + return 0; + reg = readl(gate->reg); reg &= ~(3 << gate->bit_idx); reg |= gate->cgr_val << gate->bit_idx; @@ -55,6 +60,13 @@ static int clk_gate2_disable(struct clk *clk) struct clk_gate2 *gate = to_clk_gate2(clk); u32 reg; + if (gate->share_count) { + if (WARN_ON(*gate->share_count == 0)) + return 0; + else if (--(*gate->share_count) > 0) + return 0; + } + reg = readl(gate->reg); reg &= ~(3 << gate->bit_idx); writel(reg, gate->reg); @@ -82,7 +94,7 @@ static const struct clk_ops clk_gate2_ops = { struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, u8 cgr_val, - u8 clk_gate2_flags) + u8 clk_gate2_flags, unsigned int *share_count) { struct clk_gate2 *gate; struct clk *clk; @@ -96,6 +108,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, gate->bit_idx = bit_idx; gate->cgr_val = cgr_val; gate->flags = clk_gate2_flags; + gate->share_count = share_count; clk = &gate->clk; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 46dee35..11f5dca 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -53,7 +53,7 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, struct clk *clk_register_gate2(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, u8 cgr_val, - u8 clk_gate_flags); + u8 clk_gate_flags, unsigned int *share_count); struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, const char *parent_name, void __iomem *base, @@ -63,7 +63,26 @@ static inline struct clk *imx_clk_gate2(const char *name, const char *parent, void __iomem *reg, u8 shift) { return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0x3, 0); + shift, 0x3, 0, NULL); +} + +static inline struct clk *imx_clk_gate2_shared(const char *name, + const char *parent, + void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0x3, 0, share_count); +} + +static inline struct clk *imx_clk_gate2_shared2(const char *name, + const char *parent, + void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | + CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, + share_count); } static inline struct clk *imx_clk_gate4(const char *name, const char *parent, @@ -71,7 +90,7 @@ static inline struct clk *imx_clk_gate4(const char *name, const char *parent, { return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, - reg, shift, 0x3, 0); + reg, shift, 0x3, 0, NULL); } static inline struct clk *imx_clk_gate4_flags(const char *name, @@ -80,7 +99,7 @@ static inline struct clk *imx_clk_gate4_flags(const char *name, { return clk_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, - reg, shift, 0x3, 0); + reg, shift, 0x3, 0, NULL); } static inline struct clk *imx_clk_fixed_factor(const char *name, -- 2.7.4