Segmentation fault when loading a driver as module

I have built a simple driver for a custom camera in the TX2 developer kit carrier board. Here is the driver:

/*
 * ar1335.c - ar1335 sensor driver
 *
 */

 #define DEBUG

#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>

#include <media/tegra_v4l2_camera.h>
#include <media/tegracam_core.h>
#define CREATE_TRACE_POINTS

static const struct of_device_id ar1335_of_match[] = {
	{ .compatible = "nvidia,ar1335",},
	{ },
};
MODULE_DEVICE_TABLE(of, ar1335_of_match);

static const struct regmap_config sensor_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
};

struct ar1335 {
	struct i2c_client	*i2c_client;
	struct v4l2_subdev	*subdev;
	struct camera_common_data	*s_data;
	struct tegracam_device		*tc_dev;
};

static struct tegracam_ctrl_ops ar1335_ctrl_ops = {
};

static struct camera_common_sensor_ops ar1335_common_ops = {
};

static int ar1335_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
	return 0;
}

static const struct v4l2_subdev_internal_ops ar1335_subdev_internal_ops = {
	.open = ar1335_open,
};

static int ar1335_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct device_node *node = dev->of_node;
	struct tegracam_device *tc_dev;
	struct ar1335 *priv;
	int err;

	dev_info(dev, "ar1335 probing v4l2 sensor.\n");

	if (!IS_ENABLED(CONFIG_OF) || !node)
		return -EINVAL;

	priv = devm_kzalloc(dev, sizeof(struct ar1335), GFP_KERNEL);
	if (!priv) {
		dev_err(dev, "unable to allocate memory!\n");
		return -ENOMEM;
	}
	tc_dev = devm_kzalloc(dev,
			sizeof(struct tegracam_device), GFP_KERNEL);
	if (!tc_dev)
		return -ENOMEM;

	priv->i2c_client = tc_dev->client = client;
	tc_dev->dev = dev;
	strncpy(tc_dev->name, "ar1335", sizeof(tc_dev->name));
	tc_dev->dev_regmap_config = &sensor_regmap_config;
	tc_dev->sensor_ops = &ar1335_common_ops;
	tc_dev->v4l2sd_internal_ops = &ar1335_subdev_internal_ops;
	tc_dev->tcctrl_ops = &ar1335_ctrl_ops;

	err = tegracam_device_register(tc_dev);
	if (err) {
		dev_info(dev, "tegra camera driver registration failed\n");
		dev_err(dev, "tegra camera driver registration failed\n");
		return err;
	}
	priv->tc_dev = tc_dev;
	priv->s_data = tc_dev->s_data;
	priv->subdev = &tc_dev->s_data->subdev;
	tegracam_set_privdata(tc_dev, (void *)priv);

	err = tegracam_v4l2subdev_register(tc_dev, true);
	if (err) {
		dev_info(dev, "tegra camera subdev registration failed\n");
		dev_err(dev, "tegra camera subdev registration failed\n");
		return err;
	}

	dev_info(&client->dev, "Detected AR1335 sensor\n");

	return 0;
}

static int
ar1335_remove(struct i2c_client *client)
{
	return 0;
}

