I am trying to add a new IIO sensor driver to the kernel source and build it into the existing kernel. In particular I am trying to utilize the IIO device drivers from ST in the LSM6DS family that are multi-functional IIO devices. This is not uncommon as many IIO devices on the market support several functions within the same device. These devices work by having a core framework that allows access to multiple features of the chip all using the same hardware interface. They then allocate (iio_device_alloc) and register (iio_device_register) multiple IIO devices that have the core device as the parent of the IIO devices.
However, the changes by NVIDIA here in the latest 4.9 kernel nv-tegra: linux-4.9: iio: core: add Android L support for sensors to industrialio-core.c cause issues with multi-function IIO device drivers that have a single parent device. The changes appear to be NVIDIA specific and related to the NVS (NVIDIA Sensor) support and do not exist in upstream kernels, and are possibly only for Android.
I have tested with JetPack 4.4 Developer Preview (L4T R32.4.2) release and I get the following kernel error from the industrialio-core.c in iio_device_register() @ sysfs_create_link() line 1597 when the second iio_dev gets registered with the same parent:
It appears the problem exists on all version of L4T that are using the 4.9 kernel.
The extra call to sysfs_create_link() that NVIDIA added to the industrialio-core.c iio_device_register() function, does not seem necessary. All it looks like it is doing is creating a link iio_device -> iio:deviceX in the parent device’s sysfs directory, which does not seem necessary or that helpful.
Can the calls to sysfs_create_link/sysfs_delete_link() that NVIDIA added in industrialio-core.c be completely removed?
Or if the symbolic link needs to be created for some Android API, can the error condition on failure at least be downgraded from an error condition that causes a failed iio_device_register() to just a warning message?
The reason the IIO modifications were made were to allow a multi-device part, e.g. a chip with multiple sensors, to “virtualize” each sensor as a single chip which would then load a virtualized driver for that sensor. This is strictly a NVS (NVidia Sensor) framework feature at the kernel level.
If you are not using any NVS kernel drivers, then this modification can be removed.
Is there a reason that the symlink(s) in the parent device have to be created each time iio_device_register() is called?
Why does the iio_dev->dev.type have to be changed? What was wrong with the old method of using the link_name exclusively to setup and configure the symlinks?
Would NVIDIA be open to a patch submission that would maintain the special functionality with the symlink creation for users calling nvs_device_alloc() API and all other users going through the standard kernel API iio_device_alloc() not getting the symlink created? If yes, I can submit my change here or wherever that would be appropriate, if someone (yourself) would consider merging it into the official NVIDIA Linux kernel.
Wait for device to boot with new Kernel Image that includes the ST LSM6DSO accel/gyro driver built-in
Manually add a new fake lsm6dso I2C device using the sysfs interface on bus 2: sudo bash -c "echo lsm6dso 0x6a > /sys/bus/i2c/devices/i2c-2/new_device"
The kernel will log an error message that occurred in the iio core code:
I built and verified with the L4T 32.4.2 kernel that 0001-iio-core-Remove-NVS-multi-link.patch does fix the issue I was having with the iio symlinks (all but in a different/cleaner way than my original change). I do not have CONFIG_NVS set in my kernel configuration. So I only did a code review of 0001-nvs-core-Remove-multi-link.patch and it should work properly.
Will these be merged into the git tree or do they still have to undergo more review?