Patch "media: venus: core, venc, vdec: Fix probe dependency error" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    media: venus: core, venc, vdec: Fix probe dependency error

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     media-venus-core-venc-vdec-fix-probe-dependency-erro.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit ea5585c6615cf328c53a204f29d12960bdd9bdd9
Author: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx>
Date:   Fri Feb 5 19:11:49 2021 +0100

    media: venus: core, venc, vdec: Fix probe dependency error
    
    [ Upstream commit 08b1cf474b7f72750adebe0f0a35f8e9a3eb75f6 ]
    
    Commit aaaa93eda64b ("media] media: venus: venc: add video encoder files")
    is the last in a series of three commits to add core.c vdec.c and venc.c
    adding core, encoder and decoder.
    
    The encoder and decoder check for core drvdata as set and return -EPROBE_DEFER
    if it has not been set, however both the encoder and decoder rely on
    core.v4l2_dev as valid.
    
    core.v4l2_dev will not be valid until v4l2_device_register() has completed
    in core.c's probe().
    
    Normally this is never seen however, Dmitry reported the following
    backtrace when compiling drivers and firmware directly into a kernel image.
    
    [    5.259968] Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
    [    5.269850] sd 0:0:0:3: [sdd] Optimal transfer size 524288 bytes
    [    5.275505] Workqueue: events deferred_probe_work_func
    [    5.275513] pstate: 60400005 (nZCv daif +PAN -UAO -TCO BTYPE=--)
    [    5.441211] usb 2-1: new SuperSpeedPlus Gen 2 USB device number 2 using xhci-hcd
    [    5.442486] pc : refcount_warn_saturate+0x140/0x148
    [    5.493756] hub 2-1:1.0: USB hub found
    [    5.496266] lr : refcount_warn_saturate+0x140/0x148
    [    5.500982] hub 2-1:1.0: 4 ports detected
    [    5.503440] sp : ffff80001067b730
    [    5.503442] x29: ffff80001067b730
    [    5.592660] usb 1-1: new high-speed USB device number 2 using xhci-hcd
    [    5.598478] x28: ffff6c6bc1c379b8
    [    5.598480] x27: ffffa5c673852960 x26: ffffa5c673852000
    [    5.598484] x25: ffff6c6bc1c37800 x24: 0000000000000001
    [    5.810652] x23: 0000000000000000 x22: ffffa5c673bc7118
    [    5.813777] hub 1-1:1.0: USB hub found
    [    5.816108] x21: ffffa5c674440000 x20: 0000000000000001
    [    5.820846] hub 1-1:1.0: 4 ports detected
    [    5.825415] x19: ffffa5c6744f4000 x18: ffffffffffffffff
    [    5.825418] x17: 0000000000000000 x16: 0000000000000000
    [    5.825421] x15: 00000a4810c193ba x14: 0000000000000000
    [    5.825424] x13: 00000000000002b8 x12: 000000000000f20a
    [    5.825427] x11: 000000000000f20a x10: 0000000000000038
    [    5.845447] usb 2-1.1: new SuperSpeed Gen 1 USB device number 3 using xhci-hcd
    [    5.845904]
    [    5.845905] x9 : 0000000000000000 x8 : ffff6c6d36fae780
    [    5.871208] x7 : ffff6c6d36faf240 x6 : 0000000000000000
    [    5.876664] x5 : 0000000000000004 x4 : 0000000000000085
    [    5.882121] x3 : 0000000000000119 x2 : ffffa5c6741ef478
    [    5.887578] x1 : 3acbb3926faf5f00 x0 : 0000000000000000
    [    5.893036] Call trace:
    [    5.895551]  refcount_warn_saturate+0x140/0x148
    [    5.900202]  __video_register_device+0x64c/0xd10
    [    5.904944]  venc_probe+0xc4/0x148
    [    5.908444]  platform_probe+0x68/0xe0
    [    5.912210]  really_probe+0x118/0x3e0
    [    5.915977]  driver_probe_device+0x5c/0xc0
    [    5.920187]  __device_attach_driver+0x98/0xb8
    [    5.924661]  bus_for_each_drv+0x68/0xd0
    [    5.928604]  __device_attach+0xec/0x148
    [    5.932547]  device_initial_probe+0x14/0x20
    [    5.936845]  bus_probe_device+0x9c/0xa8
    [    5.940788]  device_add+0x3e8/0x7c8
    [    5.944376]  of_device_add+0x4c/0x60
    [    5.948056]  of_platform_device_create_pdata+0xbc/0x140
    [    5.953425]  of_platform_bus_create+0x17c/0x3c0
    [    5.958078]  of_platform_populate+0x80/0x110
    [    5.962463]  venus_probe+0x2ec/0x4d8
    [    5.966143]  platform_probe+0x68/0xe0
    [    5.969907]  really_probe+0x118/0x3e0
    [    5.973674]  driver_probe_device+0x5c/0xc0
    [    5.977882]  __device_attach_driver+0x98/0xb8
    [    5.982356]  bus_for_each_drv+0x68/0xd0
    [    5.986298]  __device_attach+0xec/0x148
    [    5.990242]  device_initial_probe+0x14/0x20
    [    5.994539]  bus_probe_device+0x9c/0xa8
    [    5.998481]  deferred_probe_work_func+0x74/0xb0
    [    6.003132]  process_one_work+0x1e8/0x360
    [    6.007254]  worker_thread+0x208/0x478
    [    6.011106]  kthread+0x150/0x158
    [    6.014431]  ret_from_fork+0x10/0x30
    [    6.018111] ---[ end trace f074246b1ecdb466 ]---
    
    This patch fixes by
    
    - Only setting drvdata after v4l2_device_register() completes
    - Moving v4l2_device_register() so that suspend/reume in core::probe()
      stays as-is
    - Changes pm_ops->core_function() to take struct venus_core not struct
      device
    - Minimal rework of v4l2_device_*register in probe/remove
    
    Reported-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx>
    Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx>
    Signed-off-by: Stanimir Varbanov <stanimir.varbanov@xxxxxxxxxx>
    Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 58ddebbb84468..bad553bf9f304 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -222,7 +222,6 @@ static int venus_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	core->dev = dev;
