Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bus.c
Go to the documentation of this file.
1 /*
2  * linux/arch/arm/common/amba.c
3  *
4  * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
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 version 2 as
8  * published by the Free Software Foundation.
9  */
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/device.h>
13 #include <linux/string.h>
14 #include <linux/slab.h>
15 #include <linux/io.h>
16 #include <linux/pm.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/amba/bus.h>
19 #include <linux/sizes.h>
20 
21 #include <asm/irq.h>
22 
23 #define to_amba_driver(d) container_of(d, struct amba_driver, drv)
24 
25 static const struct amba_id *
26 amba_lookup(const struct amba_id *table, struct amba_device *dev)
27 {
28  int ret = 0;
29 
30  while (table->mask) {
31  ret = (dev->periphid & table->mask) == table->id;
32  if (ret)
33  break;
34  table++;
35  }
36 
37  return ret ? table : NULL;
38 }
39 
40 static int amba_match(struct device *dev, struct device_driver *drv)
41 {
42  struct amba_device *pcdev = to_amba_device(dev);
43  struct amba_driver *pcdrv = to_amba_driver(drv);
44 
45  return amba_lookup(pcdrv->id_table, pcdev) != NULL;
46 }
47 
48 #ifdef CONFIG_HOTPLUG
49 static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
50 {
51  struct amba_device *pcdev = to_amba_device(dev);
52  int retval = 0;
53 
54  retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid);
55  if (retval)
56  return retval;
57 
58  retval = add_uevent_var(env, "MODALIAS=amba:d%08X", pcdev->periphid);
59  return retval;
60 }
61 #else
62 #define amba_uevent NULL
63 #endif
64 
65 #define amba_attr_func(name,fmt,arg...) \
66 static ssize_t name##_show(struct device *_dev, \
67  struct device_attribute *attr, char *buf) \
68 { \
69  struct amba_device *dev = to_amba_device(_dev); \
70  return sprintf(buf, fmt, arg); \
71 }
72 
73 #define amba_attr(name,fmt,arg...) \
74 amba_attr_func(name,fmt,arg) \
75 static DEVICE_ATTR(name, S_IRUGO, name##_show, NULL)
76 
77 amba_attr_func(id, "%08x\n", dev->periphid);
78 amba_attr(irq0, "%u\n", dev->irq[0]);
79 amba_attr(irq1, "%u\n", dev->irq[1]);
80 amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
81  (unsigned long long)dev->res.start, (unsigned long long)dev->res.end,
82  dev->res.flags);
83 
84 static struct device_attribute amba_dev_attrs[] = {
85  __ATTR_RO(id),
88 };
89 
90 #ifdef CONFIG_PM_SLEEP
91 
92 static int amba_legacy_suspend(struct device *dev, pm_message_t mesg)
93 {
94  struct amba_driver *adrv = to_amba_driver(dev->driver);
95  struct amba_device *adev = to_amba_device(dev);
96  int ret = 0;
97 
98  if (dev->driver && adrv->suspend)
99  ret = adrv->suspend(adev, mesg);
100 
101  return ret;
102 }
103 
104 static int amba_legacy_resume(struct device *dev)
105 {
106  struct amba_driver *adrv = to_amba_driver(dev->driver);
107  struct amba_device *adev = to_amba_device(dev);
108  int ret = 0;
109 
110  if (dev->driver && adrv->resume)
111  ret = adrv->resume(adev);
112 
113  return ret;
114 }
115 
116 #endif /* CONFIG_PM_SLEEP */
117 
118 #ifdef CONFIG_SUSPEND
119 
120 static int amba_pm_suspend(struct device *dev)
121 {
122  struct device_driver *drv = dev->driver;
123  int ret = 0;
124 
125  if (!drv)
126  return 0;
127 
128  if (drv->pm) {
129  if (drv->pm->suspend)
130  ret = drv->pm->suspend(dev);
131  } else {
132  ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
133  }
134 
135  return ret;
136 }
137 
138 static int amba_pm_resume(struct device *dev)
139 {
140  struct device_driver *drv = dev->driver;
141  int ret = 0;
142 
143  if (!drv)
144  return 0;
145 
146  if (drv->pm) {
147  if (drv->pm->resume)
148  ret = drv->pm->resume(dev);
149  } else {
150  ret = amba_legacy_resume(dev);
151  }
152 
153  return ret;
154 }
155 
156 #else /* !CONFIG_SUSPEND */
157 
158 #define amba_pm_suspend NULL
159 #define amba_pm_resume NULL
160 
161 #endif /* !CONFIG_SUSPEND */
162 
163 #ifdef CONFIG_HIBERNATE_CALLBACKS
164 
165 static int amba_pm_freeze(struct device *dev)
166 {
167  struct device_driver *drv = dev->driver;
168  int ret = 0;
169 
170  if (!drv)
171  return 0;
172 
173  if (drv->pm) {
174  if (drv->pm->freeze)
175  ret = drv->pm->freeze(dev);
176  } else {
177  ret = amba_legacy_suspend(dev, PMSG_FREEZE);
178  }
179 
180  return ret;
181 }
182 
183 static int amba_pm_thaw(struct device *dev)
184 {
185  struct device_driver *drv = dev->driver;
186  int ret = 0;
187 
188  if (!drv)
189  return 0;
190 
191  if (drv->pm) {
192  if (drv->pm->thaw)
193  ret = drv->pm->thaw(dev);
194  } else {
195  ret = amba_legacy_resume(dev);
196  }
197 
198  return ret;
199 }
200 
201 static int amba_pm_poweroff(struct device *dev)
202 {
203  struct device_driver *drv = dev->driver;
204  int ret = 0;
205 
206  if (!drv)
207  return 0;
208 
209  if (drv->pm) {
210  if (drv->pm->poweroff)
211  ret = drv->pm->poweroff(dev);
212  } else {
213  ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
214  }
215 
216  return ret;
217 }
218 
219 static int amba_pm_restore(struct device *dev)
220 {
221  struct device_driver *drv = dev->driver;
222  int ret = 0;
223 
224  if (!drv)
225  return 0;
226 
227  if (drv->pm) {
228  if (drv->pm->restore)
229  ret = drv->pm->restore(dev);
230  } else {
231  ret = amba_legacy_resume(dev);
232  }
233 
234  return ret;
235 }
236 
237 #else /* !CONFIG_HIBERNATE_CALLBACKS */
238 
239 #define amba_pm_freeze NULL
240 #define amba_pm_thaw NULL
241 #define amba_pm_poweroff NULL
242 #define amba_pm_restore NULL
243 
244 #endif /* !CONFIG_HIBERNATE_CALLBACKS */
245 
246 #ifdef CONFIG_PM_RUNTIME
247 /*
248  * Hooks to provide runtime PM of the pclk (bus clock). It is safe to
249  * enable/disable the bus clock at runtime PM suspend/resume as this
250  * does not result in loss of context.
251  */
252 static int amba_pm_runtime_suspend(struct device *dev)
253 {
254  struct amba_device *pcdev = to_amba_device(dev);
255  int ret = pm_generic_runtime_suspend(dev);
256 
257  if (ret == 0 && dev->driver)
258  clk_disable(pcdev->pclk);
259 
260  return ret;
261 }
262 
263 static int amba_pm_runtime_resume(struct device *dev)
264 {
265  struct amba_device *pcdev = to_amba_device(dev);
266  int ret;
267 
268  if (dev->driver) {
269  ret = clk_enable(pcdev->pclk);
270  /* Failure is probably fatal to the system, but... */
271  if (ret)
272  return ret;
273  }
274 
275  return pm_generic_runtime_resume(dev);
276 }
277 #endif
278 
279 #ifdef CONFIG_PM
280 
281 static const struct dev_pm_ops amba_pm = {
283  .resume = amba_pm_resume,
284  .freeze = amba_pm_freeze,
285  .thaw = amba_pm_thaw,
286  .poweroff = amba_pm_poweroff,
287  .restore = amba_pm_restore,
289  amba_pm_runtime_suspend,
290  amba_pm_runtime_resume,
291  pm_generic_runtime_idle
292  )
293 };
294 
295 #define AMBA_PM (&amba_pm)
296 
297 #else /* !CONFIG_PM */
298 
299 #define AMBA_PM NULL
300 
301 #endif /* !CONFIG_PM */
302 
303 /*
304  * Primecells are part of the Advanced Microcontroller Bus Architecture,
305  * so we call the bus "amba".
306  */
308  .name = "amba",
309  .dev_attrs = amba_dev_attrs,
310  .match = amba_match,
311  .uevent = amba_uevent,
312  .pm = AMBA_PM,
313 };
314 
315 static int __init amba_init(void)
316 {
317  return bus_register(&amba_bustype);
318 }
319 
320 postcore_initcall(amba_init);
321 
322 static int amba_get_enable_pclk(struct amba_device *pcdev)
323 {
324  struct clk *pclk = clk_get(&pcdev->dev, "apb_pclk");
325  int ret;
326 
327  pcdev->pclk = pclk;
328 
329  if (IS_ERR(pclk))
330  return PTR_ERR(pclk);
331 
332  ret = clk_prepare(pclk);
333  if (ret) {
334  clk_put(pclk);
335  return ret;
336  }
337 
338  ret = clk_enable(pclk);
339  if (ret) {
340  clk_unprepare(pclk);
341  clk_put(pclk);
342  }
343 
344  return ret;
345 }
346 
347 static void amba_put_disable_pclk(struct amba_device *pcdev)
348 {
349  struct clk *pclk = pcdev->pclk;
350 
351  clk_disable(pclk);
352  clk_unprepare(pclk);
353  clk_put(pclk);
354 }
355 
356 /*
357  * These are the device model conversion veneers; they convert the
358  * device model structures to our more specific structures.
359  */
360 static int amba_probe(struct device *dev)
361 {
362  struct amba_device *pcdev = to_amba_device(dev);
363  struct amba_driver *pcdrv = to_amba_driver(dev->driver);
364  const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev);
365  int ret;
366 
367  do {
368  ret = amba_get_enable_pclk(pcdev);
369  if (ret)
370  break;
371 
372  pm_runtime_get_noresume(dev);
373  pm_runtime_set_active(dev);
374  pm_runtime_enable(dev);
375 
376  ret = pcdrv->probe(pcdev, id);
377  if (ret == 0)
378  break;
379 
380  pm_runtime_disable(dev);
381  pm_runtime_set_suspended(dev);
382  pm_runtime_put_noidle(dev);
383 
384  amba_put_disable_pclk(pcdev);
385  } while (0);
386 
387  return ret;
388 }
389 
390 static int amba_remove(struct device *dev)
391 {
392  struct amba_device *pcdev = to_amba_device(dev);
393  struct amba_driver *drv = to_amba_driver(dev->driver);
394  int ret;
395 
396  pm_runtime_get_sync(dev);
397  ret = drv->remove(pcdev);
398  pm_runtime_put_noidle(dev);
399 
400  /* Undo the runtime PM settings in amba_probe() */
401  pm_runtime_disable(dev);
402  pm_runtime_set_suspended(dev);
403  pm_runtime_put_noidle(dev);
404 
405  amba_put_disable_pclk(pcdev);
406 
407  return ret;
408 }
409 
410 static void amba_shutdown(struct device *dev)
411 {
412  struct amba_driver *drv = to_amba_driver(dev->driver);
413  drv->shutdown(to_amba_device(dev));
414 }
415 
425 {
426  drv->drv.bus = &amba_bustype;
427 
428 #define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn
429  SETFN(probe);
430  SETFN(remove);
431  SETFN(shutdown);
432 
433  return driver_register(&drv->drv);
434 }
435 
445 {
446  driver_unregister(&drv->drv);
447 }
448 
449 
450 static void amba_device_release(struct device *dev)
451 {
452  struct amba_device *d = to_amba_device(dev);
453 
454  if (d->res.parent)
455  release_resource(&d->res);
456  kfree(d);
457 }
458 
468 int amba_device_add(struct amba_device *dev, struct resource *parent)
469 {
470  u32 size;
471  void __iomem *tmp;
472  int i, ret;
473 
474  WARN_ON(dev->irq[0] == (unsigned int)-1);
475  WARN_ON(dev->irq[1] == (unsigned int)-1);
476 
477  ret = request_resource(parent, &dev->res);
478  if (ret)
479  goto err_out;
480 
481  /* Hard-coded primecell ID instead of plug-n-play */
482  if (dev->periphid != 0)
483  goto skip_probe;
484 
485  /*
486  * Dynamically calculate the size of the resource
487  * and use this for iomap
488  */
489  size = resource_size(&dev->res);
490  tmp = ioremap(dev->res.start, size);
491  if (!tmp) {
492  ret = -ENOMEM;
493  goto err_release;
494  }
495 
496  ret = amba_get_enable_pclk(dev);
497  if (ret == 0) {
498  u32 pid, cid;
499 
500  /*
501  * Read pid and cid based on size of resource
502  * they are located at end of region
503  */
504  for (pid = 0, i = 0; i < 4; i++)
505  pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) <<
506  (i * 8);
507  for (cid = 0, i = 0; i < 4; i++)
508  cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
509  (i * 8);
510 
511  amba_put_disable_pclk(dev);
512 
513  if (cid == AMBA_CID)
514  dev->periphid = pid;
515 
516  if (!dev->periphid)
517  ret = -ENODEV;
518  }
519 
520  iounmap(tmp);
521 
522  if (ret)
523  goto err_release;
524 
525  skip_probe:
526  ret = device_add(&dev->dev);
527  if (ret)
528  goto err_release;
529 
530  if (dev->irq[0])
531  ret = device_create_file(&dev->dev, &dev_attr_irq0);
532  if (ret == 0 && dev->irq[1])
533  ret = device_create_file(&dev->dev, &dev_attr_irq1);
534  if (ret == 0)
535  return ret;
536 
537  device_unregister(&dev->dev);
538 
539  err_release:
540  release_resource(&dev->res);
541  err_out:
542  return ret;
543 }
545 
546 static struct amba_device *
547 amba_aphb_device_add(struct device *parent, const char *name,
548  resource_size_t base, size_t size, int irq1, int irq2,
549  void *pdata, unsigned int periphid, u64 dma_mask)
550 {
551  struct amba_device *dev;
552  int ret;
553 
554  dev = amba_device_alloc(name, base, size);
555  if (!dev)
556  return ERR_PTR(-ENOMEM);
557 
558  dev->dma_mask = dma_mask;
559  dev->dev.coherent_dma_mask = dma_mask;
560  dev->irq[0] = irq1;
561  dev->irq[1] = irq2;
562  dev->periphid = periphid;
563  dev->dev.platform_data = pdata;
564  dev->dev.parent = parent;
565 
566  ret = amba_device_add(dev, &iomem_resource);
567  if (ret) {
568  amba_device_put(dev);
569  return ERR_PTR(ret);
570  }
571 
572  return dev;
573 }
574 
575 struct amba_device *
576 amba_apb_device_add(struct device *parent, const char *name,
577  resource_size_t base, size_t size, int irq1, int irq2,
578  void *pdata, unsigned int periphid)
579 {
580  return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
581  periphid, 0);
582 }
584 
585 struct amba_device *
586 amba_ahb_device_add(struct device *parent, const char *name,
587  resource_size_t base, size_t size, int irq1, int irq2,
588  void *pdata, unsigned int periphid)
589 {
590  return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
591  periphid, ~0ULL);
592 }
594 
595 static void amba_device_initialize(struct amba_device *dev, const char *name)
596 {
597  device_initialize(&dev->dev);
598  if (name)
599  dev_set_name(&dev->dev, "%s", name);
600  dev->dev.release = amba_device_release;
601  dev->dev.bus = &amba_bustype;
602  dev->dev.dma_mask = &dev->dma_mask;
603  dev->res.name = dev_name(&dev->dev);
604 }
605 
615 struct amba_device *amba_device_alloc(const char *name, resource_size_t base,
616  size_t size)
617 {
618  struct amba_device *dev;
619 
620  dev = kzalloc(sizeof(*dev), GFP_KERNEL);
621  if (dev) {
622  amba_device_initialize(dev, name);
623  dev->res.start = base;
624  dev->res.end = base + size - 1;
625  dev->res.flags = IORESOURCE_MEM;
626  }
627 
628  return dev;
629 }
631 
641 int amba_device_register(struct amba_device *dev, struct resource *parent)
642 {
643  amba_device_initialize(dev, dev->dev.init_name);
644  dev->dev.init_name = NULL;
645 
646  if (!dev->dev.coherent_dma_mask && dev->dma_mask)
647  dev_warn(&dev->dev, "coherent dma mask is unset\n");
648 
649  return amba_device_add(dev, parent);
650 }
651 
656 void amba_device_put(struct amba_device *dev)
657 {
658  put_device(&dev->dev);
659 }
661 
674 {
675  device_unregister(&dev->dev);
676 }
677 
678 
679 struct find_data {
680  struct amba_device *dev;
681  struct device *parent;
682  const char *busid;
683  unsigned int id;
684  unsigned int mask;
685 };
686 
687 static int amba_find_match(struct device *dev, void *data)
688 {
689  struct find_data *d = data;
690  struct amba_device *pcdev = to_amba_device(dev);
691  int r;
692 
693  r = (pcdev->periphid & d->mask) == d->id;
694  if (d->parent)
695  r &= d->parent == dev->parent;
696  if (d->busid)
697  r &= strcmp(dev_name(dev), d->busid) == 0;
698 
699  if (r) {
700  get_device(dev);
701  d->dev = pcdev;
702  }
703 
704  return r;
705 }
706 
721 struct amba_device *
722 amba_find_device(const char *busid, struct device *parent, unsigned int id,
723  unsigned int mask)
724 {
725  struct find_data data;
726 
727  data.dev = NULL;
728  data.parent = parent;
729  data.busid = busid;
730  data.id = id;
731  data.mask = mask;
732 
733  bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match);
734 
735  return data.dev;
736 }
737 
743 int amba_request_regions(struct amba_device *dev, const char *name)
744 {
745  int ret = 0;
746  u32 size;
747 
748  if (!name)
749  name = dev->dev.driver->name;
750 
751  size = resource_size(&dev->res);
752 
753  if (!request_mem_region(dev->res.start, size, name))
754  ret = -EBUSY;
755 
756  return ret;
757 }
758 
766 {
767  u32 size;
768 
769  size = resource_size(&dev->res);
770  release_mem_region(dev->res.start, size);
771 }
772