diff options
Diffstat (limited to 'drivers/i2c/i2c-core.c')
| -rw-r--r-- | drivers/i2c/i2c-core.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index bea4c5021d26..d231f683f576 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -425,14 +425,14 @@ static int __i2c_check_addr_busy(struct device *dev, void *addrp) | |||
| 425 | /* walk up mux tree */ | 425 | /* walk up mux tree */ |
| 426 | static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr) | 426 | static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr) |
| 427 | { | 427 | { |
| 428 | struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); | ||
| 428 | int result; | 429 | int result; |
| 429 | 430 | ||
| 430 | result = device_for_each_child(&adapter->dev, &addr, | 431 | result = device_for_each_child(&adapter->dev, &addr, |
| 431 | __i2c_check_addr_busy); | 432 | __i2c_check_addr_busy); |
| 432 | 433 | ||
| 433 | if (!result && i2c_parent_is_i2c_adapter(adapter)) | 434 | if (!result && parent) |
| 434 | result = i2c_check_mux_parents( | 435 | result = i2c_check_mux_parents(parent, addr); |
| 435 | to_i2c_adapter(adapter->dev.parent), addr); | ||
| 436 | 436 | ||
| 437 | return result; | 437 | return result; |
| 438 | } | 438 | } |
| @@ -453,11 +453,11 @@ static int i2c_check_mux_children(struct device *dev, void *addrp) | |||
| 453 | 453 | ||
| 454 | static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) | 454 | static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) |
| 455 | { | 455 | { |
| 456 | struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); | ||
| 456 | int result = 0; | 457 | int result = 0; |
| 457 | 458 | ||
| 458 | if (i2c_parent_is_i2c_adapter(adapter)) | 459 | if (parent) |
| 459 | result = i2c_check_mux_parents( | 460 | result = i2c_check_mux_parents(parent, addr); |
| 460 | to_i2c_adapter(adapter->dev.parent), addr); | ||
| 461 | 461 | ||
| 462 | if (!result) | 462 | if (!result) |
| 463 | result = device_for_each_child(&adapter->dev, &addr, | 463 | result = device_for_each_child(&adapter->dev, &addr, |
| @@ -472,8 +472,10 @@ static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) | |||
| 472 | */ | 472 | */ |
| 473 | void i2c_lock_adapter(struct i2c_adapter *adapter) | 473 | void i2c_lock_adapter(struct i2c_adapter *adapter) |
| 474 | { | 474 | { |
| 475 | if (i2c_parent_is_i2c_adapter(adapter)) | 475 | struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); |
| 476 | i2c_lock_adapter(to_i2c_adapter(adapter->dev.parent)); | 476 | |
| 477 | if (parent) | ||
| 478 | i2c_lock_adapter(parent); | ||
| 477 | else | 479 | else |
| 478 | rt_mutex_lock(&adapter->bus_lock); | 480 | rt_mutex_lock(&adapter->bus_lock); |
| 479 | } | 481 | } |
| @@ -485,8 +487,10 @@ EXPORT_SYMBOL_GPL(i2c_lock_adapter); | |||
| 485 | */ | 487 | */ |
| 486 | static int i2c_trylock_adapter(struct i2c_adapter *adapter) | 488 | static int i2c_trylock_adapter(struct i2c_adapter *adapter) |
| 487 | { | 489 | { |
| 488 | if (i2c_parent_is_i2c_adapter(adapter)) | 490 | struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); |
| 489 | return i2c_trylock_adapter(to_i2c_adapter(adapter->dev.parent)); | 491 | |
| 492 | if (parent) | ||
| 493 | return i2c_trylock_adapter(parent); | ||
| 490 | else | 494 | else |
| 491 | return rt_mutex_trylock(&adapter->bus_lock); | 495 | return rt_mutex_trylock(&adapter->bus_lock); |
| 492 | } | 496 | } |
| @@ -497,8 +501,10 @@ static int i2c_trylock_adapter(struct i2c_adapter *adapter) | |||
| 497 | */ | 501 | */ |
| 498 | void i2c_unlock_adapter(struct i2c_adapter *adapter) | 502 | void i2c_unlock_adapter(struct i2c_adapter *adapter) |
| 499 | { | 503 | { |
| 500 | if (i2c_parent_is_i2c_adapter(adapter)) | 504 | struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter); |
| 501 | i2c_unlock_adapter(to_i2c_adapter(adapter->dev.parent)); | 505 | |
| 506 | if (parent) | ||
| 507 | i2c_unlock_adapter(parent); | ||
| 502 | else | 508 | else |
| 503 | rt_mutex_unlock(&adapter->bus_lock); | 509 | rt_mutex_unlock(&adapter->bus_lock); |
| 504 | } | 510 | } |
| @@ -677,8 +683,6 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, | |||
| 677 | char *blank, end; | 683 | char *blank, end; |
| 678 | int res; | 684 | int res; |
| 679 | 685 | ||
| 680 | dev_warn(dev, "The new_device interface is still experimental " | ||
| 681 | "and may change in a near future\n"); | ||
| 682 | memset(&info, 0, sizeof(struct i2c_board_info)); | 686 | memset(&info, 0, sizeof(struct i2c_board_info)); |
| 683 | 687 | ||
| 684 | blank = strchr(buf, ' '); | 688 | blank = strchr(buf, ' '); |
| @@ -1504,26 +1508,25 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) | |||
| 1504 | if (!driver->detect || !address_list) | 1508 | if (!driver->detect || !address_list) |
| 1505 | return 0; | 1509 | return 0; |
| 1506 | 1510 | ||
| 1511 | /* Stop here if the classes do not match */ | ||
| 1512 | if (!(adapter->class & driver->class)) | ||
| 1513 | return 0; | ||
| 1514 | |||
| 1507 | /* Set up a temporary client to help detect callback */ | 1515 | /* Set up a temporary client to help detect callback */ |
| 1508 | temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); | 1516 | temp_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); |
| 1509 | if (!temp_client) | 1517 | if (!temp_client) |
| 1510 | return -ENOMEM; | 1518 | return -ENOMEM; |
| 1511 | temp_client->adapter = adapter; | 1519 | temp_client->adapter = adapter; |
| 1512 | 1520 | ||
| 1513 | /* Stop here if the classes do not match */ | ||
| 1514 | if (!(adapter->class & driver->class)) | ||
| 1515 | goto exit_free; | ||
| 1516 | |||
| 1517 | for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) { | 1521 | for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) { |
| 1518 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " | 1522 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " |
| 1519 | "addr 0x%02x\n", adap_id, address_list[i]); | 1523 | "addr 0x%02x\n", adap_id, address_list[i]); |
| 1520 | temp_client->addr = address_list[i]; | 1524 | temp_client->addr = address_list[i]; |
| 1521 | err = i2c_detect_address(temp_client, driver); | 1525 | err = i2c_detect_address(temp_client, driver); |
| 1522 | if (err) | 1526 | if (unlikely(err)) |
| 1523 | goto exit_free; | 1527 | break; |
| 1524 | } | 1528 | } |
| 1525 | 1529 | ||
| 1526 | exit_free: | ||
| 1527 | kfree(temp_client); | 1530 | kfree(temp_client); |
| 1528 | return err; | 1531 | return err; |
| 1529 | } | 1532 | } |
