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 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.)
It would be great if we had connector based DT in the kernel. Then you could generate a DT fragment for the virtual multifunction vPCI device and apply it at Greybus enumeration.
Didn't project Ara have this problem? Did it have a solution?
-- Bill
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
On 12-01-21, 06:24, Bill Mills wrote:
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.
Right and this bit controlled by GPIO needs to be handled by the host side driver, i.e. the regular driver for the controller's IP and not the greybus code. The guest of course shouldn't be required to do anything about this and shouldn't even know how the devices are connected.
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 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.)
It would be great if we had connector based DT in the kernel. Then you could generate a DT fragment for the virtual multifunction vPCI device and apply it at Greybus enumeration.
Didn't project Ara have this problem? Did it have a solution?
ARA was a bit different (the opposite) as the real hardware was controlled by the firmware running on the module and kernel doesn't need to know about the minute details. All it cares about is the transfers and not how they are done. And this is exactly what should be done here IMO.
On 12-01-21, 15:47, Arnd Bergmann wrote:
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
I am not sure I follow what we are discussing here, must be something I am missing.
But from my point of view, the guest OS will always use the same i2c driver irrespective of the controller IP used:
drivers/staging/greybus/i2c.c
While the host will keep using the controller specific drivers + something that connects them to the greybus message receiver.
On Fri, Jan 15, 2021 at 9:10 AM Viresh Kumar viresh.kumar@linaro.org wrote:
On 12-01-21, 15:47, Arnd Bergmann wrote:
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
I am not sure I follow what we are discussing here, must be something I am missing.
But from my point of view, the guest OS will always use the same i2c driver irrespective of the controller IP used:
drivers/staging/greybus/i2c.c
While the host will keep using the controller specific drivers + something that connects them to the greybus message receiver.
What I'm talking about above is the driver for the i2c slave device that is attached to the i2c controller. We would always just use one i2c controller driver (greybus or virtio) for any slave, but as i2c has no built-in discovery mechanism, the kernel still needs to be told what is attached to it.
Arnd
stratos-dev@op-lists.linaro.org