GNU Linux-libre 4.9-gnu1
[releases.git] / drivers / clk / sunxi-ng / ccu_gate.c
1 /*
2  * Copyright (C) 2016 Maxime Ripard
3  * Maxime Ripard <maxime.ripard@free-electrons.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  */
10
11 #include <linux/clk-provider.h>
12
13 #include "ccu_gate.h"
14
15 void ccu_gate_helper_disable(struct ccu_common *common, u32 gate)
16 {
17         unsigned long flags;
18         u32 reg;
19
20         if (!gate)
21                 return;
22
23         spin_lock_irqsave(common->lock, flags);
24
25         reg = readl(common->base + common->reg);
26         writel(reg & ~gate, common->base + common->reg);
27
28         spin_unlock_irqrestore(common->lock, flags);
29 }
30
31 static void ccu_gate_disable(struct clk_hw *hw)
32 {
33         struct ccu_gate *cg = hw_to_ccu_gate(hw);
34
35         return ccu_gate_helper_disable(&cg->common, cg->enable);
36 }
37
38 int ccu_gate_helper_enable(struct ccu_common *common, u32 gate)
39 {
40         unsigned long flags;
41         u32 reg;
42
43         if (!gate)
44                 return 0;
45
46         spin_lock_irqsave(common->lock, flags);
47
48         reg = readl(common->base + common->reg);
49         writel(reg | gate, common->base + common->reg);
50
51         spin_unlock_irqrestore(common->lock, flags);
52
53         return 0;
54 }
55
56 static int ccu_gate_enable(struct clk_hw *hw)
57 {
58         struct ccu_gate *cg = hw_to_ccu_gate(hw);
59
60         return ccu_gate_helper_enable(&cg->common, cg->enable);
61 }
62
63 int ccu_gate_helper_is_enabled(struct ccu_common *common, u32 gate)
64 {
65         if (!gate)
66                 return 1;
67
68         return readl(common->base + common->reg) & gate;
69 }
70
71 static int ccu_gate_is_enabled(struct clk_hw *hw)
72 {
73         struct ccu_gate *cg = hw_to_ccu_gate(hw);
74
75         return ccu_gate_helper_is_enabled(&cg->common, cg->enable);
76 }
77
78 const struct clk_ops ccu_gate_ops = {
79         .disable        = ccu_gate_disable,
80         .enable         = ccu_gate_enable,
81         .is_enabled     = ccu_gate_is_enabled,
82 };