Accessing user space memory outside uaccess.h routines

Hello,

We have developed a video card based on TX2 :

Our video pipeline is like this :

  • Channel 1: ADV7604 (Analog UXGA signal to parallel RGB888) => FPGA (Parallel RGB888 to CSI-2 Format ) => CSI0 (4 Lane configuration)

  • Channel 2: ADV7604 (Analog UXGA signal to parallel RGB888) => FPGA (Parallel RGB888 to CSI-2 Format ) => CSI2 (4 Lane configuration)

I compiled ADV7604 driver as it is in the kernel source code as a module. you can find the ADV 7604 driver here: ADV7604 Driver . Made some changes in the device tree for the ADV7604 as mentioned in the attached snippet:

i2c@3180000 {       //set this to correct i2c bus
    tca9546@70 {
        i2c@0{  //cam_i2c/Mux@70/I2C_A
            #address-cells = <1>;
            #size-cells = <0>;

            adv7604_a@20 {/* VD: Earlier it was imx185_a@1a*/

		/*VD: Changed for ADV7604 Driver */
                /* compatible = "nvidia,imx185"; */
				compatible = "adv,adv7611";

		/* VD: Updated as decoder IO Map I2C address is 0x40: For detail please refer ADV7604 H/W manual*/
               /* reg = <0x1a>; */
		/* VD: We have taken 8-Bit address as ADV driver uses 8-Bit addressing. Note: Rest of the I2C addresses are 7-Bit */
	      		reg = <0x20>, <0x42>, <0x40>, <0x3e>, <0x38>, <0x3c>, <0x26>, <0x32>, <0x36>, <0x34>, <0x30>, <0x22>, <0x24>;

		/* VD: New property added as 13 address map is in ADV7604 */
				reg-names = "io", "avlink", "cec", "infoframe", "esdp", "epp", "afe", "rep", "edid", "hdmi", "test", "cp", "vdp";

		/* VD: devnode Kept same as imx185 */
                devnode = "video0"; 

        /* VD: Physical dimensions of sensor so no need to include in our ADV7604 case */
                /* physical_w = "15.0"; */
	   		    /* physical_h = "12.5"; */

		/*VD: Clock same as for imx185 used by CTI*/
                clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH1>,
                         <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
		/* VD: Same clock name used */
                clock-names = "extperiph1", "pllp_grtba";
		/* VD: mclk is not used by ADV7604. However it is kept same as it is an output on ASG006 P17A/P17B and not used on DHV-AVSRD */
                mclk = "extperiph1";
		/* VD: Sensor model changed earlier it was imx185*/
                sensor_model = "adv7604";
		/* VD: Same delayed gain used. However not known how it is used */
                delayed_gain = "true";

		/*VD: Changed because we are using CAM2_CNTRL_RST and making it board reset. SoC GPIO is not used for Rest in DHV-AVSRD*/
                reset-gpios = <&tegra_main_gpio CAM0_RST_L GPIO_ACTIVE_HIGH>; 

		/* VD: Unknown property. However enabling as CSI driver may be using */
	   			post_crop_frame_drop = "0"; 
               	use_decibel_gain = "true"; 

		/* VD: New property added for ADV7604 driver */
					default-input = <0>;

		/* VD: Keeping these property as it is because looks like configuring the CSI-2 */
				mclk_khz = "37125";
				num_lanes = "4";
				tegra_sinterface = "serial_a"; /* VD: ? */
				phy_mode = "DPHY";
				discontinuous_clk = "no"; /* VD: ? */
				dpcm_enable = "false"; /* VD: ? */
				cil_settletime = "0"; /* VD: ? */
				dynamic_pixel_bit_depth = "12"; /* VD: ? */
				csi_pixel_bit_depth = "12"; /* VD: ? */
				mode_type = "bayer"; /* VD: ? */
				pixel_phase = "rggb"; /* VD: ? */

				active_w = "1920";
				active_h = "1080";
				readout_orientation = "0"; /* VD: ? */
				line_length = "2200"; /* VD: ? */
				inherent_gain = "1";
				mclk_multiplier = "2";
				pix_clk_hz = "74250000";

				gain_factor = "10";
				min_gain_val = "0"; /* 0dB */
				max_gain_val = "480"; /* 48dB */
				step_gain_val = "3"; /* 0.3 */
				default_gain = "0";
				min_hdr_ratio = "1";
				max_hdr_ratio = "1";
				framerate_factor = "1000000";
				min_framerate = "1500000"; /* 1.5 */
				max_framerate = "30000000"; /* 30 */
				step_framerate = "1";
				default_framerate = "30000000";
				exposure_factor = "1000000";
				min_exp_time = "30"; /* us */
				max_exp_time = "660000"; /* us */
				step_exp_time = "1";
				default_exp_time = "33334";/* us */
				embedded_metadata_height = "1";


                ports {
                    #address-cells = <1>;
                    #size-cells = <0>;

                    port@0 {
                        reg = <0>;
                        adv7604_out0: endpoint {
                            port-index = <0>;
                            bus-width = <4>;
                            remote-endpoint = <&csi_in0>;
                        };
                    };
                };
            };


        };

Error seen in the dmesg is:

[    5.117686] Internal error: Accessing user space memory outside uaccess.h routines: 96000005 [#1] PREEMPT SMP

[ 5.127688] Modules linked in: adv7604(+) nvgpu bluedroid_pm ip_tables x_tables
[ 5.135185] CPU: 2 PID: 3110 Comm: systemd-udevd Not tainted 4.9.140-tegra-tegra #7
[ 5.142879] Hardware name: quill (DT)
[ 5.146564] task: ffffffc1e3101c00 task.stack: ffffffc1dc910000
[ 5.152533] PC is at adv76xx_probe+0xb4/0xd40 [adv7604]
[ 5.157808] LR is at adv76xx_probe+0xac/0xd40 [adv7604]
[ 5.163061] pc : [] lr : [] pstate: 40400045
[ 5.170488] sp : ffffffc1dc913a10
[ 5.173825] x29: ffffffc1dc913a10 x28: 0000000000000018
[ 5.179207] x27: 00000000000001c1 x26: 0000000000000030
[ 5.184581] x25: 0000000000000000 x24: ffffff80011b1ef0
[ 5.189949] x23: ffffffc1e6892800 x22: ffffffc1e6892820
[ 5.195326] x21: 00000000ffffffff x20: 00000000ffffffea
[ 5.200703] x19: ffffffc1e68bc018 x18: 0000000000000001
[ 5.206084] x17: 0000000000000000 x16: 0000000000000000
[ 5.211456] x15: ffffffffffffffff x14: ffffffc1dd4bee8a
[ 5.216830] x13: ffffffc1dd4bee89 x12: 0000000000000018
[ 5.222202] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
[ 5.227571] x9 : 01fefefeff303035 x8 : 7f7f7f7f7f7f7f7f
[ 5.232939] x7 : 367563602b756360 x6 : 0000008080808000
[ 5.238310] x5 : 0000000000000000 x4 : 0000000000000000
[ 5.243678] x3 : ffffff80011b1c10 x2 : ffffffc1e6892800
[ 5.249048] x1 : 0000000000000000 x0 : 0000000000000000

[ 5.255920] Process systemd-udevd (pid: 3110, stack limit = 0xffffffc1dc910000)
[ 5.263260] Call trace:
[ 5.265743] [] adv76xx_probe+0xb4/0xd40 [adv7604]
[ 5.272046] [] i2c_device_probe+0x144/0x258
[ 5.277824] [] driver_probe_device+0xd8/0x408
[ 5.283774] [] __driver_attach+0xdc/0x128
[ 5.289374] [] bus_for_each_dev+0x5c/0xa8
[ 5.294974] [] driver_attach+0x30/0x40
[ 5.300314] [] bus_add_driver+0x20c/0x2a8
[ 5.305915] [] driver_register+0x6c/0x110
[ 5.311520] [] i2c_register_driver+0x4c/0xb0
[ 5.317393] [] adv76xx_driver_init+0x14/0x30 [adv7604]
[ 5.324128] [] do_one_initcall+0x44/0x130
[ 5.329730] [] do_init_module+0x64/0x1a8
[ 5.335246] [] load_module+0x10a4/0x12d8
[ 5.340762] [] SyS_finit_module+0xd8/0xf0
[ 5.346371] [] __sys_trace_return+0x0/0x4
[ 5.351972] —[ end trace 0f00039bbf0b8608 ]—

Please guide me to resolve this problem as i am very new to the device tree.

Thanks and Regards,

Vikas Dwivedi

You might be interested in these, especially the second URL:
https://forums.developer.nvidia.com/t/internal-error-accessing-user-space-memory-outside-uaccess-h-routines-solved/66264
https://github.com/derekmolloy/exploringBB/pull/24/files

I don’t know about your specific case, but there is code which used to work on the first of the ARMv8-a CPUs, and then there was a hardware revision which changed access. Somewhere in your code you will have a copy of memory, e.g., perhaps an sprintf() printing a character string. You’d then need to change it to a combination with copy_from_user().

It isn’t a software bug so much as it is old code needing an update for newer ARMv8-a revisions.

Hello,

Problem is still not resolved.

I have referred Camera Driver Development Guide for adding my driver and device tree understanding. Document refers to the IMX185 camera sensor driver which is available in Nvidia kernel source; Location: sources/kernel/nvidia/drivers/media/i2c/imx185.c.

As I can see from the sources, there a two kernel sources one is from nvidia and other one is kernel4.9(Basic Linux).

Our driver ADV7604 is not in the nvidia kernel source folder. It is in kernel4.9 folder. Location: sources/kernel/kernel-4.9/drivers/media/i2c/adv7604.c

I understand after referring to multiple documents that Nvidia has modified the V4L2. Do we need to port our ADV7604 driver taking IMX185 as reference so that it interfaces with tegra camera platform ?

Thanks and Regards,
Vikas Dwivedi

I am not “a camera guy”, so I’m not really qualified to answer that, but I suspect that some revision of code must be done to use copy_from_user() (or copy_to_user()) at some point due to evolution of a hardware revision. This is the exact function where the error shows up:
[ 5.265743] [] adv76xx_probe+0xb4/0xd40 [adv7604]

This looks like it is in one of the files you mentioned:
drivers/media/i2c/adv7604.c
(this is in the kernel-4.9/ subdirectory)

FYI, the “kernel-4.9/” seems to be mostly the basic kernel content, but some of the NVIDIA-specific content refers to their custom files via a relative path out of “kernel-4.9/” and into one of the other directory branches. A full source install typically produces these directories (and more):

.
├── hardware
│   └── nvidia
└── kernel
    ├── kernel-4.9
    ├── nvgpu
    └── nvidia

…if you don’t enable any of the NVIDIA configurations, then nothing outside of kernel-4.9 would be accessed during a kernel build. kernel-4.9/ is the “traditional” kernel source (which might have NVIDIA modifications, but the ones in there are the GPLv2 license and treated just like any other kernel file).

My suggestion is to narrow this down the point of failure by adding printk() statements in that function anywhere that a pointer might be copying data to/from some other place in memory. You don’t even need to be particularly “close” to the right spot if you are willing to space a few printk() statements throughout, look at logs to find the last one which occurs before the error (the error should be reproducible), and then add more printk() statements to find the exact spot. Then wrap with the copy_to_user() or copy_from_user() as required.

Know that evolution of the CPU core hardware seems to be the reason why some previously working code did not need a copy_to_user() (or copy_from_user()). I am no expert on this, but from what I’ve read this need did not exist on earlier CPU cores of ARMv8-a, but became a requirement on one of the revisions, e.g., maybe it was ARMv8.1-a (or ARMv8.2-a?). I don’t know the exact time this changed, but this is not so much a “driver port” for the camera as it is a patch to help with this different CPU revision.

I could of course be completely wrong, but even if I am, then you’d still want to narrow the failure down with the same printk() statements in that same function to find the failure point.

Hello,

Thank you for replying.

I tried to debug by following your suggestion. I tried to narrow down the problem area by putting printk statement in the probe function. So I came to know that problem is in this function call: oid = of_match_node(adv76xx_of_id, client->dev.of_node);

See the problem area below :

/* initialize variables */
state->restart_stdi_once = true;
state->selected_input = ~0;

if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) {
	const struct of_device_id *oid;

	oid = of_match_node(adv76xx_of_id, client->dev.of_node);
	state->info = oid->data;

	err = adv76xx_parse_dt(state);
	if (err < 0) {
		v4l_err(client, "DT parsing error\n");
		return err;
	}

I don’t think so this function call is using copy_from_user() or copy_to_user() .If yes then how what is the alternative of this function call.

I tried to disable the hardware revision dependency by following ARM Configuration Parameter but it is also not working.

One more query I posted in the forum, Can you please comment on this: Reset on Jetson Tx2.

Please help us to resolve these two problems.

Thanks and Regards,
Vikas Dwivedi

Hello,

Thank you for your help. Match id problem get resolved and system moved forward.

Again we are getting the same problem but at different stage as you can see in the log below:

[   10.871214] adv7604 30-0020: adv7604 found @ 0x40 (i2c-2-mux (chan_id 0))

[ 10.871221] tegra-vi4 15700000.vi: subdev adv7604 30-0020 bound
[ 10.871225] tegra-vi4 15700000.vi: Entity type for entity adv7604 30-0020 was not initialized!
[ 10.871588] Internal error: Accessing user space memory outside uaccess.h routines: 96000005 [#1] PREEMPT SMP
[ 10.871596] Modules linked in: adv7604(+) nvgpu bluedroid_pm ip_tables x_tables
[ 10.871600] CPU: 3 PID: 3177 Comm: systemd-udevd Not tainted 4.9.140-tegra-tegra #1
[ 10.871601] Hardware name: quill (DT)
[ 10.871603] task: ffffffc1dbef2a00 task.stack: ffffffc1dbee4000
[ 10.871610] PC is at tegra_channel_populate_dev_info+0xac/0x198
[ 10.871613] LR is at tegra_channel_populate_dev_info+0x9c/0x198
[ 10.871615] pc : lr : pstate: 40400045
[ 10.871616] sp : ffffffc1dbee7780
[ 10.871618] x29: ffffffc1dbee7780 x28: 0000000000000000
[ 10.871621] x27: 0000000000000001 x26: ffffffc1e4ccd518
[ 10.871623] x25: 00000000009a2065 x24: ffffffc1e538a050
[ 10.871625] x23: 000000000000000a x22: ffffffc1e4ccd770
[ 10.871627] x21: ffffffc1e4ccd018 x20: ffffffc1dbee7838
[ 10.871629] x19: ffffffc1eb690c10 x18: 0000000000000001
[ 10.871631] x17: 0000000000000002 x16: 0000000000000000
[ 10.871633] x15: ffffffffffffffff x14: ffffffc1dbee7780
[ 10.871635] x13: ffffffc1dbee7685 x12: ffffffffffffffff
[ 10.871637] x11: ffffffc1dbee7640 x10: ffffffc1dbee7640
[ 10.871639] x9 : 0000000000000042 x8 : 0000000000000002
[ 10.871641] x7 : ffffff8008fb6dc8 x6 : 0000000000000083
[ 10.871643] x5 : 000000000000008d x4 : 0000000000000001
[ 10.871644] x3 : 0000000000000000 x2 : 0000000000000000
[ 10.871646] x1 : 0000000000000000 x0 : 0000000000000000

[ 10.871649] Process systemd-udevd (pid: 3177, stack limit = 0xffffffc1dbee4000)
[ 10.871650] Call trace:
[ 10.871653] tegra_channel_populate_dev_info+0xac/0x198
[ 10.871656] tegra_channel_init_subdevices+0x2e8/0x7a8
[ 10.871658] tegra_vi_graph_notify_complete+0x328/0x6d8
[ 10.871662] v4l2_async_test_notify+0x104/0x120
[ 10.871664] v4l2_async_register_subdev+0x88/0x100
[ 10.871675] adv76xx_probe.part.6+0xc38/0xdd8 [adv7604]
[ 10.871683] adv76xx_probe+0x60/0x70 [adv7604]
[ 10.871686] i2c_device_probe+0x144/0x258
[ 10.871690] driver_probe_device+0xd8/0x408
[ 10.871692] __driver_attach+0xdc/0x128
[ 10.871694] bus_for_each_dev+0x5c/0xa8
[ 10.871696] driver_attach+0x30/0x40
[ 10.871698] bus_add_driver+0x20c/0x2a8
[ 10.871700] driver_register+0x6c/0x110
[ 10.871702] i2c_register_driver+0x4c/0xb0
[ 10.871710] adv76xx_driver_init+0x14/0x30 [adv7604]
[ 10.871713] do_one_initcall+0x44/0x130
[ 10.871717] do_init_module+0x64/0x1a8
[ 10.871720] load_module+0x10a4/0x12d8
[ 10.871722] SyS_finit_module+0xd8/0xf0
[ 10.871724] __sys_trace_return+0x0/0x4
[ 10.871727] —[ end trace 337b7b8903631183 ]—

Actually we have developed dual channel video input system so two ADV7604 is used in the board. Accordingly two video node should be created but as i can see only one node is getting created.

sds@sds-desktop:~$ v4l2-ctl --list-devices
vi-output, 150c0000.nvcsi–2 (platform:15700000.vi:0):
/dev/video0

sds@sds-desktop:~$ media-ctl -p -d /dev/media0
Media controller API version 0.1.0

Media device information

driver tegra-vi4
model NVIDIA Tegra Video Input Device
serial
bus info
hw revision 0x3
driver version 0.0.0

Device topology

  • entity 1: 150c0000.nvcsi–2 (2 pads, 1 link)
    type V4L2 subdev subtype Unknown flags 0
    pad0: Sink
    pad1: Source
    → “vi-output, 150c0000.nvcsi–2”:0 [ENABLED]
  • entity 4: 150c0000.nvcsi–1 (2 pads, 0 link)
    type V4L2 subdev subtype Unknown flags 0
    pad0: Sink
    pad1: Source
  • entity 7: adv7604 30-0020 (7 pads, 0 link)
    type V4L2 subdev subtype Unknown flags 0
    pad0: Sink
    pad1: Sink
    pad2: Sink
    pad3: Sink
    pad4: Sink
    pad5: Sink
    pad6: Source
  • entity 15: vi-output, 150c0000.nvcsi–2 (1 pad, 1 link)
    type Node subtype V4L flags 0
    device node name /dev/video0
    pad0: Sink
    ← “150c0000.nvcsi–2”:1 [ENABLED]

I looked at the problem area and got to know that problem is in sources/kernel/kernel-4.9/drivers/media/media-device.c file. snippet is attached and well understood that V4L2 sub device type is unknown.

	if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN ||
    entity->function == MEDIA_ENT_F_UNKNOWN)
	dev_warn(mdev->dev,
		 "Entity type for entity %s was not initialized!\n",
		 entity->name);

PC is at tegra_channel_populate_dev_info this error is in sources/kernel/nvidia/drivers/media/platform/tegra/camera/vi/channel.c . function snippet is attached.

static void tegra_channel_populate_dev_info(struct tegra_camera_dev_info *cdev,
		struct tegra_channel *chan)

{
u64 pixelclock = 0;

if (chan->pg_mode)
	cdev->sensor_type = SENSORTYPE_VIRTUAL;
else if (v4l2_subdev_has_op(chan->subdev_on_csi,
			video, g_dv_timings)) {
	cdev->sensor_type = SENSORTYPE_OTHER;
	pixelclock = tegra_channel_get_max_source_rate();
} else {
	cdev->sensor_type = tegra_channel_get_sensor_type(chan);
	pixelclock = tegra_channel_get_max_pixelclock(chan);
	/* Multiply by CPHY symbols to pixels factor. */
	if (cdev->sensor_type == SENSORTYPE_CPHY)
		pixelclock *= 16/7;
	cdev->lane_num = tegra_channel_get_num_lanes(chan);
}

cdev->pixel_rate = pixelclock;
cdev->pixel_bit_depth = chan->fmtinfo->width;
cdev->bpp = chan->fmtinfo->bpp.numerator;
/* BW in kBps */
cdev->bw = cdev->pixel_rate * cdev->bpp / 1024;

}

I am not able to understand where I should set the V4L2 subdevice type and how it will be compatible with Tegra Vi interface. what could be the reason behind only one video node is getting created. Am I missing something in the device tree ? Please review our device tree and suggest what the properties I should add. Device tree is attached below.

vikas.txt (6.5 KB)
Looking forward for your kind support.

Thanks and Regards,
Vikas Dwivedi

No, the problem is that it does not use a copy_ statement. My guess is that something in that line (which includes a struct which might end up in some way copying data to a pointer) needs to have code with direct copy changed to the copy_ type function. Even an sprintf() could do this.

Basically you need to drill down into:
of_match_node(adv76xx_of_id, client->dev.of_node);
…and add printk() statements within this to find out at which point the error occurs. Very likely it is either another statement which works on a pointer, or a copy related to a pointer.

Hello,

You are right, there was not copy_from_user or copy_to_user issue. but that problem get resolved now.

Please comment on the last query about node creation. I attached the log of problem area.

One more query I posted in the forum, Can you please comment on this: Reset on Jetson Tx2.

Regards,
Vikas Dwivedi

Were you able to fix this with a copy_ statement after finding the right place with printk()? If so, it might be useful to others to show the change you made.

As far as the other URL goes, I have no camera experience and am not really qualified to answer. All I could do is to suggest making sure any device tree changes you made were actually installed and active. You can examine device tree nodes in “/proc/device-tree/” and see if what you changed is there, but I have no ability to help beyond that.

Hello,

Thank you for your help as always.

First problem get resolved after finding right place with printk(). Problem was with compatibility name in the device tree.

Device tree changes I made is attached in the snippet below:

            i2c@2 {
            #address-cells = <1>;
            #size-cells = <0>;
 			adv7604_c@20 { 
				compatible = "adi,adv7604", "adi,adv7611", "adi,adv7612";
	      		reg = <0x20>, <0x42>, <0x40>, <0x3e>, <0x38>, <0x3c>, <0x26>, <0x32>, <0x36>, <0x34>, <0x30>, <0x22>, <0x24>;
				reg-names = "io", "avlink", "cec", "infoframe", "esdp", "epp", "afe", "rep", "edid", "hdmi", "test", "cp", "vdp";

The same changes I made in the ADV7604 probe function and of_device_id structure in the driver. Actually I am using kernel version 4.9.0 so no issue with copy_to_usr or copy_from_usr issue. L4T version is 4.2.2.

Here is my driver’s probe function:

static int adv76xx_probe(struct i2c_client *client,
		 const struct i2c_device_id *id)

{
static const struct v4l2_dv_timings cea1600x1200P60 =
V4L2_DV_BT_DMT_1600X1200P60; /* VD: Upated to support 1600x1200 @60Hz*/
struct adv76xx_state *state;
struct v4l2_ctrl_handler *hdl;
struct v4l2_ctrl *ctrl;
struct v4l2_subdev *sd;
unsigned int i;
unsigned int val, val2;
int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
v4l_dbg(1, debug, client, “detecting adv76xx client on address 0x%x\n”,
client->addr << 1);

state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
if (!state) {
	v4l_err(client, "Could not allocate adv76xx_state memory!\n");
	return -ENOMEM;
}
state->i2c_clients[ADV76XX_PAGE_IO] = client;

/* initialize variables */
state->restart_stdi_once = true;
state->selected_input = ~0;

if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) {

	const struct of_device_id *oid;

	oid = of_match_node(adv76xx_of_id, client->dev.of_node);

	if (oid == NULL){

		printk("VD: Match node value is null");
	}

	else{

	printk("VD: Match node value is not null");		
	
	}
	state->info = oid->data;

	err = adv76xx_parse_dt(state);
	if (err < 0) {
		v4l_err(client, "DT parsing error\n");
		return err;
	}
	else 
		printk("VD: Device tree parsed without error");

/*	const struct of_device_id *oid;
	
	printk("VD: Inside if");

	oid = of_match_node(adv76xx_of_id, client->dev.of_node);

	if (oid == NULL){
		client->dev.of_node = of_find_node_by_name(NULL, "adi,adv7604");
		printk("VD: manually node searched for ADV7604");
	}
	
	state->info = oid->data;
	printk("VD: Matching device node");

	printk("VD: Before parse_dt");
	err = adv76xx_parse_dt(state);
	if (err < 0) {
		v4l_err(client, "DT parsing error\n");
		return err;
	}*/
	printk("VD: Device tree parsed successfully");

} else if (client->dev.platform_data) {
	struct adv76xx_platform_data *pdata = client->dev.platform_data;
	printk("VD: Inside else-if before filling the platform data");
	state->info = (const struct adv76xx_chip_info *)id->driver_data;
	if (state->info == NULL)
	{
		printk("VD: Error in getting platform data");
	}
	
	state->pdata = *pdata;
	printk("VD: Platform data copied in state->pdata");
} else {
	v4l_err(client, "No platform data!\n");
	return -ENODEV;
}

/* Request GPIOs. */
for (i = 0; i < state->info->num_dv_ports; ++i) {
	state->hpd_gpio[i] =
		devm_gpiod_get_index_optional(&client->dev, "hpd", i,
					      GPIOD_OUT_LOW);
	if (IS_ERR(state->hpd_gpio[i]))
		return PTR_ERR(state->hpd_gpio[i]);

	if (state->hpd_gpio[i])
		v4l_info(client, "Handling HPD %u GPIO\n", i);
}
printk("VD: GPIO handeled successfully");
printk("VD: Making reset GPIO high");

state->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset",
							GPIOD_OUT_HIGH);
if (IS_ERR(state->reset_gpio))
	return PTR_ERR(state->reset_gpio);
printk("VD: Resetting Now............");

adv76xx_reset(state);

state->timings = cea1600x1200P60;					/* VD: Updated for 1600x1200 @60Hz */
state->format = adv76xx_format_info(state, MEDIA_BUS_FMT_RGB888_1X24); /* VD: Updated for SDR RGB888 as per the output channel selection sheet*/

sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &adv76xx_ops);
snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
	id->name, i2c_adapter_id(client->adapter),
	client->addr);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
sd->internal_ops = &adv76xx_int_ops;

/* Configure IO Regmap region */
err = configure_regmap(state, ADV76XX_PAGE_IO);

if (err) {
	v4l2_err(sd, "Error configuring IO regmap region\n");
	return -ENODEV;
}
else
	printk("VD: Configured IO regmap region");

/*
 * Verify that the chip is present. On ADV7604 the RD_INFO register only
 * identifies the revision, while on ADV7611 it identifies the model as
 * well. Use the HDMI slave address on ADV7604 and RD_INFO on ADV7611.
 */
//printk("device is:%s\n", state->info->type);
switch (state->info->type) {
case ADV7604:
	err = regmap_read(state->regmap[ADV76XX_PAGE_IO], 0xfb, &val);
	printk("VD: Inside ADV7604 case checking for reg IO Map");
	if (err) {
		v4l2_err(sd, "Error %d reading IO Regmap\n", err);
		return -ENODEV;
	}
	if (val != 0x68) {
		v4l2_err(sd, "not an adv7604 on address 0x%x\n",
				client->addr << 1);
		return -ENODEV;
	}
	printk("VD: Inside ADV7604 info->type");

	break;
case ADV7611:
case ADV7612:
	err = regmap_read(state->regmap[ADV76XX_PAGE_IO],
			0xea,
			&val);
	if (err) {
		v4l2_err(sd, "Error %d reading IO Regmap\n", err);
		return -ENODEV;
	}
	val2 = val << 8;
	err = regmap_read(state->regmap[ADV76XX_PAGE_IO],
		    0xeb,
		    &val);
	if (err) {
		v4l2_err(sd, "Error %d reading IO Regmap\n", err);
		return -ENODEV;
	}
	val |= val2;
	if ((state->info->type == ADV7611 && val != 0x2051) ||
		(state->info->type == ADV7612 && val != 0x2041)) {
		v4l2_err(sd, "not an adv761x on address 0x%x\n",
				client->addr << 1);
		return -ENODEV;
	}
	break;
}
	printk("VD: Before v4l2_ctrl_handler_init");

/* control handlers */
hdl = &state->hdl;
v4l2_ctrl_handler_init(hdl, adv76xx_has_afe(state) ? 9 : 8);

v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops,
		V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops,
		V4L2_CID_CONTRAST, 0, 255, 1, 128);
v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops,
		V4L2_CID_SATURATION, 0, 255, 1, 128);
