aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-03-22 14:15:18 -0400
committerThierry Reding <treding@nvidia.com>2017-04-05 12:11:50 -0400
commitb0d36daa0ab54714e05164f6e21d22f974a5eec1 (patch)
tree9afb540bbe407ca6e5b1e74dab1db3a9418644bf
parentb386c6b73ac6c2a9a2f1201d055ab65cc19890a2 (diff)
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>
-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)
267 return strcmp(dev_name(dev), drv->name) == 0; 267 return strcmp(dev_name(dev), drv->name) == 0;
268} 268}
269 269
270static int host1x_device_probe(struct device *dev)
271{
272 struct host1x_driver *driver = to_host1x_driver(dev->driver);
273 struct host1x_device *device = to_host1x_device(dev);
274
275 if (driver->probe)
276 return driver->probe(device);
277
278 return 0;
279}
280
281static int host1x_device_remove(struct device *dev)
282{
283 struct host1x_driver *driver = to_host1x_driver(dev->driver);
284 struct host1x_device *device = to_host1x_device(dev);
285
286 if (driver->remove)
287 return driver->remove(device);
288
289 return 0;
290}
291
292static void host1x_device_shutdown(struct device *dev)
293{
294 struct host1x_driver *driver = to_host1x_driver(dev->driver);
295 struct host1x_device *device = to_host1x_device(dev);
296
297 if (driver->shutdown)
298 driver->shutdown(device);
299}
300
301static const struct dev_pm_ops host1x_device_pm_ops = { 270static const struct dev_pm_ops host1x_device_pm_ops = {
302 .suspend = pm_generic_suspend, 271 .suspend = pm_generic_suspend,
303 .resume = pm_generic_resume, 272 .resume = pm_generic_resume,
@@ -310,9 +279,6 @@ static const struct dev_pm_ops host1x_device_pm_ops = {
310struct bus_type host1x_bus_type = { 279struct bus_type host1x_bus_type = {
311 .name = "host1x", 280 .name = "host1x",
312 .match = host1x_device_match, 281 .match = host1x_device_match,
313 .probe = host1x_device_probe,
314 .remove = host1x_device_remove,
315 .shutdown = host1x_device_shutdown,
316 .pm = &host1x_device_pm_ops, 282 .pm = &host1x_device_pm_ops,
317}; 283};
318 284
@@ -516,6 +482,37 @@ int host1x_unregister(struct host1x *host1x)
516 return 0; 482 return 0;
517} 483}
518 484
485static int host1x_device_probe(struct device *dev)
486{
487 struct host1x_driver *driver = to_host1x_driver(dev->driver);
488 struct host1x_device *device = to_host1x_device(dev);
489
490 if (driver->probe)
491 return driver->probe(device);
492
493 return 0;
494}
495
496static int host1x_device_remove(struct device *dev)
497{
498 struct host1x_driver *driver = to_host1x_driver(dev->driver);
499 struct host1x_device *device = to_host1x_device(dev);
500
501 if (driver->remove)
502 return driver->remove(device);
503
504 return 0;
505}
506
507static void host1x_device_shutdown(struct device *dev)
508{
509 struct host1x_driver *driver = to_host1x_driver(dev->driver);
510 struct host1x_device *device = to_host1x_device(dev);
511
512 if (driver->shutdown)
513 driver->shutdown(device);
514}
515
519int host1x_driver_register_full(struct host1x_driver *driver, 516int host1x_driver_register_full(struct host1x_driver *driver,
520 struct module *owner) 517 struct module *owner)
521{ 518{
@@ -536,6 +533,9 @@ int host1x_driver_register_full(struct host1x_driver *driver,
536 533
537 driver->driver.bus = &host1x_bus_type; 534 driver->driver.bus = &host1x_bus_type;
538 driver->driver.owner = owner; 535 driver->driver.owner = owner;
536 driver->driver.probe = host1x_device_probe;
537 driver->driver.remove = host1x_device_remove;
538 driver->driver.shutdown = host1x_device_shutdown;
539 539
540 return driver_register(&driver->driver); 540 return driver_register(&driver->driver);
541} 541}