patched tc358840 driver failing after 28.2 upgrade

I have a modified tc358840 driver that works on 28.1 but does not work on 28.2. I followed the camera sensor porting guide for 28.2, but similar to the other tcxxxxx camera drivers, there is no camera_common_parse_ports() usage so there was no need to replace the call with camera_common_initialize().

The error was a segfault in the kernel bootup when initializing this driver. The output can be seen here:

[    4.955391] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[    4.955393] pgd = ffffffc001583000
[    4.955398] [00000000] *pgd=000000017b1d8003, *pud=000000017b1d8003, *pmd=000000017b1d9003, *pte=00e8000050041707
[    4.955401] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[    4.955403] Modules linked in:
[    4.955407] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.4.38-skydio #21
[    4.955408] Hardware name: jetson_tx1 (DT)
[    4.955410] task: ffffffc0fb2f0000 ti: ffffffc0fb2a4000 task.ti: ffffffc0fb2a4000
[    4.955416] PC is at tegra_channel_init_subdevices+0x718/0xa08
[    4.955419] LR is at tegra_channel_init_subdevices+0x6fc/0xa08
[    4.955420] pc : [<ffffffc0007b1270>] lr : [<ffffffc0007b1254>] pstate: 80000145
[    4.955421] sp : ffffffc0fb2a7940
[    4.955424] x29: ffffffc0fb2a7940 x28: ffffffc07d2d3018 
[    4.955426] x27: ffffffc07d33a0d0 x26: ffffffc000c21000 
[    4.955428] x25: 0000000000000000 x24: ffffffc0f8bf5860 
[    4.955430] x23: 0000000000000000 x22: 0000000000000000 
[    4.955432] x21: ffffffc00103b008 x20: ffffffc000c21ac0 
[    4.955435] x19: ffffffc07d2d30b0 x18: 0000000000020000 
[    4.955436] x17: 0000000000000000 x16: 0000000000000000 
[    4.955438] x15: ffffffc0012fe598 x14: ffffffc001504b58 
[    4.955440] x13: ffffffc0012fe000 x12: ffffffc0014e1000 
[    4.955442] x11: 0000000000000000 x10: 0000000000000000 
[    4.955444] x9 : 000000000000f8d0 x8 : ffffffc0014f2e98 
[    4.955446] x7 : 0000000000000000 x6 : 00000000076566bb 
[    4.955448] x5 : 0000000000000015 x4 : 0000000000000090 
[    4.955450] x3 : 000000000000042f x2 : ffffffc000c21ac0 
[    4.955452] x1 : ffffffc00103b008 x0 : ffffffc07d2d30b0 
[    4.955453] 
[    4.955455] Process swapper/0 (pid: 1, stack limit = 0xffffffc0fb2a4020)
[    4.955456] Call trace:
[    4.955458] [<ffffffc0007b1270>] tegra_channel_init_subdevices+0x718/0xa08
[    4.955461] [<ffffffc0007b2380>] tegra_vi_graph_notify_complete+0x570/0x600
[    4.955465] [<ffffffc00079e2c4>] v4l2_async_test_notify+0xdc/0xf0
[    4.955467] [<ffffffc00079e410>] v4l2_async_notifier_register+0x138/0x188
[    4.955470] [<ffffffc0007b2c54>] tegra_vi_graph_init+0x1dc/0x270
[    4.955472] [<ffffffc0007aec84>] tegra_vi_media_controller_init+0x15c/0x1e8
[    4.955475] [<ffffffc0007bc220>] vi_probe+0x448/0x4e0
[    4.955479] [<ffffffc0005f07c8>] platform_drv_probe+0x50/0xb8
[    4.955481] [<ffffffc0005ee3bc>] driver_probe_device+0x17c/0x3d8
[    4.955483] [<ffffffc0005ee680>] __driver_attach+0x68/0x98
[    4.955486] [<ffffffc0005ec36c>] bus_for_each_dev+0x54/0xa8
[    4.955488] [<ffffffc0005edde0>] driver_attach+0x20/0x28
[    4.955490] [<ffffffc0005ed760>] bus_add_driver+0x110/0x268
[    4.955492] [<ffffffc0005ef4c8>] driver_register+0x90/0xd8
[    4.955494] [<ffffffc0005f071c>] __platform_driver_register+0x4c/0x58
[    4.955498] [<ffffffc0011ce530>] vi_init+0x2c/0x38
[    4.955501] [<ffffffc00008142c>] do_one_initcall+0x114/0x1c0
[    4.955504] [<ffffffc001191b74>] kernel_init_freeable+0x1dc/0x288
[    4.955508] [<ffffffc000b484c8>] kernel_init+0x18/0xe0
[    4.955511] [<ffffffc0000847a0>] ret_from_fork+0x10/0x30
[    4.955607] ---[ end trace 19dbde04e34cd11d ]---
[    4.956680] mmc2: queuing unknown CIS tuple 0x91 (3 bytes)
[    4.956703] mmc2: new ultra high speed SDR104 SDIO card at address 0001
[    4.956830] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    4.956830] 
[    4.956833] CPU1: stopping
[    4.956836] CPU: 1 PID: 96 Comm: kworker/u8:2 Tainted: G      D         4.4.38-skydio #21
[    4.956837] Hardware name: jetson_tx1 (DT)
[    4.956843] Workqueue: kmmcd mmc_rescan
[    4.956844] Call trace:
[    4.956848] [<ffffffc000088ab8>] dump_backtrace+0x0/0xe8
[    4.956851] [<ffffffc000088bb4>] show_stack+0x14/0x20
[    4.956854] [<ffffffc000369d60>] dump_stack+0xb4/0xec
[    4.956857] [<ffffffc00008dc38>] handle_IPI+0x170/0x330
[    4.956859] [<ffffffc000080f20>] gic_handle_irq+0x98/0xc8
[    4.956861] [<ffffffc000083f44>] el1_irq+0x84/0x100
[    4.956864] [<ffffffc0002406b4>] __kernfs_create_file+0x7c/0xb0
[    4.956866] [<ffffffc000241038>] sysfs_add_file_mode_ns+0x168/0x1b8
[    4.956868] [<ffffffc0002410b8>] sysfs_create_file_ns+0x30/0x38
[    4.956871] [<ffffffc0005e92c4>] device_create_file+0x54/0xa0
[    4.956873] [<ffffffc0005eaf18>] device_add+0x158/0x5b0
[    4.956876] [<ffffffc00082199c>] sdio_add_func+0xc4/0xf0
[    4.956878] [<ffffffc000820c88>] mmc_attach_sdio+0x2b8/0x3d0
[    4.956880] [<ffffffc000817e44>] mmc_rescan+0x224/0x2e8
[    4.956883] [<ffffffc0000ba888>] process_one_work+0x268/0x508
[    4.956886] [<ffffffc0000badac>] worker_thread+0x284/0x4a0
[    4.956888] [<ffffffc0000c1108>] kthread+0xf8/0x100
[    4.956890] [<ffffffc0000847a0>] ret_from_fork+0x10/0x30
[    4.956892] CPU0: stopping
[    4.956895] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G      D         4.4.38-skydio #21
[    4.956896] Hardware name: jetson_tx1 (DT)
[    4.956897] Call trace:
[    4.956900] [<ffffffc000088ab8>] dump_backtrace+0x0/0xe8
[    4.956903] [<ffffffc000088bb4>] show_stack+0x14/0x20
[    4.956905] [<ffffffc000369d60>] dump_stack+0xb4/0xec
[    4.956907] [<ffffffc00008dc38>] handle_IPI+0x170/0x330
[    4.956909] [<ffffffc000080f20>] gic_handle_irq+0x98/0xc8
[    4.956911] [<ffffffc000083f44>] el1_irq+0x84/0x100
[    4.956914] [<ffffffc000811300>] cpuidle_enter+0x18/0x20
[    4.956917] [<ffffffc0000e35e4>] call_cpuidle+0x4c/0x58
[    4.956919] [<ffffffc0000e38b8>] cpu_startup_entry+0x2c8/0x388
[    4.956922] [<ffffffc000b484a0>] rest_init+0x88/0x98
[    4.956924] [<ffffffc001191984>] start_kernel+0x39c/0x3b0
[    4.956926] [<0000000080b4f000>] 0x80b4f000
[    4.960140] CPU3: stopping
[    4.960142] CPU: 3 PID: 99 Comm: kworker/3:1 Tainted: G      D         4.4.38-skydio #21
[    4.960143] Hardware name: jetson_tx1 (DT)
[    4.960149] Workqueue: events console_callback
[    4.960149] Call trace:
[    4.960153] [<ffffffc000088ab8>] dump_backtrace+0x0/0xe8
[    4.960155] [<ffffffc000088bb4>] show_stack+0x14/0x20
[    4.960157] [<ffffffc000369d60>] dump_stack+0xb4/0xec
[    4.960159] [<ffffffc00008dc38>] handle_IPI+0x170/0x330
[    4.960161] [<ffffffc000080f20>] gic_handle_irq+0x98/0xc8
[    4.960162] [<ffffffc000083f44>] el1_irq+0x84/0x100
[    4.960165] [<ffffffc0000a71e8>] irq_exit+0x70/0xe0
[    4.960168] [<ffffffc0000f3c10>] __handle_domain_irq+0x88/0xb0
[    4.960169] [<ffffffc000080ef4>] gic_handle_irq+0x6c/0xc8
[    4.960171] [<ffffffc000083f44>] el1_irq+0x84/0x100
[    4.960173] [<ffffffc00053d918>] console_callback+0xf8/0x130
[    4.960175] [<ffffffc0000ba888>] process_one_work+0x268/0x508
[    4.960178] [<ffffffc0000badac>] worker_thread+0x284/0x4a0
[    4.960180] [<ffffffc0000c1108>] kthread+0xf8/0x100
[    4.960182] [<ffffffc0000847a0>] ret_from_fork+0x10/0x30
[    6.150214] Rebooting in 30 seconds..␀[0002.494] Find /i2c@7000c400's alias i2c1