v4l2_ctrl_new_std(hdl, &adv76xx_ctrl_ops,
		V4L2_CID_HUE, 0, 128, 1, 0);
ctrl = v4l2_ctrl_new_std_menu(hdl, &adv76xx_ctrl_ops,
		V4L2_CID_DV_RX_IT_CONTENT_TYPE, V4L2_DV_IT_CONTENT_TYPE_NO_ITC,
		0, V4L2_DV_IT_CONTENT_TYPE_NO_ITC);
if (ctrl)
	ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;

state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL,
		V4L2_CID_DV_RX_POWER_PRESENT, 0,
		(1 << state->info->num_dv_ports) - 1, 0, 0);
state->rgb_quantization_range_ctrl =
	v4l2_ctrl_new_std_menu(hdl, &adv76xx_ctrl_ops,
		V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
		0, V4L2_DV_RGB_RANGE_AUTO);

/* VD: Custom controls: 1. Analog sampling phase 2. Free run color manual 3. free run color */
if (adv76xx_has_afe(state))
	state->analog_sampling_phase_ctrl =
		v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_analog_sampling_phase, NULL);
state->free_run_color_manual_ctrl =
	v4l2_ctrl_new_custom(hdl, &adv76xx_ctrl_free_run_color_manual, NULL);
state->free_run_color_ctrl =
	v4l2_ctrl_new_custom(hdl, &adv76xx_ctrl_free_run_color, NULL);

