aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/platform.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2015-08-07 01:19:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-04 14:42:22 -0400
commitb8b2c7d845d57f7a4b9f1f941f24728165e27626 (patch)
treea3fce0301729ed7d49dea39a6a85a846dd0e77e6 /drivers/base/platform.c
parent65da3484d9be5664f5f7d2378e438bb2794f40b8 (diff)
base/platform: assert that dev_pm_domain callbacks are called unconditionally
When a platform driver doesn't provide a .remove callback the function platform_drv_remove isn't called and so the call to dev_pm_domain_attach called at probe time isn't paired by dev_pm_domain_detach at remove time. To fix this (and similar issues if different callbacks are missing) hook up the driver callbacks unconditionally and make them aware that the platform callbacks might be missing. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/platform.c')
-rw-r--r--drivers/base/platform.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index f80aaaf9f610..07cec9ba5e70 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -513,7 +513,7 @@ static int platform_drv_probe(struct device *_dev)
513 return ret; 513 return ret;
514 514
515 ret = dev_pm_domain_attach(_dev, true); 515 ret = dev_pm_domain_attach(_dev, true);
516 if (ret != -EPROBE_DEFER) { 516 if (ret != -EPROBE_DEFER && drv->probe) {
517 ret = drv->probe(dev); 517 ret = drv->probe(dev);
518 if (ret) 518 if (ret)
519 dev_pm_domain_detach(_dev, true); 519 dev_pm_domain_detach(_dev, true);
@@ -536,9 +536,10 @@ static int platform_drv_remove(struct device *_dev)
536{ 536{
537 struct platform_driver *drv = to_platform_driver(_dev->driver); 537 struct platform_driver *drv = to_platform_driver(_dev->driver);
538 struct platform_device *dev = to_platform_device(_dev); 538 struct platform_device *dev = to_platform_device(_dev);
539 int ret; 539 int ret = 0;
540 540
541 ret = drv->remove(dev); 541 if (drv->remove)
542 ret = drv->remove(dev);
542 dev_pm_domain_detach(_dev, true); 543 dev_pm_domain_detach(_dev, true);
543 544
544 return ret; 545 return ret;
@@ -549,7 +550,8 @@ static void platform_drv_shutdown(struct device *_dev)
549 struct platform_driver *drv = to_platform_driver(_dev->driver); 550 struct platform_driver *drv = to_platform_driver(_dev->driver);
550 struct platform_device *dev = to_platform_device(_dev); 551 struct platform_device *dev = to_platform_device(_dev);
551 552
552 drv->shutdown(dev); 553 if (drv->shutdown)
554 drv->shutdown(dev);
553 dev_pm_domain_detach(_dev, true); 555 dev_pm_domain_detach(_dev, true);
554} 556}
555 557
@@ -563,12 +565,9 @@ int __platform_driver_register(struct platform_driver *drv,
563{ 565{
564 drv->driver.owner = owner; 566 drv->driver.owner = owner;
565 drv->driver.bus = &platform_bus_type; 567 drv->driver.bus = &platform_bus_type;
566 if (drv->probe) 568 drv->driver.probe = platform_drv_probe;
567 drv->driver.probe = platform_drv_probe; 569 drv->driver.remove = platform_drv_remove;
568 if (drv->remove) 570 drv->driver.shutdown = platform_drv_shutdown;
569 drv->driver.remove = platform_drv_remove;
570 if (drv->shutdown)
571 drv->driver.shutdown = platform_drv_shutdown;
572 571
573 return driver_register(&drv->driver); 572 return driver_register(&drv->driver);
574} 573}