-	platform_set_drvdata(pdev, core);
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	core->base = devm_ioremap_resource(dev, r);
@@ -252,7 +251,7 @@ static int venus_probe(struct platform_device *pdev)
 		return -ENODEV;
 
 	if (core->pm_ops->core_get) {
-		ret = core->pm_ops->core_get(dev);
+		ret = core->pm_ops->core_get(core);
 		if (ret)
 			return ret;
 	}
@@ -277,6 +276,12 @@ static int venus_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_core_put;
 
+	ret = v4l2_device_register(dev, &core->v4l2_dev);
+	if (ret)
+		goto err_core_deinit;
+
+	platform_set_drvdata(pdev, core);
+
 	pm_runtime_enable(dev);
 
 	ret = pm_runtime_get_sync(dev);
@@ -311,10 +316,6 @@ static int venus_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_venus_shutdown;
 
-	ret = v4l2_device_register(dev, &core->v4l2_dev);
-	if (ret)
-		goto err_core_deinit;
-
 	ret = pm_runtime_put_sync(dev);
 	if (ret) {
 		pm_runtime_get_noresume(dev);
@@ -327,8 +328,6 @@ static int venus_probe(struct platform_device *pdev)
 
 err_dev_unregister:
 	v4l2_device_unregister(&core->v4l2_dev);
-err_core_deinit:
-	hfi_core_deinit(core, false);
 err_venus_shutdown:
 	venus_shutdown(core);
 err_runtime_disable:
@@ -336,9 +335,11 @@ static int venus_probe(struct platform_device *pdev)
 	pm_runtime_set_suspended(dev);
 	pm_runtime_disable(dev);
 	hfi_destroy(core);
+err_core_deinit:
+	hfi_core_deinit(core, false);
 err_core_put:
 	if (core->pm_ops->core_put)
-		core->pm_ops->core_put(dev);
+		core->pm_ops->core_put(core);
 	return ret;
 }
 
@@ -364,11 +365,14 @@ static int venus_remove(struct platform_device *pdev)
 	pm_runtime_disable(dev);
 
 	if (pm_ops->core_put)
-		pm_ops->core_put(dev);
+		pm_ops->core_put(core);
+
+	v4l2_device_unregister(&core->v4l2_dev);
 
 	hfi_destroy(core);
 
 	v4l2_device_unregister(&core->v4l2_dev);
+
 	mutex_destroy(&core->pm_lock);
 	mutex_destroy(&core->lock);
 	venus_dbgfs_deinit(core);
@@ -387,7 +391,7 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
 		return ret;
 
 	if (pm_ops->core_power) {
-		ret = pm_ops->core_power(dev, POWER_OFF);
+		ret = pm_ops->core_power(core, POWER_OFF);
 		if (ret)
 			return ret;
 	}
@@ -405,7 +409,7 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
 err_video_path:
 	icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0);
 err_cpucfg_path:
