diff options
author | Sakari Ailus <sakari.ailus@iki.fi> | 2015-05-19 20:08:05 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-07-06 08:25:50 -0300 |
commit | 5d479386983c5f1bb1aff4f88a027b6143f88a39 (patch) | |
tree | 6e52f2e588dd471e0382b7e034cf6fede43b1b06 /drivers/media/platform | |
parent | 9aee1ae3312daf0de4c9c614680d06d557133317 (diff) | |
download | linux-5d479386983c5f1bb1aff4f88a027b6143f88a39.tar.bz2 |
[media] v4l: omap3isp: Fix async notifier registration order
The async notifier was registered before the v4l2_device was registered and
before the notifier callbacks were set. This could lead to missing the
bound() and complete() callbacks and to attempting to spin_lock() and
uninitialised spin lock.
Also fix unregistering the async notifier in the case of an error --- the
function may not fail anymore after the notifier is registered.
Fixes: da7f3843d2c7 ("[media] omap3isp: Add support for the Device Tree")
Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r-- | drivers/media/platform/omap3isp/isp.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 18d0a871747f..d1334bb1fe37 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2000,10 +2000,8 @@ static int isp_register_entities(struct isp_device *isp) ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); done: - if (ret < 0) { + if (ret < 0) isp_unregister_entities(isp); - v4l2_async_notifier_unregister(&isp->notifier); - } return ret; } @@ -2423,10 +2421,6 @@ static int isp_probe(struct platform_device *pdev) ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier); if (ret < 0) return ret; - ret = v4l2_async_notifier_register(&isp->v4l2_dev, - &isp->notifier); - if (ret) - return ret; } else { isp->pdata = pdev->dev.platform_data; isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0"); @@ -2557,18 +2551,27 @@ static int isp_probe(struct platform_device *pdev) if (ret < 0) goto error_iommu; - isp->notifier.bound = isp_subdev_notifier_bound; - isp->notifier.complete = isp_subdev_notifier_complete; - ret = isp_register_entities(isp); if (ret < 0) goto error_modules; + if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { + isp->notifier.bound = isp_subdev_notifier_bound; + isp->notifier.complete = isp_subdev_notifier_complete; + + ret = v4l2_async_notifier_register(&isp->v4l2_dev, + &isp->notifier); + if (ret) + goto error_register_entities; + } + isp_core_init(isp, 1); omap3isp_put(isp); return 0; +error_register_entities: + isp_unregister_entities(isp); error_modules: isp_cleanup_modules(isp); error_iommu: |