i2c child devices: binding to uio device driver

Thomas De Schampheleire patrickdepinguin+devicetree at gmail.com
Mon May 23 18:13:54 EST 2011


Hi Grant,

On Thu, May 19, 2011 at 5:58 PM, Grant Likely <grant.likely at secretlab.ca> wrote:
> On Thu, May 19, 2011 at 05:32:32PM +0200, Thomas De Schampheleire wrote:
>> Hi,
>>
>> I am using the uio framework (userspace i/o) to handle devices in
>> userspace. This includes memory access and interrupt handling.
>> For i2c devices, I'm using the i2c-dev interface, to talk to these
>> devices from userspace. This already works fine.
>>
>> One of my i2c devices also has an interrupt line connected to the
>> processor. To be able to handle this interrupt with uio, I need to
>> have a kernel driver matched against the i2c device. However, the i2c
>> device described in the device tree does not bind with the driver. Is
>> this behavior supported, and if so, what am I doing wrong? Do I have
>> to create a dummy bus (non-i2c) and add a shadow node for the
>> interrupt?
>
> You're wandering into new territory here.  It is definitely the right
> thing to do to describe your i2c device in the device tree with the
> interrupt fully specified.
>
> What you probably need to do is create a uio helper driver for your
> device that takes care of finding the device node, mapping the
> interrupt, and proving the interrupt handling UIO hook to userspace.
> The easiest way to work this out would be to make your uio helper
> actually bind to the i2c device created by the device node (this is
> probably the best way too), but you don't have to.  As long as you
> arrange for you uio helper to get called at some point, you can get it
> to find the appropriate node in the DT, map the interrupt, and export
> it to userspace.

Binding the helper driver with the i2c device in the device tree is
indeed what I am trying to achieve. Unfortunately, the binding does
not happen, the probe function of my driver never gets called.

For the other UIO devices in this system (non-I2C), the mechanism is as follows:
1. the devices are described in the device tree, as children under
their respective bus node (e.g. localbus)
2. the platform code (arch/powerpc/platforms/85xx/corenet_ds.c)
iterates over all buses it understands, among which 'simple-bus'.
3. for each child device on the bus, a bind operation with a driver is
attempted, based on the device 'compatible' string

This works perfectly.
However, the i2c bus does not have any of the matched bus types, like
simple-bus, and as such it is handled differently. The i2c bus driver
(drivers/i2c/busses/i2c-mpc.c) calls of_register_i2c_devices (in
drivers/of/of_i2c.c), which handles the i2c-specific part of the
device, but does not (as far as I understand and observe) treat the
device as a regular device with a match table.

Maybe I misunderstand something. Is this where I need to play with
modaliases? How does this work in the context of device trees?

>
> g.
>
>>
>> My device tree nodes look like this:
>>
>>         soc at fe000000 {
>>                 i2c at 118100 {
>>                         #address-cells = <1>;
>>                         #size-cells = <0>;
>>                         cell-index = <1>;
>>                         compatible = "fsl-i2c";
>>                         reg = <0x118100 0x100>;
>>                         interrupts = <38 2 0 0>;
>>                         dfsrr;
>>                         mydevice at 68 {
>>                                 compatible = "mymanufacturer,mydevice";
>>                                 reg = <0x68>;
>>                                 interrupts = <7 1 0 0>; /* External
>> IRQ7, active-low level */
>>                         };
>>                 };
>
> This looks to be correct.
>
>>
>> The device driver then has:
>>
>> static const struct of_device_id mydevice_ids[] = {
>>         {
>>                 .compatible = "mymanufacturer,mydevice"
>>         },
>>         {},
>> };
>> static struct of_platform_driver mydevice_driver = {
>
> You don't want to do this.  This is an i2c device, not a platform
> device.  If anything, this should be an i2c_driver and you should use
> the normal creation of i2c devices from the DT.

Ok, so this may be the reason why my driver does not get registered
against the device...

>
> BTW, of_platform_driver is deprecated and is just a wrapper around
> plain platform_driver on recent kernels.  platform_driver should be
> used directly now.

Yes, I heard about this change. But if I recall correctly, this change
is not yet in 2.6.34, right?

Thanks,
Thomas


More information about the devicetree-discuss mailing list