-	pm_ops->core_power(dev, POWER_ON);
+	pm_ops->core_power(core, POWER_ON);
 
 	return ret;
 }
@@ -425,7 +429,7 @@ static __maybe_unused int venus_runtime_resume(struct device *dev)
 		return ret;
 
 	if (pm_ops->core_power) {
-		ret = pm_ops->core_power(dev, POWER_ON);
+		ret = pm_ops->core_power(core, POWER_ON);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
index bce9a370015fb..63095d70f8d82 100644
--- a/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -276,16 +276,13 @@ static int load_scale_v1(struct venus_inst *inst)
 	return 0;
 }
 
-static int core_get_v1(struct device *dev)
+static int core_get_v1(struct venus_core *core)
 {
-	struct venus_core *core = dev_get_drvdata(dev);
-
 	return core_clks_get(core);
 }
 
-static int core_power_v1(struct device *dev, int on)
+static int core_power_v1(struct venus_core *core, int on)
 {
-	struct venus_core *core = dev_get_drvdata(dev);
 	int ret = 0;
 
 	if (on == POWER_ON)
@@ -752,12 +749,12 @@ static int venc_power_v4(struct device *dev, int on)
 	return ret;
 }
 
-static int vcodec_domains_get(struct device *dev)
+static int vcodec_domains_get(struct venus_core *core)
 {
 	int ret;
 	struct opp_table *opp_table;
 	struct device **opp_virt_dev;
-	struct venus_core *core = dev_get_drvdata(dev);
+	struct device *dev = core->dev;
 	const struct venus_resources *res = core->res;
 	struct device *pd;
 	unsigned int i;
@@ -808,9 +805,8 @@ static int vcodec_domains_get(struct device *dev)
 	return ret;
 }
 
-static void vcodec_domains_put(struct device *dev)
+static void vcodec_domains_put(struct venus_core *core)
 {
-	struct venus_core *core = dev_get_drvdata(dev);
 	const struct venus_resources *res = core->res;
 	unsigned int i;
 
@@ -833,9 +829,9 @@ static void vcodec_domains_put(struct device *dev)
 	dev_pm_opp_detach_genpd(core->opp_table);
 }
 
-static int core_get_v4(struct device *dev)
+static int core_get_v4(struct venus_core *core)
 {
-	struct venus_core *core = dev_get_drvdata(dev);
+	struct device *dev = core->dev;
 	const struct venus_resources *res = core->res;
 	int ret;
 
@@ -874,7 +870,7 @@ static int core_get_v4(struct device *dev)
 		}
 	}
 
-	ret = vcodec_domains_get(dev);
+	ret = vcodec_domains_get(core);
 	if (ret) {
 		if (core->has_opp_table)
 			dev_pm_opp_of_remove_table(dev);
@@ -885,14 +881,14 @@ static int core_get_v4(struct device *dev)
 	return 0;
 }
 
-static void core_put_v4(struct device *dev)
+static void core_put_v4(struct venus_core *core)
 {
-	struct venus_core *core = dev_get_drvdata(dev);
+	struct device *dev = core->dev;
 
 	if (legacy_binding)
 		return;
 
-	vcodec_domains_put(dev);
+	vcodec_domains_put(core);
 
 	if (core->has_opp_table)
 		dev_pm_opp_of_remove_table(dev);
@@ -901,9 +897,9 @@ static void core_put_v4(struct device *dev)
 
 }
 
-static int core_power_v4(struct device *dev, int on)
+static int core_power_v4(struct venus_core *core, int on)
 {
-	struct venus_core *core = dev_get_drvdata(dev);
+	struct device *dev = core->dev;
 	struct device *pmctrl = core->pmdomains[0];
 	int ret = 0;
 
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.h b/drivers/media/platform/qcom/venus/pm_helpers.h
index aa2f6afa23544..a492c50c5543c 100644
--- a/drivers/media/platform/qcom/venus/pm_helpers.h
+++ b/drivers/media/platform/qcom/venus/pm_helpers.h
@@ -4,14 +4,15 @@
 #define __VENUS_PM_HELPERS_H__
 
 struct device;
+struct venus_core;
 
 #define POWER_ON	1
 #define POWER_OFF	0
 
 struct venus_pm_ops {
-	int (*core_get)(struct device *dev);
-	void (*core_put)(struct device *dev);
-	int (*core_power)(struct device *dev, int on);
+	int (*core_get)(struct venus_core *core);
+	void (*core_put)(struct venus_core *core);
+	int (*core_power)(struct venus_core *core, int on);
 
 	int (*vdec_get)(struct device *dev);
 	void (*vdec_put)(struct device *dev);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux