Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
em_sti.c
Go to the documentation of this file.
1 /*
2  * Emma Mobile Timer Support - STI
3  *
4  * Copyright (C) 2012 Magnus Damm
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #include <linux/init.h>
21 #include <linux/platform_device.h>
22 #include <linux/spinlock.h>
23 #include <linux/interrupt.h>
24 #include <linux/ioport.h>
25 #include <linux/io.h>
26 #include <linux/clk.h>
27 #include <linux/irq.h>
28 #include <linux/err.h>
29 #include <linux/delay.h>
30 #include <linux/clocksource.h>
31 #include <linux/clockchips.h>
32 #include <linux/slab.h>
33 #include <linux/module.h>
34 
36 
37 struct em_sti_priv {
38  void __iomem *base;
39  struct clk *clk;
41  unsigned int active[USER_NR];
42  unsigned long rate;
44  struct clock_event_device ced;
45  struct clocksource cs;
46 };
47 
48 #define STI_CONTROL 0x00
49 #define STI_COMPA_H 0x10
50 #define STI_COMPA_L 0x14
51 #define STI_COMPB_H 0x18
52 #define STI_COMPB_L 0x1c
53 #define STI_COUNT_H 0x20
54 #define STI_COUNT_L 0x24
55 #define STI_COUNT_RAW_H 0x28
56 #define STI_COUNT_RAW_L 0x2c
57 #define STI_SET_H 0x30
58 #define STI_SET_L 0x34
59 #define STI_INTSTATUS 0x40
60 #define STI_INTRAWSTATUS 0x44
61 #define STI_INTENSET 0x48
62 #define STI_INTENCLR 0x4c
63 #define STI_INTFFCLR 0x50
64 
65 static inline unsigned long em_sti_read(struct em_sti_priv *p, int offs)
66 {
67  return ioread32(p->base + offs);
68 }
69 
70 static inline void em_sti_write(struct em_sti_priv *p, int offs,
71  unsigned long value)
72 {
73  iowrite32(value, p->base + offs);
74 }
75 
76 static int em_sti_enable(struct em_sti_priv *p)
77 {
78  int ret;
79 
80  /* enable clock */
81  ret = clk_enable(p->clk);
82  if (ret) {
83  dev_err(&p->pdev->dev, "cannot enable clock\n");
84  return ret;
85  }
86 
87  /* configure channel, periodic mode and maximum timeout */
88  p->rate = clk_get_rate(p->clk);
89 
90  /* reset the counter */
91  em_sti_write(p, STI_SET_H, 0x40000000);
92  em_sti_write(p, STI_SET_L, 0x00000000);
93 
94  /* mask and clear pending interrupts */
95  em_sti_write(p, STI_INTENCLR, 3);
96  em_sti_write(p, STI_INTFFCLR, 3);
97 
98  /* enable updates of counter registers */
99  em_sti_write(p, STI_CONTROL, 1);
100 
101  return 0;
102 }
103 
104 static void em_sti_disable(struct em_sti_priv *p)
105 {
106  /* mask interrupts */
107  em_sti_write(p, STI_INTENCLR, 3);
108 
109  /* stop clock */
110  clk_disable(p->clk);
111 }
112 
113 static cycle_t em_sti_count(struct em_sti_priv *p)
114 {
115  cycle_t ticks;
116  unsigned long flags;
117 
118  /* the STI hardware buffers the 48-bit count, but to
119  * break it out into two 32-bit access the registers
120  * must be accessed in a certain order.
121  * Always read STI_COUNT_H before STI_COUNT_L.
122  */
123  raw_spin_lock_irqsave(&p->lock, flags);
124  ticks = (cycle_t)(em_sti_read(p, STI_COUNT_H) & 0xffff) << 32;
125  ticks |= em_sti_read(p, STI_COUNT_L);
126  raw_spin_unlock_irqrestore(&p->lock, flags);
127 
128  return ticks;
129 }
130 
131 static cycle_t em_sti_set_next(struct em_sti_priv *p, cycle_t next)
132 {
133  unsigned long flags;
134 
135  raw_spin_lock_irqsave(&p->lock, flags);
136 
137  /* mask compare A interrupt */
138  em_sti_write(p, STI_INTENCLR, 1);
139 
140  /* update compare A value */
141  em_sti_write(p, STI_COMPA_H, next >> 32);
142  em_sti_write(p, STI_COMPA_L, next & 0xffffffff);
143 
144  /* clear compare A interrupt source */
145  em_sti_write(p, STI_INTFFCLR, 1);
146 
147  /* unmask compare A interrupt */
148  em_sti_write(p, STI_INTENSET, 1);
149 
150  raw_spin_unlock_irqrestore(&p->lock, flags);
151 
152  return next;
153 }
154 
155 static irqreturn_t em_sti_interrupt(int irq, void *dev_id)
156 {
157  struct em_sti_priv *p = dev_id;
158 
159  p->ced.event_handler(&p->ced);
160  return IRQ_HANDLED;
161 }
162 
163 static int em_sti_start(struct em_sti_priv *p, unsigned int user)
164 {
165  unsigned long flags;
166  int used_before;
167  int ret = 0;
168 
169  raw_spin_lock_irqsave(&p->lock, flags);
170  used_before = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT];
171  if (!used_before)
172  ret = em_sti_enable(p);
173 
174  if (!ret)
175  p->active[user] = 1;
176  raw_spin_unlock_irqrestore(&p->lock, flags);
177 
178  return ret;
179 }
180 
181 static void em_sti_stop(struct em_sti_priv *p, unsigned int user)
182 {
183  unsigned long flags;
184  int used_before, used_after;
185 
186  raw_spin_lock_irqsave(&p->lock, flags);
187  used_before = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT];
188  p->active[user] = 0;
189  used_after = p->active[USER_CLOCKSOURCE] | p->active[USER_CLOCKEVENT];
190 
191  if (used_before && !used_after)
192  em_sti_disable(p);
193  raw_spin_unlock_irqrestore(&p->lock, flags);
194 }
195 
196 static struct em_sti_priv *cs_to_em_sti(struct clocksource *cs)
197 {
198  return container_of(cs, struct em_sti_priv, cs);
199 }
200 
201 static cycle_t em_sti_clocksource_read(struct clocksource *cs)
202 {
203  return em_sti_count(cs_to_em_sti(cs));
204 }
205 
206 static int em_sti_clocksource_enable(struct clocksource *cs)
207 {
208  int ret;
209  struct em_sti_priv *p = cs_to_em_sti(cs);
210 
211  ret = em_sti_start(p, USER_CLOCKSOURCE);
212  if (!ret)
213  __clocksource_updatefreq_hz(cs, p->rate);
214  return ret;
215 }
216 
217 static void em_sti_clocksource_disable(struct clocksource *cs)
218 {
219  em_sti_stop(cs_to_em_sti(cs), USER_CLOCKSOURCE);
220 }
221 
222 static void em_sti_clocksource_resume(struct clocksource *cs)
223 {
224  em_sti_clocksource_enable(cs);
225 }
226 
227 static int em_sti_register_clocksource(struct em_sti_priv *p)
228 {
229  struct clocksource *cs = &p->cs;
230 
231  memset(cs, 0, sizeof(*cs));
232  cs->name = dev_name(&p->pdev->dev);
233  cs->rating = 200;
234  cs->read = em_sti_clocksource_read;
235  cs->enable = em_sti_clocksource_enable;
236  cs->disable = em_sti_clocksource_disable;
237  cs->suspend = em_sti_clocksource_disable;
238  cs->resume = em_sti_clocksource_resume;
239  cs->mask = CLOCKSOURCE_MASK(48);
241 
242  dev_info(&p->pdev->dev, "used as clock source\n");
243 
244  /* Register with dummy 1 Hz value, gets updated in ->enable() */
245  clocksource_register_hz(cs, 1);
246  return 0;
247 }
248 
249 static struct em_sti_priv *ced_to_em_sti(struct clock_event_device *ced)
250 {
251  return container_of(ced, struct em_sti_priv, ced);
252 }
253 
254 static void em_sti_clock_event_mode(enum clock_event_mode mode,
255  struct clock_event_device *ced)
256 {
257  struct em_sti_priv *p = ced_to_em_sti(ced);
258 
259  /* deal with old setting first */
260  switch (ced->mode) {
261  case CLOCK_EVT_MODE_ONESHOT:
262  em_sti_stop(p, USER_CLOCKEVENT);
263  break;
264  default:
265  break;
266  }
267 
268  switch (mode) {
269  case CLOCK_EVT_MODE_ONESHOT:
270  dev_info(&p->pdev->dev, "used for oneshot clock events\n");
271  em_sti_start(p, USER_CLOCKEVENT);
272  clockevents_config(&p->ced, p->rate);
273  break;
274  case CLOCK_EVT_MODE_SHUTDOWN:
275  case CLOCK_EVT_MODE_UNUSED:
276  em_sti_stop(p, USER_CLOCKEVENT);
277  break;
278  default:
279  break;
280  }
281 }
282 
283 static int em_sti_clock_event_next(unsigned long delta,
284  struct clock_event_device *ced)
285 {
286  struct em_sti_priv *p = ced_to_em_sti(ced);
287  cycle_t next;
288  int safe;
289 
290  next = em_sti_set_next(p, em_sti_count(p) + delta);
291  safe = em_sti_count(p) < (next - 1);
292 
293  return !safe;
294 }
295 
296 static void em_sti_register_clockevent(struct em_sti_priv *p)
297 {
298  struct clock_event_device *ced = &p->ced;
299 
300  memset(ced, 0, sizeof(*ced));
301  ced->name = dev_name(&p->pdev->dev);
302  ced->features = CLOCK_EVT_FEAT_ONESHOT;
303  ced->rating = 200;
304  ced->cpumask = cpumask_of(0);
305  ced->set_next_event = em_sti_clock_event_next;
306  ced->set_mode = em_sti_clock_event_mode;
307 
308  dev_info(&p->pdev->dev, "used for clock events\n");
309 
310  /* Register with dummy 1 Hz value, gets updated in ->set_mode() */
311  clockevents_config_and_register(ced, 1, 2, 0xffffffff);
312 }
313 
314 static int __devinit em_sti_probe(struct platform_device *pdev)
315 {
316  struct em_sti_priv *p;
317  struct resource *res;
318  int irq, ret;
319 
320  p = kzalloc(sizeof(*p), GFP_KERNEL);
321  if (p == NULL) {
322  dev_err(&pdev->dev, "failed to allocate driver data\n");
323  ret = -ENOMEM;
324  goto err0;
325  }
326 
327  p->pdev = pdev;
328  platform_set_drvdata(pdev, p);
329 
330  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
331  if (!res) {
332  dev_err(&pdev->dev, "failed to get I/O memory\n");
333  ret = -EINVAL;
334  goto err0;
335  }
336 
337  irq = platform_get_irq(pdev, 0);
338  if (irq < 0) {
339  dev_err(&pdev->dev, "failed to get irq\n");
340  ret = -EINVAL;
341  goto err0;
342  }
343 
344  /* map memory, let base point to the STI instance */
345  p->base = ioremap_nocache(res->start, resource_size(res));
346  if (p->base == NULL) {
347  dev_err(&pdev->dev, "failed to remap I/O memory\n");
348  ret = -ENXIO;
349  goto err0;
350  }
351 
352  /* get hold of clock */
353  p->clk = clk_get(&pdev->dev, "sclk");
354  if (IS_ERR(p->clk)) {
355  dev_err(&pdev->dev, "cannot get clock\n");
356  ret = PTR_ERR(p->clk);
357  goto err1;
358  }
359 
360  if (request_irq(irq, em_sti_interrupt,
362  dev_name(&pdev->dev), p)) {
363  dev_err(&pdev->dev, "failed to request low IRQ\n");
364  ret = -ENOENT;
365  goto err2;
366  }
367 
369  em_sti_register_clockevent(p);
370  em_sti_register_clocksource(p);
371  return 0;
372 
373 err2:
374  clk_put(p->clk);
375 err1:
376  iounmap(p->base);
377 err0:
378  kfree(p);
379  return ret;
380 }
381 
382 static int __devexit em_sti_remove(struct platform_device *pdev)
383 {
384  return -EBUSY; /* cannot unregister clockevent and clocksource */
385 }
386 
387 static const struct of_device_id em_sti_dt_ids[] __devinitconst = {
388  { .compatible = "renesas,em-sti", },
389  {},
390 };
391 MODULE_DEVICE_TABLE(of, em_sti_dt_ids);
392 
393 static struct platform_driver em_sti_device_driver = {
394  .probe = em_sti_probe,
395  .remove = __devexit_p(em_sti_remove),
396  .driver = {
397  .name = "em_sti",
398  .of_match_table = em_sti_dt_ids,
399  }
400 };
401 
402 module_platform_driver(em_sti_device_driver);
403 
404 MODULE_AUTHOR("Magnus Damm");
405 MODULE_DESCRIPTION("Renesas Emma Mobile STI Timer Driver");
406 MODULE_LICENSE("GPL v2");