Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / clk / at91 / clk-master.c
1 /*
2  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  */
10
11 #include <linux/clk-provider.h>
12 #include <linux/clkdev.h>
13 #include <linux/clk/at91_pmc.h>
14 #include <linux/of.h>
15 #include <linux/of_address.h>
16 #include <linux/of_irq.h>
17 #include <linux/io.h>
18 #include <linux/wait.h>
19 #include <linux/sched.h>
20 #include <linux/interrupt.h>
21 #include <linux/irq.h>
22
23 #include "pmc.h"
24
25 #define MASTER_SOURCE_MAX       4
26
27 #define MASTER_PRES_MASK        0x7
28 #define MASTER_PRES_MAX         MASTER_PRES_MASK
29 #define MASTER_DIV_SHIFT        8
30 #define MASTER_DIV_MASK         0x3
31
32 struct clk_master_characteristics {
33         struct clk_range output;
34         u32 divisors[4];
35         u8 have_div3_pres;
36 };
37
38 struct clk_master_layout {
39         u32 mask;
40         u8 pres_shift;
41 };
42
43 #define to_clk_master(hw) container_of(hw, struct clk_master, hw)
44
45 struct clk_master {
46         struct clk_hw hw;
47         struct at91_pmc *pmc;
48         unsigned int irq;
49         wait_queue_head_t wait;
50         const struct clk_master_layout *layout;
51         const struct clk_master_characteristics *characteristics;
52 };
53
54 static irqreturn_t clk_master_irq_handler(int irq, void *dev_id)
55 {
56         struct clk_master *master = (struct clk_master *)dev_id;
57
58         wake_up(&master->wait);
59         disable_irq_nosync(master->irq);
60
61         return IRQ_HANDLED;
62 }
63 static int clk_master_prepare(struct clk_hw *hw)
64 {
65         struct clk_master *master = to_clk_master(hw);
66         struct at91_pmc *pmc = master->pmc;
67
68         while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) {
69                 enable_irq(master->irq);
70                 wait_event(master->wait,
71                            pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
72         }
73
74         return 0;
75 }
76
77 static int clk_master_is_prepared(struct clk_hw *hw)
78 {
79         struct clk_master *master = to_clk_master(hw);
80
81         return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY);
82 }
83
84 static unsigned long clk_master_recalc_rate(struct clk_hw *hw,
85                                             unsigned long parent_rate)
86 {
87         u8 pres;
88         u8 div;
89         unsigned long rate = parent_rate;
90         struct clk_master *master = to_clk_master(hw);
91         struct at91_pmc *pmc = master->pmc;
92         const struct clk_master_layout *layout = master->layout;
93         const struct clk_master_characteristics *characteristics =
94                                                 master->characteristics;
95         u32 tmp;
96
97         pmc_lock(pmc);
98         tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask;
99         pmc_unlock(pmc);
100
101         pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK;
102         div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK;
103
104         if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX)
105                 rate /= 3;
106         else
107                 rate >>= pres;
108
109         rate /= characteristics->divisors[div];
110
111         if (rate < characteristics->output.min)
112                 pr_warn("master clk is underclocked");
113         else if (rate > characteristics->output.max)
114                 pr_warn("master clk is overclocked");
115
116         return rate;
117 }
118
119 static u8 clk_master_get_parent(struct clk_hw *hw)
120 {
121         struct clk_master *master = to_clk_master(hw);
122         struct at91_pmc *pmc = master->pmc;
123
124         return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS;
125 }
126
127 static const struct clk_ops master_ops = {
128         .prepare = clk_master_prepare,
129         .is_prepared = clk_master_is_prepared,
130         .recalc_rate = clk_master_recalc_rate,
131         .get_parent = clk_master_get_parent,
132 };
133
134 static struct clk * __init
135 at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq,
136                 const char *name, int num_parents,
137                 const char **parent_names,
138                 const struct clk_master_layout *layout,
139                 const struct clk_master_characteristics *characteristics)
140 {
141         int ret;
142         struct clk_master *master;
143         struct clk *clk = NULL;
144         struct clk_init_data init;
145
146         if (!pmc || !irq || !name || !num_parents || !parent_names)
147                 return ERR_PTR(-EINVAL);
148
149         master = kzalloc(sizeof(*master), GFP_KERNEL);
150         if (!master)
151                 return ERR_PTR(-ENOMEM);
152
153         init.name = name;
154         init.ops = &master_ops;
155         init.parent_names = parent_names;
156         init.num_parents = num_parents;
157         init.flags = 0;
158
159         master->hw.init = &init;
160         master->layout = layout;
161         master->characteristics = characteristics;
162         master->pmc = pmc;
163         master->irq = irq;
164         init_waitqueue_head(&master->wait);
165         irq_set_status_flags(master->irq, IRQ_NOAUTOEN);
166         ret = request_irq(master->irq, clk_master_irq_handler,
167                           IRQF_TRIGGER_HIGH, "clk-master", master);
168         if (ret)
169                 return ERR_PTR(ret);
170
171         clk = clk_register(NULL, &master->hw);
172         if (IS_ERR(clk))
173                 kfree(master);
174
175         return clk;
176 }
177
178
179 static const struct clk_master_layout at91rm9200_master_layout = {
180         .mask = 0x31F,
181         .pres_shift = 2,
182 };
183
184 static const struct clk_master_layout at91sam9x5_master_layout = {
185         .mask = 0x373,
186         .pres_shift = 4,
187 };
188
189
190 static struct clk_master_characteristics * __init
191 of_at91_clk_master_get_characteristics(struct device_node *np)
192 {
193         struct clk_master_characteristics *characteristics;
194
195         characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
196         if (!characteristics)
197                 return NULL;
198
199         if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
200                 goto out_free_characteristics;
201
202         of_property_read_u32_array(np, "atmel,clk-divisors",
203                                    characteristics->divisors, 4);
204
205         characteristics->have_div3_pres =
206                 of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
207
208         return characteristics;
209
210 out_free_characteristics:
211         kfree(characteristics);
212         return NULL;
213 }
214
215 static void __init
216 of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc,
217                          const struct clk_master_layout *layout)
218 {
219         struct clk *clk;
220         int num_parents;
221         int i;
222         unsigned int irq;
223         const char *parent_names[MASTER_SOURCE_MAX];
224         const char *name = np->name;
225         struct clk_master_characteristics *characteristics;
226
227         num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
228         if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX)
229                 return;
230
231         for (i = 0; i < num_parents; ++i) {
232                 parent_names[i] = of_clk_get_parent_name(np, i);
233                 if (!parent_names[i])
234                         return;
235         }
236
237         of_property_read_string(np, "clock-output-names", &name);
238
239         characteristics = of_at91_clk_master_get_characteristics(np);
240         if (!characteristics)
241                 return;
242
243         irq = irq_of_parse_and_map(np, 0);
244         if (!irq)
245                 goto out_free_characteristics;
246
247         clk = at91_clk_register_master(pmc, irq, name, num_parents,
248                                        parent_names, layout,
249                                        characteristics);
250         if (IS_ERR(clk))
251                 goto out_free_characteristics;
252
253         of_clk_add_provider(np, of_clk_src_simple_get, clk);
254         return;
255
256 out_free_characteristics:
257         kfree(characteristics);
258 }
259
260 void __init of_at91rm9200_clk_master_setup(struct device_node *np,
261                                            struct at91_pmc *pmc)
262 {
263         of_at91_clk_master_setup(np, pmc, &at91rm9200_master_layout);
264 }
265
266 void __init of_at91sam9x5_clk_master_setup(struct device_node *np,
267                                            struct at91_pmc *pmc)
268 {
269         of_at91_clk_master_setup(np, pmc, &at91sam9x5_master_layout);
270 }