return rc;
}
-static struct bus_type i2c_bus_type = {
+struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
.suspend = i2c_bus_suspend,
return 0;
}
-static void i2c_adapter_dev_release(struct device *dev)
+void i2c_adapter_dev_release(struct device *dev)
{
struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
complete(&adap->dev_released);
}
-static struct device_driver i2c_adapter_driver = {
+struct device_driver i2c_adapter_driver = {
.name = "i2c_adapter",
.bus = &i2c_bus_type,
.probe = i2c_device_probe,
complete(&adap->class_dev_released);
}
-static struct class i2c_adapter_class = {
+struct class i2c_adapter_class = {
.name = "i2c-adapter",
.release = &i2c_adapter_class_dev_release,
};
goto out_unlock;
}
- res = idr_get_new(&i2c_adapter_idr, NULL, &id);
+ res = idr_get_new(&i2c_adapter_idr, adap, &id);
if (res < 0) {
if (res == -EAGAIN)
res = -ENOMEM;
strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE);
class_device_register(&adap->class_dev);
+ dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);
+
/* inform drivers of new adapters */
list_for_each(item,&drivers) {
driver = list_entry(item, struct i2c_driver, list);
driver->attach_adapter(adap);
}
- dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr);
-
out_unlock:
up(&core_lists);
return res;
break;
}
if (adap_from_list != adap) {
- pr_debug("I2C: Attempting to delete an unregistered "
- "adapter\n");
+ pr_debug("i2c-core: attempting to delete unregistered "
+ "adapter [%s]\n", adap->name);
res = -EINVAL;
goto out_unlock;
}
driver = list_entry(item, struct i2c_driver, list);
if (driver->detach_adapter)
if ((res = driver->detach_adapter(adap))) {
- dev_warn(&adap->dev, "can't detach adapter "
- "while detaching driver %s: driver not "
- "detached!", driver->name);
+ dev_err(&adap->dev, "detach_adapter failed "
+ "for driver [%s]\n", driver->name);
goto out_unlock;
}
}
* must be deleted, as this would cause invalid states.
*/
if ((res=client->driver->detach_client(client))) {
- dev_err(&adap->dev, "adapter not "
- "unregistered, because client at "
- "address %02x can't be detached. ",
+ dev_err(&adap->dev, "detach_client failed for client "
+ "[%s] at address 0x%02x\n", client->name,
client->addr);
goto out_unlock;
}
/* free dynamically allocated bus id */
idr_remove(&i2c_adapter_idr, adap->nr);
- dev_dbg(&adap->dev, "adapter unregistered\n");
+ dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
out_unlock:
up(&core_lists);
goto out_unlock;
list_add_tail(&driver->list,&drivers);
- pr_debug("i2c-core: driver %s registered.\n", driver->name);
+ pr_debug("i2c-core: driver [%s] registered\n", driver->name);
/* now look for instances of driver on our adapters */
if (driver->flags & I2C_DF_NOTIFY) {
/* Have a look at each adapter, if clients of this driver are still
* attached. If so, detach them to be able to kill the driver
* afterwards.
- */
- pr_debug("i2c-core: unregister_driver - looking for clients.\n");
- /* removing clients does not depend on the notify flag, else
+ *
+ * Removing clients does not depend on the notify flag, else
* invalid operation might (will!) result, when using stale client
* pointers.
*/
list_for_each(item1,&adapters) {
adap = list_entry(item1, struct i2c_adapter, list);
- dev_dbg(&adap->dev, "examining adapter\n");
if (driver->detach_adapter) {
if ((res = driver->detach_adapter(adap))) {
- dev_warn(&adap->dev, "while unregistering "
- "dummy driver %s, adapter could "
- "not be detached properly; driver "
- "not unloaded!",driver->name);
+ dev_err(&adap->dev, "detach_adapter failed "
+ "for driver [%s]\n", driver->name);
goto out_unlock;
}
} else {
client = list_entry(item2, struct i2c_client, list);
if (client->driver != driver)
continue;
- pr_debug("i2c-core.o: detaching client %s:\n", client->name);
+ dev_dbg(&adap->dev, "detaching client [%s] "
+ "at 0x%02x\n", client->name,
+ client->addr);
if ((res = driver->detach_client(client))) {
- dev_err(&adap->dev, "while "
- "unregistering driver "
- "`%s', the client at "
- "address %02x of "
- "adapter could not "
- "be detached; driver "
- "not unloaded!",
- driver->name,
+ dev_err(&adap->dev, "detach_client "
+ "failed for client [%s] at "
+ "0x%02x\n", client->name,
client->addr);
goto out_unlock;
}
driver_unregister(&driver->driver);
list_del(&driver->list);
- pr_debug("i2c-core: driver unregistered: %s\n", driver->name);
+ pr_debug("i2c-core: driver [%s] unregistered\n", driver->name);
out_unlock:
up(&core_lists);
if (adapter->client_register) {
if (adapter->client_register(client)) {
- dev_warn(&adapter->dev, "warning: client_register "
- "seems to have failed for client %02x\n",
- client->addr);
+ dev_dbg(&adapter->dev, "client_register "
+ "failed for client [%s] at 0x%02x\n",
+ client->name, client->addr);
}
}
- dev_dbg(&adapter->dev, "client [%s] registered to adapter\n",
- client->name);
-
if (client->flags & I2C_CLIENT_ALLOW_USE)
client->usage_count = 0;
snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
"%d-%04x", i2c_adapter_id(adapter), client->addr);
- pr_debug("registering %s\n", client->dev.bus_id);
+ dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
+ client->name, client->dev.bus_id);
device_register(&client->dev);
device_create_file(&client->dev, &dev_attr_client_name);
struct i2c_adapter *adapter = client->adapter;
int res = 0;
- if ((client->flags & I2C_CLIENT_ALLOW_USE) && (client->usage_count > 0))
+ if ((client->flags & I2C_CLIENT_ALLOW_USE)
+ && (client->usage_count > 0)) {
+ dev_warn(&client->dev, "Client [%s] still busy, "
+ "can't detach\n", client->name);
return -EBUSY;
+ }
if (adapter->client_unregister) {
res = adapter->client_unregister(client);
if (res) {
dev_err(&client->dev,
- "client_unregister [%s] failed, "
- "client not detached", client->name);
+ "client_unregister [%s] failed, "
+ "client not detached\n", client->name);
goto out;
}
}
* Will not work for 10-bit addresses!
* ----------------------------------------------------
*/
+/* Return: kind (>= 0) if force found, -1 if not found */
+static inline int i2c_probe_forces(struct i2c_adapter *adapter, int addr,
+ unsigned short **forces)
+{
+ unsigned short kind;
+ int j, adap_id = i2c_adapter_id(adapter);
+
+ for (kind = 0; forces[kind]; kind++) {
+ for (j = 0; forces[kind][j] != I2C_CLIENT_END; j += 2) {
+ if ((forces[kind][j] == adap_id ||
+ forces[kind][j] == ANY_I2C_BUS)
+ && forces[kind][j + 1] == addr) {
+ dev_dbg(&adapter->dev, "found force parameter, "
+ "addr 0x%02x, kind %u\n", addr, kind);
+ return kind;
+ }
+ }
+ }
+
+ return -1;
+}
+
int i2c_probe(struct i2c_adapter *adapter,
struct i2c_client_address_data *address_data,
int (*found_proc) (struct i2c_adapter *, int, int))
at all */
found = 0;
- for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 2) {
- if (((adap_id == address_data->force[i]) ||
- (address_data->force[i] == ANY_I2C_BUS)) &&
- (addr == address_data->force[i+1])) {
- dev_dbg(&adapter->dev, "found force parameter for adapter %d, addr %04x\n",
- adap_id, addr);
- if ((err = found_proc(adapter,addr,0)))
+ if (address_data->forces) {
+ int kind = i2c_probe_forces(adapter, addr,
+ address_data->forces);
+ if (kind >= 0) { /* force found */
+ if ((err = found_proc(adapter, addr, kind)))
return err;
- found = 1;
+ continue;
}
}
- if (found)
- continue;
/* If this address is in one of the ignores, we can forget about
it right now */
return 0;
}
-/*
- * return id number for a specific adapter
- */
-int i2c_adapter_id(struct i2c_adapter *adap)
-{
- return adap->nr;
-}
-
struct i2c_adapter* i2c_get_adapter(int id)
{
- struct list_head *item;
struct i2c_adapter *adapter;
down(&core_lists);
- list_for_each(item,&adapters) {
- adapter = list_entry(item, struct i2c_adapter, list);
- if (id == adapter->nr &&
- try_module_get(adapter->owner)) {
- up(&core_lists);
- return adapter;
- }
- }
+ adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
+ if (adapter && !try_module_get(adapter->owner))
+ adapter = NULL;
+
up(&core_lists);
- return NULL;
+ return adapter;
}
void i2c_put_adapter(struct i2c_adapter *adap)
}
+/* Next four are needed by i2c-isa */
+EXPORT_SYMBOL_GPL(i2c_adapter_dev_release);
+EXPORT_SYMBOL_GPL(i2c_adapter_driver);
+EXPORT_SYMBOL_GPL(i2c_adapter_class);
+EXPORT_SYMBOL_GPL(i2c_bus_type);
+
EXPORT_SYMBOL(i2c_add_adapter);
EXPORT_SYMBOL(i2c_del_adapter);
EXPORT_SYMBOL(i2c_add_driver);
EXPORT_SYMBOL(i2c_master_recv);
EXPORT_SYMBOL(i2c_control);
EXPORT_SYMBOL(i2c_transfer);
-EXPORT_SYMBOL(i2c_adapter_id);
EXPORT_SYMBOL(i2c_get_adapter);
EXPORT_SYMBOL(i2c_put_adapter);
EXPORT_SYMBOL(i2c_probe);