summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/host1x
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-03-22 19:15:18 +0100
committerThierry Reding <treding@nvidia.com>2017-04-05 18:11:50 +0200
commitb0d36daa0ab54714e05164f6e21d22f974a5eec1 (patch)
tree9afb540bbe407ca6e5b1e74dab1db3a9418644bf /drivers/gpu/host1x
parentb386c6b73ac6c2a9a2f1201d055ab65cc19890a2 (diff)
downloadlinux-b0d36daa0ab54714e05164f6e21d22f974a5eec1.tar.bz2
gpu: host1x: Fix host1x driver shutdown
Shutting down a host1x device currently crashes if the device has failed to probe. The root cause is that the host1x shutdown is implemented as a struct bus_type callback, but in turn relies on the driver bound to the device. On failure to probe, no driver will be bound and cause the code to crash. Fix this by moving the ->probe(), ->remove() and ->shutdown() callbacks to the driver rather than the bus. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/host1x')
-rw-r--r--drivers/gpu/host1x/bus.c68
1 files changed, 34 insertions, 34 deletions
diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index eeb021fe6410..561831e1ae2c 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -267,37 +267,6 @@ static int host1x_device_match(struct device *dev, struct device_driver *drv)
return strcmp(dev_name(dev), drv->name) == 0;
}
-static int host1x_device_probe(struct device *dev)
-{
- struct host1x_driver *driver = to_host1x_driver(dev->driver);
- struct host1x_device *device = to_host1x_device(dev);
-
- if (driver->probe)
- return driver->probe(device);
-
- return 0;
-}
-
-static int host1x_device_remove(struct device *dev)
-{
- struct host1x_driver *driver = to_host1x_driver(dev->driver);
- struct host1x_device *device = to_host1x_device(dev);
-
- if (driver->remove)
- return driver->remove(device);
-
- return 0;
-}
-
-static void host1x_device_shutdown(struct device *dev)
-{
- struct host1x_driver *driver = to_host1x_driver(dev->driver);
- struct host1x_device *device = to_host1x_device(dev);
-
- if (driver->shutdown)
- driver->shutdown(device);
-}
-
static const struct dev_pm_ops host1x_device_pm_ops = {
.suspend = pm_generic_suspend,
.resume = pm_generic_resume,
@@ -310,9 +279,6 @@ static const struct dev_pm_ops host1x_device_pm_ops = {
struct bus_type host1x_bus_type = {
.name = "host1x",
.match = host1x_device_match,
- .probe = host1x_device_probe,
- .remove = host1x_device_remove,
- .shutdown = host1x_device_shutdown,
.pm = &host1x_device_pm_ops,
};
@@ -516,6 +482,37 @@ int host1x_unregister(struct host1x *host1x)
return 0;
}
+static int host1x_device_probe(struct device *dev)
+{
+ struct host1x_driver *driver = to_host1x_driver(dev->driver);
+ struct host1x_device *device = to_host1x_device(dev);
+
+ if (driver->probe)
+ return driver->probe(device);
+
+ return 0;
+}
+
+static int host1x_device_remove(struct device *dev)
+{
+ struct host1x_driver *driver = to_host1x_driver(dev->driver);
+ struct host1x_device *device = to_host1x_device(dev);
+
+ if (driver->remove)
+ return driver->remove(device);
+
+ return 0;
+}
+
+static void host1x_device_shutdown(struct device *dev)
+{
+ struct host1x_driver *driver = to_host1x_driver(dev->driver);
+ struct host1x_device *device = to_host1x_device(dev);
+
+ if (driver->shutdown)
+ driver->shutdown(device);
+}
+
int host1x_driver_register_full(struct host1x_driver *driver,
struct module *owner)
{
@@ -536,6 +533,9 @@ int host1x_driver_register_full(struct host1x_driver *driver,
driver->driver.bus = &host1x_bus_type;
driver->driver.owner = owner;
+ driver->driver.probe = host1x_device_probe;
+ driver->driver.remove = host1x_device_remove;
+ driver->driver.shutdown = host1x_device_shutdown;
return driver_register(&driver->driver);
}