static const struct i2c_device_id ar1335_id[] = {
	{ "ar1335", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, ar1335_id);

static struct i2c_driver ar1335_i2c_driver = {
	.driver = {
		.name = "ar1335",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(ar1335_of_match),
	},
	.probe = ar1335_probe,
	.remove = ar1335_remove,
	.id_table = ar1335_id,
};

module_i2c_driver(ar1335_i2c_driver);

MODULE_DESCRIPTION("Media Controller driver for AR1335");
MODULE_AUTHOR("NVIDIA Corporation");
MODULE_LICENSE("GPL v2");

When not registering the tegracam_device, the module can be successfully loaded and removed. I’ve modified the device tree too and flashed the kernel-dtb. Anyway, when registering the tegracam_device, I get the following error in the kernel:

[ 1205.850982] mar jul 23 12:55:58 CEST 2019
[ 1243.731901] ar1335 1-003c: ar1335 probing v4l2 sensor.
[ 1243.731967] Internal error: Attempting to execute userspace memory: 86000005 [#1] PREEMPT SMP
[ 1243.740495] Modules linked in: ar1335(O+) bnep fuse zram bcmdhd cfg80211 nvgpu bluedroid_pm ip_tables x_tables [last unloaded: ar1335]
[ 1243.752693] CPU: 4 PID: 9699 Comm: insmod Tainted: G           O    4.9.140-tegra #1
[ 1243.760420] Hardware name: quill (DT)
[ 1243.764074] task: ffffffc1564b2a00 task.stack: ffffffc1d9d44000
[ 1243.769983] PC is at 0x0
[ 1243.772514] LR is at tegracam_device_register+0xac/0x298
[ 1243.777815] pc : [<0000000000000000>] lr : [<ffffff8008b3e974>] pstate: 80400045
[ 1243.785194] sp : ffffffc1d9d47a30
[ 1243.788500] x29: ffffffc1d9d47a30 x28: 0000000000000018 
[ 1243.793823] x27: 0000000000000053 x26: 0000000000000030 
[ 1243.799142] x25: 0000000000000000 x24: ffffff8008f6b958 
[ 1243.804464] x23: ffffff8000f69040 x22: ffffffc1eb55b020 
[ 1243.809783] x21: ffffffc14fd7f458 x20: ffffffc1881adc18 
[ 1243.815102] x19: ffffffc1927a5018 x18: 0000000000000001 
[ 1243.820420] x17: 0000000000000000 x16: 0000000000000000 
[ 1243.825738] x15: ffffffffffffffff x14: ffffffc14fd7f68a 
[ 1243.831058] x13: 0000000000000000 x12: 0000000000000030 
[ 1243.836378] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f 
[ 1243.839601] x9 : 6364626d60756340 
[ 1243.839602] x8 : ffffffc14fd7f140 
[ 1243.839603] x7 : 0000000000000000 
[ 1243.839606] x6 : ffffff8009e5cf38 
[ 1243.839608] x5 : ffffffc1564b2a00 x4 : ffffffc1eb55b220 
[ 1243.839610] x3 : ffffffc14fd7f100 x2 : ffffffc14fd7f680 
[ 1243.839612] x1 : 0000000000000000 x0 : ffffffc1881adc18 

[ 1243.839616] Process insmod (pid: 9699, stack limit = 0xffffffc1d9d44000)
[ 1243.839617] Call trace:
[ 1243.839621] [<          (null)>]           (null)
[ 1243.839628] [<ffffff8000f690ec>] ar1335_probe+0xac/0x1b0 [ar1335]
[ 1243.839634] [<ffffff8008acf75c>] i2c_device_probe+0x144/0x258
[ 1243.839641] [<ffffff800876cdf8>] driver_probe_device+0xd8/0x408
[ 1243.839643] [<ffffff800876d204>] __driver_attach+0xdc/0x128
[ 1243.839646] [<ffffff800876a874>] bus_for_each_dev+0x5c/0xa8
[ 1243.839649] [<ffffff800876c5f8>] driver_attach+0x30/0x40
[ 1243.839651] [<ffffff800876c02c>] bus_add_driver+0x20c/0x2a8
[ 1243.839653] [<ffffff800876e13c>] driver_register+0x6c/0x110
[ 1243.839656] [<ffffff8008acfe4c>] i2c_register_driver+0x4c/0xb0
[ 1243.839660] [<ffffff8000f6c014>] ar1335_i2c_driver_init+0x14/0x30 [ar1335]
[ 1243.839663] [<ffffff8008083afc>] do_one_initcall+0x44/0x130
[ 1243.839667] [<ffffff80081c2ddc>] do_init_module+0x64/0x1a8
[ 1243.839670] [<ffffff80081581dc>] load_module+0x10a4/0x12d8
[ 1243.839672] [<ffffff80081586c0>] SyS_finit_module+0xd8/0xf0
[ 1243.839674] [<ffffff80080838c0>] el0_svc_naked+0x34/0x38
[ 1243.839678] ---[ end trace 6a0f6031f93cf57d ]---

Any idea why is this happening?

Is this R28.x.x or R32.x?

In R28 we encountered difficulty with camera drivers as modules. In R32 I believe camera drivers work as modules.

It’s R32.2, but it happened in R32.1 too. Didn’t test in R28.x.

Hi euskadi,

It looks currently the tegracam_device supports only Bayer sensor driver.The support for YUV sensor might get add in future.Since you are using YUV sensor,the sensor driver have to use camera_common until the support will get added in future release.

Hi Euskadi,

Have you fixed the segmentation problem? I am also facing the same problem. How to fix this?

Best,
Jebaraj

I have no knowledge of the particular driver, but not all drivers can be built as a module. If you use something like “make nconfig”, and the “=m” option is not there, then this is not a candidate…the module code does not exist in such cases.