2 * linux/arch/arm/common/amba.c
4 * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
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.
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>
17 #include <linux/pm_runtime.h>
18 #include <linux/amba/bus.h>
21 #include <asm/sizes.h>
23 #define to_amba_driver(d) container_of(d, struct amba_driver, drv)
25 static const struct amba_id *
26 amba_lookup(const struct amba_id *table, struct amba_device *dev)
31 ret = (dev->periphid & table->mask) == table->id;
37 return ret ? table : NULL;
40 static int amba_match(struct device *dev, struct device_driver *drv)
42 struct amba_device *pcdev = to_amba_device(dev);
43 struct amba_driver *pcdrv = to_amba_driver(drv);
45 return amba_lookup(pcdrv->id_table, pcdev) != NULL;
49 static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
51 struct amba_device *pcdev = to_amba_device(dev);
54 retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid);
58 retval = add_uevent_var(env, "MODALIAS=amba:d%08X", pcdev->periphid);
62 #define amba_uevent NULL
65 #define amba_attr_func(name,fmt,arg...) \
66 static ssize_t name##_show(struct device *_dev, \
67 struct device_attribute *attr, char *buf) \
69 struct amba_device *dev = to_amba_device(_dev); \
70 return sprintf(buf, fmt, arg); \
73 #define amba_attr(name,fmt,arg...) \
74 amba_attr_func(name,fmt,arg) \
75 static DEVICE_ATTR(name, S_IRUGO, name##_show, NULL)
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,
84 static struct device_attribute amba_dev_attrs[] = {
90 #ifdef CONFIG_PM_SLEEP
92 static int amba_legacy_suspend(struct device *dev, pm_message_t mesg)
94 struct amba_driver *adrv = to_amba_driver(dev->driver);
95 struct amba_device *adev = to_amba_device(dev);
98 if (dev->driver && adrv->suspend)
99 ret = adrv->suspend(adev, mesg);
104 static int amba_legacy_resume(struct device *dev)
106 struct amba_driver *adrv = to_amba_driver(dev->driver);
107 struct amba_device *adev = to_amba_device(dev);
110 if (dev->driver && adrv->resume)
111 ret = adrv->resume(adev);
116 static int amba_pm_prepare(struct device *dev)
118 struct device_driver *drv = dev->driver;
121 if (drv && drv->pm && drv->pm->prepare)
122 ret = drv->pm->prepare(dev);
127 static void amba_pm_complete(struct device *dev)
129 struct device_driver *drv = dev->driver;
131 if (drv && drv->pm && drv->pm->complete)
132 drv->pm->complete(dev);
135 #else /* !CONFIG_PM_SLEEP */
137 #define amba_pm_prepare NULL
138 #define amba_pm_complete NULL
140 #endif /* !CONFIG_PM_SLEEP */
142 #ifdef CONFIG_SUSPEND
144 static int amba_pm_suspend(struct device *dev)
146 struct device_driver *drv = dev->driver;
153 if (drv->pm->suspend)
154 ret = drv->pm->suspend(dev);
156 ret = amba_legacy_suspend(dev, PMSG_SUSPEND);
162 static int amba_pm_suspend_noirq(struct device *dev)
164 struct device_driver *drv = dev->driver;
171 if (drv->pm->suspend_noirq)
172 ret = drv->pm->suspend_noirq(dev);
178 static int amba_pm_resume(struct device *dev)
180 struct device_driver *drv = dev->driver;
188 ret = drv->pm->resume(dev);
190 ret = amba_legacy_resume(dev);
196 static int amba_pm_resume_noirq(struct device *dev)
198 struct device_driver *drv = dev->driver;
205 if (drv->pm->resume_noirq)
206 ret = drv->pm->resume_noirq(dev);
212 #else /* !CONFIG_SUSPEND */
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
219 #endif /* !CONFIG_SUSPEND */
221 #ifdef CONFIG_HIBERNATE_CALLBACKS
223 static int amba_pm_freeze(struct device *dev)
225 struct device_driver *drv = dev->driver;
233 ret = drv->pm->freeze(dev);
235 ret = amba_legacy_suspend(dev, PMSG_FREEZE);
241 static int amba_pm_freeze_noirq(struct device *dev)
243 struct device_driver *drv = dev->driver;
250 if (drv->pm->freeze_noirq)
251 ret = drv->pm->freeze_noirq(dev);
257 static int amba_pm_thaw(struct device *dev)
259 struct device_driver *drv = dev->driver;
267 ret = drv->pm->thaw(dev);
269 ret = amba_legacy_resume(dev);
275 static int amba_pm_thaw_noirq(struct device *dev)
277 struct device_driver *drv = dev->driver;
284 if (drv->pm->thaw_noirq)
285 ret = drv->pm->thaw_noirq(dev);
291 static int amba_pm_poweroff(struct device *dev)
293 struct device_driver *drv = dev->driver;
300 if (drv->pm->poweroff)
301 ret = drv->pm->poweroff(dev);
303 ret = amba_legacy_suspend(dev, PMSG_HIBERNATE);
309 static int amba_pm_poweroff_noirq(struct device *dev)
311 struct device_driver *drv = dev->driver;
318 if (drv->pm->poweroff_noirq)
319 ret = drv->pm->poweroff_noirq(dev);
325 static int amba_pm_restore(struct device *dev)
327 struct device_driver *drv = dev->driver;
334 if (drv->pm->restore)
335 ret = drv->pm->restore(dev);
337 ret = amba_legacy_resume(dev);
343 static int amba_pm_restore_noirq(struct device *dev)
345 struct device_driver *drv = dev->driver;
352 if (drv->pm->restore_noirq)
353 ret = drv->pm->restore_noirq(dev);
359 #else /* !CONFIG_HIBERNATE_CALLBACKS */
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
370 #endif /* !CONFIG_HIBERNATE_CALLBACKS */
372 #ifdef CONFIG_PM_RUNTIME
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.
379 static int amba_pm_runtime_suspend(struct device *dev)
381 struct amba_device *pcdev = to_amba_device(dev);
382 int ret = pm_generic_runtime_suspend(dev);
384 if (ret == 0 && dev->driver)
385 clk_disable(pcdev->pclk);
390 static int amba_pm_runtime_resume(struct device *dev)
392 struct amba_device *pcdev = to_amba_device(dev);
396 ret = clk_enable(pcdev->pclk);
397 /* Failure is probably fatal to the system, but... */
402 return pm_generic_runtime_resume(dev);
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,
424 amba_pm_runtime_suspend,
425 amba_pm_runtime_resume,
426 pm_generic_runtime_idle
430 #define AMBA_PM (&amba_pm)
432 #else /* !CONFIG_PM */
436 #endif /* !CONFIG_PM */
439 * Primecells are part of the Advanced Microcontroller Bus Architecture,
440 * so we call the bus "amba".
442 struct bus_type amba_bustype = {
444 .dev_attrs = amba_dev_attrs,
446 .uevent = amba_uevent,
450 static int __init amba_init(void)
452 return bus_register(&amba_bustype);
455 postcore_initcall(amba_init);
457 static int amba_get_enable_pclk(struct amba_device *pcdev)
459 struct clk *pclk = clk_get(&pcdev->dev, "apb_pclk");
465 return PTR_ERR(pclk);
467 ret = clk_prepare(pclk);
473 ret = clk_enable(pclk);
482 static void amba_put_disable_pclk(struct amba_device *pcdev)
484 struct clk *pclk = pcdev->pclk;
491 static int amba_get_enable_vcore(struct amba_device *pcdev)
493 struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
496 pcdev->vcore = vcore;
499 /* It is OK not to supply a vcore regulator */
500 if (PTR_ERR(vcore) == -ENODEV)
502 return PTR_ERR(vcore);
505 ret = regulator_enable(vcore);
507 regulator_put(vcore);
508 pcdev->vcore = ERR_PTR(-ENODEV);
514 static void amba_put_disable_vcore(struct amba_device *pcdev)
516 struct regulator *vcore = pcdev->vcore;
518 if (!IS_ERR(vcore)) {
519 regulator_disable(vcore);
520 regulator_put(vcore);
525 * These are the device model conversion veneers; they convert the
526 * device model structures to our more specific structures.
528 static int amba_probe(struct device *dev)
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);
536 ret = amba_get_enable_vcore(pcdev);
540 ret = amba_get_enable_pclk(pcdev);
544 pm_runtime_get_noresume(dev);
545 pm_runtime_set_active(dev);
546 pm_runtime_enable(dev);
548 ret = pcdrv->probe(pcdev, id);
552 pm_runtime_disable(dev);
553 pm_runtime_set_suspended(dev);
554 pm_runtime_put_noidle(dev);
556 amba_put_disable_pclk(pcdev);
557 amba_put_disable_vcore(pcdev);
563 static int amba_remove(struct device *dev)
565 struct amba_device *pcdev = to_amba_device(dev);
566 struct amba_driver *drv = to_amba_driver(dev->driver);
569 pm_runtime_get_sync(dev);
570 ret = drv->remove(pcdev);
571 pm_runtime_put_noidle(dev);
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);
578 amba_put_disable_pclk(pcdev);
579 amba_put_disable_vcore(pcdev);
584 static void amba_shutdown(struct device *dev)
586 struct amba_driver *drv = to_amba_driver(dev->driver);
587 drv->shutdown(to_amba_device(dev));
591 * amba_driver_register - register an AMBA device driver
592 * @drv: amba device driver structure
594 * Register an AMBA device driver with the Linux device model
595 * core. If devices pre-exist, the drivers probe function will
598 int amba_driver_register(struct amba_driver *drv)
600 drv->drv.bus = &amba_bustype;
602 #define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn
607 return driver_register(&drv->drv);
611 * amba_driver_unregister - remove an AMBA device driver
612 * @drv: AMBA device driver structure to remove
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.
618 void amba_driver_unregister(struct amba_driver *drv)
620 driver_unregister(&drv->drv);
624 static void amba_device_release(struct device *dev)
626 struct amba_device *d = to_amba_device(dev);
629 release_resource(&d->res);
634 * amba_device_register - register an AMBA device
635 * @dev: AMBA device to register
636 * @parent: parent memory resource
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.
642 int amba_device_register(struct amba_device *dev, struct resource *parent)
648 device_initialize(&dev->dev);
651 * Copy from device_add
653 if (dev->dev.init_name) {
654 dev_set_name(&dev->dev, "%s", dev->dev.init_name);
655 dev->dev.init_name = NULL;
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);
663 if (!dev->dev.coherent_dma_mask && dev->dma_mask)
664 dev_warn(&dev->dev, "coherent dma mask is unset\n");
666 ret = request_resource(parent, &dev->res);
670 /* Hard-coded primecell ID instead of plug-n-play */
671 if (dev->periphid != 0)
675 * Dynamically calculate the size of the resource
676 * and use this for iomap
678 size = resource_size(&dev->res);
679 tmp = ioremap(dev->res.start, size);
685 ret = amba_get_enable_pclk(dev);
690 * Read pid and cid based on size of resource
691 * they are located at end of region
693 for (pid = 0, i = 0; i < 4; i++)
694 pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) <<
696 for (cid = 0, i = 0; i < 4; i++)
697 cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
700 amba_put_disable_pclk(dev);
715 ret = device_add(&dev->dev);
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);
726 device_unregister(&dev->dev);
729 release_resource(&dev->res);
735 * amba_device_unregister - unregister an AMBA device
736 * @dev: AMBA device to remove
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.
745 void amba_device_unregister(struct amba_device *dev)
747 device_unregister(&dev->dev);
752 struct amba_device *dev;
753 struct device *parent;
759 static int amba_find_match(struct device *dev, void *data)
761 struct find_data *d = data;
762 struct amba_device *pcdev = to_amba_device(dev);
765 r = (pcdev->periphid & d->mask) == d->id;
767 r &= d->parent == dev->parent;
769 r &= strcmp(dev_name(dev), d->busid) == 0;
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)
786 * Return the AMBA device corresponding to the supplied parameters.
787 * If no device matches, returns NULL.
789 * NOTE: When a valid device is found, its refcount is
790 * incremented, and must be decremented before the returned
794 amba_find_device(const char *busid, struct device *parent, unsigned int id,
797 struct find_data data;
800 data.parent = parent;
805 bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match);
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
815 int amba_request_regions(struct amba_device *dev, const char *name)
821 name = dev->dev.driver->name;
823 size = resource_size(&dev->res);
825 if (!request_mem_region(dev->res.start, size, name))
832 * amba_release_regions - release mem regions associated with device
833 * @dev: amba_device structure for device
835 * Release regions claimed by a successful call to amba_request_regions.
837 void amba_release_regions(struct amba_device *dev)
841 size = resource_size(&dev->res);
842 release_mem_region(dev->res.start, size);
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);