08b1cf474b
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@linaro.org> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
67 lines
1.5 KiB
C
67 lines
1.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/* Copyright (C) 2019 Linaro Ltd. */
|
|
#ifndef __VENUS_PM_HELPERS_H__
|
|
#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 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);
|
|
int (*vdec_power)(struct device *dev, int on);
|
|
|
|
int (*venc_get)(struct device *dev);
|
|
void (*venc_put)(struct device *dev);
|
|
int (*venc_power)(struct device *dev, int on);
|
|
|
|
int (*coreid_power)(struct venus_inst *inst, int on);
|
|
|
|
int (*load_scale)(struct venus_inst *inst);
|
|
};
|
|
|
|
const struct venus_pm_ops *venus_pm_get(enum hfi_version version);
|
|
|
|
static inline int venus_pm_load_scale(struct venus_inst *inst)
|
|
{
|
|
struct venus_core *core = inst->core;
|
|
|
|
if (!core->pm_ops || !core->pm_ops->load_scale)
|
|
return 0;
|
|
|
|
return core->pm_ops->load_scale(inst);
|
|
}
|
|
|
|
static inline int venus_pm_acquire_core(struct venus_inst *inst)
|
|
{
|
|
struct venus_core *core = inst->core;
|
|
const struct venus_pm_ops *pm_ops = core->pm_ops;
|
|
int ret = 0;
|
|
|
|
if (pm_ops && pm_ops->coreid_power)
|
|
ret = pm_ops->coreid_power(inst, POWER_ON);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static inline int venus_pm_release_core(struct venus_inst *inst)
|
|
{
|
|
struct venus_core *core = inst->core;
|
|
const struct venus_pm_ops *pm_ops = core->pm_ops;
|
|
int ret = 0;
|
|
|
|
if (pm_ops && pm_ops->coreid_power)
|
|
ret = pm_ops->coreid_power(inst, POWER_OFF);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif
|