]> Pileus Git - ~andy/linux/blob - drivers/amba/bus.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/blueto...
[~andy/linux] / drivers / amba / bus.c
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
20 #include <asm/irq.h>
21 #include <asm/sizes.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),
86         __ATTR_RO(resource),
87         __ATTR_NULL,
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 static int amba_pm_prepare(struct device *dev)
117 {
118         struct device_driver *drv = dev->driver;
119         int ret = 0;
120
121         if (drv && drv->pm && drv->pm->prepare)
122                 ret = drv->pm->prepare(dev);
123
124         return ret;
125 }
126
127 static void amba_pm_complete(struct device *dev)
128 {
129         struct device_driver *drv = dev->driver;
130
131         if (drv && drv->pm && drv->pm->complete)
132                 drv->pm->complete(dev);
133 }
134
135 #else /* !CONFIG_PM_SLEEP */
136
137 #define amba_pm_prepare         NULL
138 #define amba_pm_complete                NULL
139
140 #endif /* !CONFIG_PM_SLEEP */
141
142 #ifdef CONFIG_SUSPEND
143
144 static int amba_pm_suspend(struct device *dev)
145 {
146         struct device_driver *drv = dev->driver;
147         int ret = 0;
148
149         if (!drv)
150                 return 0;
151
152         if (drv->pm) {
153                 if (drv->pm->suspend)
154                         ret = drv->pm->suspend(dev);
155         } else {
156                 ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
157         }
158
159         return ret;
160 }
161
162 static int amba_pm_suspend_noirq(struct device *dev)
163 {
164         struct device_driver *drv = dev->driver;
165         int ret = 0;
166
167         if (!drv)
168                 return 0;
169
170         if (drv->pm) {
171                 if (drv->pm->suspend_noirq)
172                         ret = drv->pm->suspend_noirq(dev);
173         }
174
175         return ret;
176 }
177
178 static int amba_pm_resume(struct device *dev)
179 {
180         struct device_driver *drv = dev->driver;
181         int ret = 0;
182
183         if (!drv)
184                 return 0;
185
186         if (drv->pm) {
187                 if (drv->pm->resume)
188                         ret = drv->pm->resume(dev);
189         } else {
190                 ret = amba_legacy_resume(dev);
191         }
192
193         return ret;
194 }
195
196 static int amba_pm_resume_noirq(struct device *dev)
197 {
198         struct device_driver *drv = dev->driver;
199         int ret = 0;
200
201         if (!drv)
202                 return 0;
203
204         if (drv->pm) {
205                 if (drv->pm->resume_noirq)
206                         ret = drv->pm->resume_noirq(dev);
207         }
208
209         return ret;
210 }
211
212 #else /* !CONFIG_SUSPEND */
213
214 #define amba_pm_suspend         NULL
215 #define amba_pm_resume          NULL
216 #define amba_pm_suspend_noirq   NULL
217 #define amba_pm_resume_noirq    NULL
218
219 #endif /* !CONFIG_SUSPEND */
220
221 #ifdef CONFIG_HIBERNATE_CALLBACKS
222
223 static int amba_pm_freeze(struct device *dev)
224 {
225         struct device_driver *drv = dev->driver;
226         int ret = 0;
227
228         if (!drv)
229                 return 0;
230
231         if (drv->pm) {
232                 if (drv->pm->freeze)
233                         ret = drv->pm->freeze(dev);
234         } else {
235                 ret = amba_legacy_suspend(dev, PMSG_FREEZE);
236         }
237
238         return ret;
239 }
240
241 static int amba_pm_freeze_noirq(struct device *dev)
242 {
243         struct device_driver *drv = dev->driver;
244         int ret = 0;
245
246         if (!drv)
247                 return 0;
248
249         if (drv->pm) {
250                 if (drv->pm->freeze_noirq)
251                         ret = drv->pm->freeze_noirq(dev);
252         }
253
254         return ret;
255 }
256
257 static int amba_pm_thaw(struct device *dev)
258 {
259         struct device_driver *drv = dev->driver;
260         int ret = 0;
261
262         if (!drv)
263                 return 0;
264
265         if (drv->pm) {
266                 if (drv->pm->thaw)
267                         ret = drv->pm->thaw(dev);
268         } else {
269                 ret = amba_legacy_resume(dev);
270         }
271
272         return ret;
273 }
274
275 static int amba_pm_thaw_noirq(struct device *dev)
276 {
277         struct device_driver *drv = dev->driver;
278         int ret = 0;
279
280         if (!drv)
281                 return 0;
282
283         if (drv->pm) {
284                 if (drv->pm->thaw_noirq)
285                         ret = drv->pm->thaw_noirq(dev);
286         }
287
288         return ret;
289 }
290
291 static int amba_pm_poweroff(struct device *dev)
292 {
293         struct device_driver *drv = dev->driver;
294         int ret = 0;
295
296         if (!drv)
297                 return 0;
298
299         if (drv->pm) {
300                 if (drv->pm->poweroff)
301                         ret = drv->pm->poweroff(dev);
302         } else {
303                 ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
304         }
305
306         return ret;
307 }
308
309 static int amba_pm_poweroff_noirq(struct device *dev)
310 {
311         struct device_driver *drv = dev->driver;
312         int ret = 0;
313
314         if (!drv)
315                 return 0;
316
317         if (drv->pm) {
318                 if (drv->pm->poweroff_noirq)
319                         ret = drv->pm->poweroff_noirq(dev);
320         }
321
322         return ret;
323 }
324
325 static int amba_pm_restore(struct device *dev)
326 {
327         struct device_driver *drv = dev->driver;
328         int ret = 0;
329
330         if (!drv)
331                 return 0;
332
333         if (drv->pm) {
334                 if (drv->pm->restore)
335                         ret = drv->pm->restore(dev);
336         } else {
337                 ret = amba_legacy_resume(dev);
338         }
339
340         return ret;
341 }
342
343 static int amba_pm_restore_noirq(struct device *dev)
344 {
345         struct device_driver *drv = dev->driver;
346         int ret = 0;
347
348         if (!drv)
349                 return 0;
350
351         if (drv->pm) {
352                 if (drv->pm->restore_noirq)
353                         ret = drv->pm->restore_noirq(dev);
354         }
355
356         return ret;
357 }
358
359 #else /* !CONFIG_HIBERNATE_CALLBACKS */
360
361 #define amba_pm_freeze          NULL
362 #define amba_pm_thaw            NULL
363 #define amba_pm_poweroff                NULL
364 #define amba_pm_restore         NULL
365 #define amba_pm_freeze_noirq    NULL
366 #define amba_pm_thaw_noirq              NULL
367 #define amba_pm_poweroff_noirq  NULL
368 #define amba_pm_restore_noirq   NULL
369
370 #endif /* !CONFIG_HIBERNATE_CALLBACKS */
371
372 #ifdef CONFIG_PM_RUNTIME
373 /*
374  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
375  * enable/disable the bus clock at runtime PM suspend/resume as this
376  * does not result in loss of context.  However, disabling vcore power
377  * would do, so we leave that to the driver.
378  */
379 static int amba_pm_runtime_suspend(struct device *dev)
380 {
381         struct amba_device *pcdev = to_amba_device(dev);
382         int ret = pm_generic_runtime_suspend(dev);
383
384         if (ret == 0 && dev->driver)
385                 clk_disable(pcdev->pclk);
386
387         return ret;
388 }
389
390 static int amba_pm_runtime_resume(struct device *dev)
391 {
392         struct amba_device *pcdev = to_amba_device(dev);
393         int ret;
394
395         if (dev->driver) {
396                 ret = clk_enable(pcdev->pclk);
397                 /* Failure is probably fatal to the system, but... */
398                 if (ret)
399                         return ret;
400         }
401
402         return pm_generic_runtime_resume(dev);
403 }
404 #endif
405
406 #ifdef CONFIG_PM
407
408 static const struct dev_pm_ops amba_pm = {
409         .prepare        = amba_pm_prepare,
410         .complete       = amba_pm_complete,
411         .suspend        = amba_pm_suspend,
412         .resume         = amba_pm_resume,
413         .freeze         = amba_pm_freeze,
414         .thaw           = amba_pm_thaw,
415         .poweroff       = amba_pm_poweroff,
416         .restore        = amba_pm_restore,
417         .suspend_noirq  = amba_pm_suspend_noirq,
418         .resume_noirq   = amba_pm_resume_noirq,
419         .freeze_noirq   = amba_pm_freeze_noirq,
420         .thaw_noirq     = amba_pm_thaw_noirq,
421         .poweroff_noirq = amba_pm_poweroff_noirq,
422         .restore_noirq  = amba_pm_restore_noirq,
423         SET_RUNTIME_PM_OPS(
424                 amba_pm_runtime_suspend,
425                 amba_pm_runtime_resume,
426                 pm_generic_runtime_idle
427         )
428 };
429
430 #define AMBA_PM (&amba_pm)
431
432 #else /* !CONFIG_PM */
433
434 #define AMBA_PM NULL
435
436 #endif /* !CONFIG_PM */
437
438 /*
439  * Primecells are part of the Advanced Microcontroller Bus Architecture,
440  * so we call the bus "amba".
441  */
442 struct bus_type amba_bustype = {
443         .name           = "amba",
444         .dev_attrs      = amba_dev_attrs,
445         .match          = amba_match,
446         .uevent         = amba_uevent,
447         .pm             = AMBA_PM,
448 };
449
450 static int __init amba_init(void)
451 {
452         return bus_register(&amba_bustype);
453 }
454
455 postcore_initcall(amba_init);
456
457 static int amba_get_enable_pclk(struct amba_device *pcdev)
458 {
459         struct clk *pclk = clk_get(&pcdev->dev, "apb_pclk");
460         int ret;
461
462         pcdev->pclk = pclk;
463
464         if (IS_ERR(pclk))
465                 return PTR_ERR(pclk);
466
467         ret = clk_prepare(pclk);
468         if (ret) {
469                 clk_put(pclk);
470                 return ret;
471         }
472
473         ret = clk_enable(pclk);
474         if (ret) {
475                 clk_unprepare(pclk);
476                 clk_put(pclk);
477         }
478
479         return ret;
480 }
481
482 static void amba_put_disable_pclk(struct amba_device *pcdev)
483 {
484         struct clk *pclk = pcdev->pclk;
485
486         clk_disable(pclk);
487         clk_unprepare(pclk);
488         clk_put(pclk);
489 }
490
491 static int amba_get_enable_vcore(struct amba_device *pcdev)
492 {
493         struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
494         int ret;
495
496         pcdev->vcore = vcore;
497
498         if (IS_ERR(vcore)) {
499                 /* It is OK not to supply a vcore regulator */
500                 if (PTR_ERR(vcore) == -ENODEV)
501                         return 0;
502                 return PTR_ERR(vcore);
503         }
504
505         ret = regulator_enable(vcore);
506         if (ret) {
507                 regulator_put(vcore);
508                 pcdev->vcore = ERR_PTR(-ENODEV);
509         }
510
511         return ret;
512 }
513
514 static void amba_put_disable_vcore(struct amba_device *pcdev)
515 {
516         struct regulator *vcore = pcdev->vcore;
517
518         if (!IS_ERR(vcore)) {
519                 regulator_disable(vcore);
520                 regulator_put(vcore);
521         }
522 }
523
524 /*
525  * These are the device model conversion veneers; they convert the
526  * device model structures to our more specific structures.
527  */
528 static int amba_probe(struct device *dev)
529 {
530         struct amba_device *pcdev = to_amba_device(dev);
531         struct amba_driver *pcdrv = to_amba_driver(dev->driver);
532         const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev);
533         int ret;
534
535         do {
536                 ret = amba_get_enable_vcore(pcdev);
537                 if (ret)
538                         break;
539
540                 ret = amba_get_enable_pclk(pcdev);
541                 if (ret)
542                         break;
543
544                 pm_runtime_get_noresume(dev);
545                 pm_runtime_set_active(dev);
546                 pm_runtime_enable(dev);
547
548                 ret = pcdrv->probe(pcdev, id);
549                 if (ret == 0)
550                         break;
551
552                 pm_runtime_disable(dev);
553                 pm_runtime_set_suspended(dev);
554                 pm_runtime_put_noidle(dev);
555
556                 amba_put_disable_pclk(pcdev);
557                 amba_put_disable_vcore(pcdev);
558         } while (0);
559
560         return ret;
561 }
562
563 static int amba_remove(struct device *dev)
564 {
565         struct amba_device *pcdev = to_amba_device(dev);
566         struct amba_driver *drv = to_amba_driver(dev->driver);
567         int ret;
568
569         pm_runtime_get_sync(dev);
570         ret = drv->remove(pcdev);
571         pm_runtime_put_noidle(dev);
572
573         /* Undo the runtime PM settings in amba_probe() */
574         pm_runtime_disable(dev);
575         pm_runtime_set_suspended(dev);
576         pm_runtime_put_noidle(dev);
577
578         amba_put_disable_pclk(pcdev);
579         amba_put_disable_vcore(pcdev);
580
581         return ret;
582 }
583
584 static void amba_shutdown(struct device *dev)
585 {
586         struct amba_driver *drv = to_amba_driver(dev->driver);
587         drv->shutdown(to_amba_device(dev));
588 }
589
590 /**
591  *      amba_driver_register - register an AMBA device driver
592  *      @drv: amba device driver structure
593  *
594  *      Register an AMBA device driver with the Linux device model
595  *      core.  If devices pre-exist, the drivers probe function will
596  *      be called.
597  */
598 int amba_driver_register(struct amba_driver *drv)
599 {
600         drv->drv.bus = &amba_bustype;
601
602 #define SETFN(fn)       if (drv->fn) drv->drv.fn = amba_##fn
603         SETFN(probe);
604         SETFN(remove);
605         SETFN(shutdown);
606
607         return driver_register(&drv->drv);
608 }
609
610 /**
611  *      amba_driver_unregister - remove an AMBA device driver
612  *      @drv: AMBA device driver structure to remove
613  *
614  *      Unregister an AMBA device driver from the Linux device
615  *      model.  The device model will call the drivers remove function
616  *      for each device the device driver is currently handling.
617  */
618 void amba_driver_unregister(struct amba_driver *drv)
619 {
620         driver_unregister(&drv->drv);
621 }
622
623
624 static void amba_device_release(struct device *dev)
625 {
626         struct amba_device *d = to_amba_device(dev);
627
628         if (d->res.parent)
629                 release_resource(&d->res);
630         kfree(d);
631 }
632
633 /**
634  *      amba_device_register - register an AMBA device
635  *      @dev: AMBA device to register
636  *      @parent: parent memory resource
637  *
638  *      Setup the AMBA device, reading the cell ID if present.
639  *      Claim the resource, and register the AMBA device with
640  *      the Linux device manager.
641  */
642 int amba_device_register(struct amba_device *dev, struct resource *parent)
643 {
644         u32 size;
645         void __iomem *tmp;
646         int i, ret;
647
648         device_initialize(&dev->dev);
649
650         /*
651          * Copy from device_add
652          */
653         if (dev->dev.init_name) {
654                 dev_set_name(&dev->dev, "%s", dev->dev.init_name);
655                 dev->dev.init_name = NULL;
656         }
657
658         dev->dev.release = amba_device_release;
659         dev->dev.bus = &amba_bustype;
660         dev->dev.dma_mask = &dev->dma_mask;
661         dev->res.name = dev_name(&dev->dev);
662
663         if (!dev->dev.coherent_dma_mask && dev->dma_mask)
664                 dev_warn(&dev->dev, "coherent dma mask is unset\n");
665
666         ret = request_resource(parent, &dev->res);
667         if (ret)
668                 goto err_out;
669
670         /* Hard-coded primecell ID instead of plug-n-play */
671         if (dev->periphid != 0)
672                 goto skip_probe;
673
674         /*
675          * Dynamically calculate the size of the resource
676          * and use this for iomap
677          */
678         size = resource_size(&dev->res);
679         tmp = ioremap(dev->res.start, size);
680         if (!tmp) {
681                 ret = -ENOMEM;
682                 goto err_release;
683         }
684
685         ret = amba_get_enable_pclk(dev);
686         if (ret == 0) {
687                 u32 pid, cid;
688
689                 /*
690                  * Read pid and cid based on size of resource
691                  * they are located at end of region
692                  */
693                 for (pid = 0, i = 0; i < 4; i++)
694                         pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) <<
695                                 (i * 8);
696                 for (cid = 0, i = 0; i < 4; i++)
697                         cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
698                                 (i * 8);
699
700                 amba_put_disable_pclk(dev);
701
702                 if (cid == AMBA_CID)
703                         dev->periphid = pid;
704
705                 if (!dev->periphid)
706                         ret = -ENODEV;
707         }
708
709         iounmap(tmp);
710
711         if (ret)
712                 goto err_release;
713
714  skip_probe:
715         ret = device_add(&dev->dev);
716         if (ret)
717                 goto err_release;
718
719         if (dev->irq[0] != NO_IRQ)
720                 ret = device_create_file(&dev->dev, &dev_attr_irq0);
721         if (ret == 0 && dev->irq[1] != NO_IRQ)
722                 ret = device_create_file(&dev->dev, &dev_attr_irq1);
723         if (ret == 0)
724                 return ret;
725
726         device_unregister(&dev->dev);
727
728  err_release:
729         release_resource(&dev->res);
730  err_out:
731         return ret;
732 }
733
734 /**
735  *      amba_device_unregister - unregister an AMBA device
736  *      @dev: AMBA device to remove
737  *
738  *      Remove the specified AMBA device from the Linux device
739  *      manager.  All files associated with this object will be
740  *      destroyed, and device drivers notified that the device has
741  *      been removed.  The AMBA device's resources including
742  *      the amba_device structure will be freed once all
743  *      references to it have been dropped.
744  */
745 void amba_device_unregister(struct amba_device *dev)
746 {
747         device_unregister(&dev->dev);
748 }
749
750
751 struct find_data {
752         struct amba_device *dev;
753         struct device *parent;
754         const char *busid;
755         unsigned int id;
756         unsigned int mask;
757 };
758
759 static int amba_find_match(struct device *dev, void *data)
760 {
761         struct find_data *d = data;
762         struct amba_device *pcdev = to_amba_device(dev);
763         int r;
764
765         r = (pcdev->periphid & d->mask) == d->id;
766         if (d->parent)
767                 r &= d->parent == dev->parent;
768         if (d->busid)
769                 r &= strcmp(dev_name(dev), d->busid) == 0;
770
771         if (r) {
772                 get_device(dev);
773                 d->dev = pcdev;
774         }
775
776         return r;
777 }
778
779 /**
780  *      amba_find_device - locate an AMBA device given a bus id
781  *      @busid: bus id for device (or NULL)
782  *      @parent: parent device (or NULL)
783  *      @id: peripheral ID (or 0)
784  *      @mask: peripheral ID mask (or 0)
785  *
786  *      Return the AMBA device corresponding to the supplied parameters.
787  *      If no device matches, returns NULL.
788  *
789  *      NOTE: When a valid device is found, its refcount is
790  *      incremented, and must be decremented before the returned
791  *      reference.
792  */
793 struct amba_device *
794 amba_find_device(const char *busid, struct device *parent, unsigned int id,
795                  unsigned int mask)
796 {
797         struct find_data data;
798
799         data.dev = NULL;
800         data.parent = parent;
801         data.busid = busid;
802         data.id = id;
803         data.mask = mask;
804
805         bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match);
806
807         return data.dev;
808 }
809
810 /**
811  *      amba_request_regions - request all mem regions associated with device
812  *      @dev: amba_device structure for device
813  *      @name: name, or NULL to use driver name
814  */
815 int amba_request_regions(struct amba_device *dev, const char *name)
816 {
817         int ret = 0;
818         u32 size;
819
820         if (!name)
821                 name = dev->dev.driver->name;
822
823         size = resource_size(&dev->res);
824
825         if (!request_mem_region(dev->res.start, size, name))
826                 ret = -EBUSY;
827
828         return ret;
829 }
830
831 /**
832  *      amba_release_regions - release mem regions associated with device
833  *      @dev: amba_device structure for device
834  *
835  *      Release regions claimed by a successful call to amba_request_regions.
836  */
837 void amba_release_regions(struct amba_device *dev)
838 {
839         u32 size;
840
841         size = resource_size(&dev->res);
842         release_mem_region(dev->res.start, size);
843 }
844
845 EXPORT_SYMBOL(amba_driver_register);
846 EXPORT_SYMBOL(amba_driver_unregister);
847 EXPORT_SYMBOL(amba_device_register);
848 EXPORT_SYMBOL(amba_device_unregister);
849 EXPORT_SYMBOL(amba_find_device);
850 EXPORT_SYMBOL(amba_request_regions);
851 EXPORT_SYMBOL(amba_release_regions);