diff options
Diffstat (limited to 'drivers/clk/imx/clk-gate2.c')
-rw-r--r-- | drivers/clk/imx/clk-gate2.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index 40b2d4caab..da27230237 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -20,6 +20,7 @@ #include <clk-uclass.h> #include <dm/device.h> #include <dm/devres.h> +#include <linux/bug.h> #include <linux/clk-provider.h> #include <clk.h> #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; |