Hi Daniel,
thanks for the infos!

The code to register the platform device is in a arch_initcall:

struct platform_device jz_i2c_device = {
        .name = "jz_i2c",
        .id = 0,
        .dev = {
                .dma_mask               = &jz_i2c_dmamask,
                .coherent_dma_mask      = 0xffffffff,
        },
        .num_resources  = ARRAY_SIZE(jz_i2c_resources),
        .resource       = jz_i2c_resources,
};

/* All */

static struct platform_device *jz_platform_devices[] __initdata = {
        &jz_usb_ohci_device,
        &jz_lcd_device,
        &jz_usb_gdt_device,
        &jz_mmc_device,
        &jz_i2c_device,
};

static int __init jz_platform_init(void)
{
        printk(KERN_DEBUG "adding jz platform devices\n");
        int ret = platform_add_devices(jz_platform_devices, 
ARRAY_SIZE(jz_platform_devices));
        printk(KERN_DEBUG "i2c_get_adapter() -> %p\n", i2c_get_adapter(0));
        return ret;
}

arch_initcall(jz_platform_init);

The code behind i2c_get_adapter(0) is:

struct i2c_adapter* i2c_get_adapter(int id)
{
        struct i2c_adapter *adapter;

        mutex_lock(&core_lists);
        adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
        if (adapter && !try_module_get(adapter->owner))
                adapter = NULL;

        mutex_unlock(&core_lists);
        return adapter;
}
EXPORT_SYMBOL(i2c_get_adapter);

So I think it looks for the id field of the jz_i2c_device which should be 0 but
it is not found.


Am 11.09.2010 um 00:37 schrieb Daniel Glöckner:

> On Fri, Sep 10, 2010 at 09:54:57PM +0200, Dr. H. Nikolaus Schaller wrote:
>> Does anyone have an idea or knowledge how initialization of the
>> i2c subsystem really works in the 2.6.24 kernel?
>> 
>> As far as I did understand, the platform initialization file just registers
>> a i2c adapter in some list but does not touch it.
>> 
>> The function i2c_get_adapter() should search this list to identify the driver
>> according to some "id" value (which one is this? How is it related to
>> the initialization structure in the platform file?).
> 
> - arch_initcall causes jz_platform_init to be executed
> - it registers a platform device with id 0
> - module_init later causes i2c_adap_jz_init to be called
> - it registers a platform driver
> - during registration the list of devices is scanned and all devices
>  with the correct name "jz_i2c" are probed
> - this causes i2c_jz_probe to be called
> - it takes the id from the platform_device structure and puts it into
>  the adapter's nr field.
> - then the adapter is registered, giving it that number
> 
>> Then, the first device that is probed initializes the i2c adapter.
>> But that is far beyond the first call to the old-style i2c_open(), i.e.
>> the adapter is not initialized.
> 
> The problem is that module_init is way too late for an i2c adapter.
> Try subsys_initcall instead.

The problem is that there are some hack-style drivers using
i2c_open() where I don't even know when the drivers are initialized.

Well, we could rewrite them to be friendly new-style drivers and
completely get rid of the i2c_open calls, but in a first step I would
like to make them work again to better understand their function.

Do you think I think I can add a call to i2c_jz_probe() to the i2c_open() 
wrapper? After I finally manage to find the adapter through i2_get_adapter(0)?

Or do you mean changeing the module_init(i2c_adap_jz_init); to
subsys_initcall(i2c_adap_jz_init); ?

BR,
Nikolaus
_______________________________________________
Mipsbook-devel mailing list
Mipsbook-devel@linuxtogo.org
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/mipsbook-devel

Reply via email to