sd->ctrl_handler = hdl;
if (hdl->error) {
	err = hdl->error;
	goto err_hdl;
}
if (adv76xx_s_detect_tx_5v_ctrl(sd)) {
	err = -ENODEV;
	goto err_hdl;
}
	printk("VD: Before I2C client create");

for (i = 1; i < ADV76XX_PAGE_MAX; ++i) {
	if (!(BIT(i) & state->info->page_mask))
		continue;

	state->i2c_clients[i] =
		adv76xx_dummy_client(sd, state->pdata.i2c_addresses[i],
				     0xf2 + i);
	if (state->i2c_clients[i] == NULL) {
		err = -ENOMEM;
		v4l2_err(sd, "failed to create i2c client %u\n", i);
		goto err_i2c;
	}
}

INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug,
		adv76xx_delayed_work_enable_hotplug);

state->source_pad = state->info->num_dv_ports
		  + (state->info->has_afe ? 2 : 0);
for (i = 0; i < state->source_pad; ++i){
	state->pads[i].flags = MEDIA_PAD_FL_SINK;
	printk(" VD: Inside the for loop counting MEDIA_PAD_FL_SINK ");
}
state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE;
//state->sd->entity.type = MEDIA_ENT_F_IF_VID_DECODER;
/* 
state->pad.flags = MEDIA_PAD_FL_SOURCE;
state->sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
	state->sd->entity.ops = &adv7482_media_ops;	
*/