I tracked the segfault down to the tegra_channel_sensorprops_setup() function in channel.c.

static int tegra_channel_sensorprops_setup(struct tegra_channel *chan)
{
	const struct v4l2_subdev *sd = chan->subdev_on_csi;
	const struct camera_common_data *s_data =
			to_camera_common_data(sd->dev);
	const struct sensor_mode_properties *modes;
	struct v4l2_ctrl *ctrl_modes;
	struct v4l2_ctrl *ctrl_signalprops;
	struct v4l2_ctrl *ctrl_imageprops;
	struct v4l2_ctrl *ctrl_controlprops;
	struct v4l2_ctrl *ctrl_dvtimings;
	u32 i;

	GET_TEGRA_CAMERA_CTRL(SENSOR_MODES, ctrl_modes);
	GET_TEGRA_CAMERA_CTRL(SENSOR_SIGNAL_PROPERTIES, ctrl_signalprops);
	GET_TEGRA_CAMERA_CTRL(SENSOR_IMAGE_PROPERTIES, ctrl_imageprops);
	GET_TEGRA_CAMERA_CTRL(SENSOR_CONTROL_PROPERTIES, ctrl_controlprops);
	GET_TEGRA_CAMERA_CTRL(SENSOR_DV_TIMINGS, ctrl_dvtimings);

	ctrl_modes->val = s_data->sensor_props.num_modes;
	ctrl_modes->cur.val = s_data->sensor_props.num_modes;

	modes = s_data->sensor_props.sensor_modes;
	for (i = 0; i < s_data->sensor_props.num_modes; i++) {
		void *ptr = NULL;
		u32 size;

		size = sizeof(struct sensor_signal_properties);
		ptr = ctrl_signalprops->p_new.p + (i * size);
		memcpy(ptr, &modes[i].signal_properties, size);  // FAILS HERE DEREFERENCING THE NULL ARRAY

		size = sizeof(struct sensor_image_properties);
		ptr = ctrl_imageprops->p_new.p + (i * size);
		memcpy(ptr, &modes[i].image_properties, size);

		size = sizeof(struct sensor_control_properties);
		ptr = ctrl_controlprops->p_new.p + (i * size);
		memcpy(ptr, &modes[i].control_properties, size);

		size = sizeof(struct sensor_dv_timings);
		ptr = ctrl_dvtimings->p_new.p + (i * size);
		memcpy(ptr, &modes[i].dv_timings, size);
	}
	ctrl_signalprops->p_cur.p = ctrl_signalprops->p_new.p;
	ctrl_imageprops->p_cur.p = ctrl_imageprops->p_new.p;
	ctrl_controlprops->p_cur.p = ctrl_controlprops->p_new.p;
	ctrl_dvtimings->p_cur.p = ctrl_dvtimings->p_new.p;

	return 0;
}

The sensor_props.sensor_modes return a null pointer which is causing the problem. I’m guessing if I just pass in a zeroed out common data structure, this will just be ignored? However, looking at the other l4t included tcxxx drivers, I see no initialization of camera_common_data which has caused doubts. Do I need to add in a call in the probe() to camera_common_initialize() even though it is not used?

Going to test out the camera_common_data initialization anyway but figured I’d post here as well.

Hi

I find git commit link for your question.

please refer to it.

Turns out the issue was due to poor handling of the case where no devices were provided. Also the IOCTL command values changed.