diff options
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, | |||
388 | unsigned long event, void *dev) | 388 | unsigned long event, void *dev) |
389 | { | 389 | { |
390 | struct platform_device *pdev = to_platform_device(dev); | 390 | struct platform_device *pdev = to_platform_device(dev); |
391 | struct omap_device *od; | ||
391 | 392 | ||
392 | switch (event) { | 393 | switch (event) { |
393 | case BUS_NOTIFY_ADD_DEVICE: | ||
394 | if (pdev->dev.of_node) | ||
395 | omap_device_build_from_dt(pdev); | ||
396 | break; | ||
397 | |||
398 | case BUS_NOTIFY_DEL_DEVICE: | 394 | case BUS_NOTIFY_DEL_DEVICE: |
399 | if (pdev->archdata.od) | 395 | if (pdev->archdata.od) |
400 | omap_device_delete(pdev->archdata.od); | 396 | omap_device_delete(pdev->archdata.od); |
401 | break; | 397 | break; |
398 | case BUS_NOTIFY_ADD_DEVICE: | ||
399 | if (pdev->dev.of_node) | ||
400 | omap_device_build_from_dt(pdev); | ||
401 | /* fall through */ | ||
402 | default: | ||
403 | od = to_omap_device(pdev); | ||
404 | if (od) | ||
405 | od->_driver_status = event; | ||
402 | } | 406 | } |
403 | 407 | ||
404 | return NOTIFY_DONE; | 408 | return NOTIFY_DONE; |
@@ -802,6 +806,10 @@ static int _od_suspend_noirq(struct device *dev) | |||
802 | struct omap_device *od = to_omap_device(pdev); | 806 | struct omap_device *od = to_omap_device(pdev); |
803 | int ret; | 807 | int ret; |
804 | 808 | ||
809 | /* Don't attempt late suspend on a driver that is not bound */ | ||
810 | if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) | ||
811 | return 0; | ||
812 | |||
805 | ret = pm_generic_suspend_noirq(dev); | 813 | ret = pm_generic_suspend_noirq(dev); |
806 | 814 | ||
807 | if (!ret && !pm_runtime_status_suspended(dev)) { | 815 | if (!ret && !pm_runtime_status_suspended(dev)) { |
@@ -1175,3 +1183,41 @@ static int __init omap_device_init(void) | |||
1175 | return 0; | 1183 | return 0; |
1176 | } | 1184 | } |
1177 | core_initcall(omap_device_init); | 1185 | core_initcall(omap_device_init); |
1186 | |||
1187 | /** | ||
1188 | * omap_device_late_idle - idle devices without drivers | ||
1189 | * @dev: struct device * associated with omap_device | ||
1190 | * @data: unused | ||
1191 | * | ||
1192 | * Check the driver bound status of this device, and idle it | ||
1193 | * if there is no driver attached. | ||
1194 | */ | ||
1195 | static int __init omap_device_late_idle(struct device *dev, void *data) | ||
1196 | { | ||
1197 | struct platform_device *pdev = to_platform_device(dev); | ||
1198 | struct omap_device *od = to_omap_device(pdev); | ||
1199 | |||
1200 | if (!od) | ||
1201 | return 0; | ||
1202 | |||
1203 | /* | ||
1204 | * If omap_device state is enabled, but has no driver bound, | ||
1205 | * idle it. | ||
1206 | */ | ||
1207 | if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { | ||
1208 | if (od->_state == OMAP_DEVICE_STATE_ENABLED) { | ||
1209 | dev_warn(dev, "%s: enabled but no driver. Idling\n", | ||
1210 | __func__); | ||
1211 | omap_device_idle(pdev); | ||
1212 | } | ||
1213 | } | ||
1214 | |||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | static int __init omap_device_late_init(void) | ||
1219 | { | ||
1220 | bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); | ||
1221 | return 0; | ||
1222 | } | ||
1223 | late_initcall(omap_device_late_init); | ||