/*
priv->subdev->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
priv->subdev->entity.ops = &imx185_media_ops;
err = tegra_media_entity_init(&priv->subdev->entity, 1,
			&priv->pad, true, true);

state->pad[0].flags = MEDIA_PAD_FL_SOURCE;
state->pad[1].flags = MEDIA_PAD_FL_SOURCE;
sd->entity.ops = &tc358840_media_ops


err = tegra_media_entity_init(&sd->entity, 2,
			state->pad, true, true);
if (err < 0) {
	dev_err(&client->dev, "unable to init media entity\n");
	return err;
}

*/
/* VD: updated because we were getting error for unknown device entity of ADV7604. so defined as V4L2 subdevice */
sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV;
sd->entity.function = MEDIA_ENT_F_CAM_HW;

err = media_entity_pads_init(&sd->entity, state->source_pad + 1,
			state->pads);

if (err){
	printk(" VD: media_entity_pads_init Failed ");
	goto err_work_queues;
	}
/* Configure regmaps */
err = configure_regmaps(state);
if (err){
	printk(" VD: configure_regmaps failed ");
	goto err_entity;
	}
err = adv76xx_core_init(sd);
if (err){
	printk(" VD: adv76xx_core_init failed ");
	goto err_entity;
	}

#if IS_ENABLED(CONFIG_VIDEO_ADV7604_CEC)
state->cec_adap = cec_allocate_adapter(&adv76xx_cec_adap_ops,
state, dev_name(&client->dev),
CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS |
CEC_CAP_PASSTHROUGH | CEC_CAP_RC, ADV76XX_MAX_ADDRS,
&client->dev);
err = PTR_ERR_OR_ZERO(state->cec_adap);
if (err)
goto err_entity;
#endif

