I’m trying to get a v4l2 driver off the ground based on the ov5693.c driver. The device is recognized and probed and everything works great up until “v4l2_async_register_subdev(priv->subdev);” If I comment out that line there’s no error and probe completes, but the device doesn’t get registered.
Here’s the output of vi to dmesg right before the crash:
[ 9.602431] vi vi: notify complete, all subdevs registered
[ 9.602435] vi vi: creating links for entity daxc02 6-0010
[ 9.602440] vi vi: processing endpoint /host1x/i2c@546c0000/daxc02@10/ports/port@0/endpoint
[ 9.602466] vi vi: skipping channel port /host1x/i2c@546c0000/daxc02@10:0
[ 9.602470] vi vi: creating links for channels
[ 9.602475] vi vi: processing endpoint /host1x/vi/ports/port@0/endpoint
[ 9.602493] vi vi: creating link for channel vi-output-0
[ 9.602497] vi vi: creating daxc02 6-0010:0 -> vi-output-0:0 link
[ 9.602513] Unable to handle kernel NULL pointer dereference at virtual address 00000010
[ 9.612577] pgd = ffffffc0f40ec000
[ 9.619792] [00000010] *pgd=0000000000000000
[ 9.626524] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 9.632821] Enter nvdumper_crash_setup_regs
[ 9.325255] nvdumper: all registers are saved.
[ 9.325257] nvdumper: all registers are saved.
[ 9.325259] nvdumper: all registers are saved.
[ 9.341779] nvdumper: all registers are saved.
[ 9.346868] Modules linked in: daxc02(O+) tps22994(O) bluedroid_pm
[ 9.354534] CPU: 1 PID: 221 Comm: systemd-udevd Tainted: G O 3.10.96-nova+ #13
[ 9.365064] task: ffffffc0f7579280 ti: ffffffc0f4130000 task.ti: ffffffc0f4130000
[ 9.373892] PC is at handler_new_ref+0x190/0x1c0
[ 9.379199] LR is at handler_new_ref+0xd4/0x1c0
and here’s the stack trace:
[ 9.623393] Call trace:
[ 9.623397] [<ffffffc0006f8990>] handler_new_ref+0x190/0x1c0
[ 9.623400] [<ffffffc0006f851c>] v4l2_ctrl_new+0x240/0x2b8
[ 9.623403] [<ffffffc0006f87ec>] v4l2_ctrl_new_std+0xbc/0xd0
[ 9.623405] [<ffffffc0006f8860>] handler_new_ref+0x60/0x1c0
[ 9.623408] [<ffffffc0006f8ab8>] v4l2_ctrl_add_handler+0x88/0xd8
[ 9.623412] [<ffffffc0007152cc>] tegra_channel_setup_controls+0x40/0xcc
[ 9.623415] [<ffffffc0007172c8>] tegra_channel_init_subdevices+0x100/0x12c
[ 9.623417] [<ffffffc000717990>] tegra_vi_graph_build_links+0x1e8/0x20c
[ 9.623420] [<ffffffc000717a18>] tegra_vi_graph_notify_complete+0x64/0xa8
[ 9.623424] [<ffffffc0006fbc98>] v4l2_async_test_notify+0xf4/0x110
[ 9.623425] [<ffffffc0006fbeb8>] v4l2_async_register_subdev+0x80/0xe0
[ 9.623432] [<ffffffbffc00dfa8>] daxc02_probe+0x2f4/0x33c [daxc02]
[ 9.623435] [<ffffffc0006d68f0>] i2c_device_probe+0xb4/0xfc
[ 9.623439] [<ffffffc000508b98>] really_probe+0x120/0x2c8
[ 9.623441] [<ffffffc000508e38>] driver_probe_device+0x78/0xa4
[ 9.623443] [<ffffffc000508f0c>] __driver_attach+0x60/0x8c
[ 9.623446] [<ffffffc000506da8>] bus_for_each_dev+0x54/0x98
[ 9.623448] [<ffffffc00050870c>] driver_attach+0x20/0x28
[ 9.623450] [<ffffffc0005080f0>] bus_add_driver+0xe4/0x1d0
[ 9.623452] [<ffffffc000509c28>] driver_register+0xb8/0xfc
[ 9.623455] [<ffffffc0006d7fb0>] i2c_register_driver+0xcc/0xdc
[ 9.623458] [<ffffffbffc012020>] $x+0x20/0x28 [daxc02]
[ 9.623461] [<ffffffc0000815f0>] do_one_initcall+0x40/0x100
[ 9.623465] [<ffffffc00010efc8>] do_init_module+0x50/0x194
[ 9.623467] [<ffffffc00010fbd8>] load_module+0x1f8/0x2c0
[ 9.623470] [<ffffffc00010ff64>] SyS_finit_module+0x11c/0x1b4
[ 9.623473] Code: 1ad80aa0 1b18d415 93407eb5 f9402e60 (f8757800)
[ 9.624842] ---[ end trace 7ce286733e27efde ]---
Any thoughts on what I should try?
Thanks!
The handler_new_ref function says it’s for registering the controls. I tried commenting out everything in my v4l2_ctrl_config list, but even with 0 controls it still errors. However it takes a different route through v4l2_ctrl_new_custom instead.
[ 9.638452] Call trace:
[ 9.638456] [<ffffffc0006f8990>] handler_new_ref+0x190/0x1c0
[ 9.638459] [<ffffffc0006f851c>] v4l2_ctrl_new+0x240/0x2b8
[ 9.638462] [<ffffffc0006f87ec>] v4l2_ctrl_new_std+0xbc/0xd0
[ 9.638464] [<ffffffc0006f8860>] handler_new_ref+0x60/0x1c0
[ 9.638466] [<ffffffc0006f851c>] v4l2_ctrl_new+0x240/0x2b8
<b>[ 9.638469] [<ffffffc0006f8704>] v4l2_ctrl_new_custom+0x170/0x19c</b>
[ 9.638473] [<ffffffc000715318>] tegra_channel_setup_controls+0x8c/0xcc
[ 9.638476] [<ffffffc0007172c8>] tegra_channel_init_subdevices+0x100/0x12c
[ 9.638479] [<ffffffc000717990>] tegra_vi_graph_build_links+0x1e8/0x20c
[ 9.638481] [<ffffffc000717a18>] tegra_vi_graph_notify_complete+0x64/0xa8
[ 9.638485] [<ffffffc0006fbc98>] v4l2_async_test_notify+0xf4/0x110
[ 9.638487] [<ffffffc0006fbeb8>] v4l2_async_register_subdev+0x80/0xe0
[ 9.638492] [<ffffffbffc00d67c>] daxc02_probe+0x2f0/0x338 [daxc02]
[ 9.638495] [<ffffffc0006d68f0>] i2c_device_probe+0xb4/0xfc
[ 9.638499] [<ffffffc000508b98>] really_probe+0x120/0x2c8
[ 9.638501] [<ffffffc000508e38>] driver_probe_device+0x78/0xa4
[ 9.638503] [<ffffffc000508f0c>] __driver_attach+0x60/0x8c
[ 9.638505] [<ffffffc000506da8>] bus_for_each_dev+0x54/0x98
[ 9.638507] [<ffffffc00050870c>] driver_attach+0x20/0x28
[ 9.638509] [<ffffffc0005080f0>] bus_add_driver+0xe4/0x1d0
[ 9.638512] [<ffffffc000509c28>] driver_register+0xb8/0xfc
[ 9.638514] [<ffffffc0006d7fb0>] i2c_register_driver+0xcc/0xdc
[ 9.638518] [<ffffffbffc011020>] $x+0x20/0x28 [daxc02]
[ 9.638521] [<ffffffc0000815f0>] do_one_initcall+0x40/0x100
[ 9.638525] [<ffffffc00010efc8>] do_init_module+0x50/0x194
[ 9.638527] [<ffffffc00010fbd8>] load_module+0x1f8/0x2c0
[ 9.638529] [<ffffffc00010ff64>] SyS_finit_module+0x11c/0x1b4
[ 9.638532] Code: 1ad80aa0 1b18d415 93407eb5 f9402e60 (f8757800)
[ 9.639415] ---[ end trace 1439ab4534aa3e8f ]---
Looking at kernel_source/drivers/media/platform/tegra/camera/channel.c here’s the source of tegra_channel_setup_controls:
/**
* By default channel will be in VI mode
* User space can set it to 0 for working in bypass mode
*/
static const struct v4l2_ctrl_config bypass_mode_ctrl = {
.ops = &channel_ctrl_ops,
.id = V4L2_CID_VI_BYPASS_MODE,
.name = "Bypass Mode",
.type = V4L2_CTRL_TYPE_INTEGER_MENU,
.def = 0,
.min = 0,
.max = ARRAY_SIZE(switch_ctrl_qmenu) - 1,
.menu_skip_mask = 0,
.qmenu_int = switch_ctrl_qmenu,
};
static int tegra_channel_setup_controls(struct tegra_channel *chan)
{
int num_sd = 0;
struct v4l2_subdev *sd = NULL;
/* Initialize the subdev and controls here at first open */
sd = chan->subdev[num_sd];
while ((sd = chan->subdev[num_sd++]) &&
(num_sd <= chan->num_subdevs)) {
/* Add control handler for the subdevice */
v4l2_ctrl_add_handler(&chan->ctrl_handler,
sd->ctrl_handler, NULL);
if (chan->ctrl_handler.error)
dev_err(chan->vi->dev,
"Failed to add sub-device controls\n");
}
/* Add the bypass mode ctrl */
v4l2_ctrl_new_custom(&chan->ctrl_handler, &bypass_mode_ctrl, NULL);
if (chan->ctrl_handler.error) {
dev_err(chan->vi->dev,
"Failed to add bypass control\n");
return chan->ctrl_handler.error;
}
/* setup the controls */
return v4l2_ctrl_handler_setup(&chan->ctrl_handler);
}
Looks to me like my controls are getting skipped correctly, but the error happens when it loads in the bypass_mode_ctrl control using v4l2_ctrl_new_custom.
Thus I think the null pointer is in &chan->ctrl_handler
I’ll keep poking at it.
the handler itself isn’t NULL because the first thing that v4l2_ctrl does is call
if (hdl->error) return NULL:
First run through handler_new_ref hits this block:
1867 /*
1868 * Automatically add the control class if it is not yet present and
1869 * the new control is not a compound control.
1870 */
1871 if (ctrl->type < V4L2_CTRL_COMPOUND_TYPES &&
1872 id != class_ctrl && find_ref_lock(hdl, class_ctrl) == NULL)
1873 if (!v4l2_ctrl_new_std(hdl, NULL, class_ctrl, 0, 0, 0, 0))
1874 return hdl->error;
v4l2_ctrl_new_std returns v4l2_ctrl_new which goes through handler_new_ref again.
Candidates for being null:
hdl->lock
hdl->ctrl_refs
hdl->buckets
I’ll print those out and see which one it is
hdl->lock and hdl->buckets seem to be initialized but I can’t find anywhere that hdl->ctrl_refs is defined.
I never made an equivalent to
ov5693_otp_setup(priv);
or
ov5693_fuse_id_setup(priv);
So maybe that’s the issue.
The ov5693 driver needs to be “built-in” in the kernel, i.e. not compiled as a .ko module which gets loaded at a later time during kernel booting process. The real problem is tegra vi/channel driver code does not handle sensor drivers as modules correctly.
Please emphasize this in the Sensor Driver Programming Guide.
I beat my head against this wall repeatedly before finding this post.
Well, indeed. I spent almost a week reading NVIDIA (tegra vi & channel) driver code and printing debug messages before I finally figured out what the problem was…
Same, started going down such a deep rabbit hole
Hi All
Thanks for your input we will consider to at a note to the developer guide.