diff options
Diffstat (limited to 'drivers/clk/ti/clk.c')
-rw-r--r-- | drivers/clk/ti/clk.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index f4d6802a8544..7d22e1af2247 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c | |||
@@ -55,6 +55,29 @@ static void clk_memmap_writel(u32 val, const struct clk_omap_reg *reg) | |||
55 | writel_relaxed(val, io->mem + reg->offset); | 55 | writel_relaxed(val, io->mem + reg->offset); |
56 | } | 56 | } |
57 | 57 | ||
58 | static void _clk_rmw(u32 val, u32 mask, void __iomem *ptr) | ||
59 | { | ||
60 | u32 v; | ||
61 | |||
62 | v = readl_relaxed(ptr); | ||
63 | v &= ~mask; | ||
64 | v |= val; | ||
65 | writel_relaxed(v, ptr); | ||
66 | } | ||
67 | |||
68 | static void clk_memmap_rmw(u32 val, u32 mask, const struct clk_omap_reg *reg) | ||
69 | { | ||
70 | struct clk_iomap *io = clk_memmaps[reg->index]; | ||
71 | |||
72 | if (reg->ptr) { | ||
73 | _clk_rmw(val, mask, reg->ptr); | ||
74 | } else if (io->regmap) { | ||
75 | regmap_update_bits(io->regmap, reg->offset, mask, val); | ||
76 | } else { | ||
77 | _clk_rmw(val, mask, io->mem + reg->offset); | ||
78 | } | ||
79 | } | ||
80 | |||
58 | static u32 clk_memmap_readl(const struct clk_omap_reg *reg) | 81 | static u32 clk_memmap_readl(const struct clk_omap_reg *reg) |
59 | { | 82 | { |
60 | u32 val; | 83 | u32 val; |
@@ -89,6 +112,7 @@ int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops) | |||
89 | ti_clk_ll_ops = ops; | 112 | ti_clk_ll_ops = ops; |
90 | ops->clk_readl = clk_memmap_readl; | 113 | ops->clk_readl = clk_memmap_readl; |
91 | ops->clk_writel = clk_memmap_writel; | 114 | ops->clk_writel = clk_memmap_writel; |
115 | ops->clk_rmw = clk_memmap_rmw; | ||
92 | 116 | ||
93 | return 0; | 117 | return 0; |
94 | } | 118 | } |
@@ -251,6 +275,20 @@ int ti_clk_get_reg_addr(struct device_node *node, int index, | |||
251 | return 0; | 275 | return 0; |
252 | } | 276 | } |
253 | 277 | ||
278 | void ti_clk_latch(struct clk_omap_reg *reg, s8 shift) | ||
279 | { | ||
280 | u32 latch; | ||
281 | |||
282 | if (shift < 0) | ||
283 | return; | ||
284 | |||
285 | latch = 1 << shift; | ||
286 | |||
287 | ti_clk_ll_ops->clk_rmw(latch, latch, reg); | ||
288 | ti_clk_ll_ops->clk_rmw(0, latch, reg); | ||
289 | ti_clk_ll_ops->clk_readl(reg); /* OCP barrier */ | ||
290 | } | ||
291 | |||
254 | /** | 292 | /** |
255 | * omap2_clk_provider_init - init master clock provider | 293 | * omap2_clk_provider_init - init master clock provider |
256 | * @parent: master node | 294 | * @parent: master node |