aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-11-05 11:43:26 +0100
committerThierry Reding <treding@nvidia.com>2015-01-23 12:07:00 +0100
commit536e1715226c94037df12f7c6280cbe0f6009f92 (patch)
tree142cc1db3c1d1cb714d6c14b3217764475636bc9
parentMerge remote-tracking branch 'origin/master' into drm-next (diff)
downloadlinux-dev-536e1715226c94037df12f7c6280cbe0f6009f92.tar.xz
linux-dev-536e1715226c94037df12f7c6280cbe0f6009f92.zip
gpu: host1x: Call ->remove() only when a device is bound
When a driver's ->probe() function fails, the host1x bus must not call its ->remove() function because the driver will already have cleaned up in the error handling path in ->probe(). Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/host1x/bus.c9
-rw-r--r--include/linux/host1x.h2
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index aaf54859adb0..e4182e68e29c 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -116,7 +116,10 @@ static void host1x_subdev_register(struct host1x_device *device,
if (list_empty(&device->subdevs)) {
err = device->driver->probe(device);
if (err < 0)
- dev_err(&device->dev, "probe failed: %d\n", err);
+ dev_err(&device->dev, "probe failed for %ps: %d\n",
+ device->driver, err);
+ else
+ device->bound = true;
}
}
@@ -130,10 +133,12 @@ static void __host1x_subdev_unregister(struct host1x_device *device,
* If all subdevices have been activated, we're about to remove the
* first active subdevice, so unload the driver first.
*/
- if (list_empty(&device->subdevs)) {
+ if (list_empty(&device->subdevs) && device->bound) {
err = device->driver->remove(device);
if (err < 0)
dev_err(&device->dev, "remove failed: %d\n", err);
+
+ device->bound = false;
}
/*
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index bb9840fd1e18..7890b553d12e 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -272,6 +272,8 @@ struct host1x_device {
struct mutex clients_lock;
struct list_head clients;
+
+ bool bound;
};
static inline struct host1x_device *to_host1x_device(struct device *dev)