X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fi2c%2Fi2c-core.c;h=42e852d79ffaa5b001dda2c44219cad064a537e7;hb=a45fbc33137b11e479ea8b7d478a1d7e6488971b;hp=b346a687ab593a89834270e64b91f2b8b1c4c66f;hpb=63e5c39859a41591662466028c4d1281c033c05a;p=linux-2.6-omap-h63xx.git diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b346a687ab5..42e852d79ff 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -437,6 +437,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap) { int res = 0, dummy; + /* Can't register until after driver model init */ + if (unlikely(WARN_ON(!i2c_bus_type.p))) + return -EAGAIN; + mutex_init(&adap->bus_lock); mutex_init(&adap->clist_lock); INIT_LIST_HEAD(&adap->clients); @@ -696,6 +700,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) { int res; + /* Can't register until after driver model init */ + if (unlikely(WARN_ON(!i2c_bus_type.p))) + return -EAGAIN; + /* new style driver methods can't mix with legacy ones */ if (is_newstyle_driver(driver)) { if (driver->attach_adapter || driver->detach_adapter @@ -978,7 +986,10 @@ static void __exit i2c_exit(void) bus_unregister(&i2c_bus_type); } -subsys_initcall(i2c_init); +/* We must initialize early, because some subsystems register i2c drivers + * in subsys_initcall() code, but are linked (and initialized) before i2c. + */ +postcore_initcall(i2c_init); module_exit(i2c_exit); /* ---------------------------------------------------- @@ -1676,6 +1687,28 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) } EXPORT_SYMBOL(i2c_smbus_write_word_data); +/** + * i2c_smbus_process_call - SMBus "process call" protocol + * @client: Handle to slave device + * @command: Byte interpreted by slave + * @value: 16-bit "word" being written + * + * This executes the SMBus "process call" protocol, returning negative errno + * else a 16-bit unsigned "word" received from the device. + */ +s32 i2c_smbus_process_call(struct i2c_client *client, u8 command, u16 value) +{ + union i2c_smbus_data data; + int status; + data.word = value; + + status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, + I2C_SMBUS_WRITE, command, + I2C_SMBUS_PROC_CALL, &data); + return (status < 0) ? status : data.word; +} +EXPORT_SYMBOL(i2c_smbus_process_call); + /** * i2c_smbus_read_block_data - SMBus "block read" protocol * @client: Handle to slave device