diff options
author | Olof Johansson <olof@lixom.net> | 2012-09-20 21:27:41 -0700 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-09-20 21:27:41 -0700 |
commit | b612a85792192b70e6497619521772c38ace758e (patch) | |
tree | 0405e78c23b600153bee5a0e19a5129ddca832f9 /arch/arm/plat-omap/omap_device.c | |
parent | ea832c41dacbc4a5f3888d9ef7c38213914aba2a (diff) | |
parent | 3aec092eed5d8d2b19a62b0aeed3acea9471099a (diff) | |
download | linux-stable-b612a85792192b70e6497619521772c38ace758e.tar.gz linux-stable-b612a85792192b70e6497619521772c38ace758e.tar.bz2 linux-stable-b612a85792192b70e6497619521772c38ace758e.zip |
Merge branch 'next/soc' into next/multiplatform
* next/soc: (50 commits)
ARM: OMAP: AM33xx hwmod: fixup SPI after platform_data move
MAINTAINERS: add an entry for the BCM2835 ARM sub-architecture
ARM: bcm2835: instantiate console UART
ARM: bcm2835: add stub clock driver
ARM: bcm2835: add system timer
ARM: bcm2835: add interrupt controller driver
ARM: add infra-structure for BCM2835 and Raspberry Pi
ARM: tegra20: add CPU hotplug support
ARM: tegra30: add CPU hotplug support
ARM: tegra: clean up the common assembly macros into sleep.h
ARM: tegra: replace the CPU CAR access code by tegra_cpu_car_ops
ARM: tegra: introduce tegra_cpu_car_ops structures
ARM: Tegra: Add smp_twd clock for Tegra20
ARM: AM33XX: clock: Add dcan clock aliases for device-tree
ARM: OMAP2+: dpll: Add missing soc_is_am33xx() check for common functions
ARM: OMAP: omap_device: idle devices with no driver bound
ARM: OMAP: omap_device: don't attempt late suspend if no driver bound
ARM: OMAP: omap_device: keep track of driver bound status
ARM: OMAP3+: hwmod: Add AM33XX HWMOD data
ARM: OMAP2+: hwmod: Hook-up am33xx support in omap_hwmod framework
...
Change/remove conflict in arch/arm/mach-ux500/clock.c resolved.
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/plat-omap/omap_device.c')
-rw-r--r-- | arch/arm/plat-omap/omap_device.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 2dddfc4c63af..d5f617c542d3 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -388,17 +388,21 @@ static int _omap_device_notifier_call(struct notifier_block *nb, unsigned long event, void *dev) { struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od; switch (event) { - case BUS_NOTIFY_ADD_DEVICE: - if (pdev->dev.of_node) - omap_device_build_from_dt(pdev); - break; - case BUS_NOTIFY_DEL_DEVICE: if (pdev->archdata.od) omap_device_delete(pdev->archdata.od); break; + case BUS_NOTIFY_ADD_DEVICE: + if (pdev->dev.of_node) + omap_device_build_from_dt(pdev); + /* fall through */ + default: + od = to_omap_device(pdev); + if (od) + od->_driver_status = event; } return NOTIFY_DONE; @@ -802,6 +806,10 @@ static int _od_suspend_noirq(struct device *dev) struct omap_device *od = to_omap_device(pdev); int ret; + /* Don't attempt late suspend on a driver that is not bound */ + if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) + return 0; + ret = pm_generic_suspend_noirq(dev); if (!ret && !pm_runtime_status_suspended(dev)) { @@ -1175,3 +1183,41 @@ static int __init omap_device_init(void) return 0; } core_initcall(omap_device_init); + +/** + * omap_device_late_idle - idle devices without drivers + * @dev: struct device * associated with omap_device + * @data: unused + * + * Check the driver bound status of this device, and idle it + * if there is no driver attached. + */ +static int __init omap_device_late_idle(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_device *od = to_omap_device(pdev); + + if (!od) + return 0; + + /* + * If omap_device state is enabled, but has no driver bound, + * idle it. + */ + if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { + if (od->_state == OMAP_DEVICE_STATE_ENABLED) { + dev_warn(dev, "%s: enabled but no driver. Idling\n", + __func__); + omap_device_idle(pdev); + } + } + + return 0; +} + +static int __init omap_device_late_init(void) +{ + bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); + return 0; +} +late_initcall(omap_device_late_init); |