Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
clk-gate.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010-2011 Canonical Ltd <[email protected]>
3  * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <[email protected]>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Gated clock implementation
10  */
11 
12 #include <linux/clk-provider.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/io.h>
16 #include <linux/err.h>
17 #include <linux/string.h>
18 
29 #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
30 
31 /*
32  * It works on following logic:
33  *
34  * For enabling clock, enable = 1
35  * set2dis = 1 -> clear bit -> set = 0
36  * set2dis = 0 -> set bit -> set = 1
37  *
38  * For disabling clock, enable = 0
39  * set2dis = 1 -> set bit -> set = 1
40  * set2dis = 0 -> clear bit -> set = 0
41  *
42  * So, result is always: enable xor set2dis.
43  */
44 static void clk_gate_endisable(struct clk_hw *hw, int enable)
45 {
46  struct clk_gate *gate = to_clk_gate(hw);
47  int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
48  unsigned long flags = 0;
49  u32 reg;
50 
51  set ^= enable;
52 
53  if (gate->lock)
54  spin_lock_irqsave(gate->lock, flags);
55 
56  reg = readl(gate->reg);
57 
58  if (set)
59  reg |= BIT(gate->bit_idx);
60  else
61  reg &= ~BIT(gate->bit_idx);
62 
63  writel(reg, gate->reg);
64 
65  if (gate->lock)
66  spin_unlock_irqrestore(gate->lock, flags);
67 }
68 
69 static int clk_gate_enable(struct clk_hw *hw)
70 {
71  clk_gate_endisable(hw, 1);
72 
73  return 0;
74 }
75 
76 static void clk_gate_disable(struct clk_hw *hw)
77 {
78  clk_gate_endisable(hw, 0);
79 }
80 
81 static int clk_gate_is_enabled(struct clk_hw *hw)
82 {
83  u32 reg;
84  struct clk_gate *gate = to_clk_gate(hw);
85 
86  reg = readl(gate->reg);
87 
88  /* if a set bit disables this clk, flip it before masking */
89  if (gate->flags & CLK_GATE_SET_TO_DISABLE)
90  reg ^= BIT(gate->bit_idx);
91 
92  reg &= BIT(gate->bit_idx);
93 
94  return reg ? 1 : 0;
95 }
96 
97 const struct clk_ops clk_gate_ops = {
98  .enable = clk_gate_enable,
99  .disable = clk_gate_disable,
100  .is_enabled = clk_gate_is_enabled,
101 };
102 EXPORT_SYMBOL_GPL(clk_gate_ops);
103 
115 struct clk *clk_register_gate(struct device *dev, const char *name,
116  const char *parent_name, unsigned long flags,
117  void __iomem *reg, u8 bit_idx,
118  u8 clk_gate_flags, spinlock_t *lock)
119 {
120  struct clk_gate *gate;
121  struct clk *clk;
122  struct clk_init_data init;
123 
124  /* allocate the gate */
125  gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
126  if (!gate) {
127  pr_err("%s: could not allocate gated clk\n", __func__);
128  return ERR_PTR(-ENOMEM);
129  }
130 
131  init.name = name;
132  init.ops = &clk_gate_ops;
133  init.flags = flags | CLK_IS_BASIC;
134  init.parent_names = (parent_name ? &parent_name: NULL);
135  init.num_parents = (parent_name ? 1 : 0);
136 
137  /* struct clk_gate assignments */
138  gate->reg = reg;
139  gate->bit_idx = bit_idx;
140  gate->flags = clk_gate_flags;
141  gate->lock = lock;
142  gate->hw.init = &init;
143 
144  clk = clk_register(dev, &gate->hw);
145 
146  if (IS_ERR(clk))
147  kfree(gate);
148 
149  return clk;
150 }