v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
		client->addr << 1, client->adapter->name);
printk("VD: Before v4l2_async_register_subdev");
err = v4l2_async_register_subdev(sd);
if (err){
		printk(" VD: v4l2_async_register_subdev Error ");
		goto err_entity;
	}

else
	printk(" VD: ADV7604 driver probed successfully");


return 0;

err_entity:
media_entity_cleanup(&sd->entity);
err_work_queues:
cancel_delayed_work(&state->delayed_work_enable_hotplug);
err_i2c:
adv76xx_unregister_clients(state);
err_hdl:
v4l2_ctrl_handler_free(hdl);
return err;
}

/* ----------------------------------------------------------------------- */

I hope it will help others.

I don’t know what the effect of this will be. Is there a reason you are not using the NVIDIA kernel (4.9.140)?

When it comes to camera drivers I am not of much use, it isn’t something I’ve experimented with. However, if the original uaccess.h issue is fixed, you will probably want to start a new topic based on that. I simply do not know enough about cameras and video to help.

Hello,

This problem get resolved please refer my another thread vi-hasnt-found-active-link.

So as per my understanding now that if you haven’t written your device tree properly you will get Accessing user space memory outside uaccess.h routines error again and again.

So I don’t think so for this kernel version you have to replace any API with copy_from_user()

My kernel version is: 4.9.140-tegra-tegra.
L4T version is : 32.2.1

That would make sense: Trying to access user space without the proper copy would result in an error which is no different than if the kernel did not know the copy destination is not user space.