1
2
3
4
5
6
7
8
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/list.h>
12#include <linux/spinlock.h>
13#include <linux/clk.h>
14#include <linux/io.h>
15
16#include "regs-apbc.h"
17#include "clock.h"
18
19static void apbc_clk_enable(struct clk *clk)
20{
21 uint32_t clk_rst;
22
23 clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
24 __raw_writel(clk_rst, clk->clk_rst);
25}
26
27static void apbc_clk_disable(struct clk *clk)
28{
29 __raw_writel(0, clk->clk_rst);
30}
31
32struct clkops apbc_clk_ops = {
33 .enable = apbc_clk_enable,
34 .disable = apbc_clk_disable,
35};
36
37static void apmu_clk_enable(struct clk *clk)
38{
39 __raw_writel(clk->enable_val, clk->clk_rst);
40}
41
42static void apmu_clk_disable(struct clk *clk)
43{
44 __raw_writel(0, clk->clk_rst);
45}
46
47struct clkops apmu_clk_ops = {
48 .enable = apmu_clk_enable,
49 .disable = apmu_clk_disable,
50};
51
52static DEFINE_SPINLOCK(clocks_lock);
53
54int clk_enable(struct clk *clk)
55{
56 unsigned long flags;
57
58 spin_lock_irqsave(&clocks_lock, flags);
59 if (clk->enabled++ == 0)
60 clk->ops->enable(clk);
61 spin_unlock_irqrestore(&clocks_lock, flags);
62 return 0;
63}
64EXPORT_SYMBOL(clk_enable);
65
66void clk_disable(struct clk *clk)
67{
68 unsigned long flags;
69
70 if (!clk)
71 return;
72
73 WARN_ON(clk->enabled == 0);
74
75 spin_lock_irqsave(&clocks_lock, flags);
76 if (--clk->enabled == 0)
77 clk->ops->disable(clk);
78 spin_unlock_irqrestore(&clocks_lock, flags);
79}
80EXPORT_SYMBOL(clk_disable);
81
82unsigned long clk_get_rate(struct clk *clk)
83{
84 unsigned long rate;
85
86 if (clk->ops->getrate)
87 rate = clk->ops->getrate(clk);
88 else
89 rate = clk->rate;
90
91 return rate;
92}
93EXPORT_SYMBOL(clk_get_rate);
94
95int clk_set_rate(struct clk *clk, unsigned long rate)
96{
97 unsigned long flags;
98 int ret = -EINVAL;
99
100 if (clk->ops->setrate) {
101 spin_lock_irqsave(&clocks_lock, flags);
102 ret = clk->ops->setrate(clk, rate);
103 spin_unlock_irqrestore(&clocks_lock, flags);
104 }
105
106 return ret;
107}
108EXPORT_SYMBOL(clk_set_rate);
109