summaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/tegra-vde/vde.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-08-07 13:00:53 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-08-07 13:00:53 -0700
commitfa73e212318a3277ae1f304febbc617c75d4d2db (patch)
tree54fea325ba419be2388cb9515e778f5c0d9a2f8c /drivers/staging/media/tegra-vde/vde.c
parent75dee3b6de4ce31464ffb827b81ddb5414599159 (diff)
parentf45882cfb152f5d3a421fd58f177f227e44843b9 (diff)
downloadlinux-fa73e212318a3277ae1f304febbc617c75d4d2db.tar.bz2
Merge tag 'media/v5.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - Legacy soc_camera driver was removed from staging - New I2C sensor related drivers: dw9768, ch7322, max9271, rdacm20 - TI vpe driver code was re-organized and had new features added - Added Xilinx MIPI CSI-2 Rx Subsystem driver - Added support for Infrared Toy and IR Droid devices - Lots of random driver fixes, new features and cleanups * tag 'media/v5.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (318 commits) media: camss: fix memory leaks on error handling paths in probe media: davinci: vpif_capture: fix potential double free media: radio: remove redundant assignment to variable retval media: allegro: fix potential null dereference on header media: mtk-mdp: Fix a refcounting bug on error in init media: allegro: fix an error pointer vs NULL check media: meye: fix missing pm_mchip_mode field media: cafe-driver: use generic power management media: saa7164: use generic power management media: v4l2-dev/ioctl: Fix document for VIDIOC_QUERYCAP media: v4l2: Correct kernel-doc inconsistency media: v4l2: Correct kernel-doc inconsistency media: dvbdev.h: keep * together with the type media: v4l2-subdev.h: keep * together with the type media: videobuf2: Print videobuf2 buffer state by name media: colorspaces-details.rst: fix V4L2_COLORSPACE_JPEG description media: tw68: use generic power management media: meye: use generic power management media: cx88: use generic power management media: cx25821: use generic power management ...
Diffstat (limited to 'drivers/staging/media/tegra-vde/vde.c')
-rw-r--r--drivers/staging/media/tegra-vde/vde.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/staging/media/tegra-vde/vde.c b/drivers/staging/media/tegra-vde/vde.c
index d3e63512a765..a3c24d96d5b9 100644
--- a/drivers/staging/media/tegra-vde/vde.c
+++ b/drivers/staging/media/tegra-vde/vde.c
@@ -777,7 +777,7 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
ret = pm_runtime_get_sync(dev);
if (ret < 0)
- goto unlock;
+ goto put_runtime_pm;
/*
* We rely on the VDE registers reset value, otherwise VDE
@@ -843,8 +843,6 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
put_runtime_pm:
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
-
-unlock:
mutex_unlock(&vde->lock);
release_dpb_frames:
@@ -1066,17 +1064,16 @@ static int tegra_vde_probe(struct platform_device *pdev)
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 300);
- if (!pm_runtime_enabled(dev)) {
- err = tegra_vde_runtime_resume(dev);
- if (err)
- goto err_misc_unreg;
- }
+ /*
+ * VDE partition may be left ON after bootloader, hence let's
+ * power-cycle it in order to put hardware into a predictable lower
+ * power state.
+ */
+ pm_runtime_get_sync(dev);
+ pm_runtime_put(dev);
return 0;
-err_misc_unreg:
- misc_deregister(&vde->miscdev);
-
err_deinit_iommu:
tegra_vde_iommu_deinit(vde);
@@ -1091,17 +1088,18 @@ static int tegra_vde_remove(struct platform_device *pdev)
{
struct tegra_vde *vde = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
- int err;
-
- if (!pm_runtime_enabled(dev)) {
- err = tegra_vde_runtime_suspend(dev);
- if (err)
- return err;
- }
+ pm_runtime_get_sync(dev);
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_disable(dev);
+ /*
+ * Balance RPM state, the VDE power domain is left ON and hardware
+ * is clock-gated. It's safe to reboot machine now.
+ */
+ pm_runtime_put_noidle(dev);
+ clk_disable_unprepare(vde->clk);
+
misc_deregister(&vde->miscdev);
tegra_vde_dmabuf_cache_unmap_all(vde);
@@ -1113,6 +1111,16 @@ static int tegra_vde_remove(struct platform_device *pdev)
return 0;
}
+static void tegra_vde_shutdown(struct platform_device *pdev)
+{
+ /*
+ * On some devices bootloader isn't ready to a power-gated VDE on
+ * a warm-reboot, machine will hang in that case.
+ */
+ if (pm_runtime_status_suspended(&pdev->dev))
+ tegra_vde_runtime_resume(&pdev->dev);
+}
+
static __maybe_unused int tegra_vde_pm_suspend(struct device *dev)
{
struct tegra_vde *vde = dev_get_drvdata(dev);
@@ -1158,6 +1166,7 @@ MODULE_DEVICE_TABLE(of, tegra_vde_of_match);
static struct platform_driver tegra_vde_driver = {
.probe = tegra_vde_probe,
.remove = tegra_vde_remove,
+ .shutdown = tegra_vde_shutdown,
.driver = {
.name = "tegra-vde",
.of_match_table = tegra_vde_of_match,