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.

https://github.com/InES-HPMM/linux-l4t-4.4-kernel/commit/5e36ca164a27cbbcf6ea1c6239da3acaa385bd8e

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.