diff options
author | Tony Lindgren <tony@atomide.com> | 2016-02-12 11:56:52 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2016-02-12 11:56:52 -0500 |
commit | cf26f1137333251f3515dea31f95775b99df0fd5 (patch) | |
tree | 6db45242fd172ed2fa1f56b0c5fb97c2f78fae81 /arch/arm/mach-omap2/omap_device.c | |
parent | 08c78e9d61a857c9077240e7ddb67550c6f96d06 (diff) |
ARM: OMAP2+: Fix omap_device for module reload on PM runtime forbid
If a driver PM runtime is disabled via sysfs, and the module is
unloaded, PM runtime can't do anything to disable the device. Let's
let the interconnect disable the device on BUS_NOTIFY_UNBOUND_DRIVER.
Otherwise omap_device will produce and error on the following module
reload. This can be easily tested with something like:
# modprobe omap_hsmmc
# echo on > /sys/devices/platform/68000000.ocp/4809c000.mmc/power/control
# rmmod omap_hsmmc
# modprobe omap_hsmmc
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Nishanth Menon <nm@ti.com>
Cc: Rafael J. Wysocki <rafael@kernel.org>
Cc: Tero Kristo <t-kristo@ti.com>
Reported-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Kevin Hilman <khilman@baylibre.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_device.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_device.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index ebd83690ba48..f7ff3b9dad87 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c | |||
@@ -191,12 +191,22 @@ static int _omap_device_notifier_call(struct notifier_block *nb, | |||
191 | { | 191 | { |
192 | struct platform_device *pdev = to_platform_device(dev); | 192 | struct platform_device *pdev = to_platform_device(dev); |
193 | struct omap_device *od; | 193 | struct omap_device *od; |
194 | int err; | ||
194 | 195 | ||
195 | switch (event) { | 196 | switch (event) { |
196 | case BUS_NOTIFY_DEL_DEVICE: | 197 | case BUS_NOTIFY_DEL_DEVICE: |
197 | if (pdev->archdata.od) | 198 | if (pdev->archdata.od) |
198 | omap_device_delete(pdev->archdata.od); | 199 | omap_device_delete(pdev->archdata.od); |
199 | break; | 200 | break; |
201 | case BUS_NOTIFY_UNBOUND_DRIVER: | ||
202 | od = to_omap_device(pdev); | ||
203 | if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED)) { | ||
204 | dev_info(dev, "enabled after unload, idling\n"); | ||
205 | err = omap_device_idle(pdev); | ||
206 | if (err) | ||
207 | dev_err(dev, "failed to idle\n"); | ||
208 | } | ||
209 | break; | ||
200 | case BUS_NOTIFY_ADD_DEVICE: | 210 | case BUS_NOTIFY_ADD_DEVICE: |
201 | if (pdev->dev.of_node) | 211 | if (pdev->dev.of_node) |
202 | omap_device_build_from_dt(pdev); | 212 | omap_device_build_from_dt(pdev); |