On Tue, Jan 12, 2021 at 12:24 PM Bill Mills bill.mills@linaro.org wrote:
On 1/12/21 5:57 AM, Viresh Kumar via Stratos-dev wrote:
On 16-12-20, 14:54, Arnd Bergmann wrote:
The problem we get into though is once we try to make this work for arbitrary i2c or spi devices. The kernel has around 1400 such drivers, and usually we use a device tree description based on a unique string for every such device plus additional properties for things like gpio lines or out-of-band interrupts.
If we want to use greybus manifests in place of device trees, that means either needing to find a way to map DT properties into the manifest, or have the same data in another format for each device we might want to use behind greybus, and adapting the corresponding drivers to understand this additional format.
I am a bit confused about this. I don't think we need to expose all that information over the manifest.
The SPI controller will be accessible by the host OS (lets say both host and guest run Linux), the host will give/pass a manifest to the guest and the guest will send simple commands like read/write to the host. The Guest doesn't need minute details of how the controller is getting programmed, which is the responsibility of the host side controller driver which will have all this information from the DT passed from bootloader anyway. And so the manifest shouldn't be required to have equivalent of all DT properties.
Isn't it ?
Yes for the interrupt for the SPI or I2C controller.
I presume Arnd is talking about side band signals from the devices. I2C and SPI don't have a client side concept of interrupt and the originator side (trying to not use the word master) would have to poll otherwise. So many devices hook up a side band interrupt request to a GPIO. Likewise an I2C EEPROM may have a write protect bit that is controlled by a GPIO.
Coordinating this between a virtual I2C and a virtual GPIO bank would be complicated to do in the manifest if each is a separate device.
However if we expand the definition of "I2C virtual device" to have an interrupt request line and a couple outputs, the details are in fact on the host side and the guest does not need to understand it all.
What would this mean for the 1400 devices in the kernel? Would we need to add a Greybus binding to the existing DT binding? That sounds like the wrong way. It would be nice to leverage the DT binding that was already in the kernel.
I believe the majority of the devices are fairly simple, and the main thing they need is a character string for identification to work around the lack of a device/vendor ID mechanism that PCI or USB use.
The kernel supports three string based identification methods at the moment. Take a minimal wrapper like drivers/iio/imu/bmi160/bmi160_i2c.c as an example, where we have
static const struct i2c_device_id bmi160_i2c_id[] = { {"bmi160", 0}, {} }; MODULE_DEVICE_TABLE(i2c, bmi160_i2c_id);
static const struct acpi_device_id bmi160_acpi_match[] = { {"BMI0160", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match);
#ifdef CONFIG_OF static const struct of_device_id bmi160_of_match[] = { { .compatible = "bosch,bmi160" }, { }, }; MODULE_DEVICE_TABLE(of, bmi160_of_match); #endif
static struct i2c_driver bmi160_i2c_driver = { .driver = { .name = "bmi160_i2c", .acpi_match_table = ACPI_PTR(bmi160_acpi_match), .of_match_table = of_match_ptr(bmi160_of_match), }, .probe = bmi160_i2c_probe, .id_table = bmi160_i2c_id, }; module_i2c_driver(bmi160_i2c_driver);
The "i2c_device_id" structure has a list of strings that is unique in the Linux kernel but not standardized. I assume a greybus driver would be used to map the numbers from the manifest into this OS specific string, but this has to be done for each supported device that can be attached to a greybus device.
The "of_device_id" is a similar list but meant to be globally unique through the DT binding.
I hear that ACPI can bind to SPI and I2C. Is this true and how does that work?? (I ask for a reference. I am NOT suggesting we bring ACPI into this.)
The acpi_device_id has the same purpose as of_device_id, but uses a different namespace and is only used on PC-style machines.
$ git grep -wl "i2c_driver|spi_driver" drivers sound | wc -l 1424 $ git grep -wl "i2c_driver|spi_driver" drivers sound | xargs git grep -l of_device_id | wc -l 876 $ git grep -wl "i2c_driver|spi_driver" drivers sound | xargs git grep -l acpi_device_id | wc -l 145
Arnd