diff options
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 158 |
1 files changed, 118 insertions, 40 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index df937df845eb..6649176de940 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -20,7 +20,9 @@ | |||
20 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>. | 20 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>. |
21 | All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> | 21 | All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl> |
22 | SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and | 22 | SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and |
23 | Jean Delvare <khali@linux-fr.org> */ | 23 | Jean Delvare <khali@linux-fr.org> |
24 | Mux support by Rodolfo Giometti <giometti@enneenne.com> and | ||
25 | Michael Lawnick <michael.lawnick.ext@nsn.com> */ | ||
24 | 26 | ||
25 | #include <linux/module.h> | 27 | #include <linux/module.h> |
26 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
@@ -423,11 +425,87 @@ static int __i2c_check_addr_busy(struct device *dev, void *addrp) | |||
423 | return 0; | 425 | return 0; |
424 | } | 426 | } |
425 | 427 | ||
428 | /* walk up mux tree */ | ||
429 | static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr) | ||
430 | { | ||
431 | int result; | ||
432 | |||
433 | result = device_for_each_child(&adapter->dev, &addr, | ||
434 | __i2c_check_addr_busy); | ||
435 | |||
436 | if (!result && i2c_parent_is_i2c_adapter(adapter)) | ||
437 | result = i2c_check_mux_parents( | ||
438 | to_i2c_adapter(adapter->dev.parent), addr); | ||
439 | |||
440 | return result; | ||
441 | } | ||
442 | |||
443 | /* recurse down mux tree */ | ||
444 | static int i2c_check_mux_children(struct device *dev, void *addrp) | ||
445 | { | ||
446 | int result; | ||
447 | |||
448 | if (dev->type == &i2c_adapter_type) | ||
449 | result = device_for_each_child(dev, addrp, | ||
450 | i2c_check_mux_children); | ||
451 | else | ||
452 | result = __i2c_check_addr_busy(dev, addrp); | ||
453 | |||
454 | return result; | ||
455 | } | ||
456 | |||
426 | static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) | 457 | static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr) |
427 | { | 458 | { |
428 | return device_for_each_child(&adapter->dev, &addr, | 459 | int result = 0; |
429 | __i2c_check_addr_busy); | 460 | |
461 | if (i2c_parent_is_i2c_adapter(adapter)) | ||
462 | result = i2c_check_mux_parents( | ||
463 | to_i2c_adapter(adapter->dev.parent), addr); | ||
464 | |||
465 | if (!result) | ||
466 | result = device_for_each_child(&adapter->dev, &addr, | ||
467 | i2c_check_mux_children); | ||
468 | |||
469 | return result; | ||
470 | } | ||
471 | |||
472 | /** | ||
473 | * i2c_lock_adapter - Get exclusive access to an I2C bus segment | ||
474 | * @adapter: Target I2C bus segment | ||
475 | */ | ||
476 | void i2c_lock_adapter(struct i2c_adapter *adapter) | ||
477 | { | ||
478 | if (i2c_parent_is_i2c_adapter(adapter)) | ||
479 | i2c_lock_adapter(to_i2c_adapter(adapter->dev.parent)); | ||
480 | else | ||
481 | rt_mutex_lock(&adapter->bus_lock); | ||
482 | } | ||
483 | EXPORT_SYMBOL_GPL(i2c_lock_adapter); | ||
484 | |||
485 | /** | ||
486 | * i2c_trylock_adapter - Try to get exclusive access to an I2C bus segment | ||
487 | * @adapter: Target I2C bus segment | ||
488 | */ | ||
489 | static int i2c_trylock_adapter(struct i2c_adapter *adapter) | ||
490 | { | ||
491 | if (i2c_parent_is_i2c_adapter(adapter)) | ||
492 | return i2c_trylock_adapter(to_i2c_adapter(adapter->dev.parent)); | ||
493 | else | ||
494 | return rt_mutex_trylock(&adapter->bus_lock); | ||
495 | } | ||
496 | |||
497 | /** | ||
498 | * i2c_unlock_adapter - Release exclusive access to an I2C bus segment | ||
499 | * @adapter: Target I2C bus segment | ||
500 | */ | ||
501 | void i2c_unlock_adapter(struct i2c_adapter *adapter) | ||
502 | { | ||
503 | if (i2c_parent_is_i2c_adapter(adapter)) | ||
504 | i2c_unlock_adapter(to_i2c_adapter(adapter->dev.parent)); | ||
505 | else | ||
506 | rt_mutex_unlock(&adapter->bus_lock); | ||
430 | } | 507 | } |
508 | EXPORT_SYMBOL_GPL(i2c_unlock_adapter); | ||
431 | 509 | ||
432 | /** | 510 | /** |
433 | * i2c_new_device - instantiate an i2c device | 511 | * i2c_new_device - instantiate an i2c device |
@@ -633,9 +711,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr, | |||
633 | return -EINVAL; | 711 | return -EINVAL; |
634 | 712 | ||
635 | /* Keep track of the added device */ | 713 | /* Keep track of the added device */ |
636 | i2c_lock_adapter(adap); | 714 | mutex_lock(&adap->userspace_clients_lock); |
637 | list_add_tail(&client->detected, &adap->userspace_clients); | 715 | list_add_tail(&client->detected, &adap->userspace_clients); |
638 | i2c_unlock_adapter(adap); | 716 | mutex_unlock(&adap->userspace_clients_lock); |
639 | dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device", | 717 | dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device", |
640 | info.type, info.addr); | 718 | info.type, info.addr); |
641 | 719 | ||
@@ -674,7 +752,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
674 | 752 | ||
675 | /* Make sure the device was added through sysfs */ | 753 | /* Make sure the device was added through sysfs */ |
676 | res = -ENOENT; | 754 | res = -ENOENT; |
677 | i2c_lock_adapter(adap); | 755 | mutex_lock(&adap->userspace_clients_lock); |
678 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 756 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
679 | detected) { | 757 | detected) { |
680 | if (client->addr == addr) { | 758 | if (client->addr == addr) { |
@@ -687,7 +765,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
687 | break; | 765 | break; |
688 | } | 766 | } |
689 | } | 767 | } |
690 | i2c_unlock_adapter(adap); | 768 | mutex_unlock(&adap->userspace_clients_lock); |
691 | 769 | ||
692 | if (res < 0) | 770 | if (res < 0) |
693 | dev_err(dev, "%s: Can't find device in list\n", | 771 | dev_err(dev, "%s: Can't find device in list\n", |
@@ -714,10 +792,11 @@ static const struct attribute_group *i2c_adapter_attr_groups[] = { | |||
714 | NULL | 792 | NULL |
715 | }; | 793 | }; |
716 | 794 | ||
717 | static struct device_type i2c_adapter_type = { | 795 | struct device_type i2c_adapter_type = { |
718 | .groups = i2c_adapter_attr_groups, | 796 | .groups = i2c_adapter_attr_groups, |
719 | .release = i2c_adapter_dev_release, | 797 | .release = i2c_adapter_dev_release, |
720 | }; | 798 | }; |
799 | EXPORT_SYMBOL_GPL(i2c_adapter_type); | ||
721 | 800 | ||
722 | #ifdef CONFIG_I2C_COMPAT | 801 | #ifdef CONFIG_I2C_COMPAT |
723 | static struct class_compat *i2c_adapter_compat_class; | 802 | static struct class_compat *i2c_adapter_compat_class; |
@@ -760,7 +839,7 @@ static int __process_new_adapter(struct device_driver *d, void *data) | |||
760 | 839 | ||
761 | static int i2c_register_adapter(struct i2c_adapter *adap) | 840 | static int i2c_register_adapter(struct i2c_adapter *adap) |
762 | { | 841 | { |
763 | int res = 0, dummy; | 842 | int res = 0; |
764 | 843 | ||
765 | /* Can't register until after driver model init */ | 844 | /* Can't register until after driver model init */ |
766 | if (unlikely(WARN_ON(!i2c_bus_type.p))) { | 845 | if (unlikely(WARN_ON(!i2c_bus_type.p))) { |
@@ -769,6 +848,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
769 | } | 848 | } |
770 | 849 | ||
771 | rt_mutex_init(&adap->bus_lock); | 850 | rt_mutex_init(&adap->bus_lock); |
851 | mutex_init(&adap->userspace_clients_lock); | ||
772 | INIT_LIST_HEAD(&adap->userspace_clients); | 852 | INIT_LIST_HEAD(&adap->userspace_clients); |
773 | 853 | ||
774 | /* Set default timeout to 1 second if not already set */ | 854 | /* Set default timeout to 1 second if not already set */ |
@@ -801,8 +881,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
801 | 881 | ||
802 | /* Notify drivers */ | 882 | /* Notify drivers */ |
803 | mutex_lock(&core_lock); | 883 | mutex_lock(&core_lock); |
804 | dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, | 884 | bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); |
805 | __process_new_adapter); | ||
806 | mutex_unlock(&core_lock); | 885 | mutex_unlock(&core_lock); |
807 | 886 | ||
808 | return 0; | 887 | return 0; |
@@ -975,7 +1054,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
975 | return res; | 1054 | return res; |
976 | 1055 | ||
977 | /* Remove devices instantiated from sysfs */ | 1056 | /* Remove devices instantiated from sysfs */ |
978 | i2c_lock_adapter(adap); | 1057 | mutex_lock(&adap->userspace_clients_lock); |
979 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 1058 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
980 | detected) { | 1059 | detected) { |
981 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, | 1060 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, |
@@ -983,7 +1062,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
983 | list_del(&client->detected); | 1062 | list_del(&client->detected); |
984 | i2c_unregister_device(client); | 1063 | i2c_unregister_device(client); |
985 | } | 1064 | } |
986 | i2c_unlock_adapter(adap); | 1065 | mutex_unlock(&adap->userspace_clients_lock); |
987 | 1066 | ||
988 | /* Detach any active clients. This can't fail, thus we do not | 1067 | /* Detach any active clients. This can't fail, thus we do not |
989 | checking the returned value. */ | 1068 | checking the returned value. */ |
@@ -1238,12 +1317,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
1238 | #endif | 1317 | #endif |
1239 | 1318 | ||
1240 | if (in_atomic() || irqs_disabled()) { | 1319 | if (in_atomic() || irqs_disabled()) { |
1241 | ret = rt_mutex_trylock(&adap->bus_lock); | 1320 | ret = i2c_trylock_adapter(adap); |
1242 | if (!ret) | 1321 | if (!ret) |
1243 | /* I2C activity is ongoing. */ | 1322 | /* I2C activity is ongoing. */ |
1244 | return -EAGAIN; | 1323 | return -EAGAIN; |
1245 | } else { | 1324 | } else { |
1246 | rt_mutex_lock(&adap->bus_lock); | 1325 | i2c_lock_adapter(adap); |
1247 | } | 1326 | } |
1248 | 1327 | ||
1249 | /* Retry automatically on arbitration loss */ | 1328 | /* Retry automatically on arbitration loss */ |
@@ -1255,7 +1334,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
1255 | if (time_after(jiffies, orig_jiffies + adap->timeout)) | 1334 | if (time_after(jiffies, orig_jiffies + adap->timeout)) |
1256 | break; | 1335 | break; |
1257 | } | 1336 | } |
1258 | rt_mutex_unlock(&adap->bus_lock); | 1337 | i2c_unlock_adapter(adap); |
1259 | 1338 | ||
1260 | return ret; | 1339 | return ret; |
1261 | } else { | 1340 | } else { |
@@ -1350,13 +1429,17 @@ static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr) | |||
1350 | I2C_SMBUS_BYTE_DATA, &dummy); | 1429 | I2C_SMBUS_BYTE_DATA, &dummy); |
1351 | else | 1430 | else |
1352 | #endif | 1431 | #endif |
1353 | if ((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50 | 1432 | if (!((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50) |
1354 | || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) | 1433 | && i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) |
1355 | err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, | ||
1356 | I2C_SMBUS_BYTE, &dummy); | ||
1357 | else | ||
1358 | err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0, | 1434 | err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0, |
1359 | I2C_SMBUS_QUICK, NULL); | 1435 | I2C_SMBUS_QUICK, NULL); |
1436 | else if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) | ||
1437 | err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, | ||
1438 | I2C_SMBUS_BYTE, &dummy); | ||
1439 | else { | ||
1440 | dev_warn(&adap->dev, "No suitable probing method supported\n"); | ||
1441 | err = -EOPNOTSUPP; | ||
1442 | } | ||
1360 | 1443 | ||
1361 | return err >= 0; | 1444 | return err >= 0; |
1362 | } | 1445 | } |
@@ -1437,16 +1520,6 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) | |||
1437 | if (!(adapter->class & driver->class)) | 1520 | if (!(adapter->class & driver->class)) |
1438 | goto exit_free; | 1521 | goto exit_free; |
1439 | 1522 | ||
1440 | /* Stop here if the bus doesn't support probing */ | ||
1441 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE)) { | ||
1442 | if (address_list[0] == I2C_CLIENT_END) | ||
1443 | goto exit_free; | ||
1444 | |||
1445 | dev_warn(&adapter->dev, "Probing not supported\n"); | ||
1446 | err = -EOPNOTSUPP; | ||
1447 | goto exit_free; | ||
1448 | } | ||
1449 | |||
1450 | for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) { | 1523 | for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) { |
1451 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " | 1524 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " |
1452 | "addr 0x%02x\n", adap_id, address_list[i]); | 1525 | "addr 0x%02x\n", adap_id, address_list[i]); |
@@ -1461,18 +1534,23 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) | |||
1461 | return err; | 1534 | return err; |
1462 | } | 1535 | } |
1463 | 1536 | ||
1537 | int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr) | ||
1538 | { | ||
1539 | return i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0, | ||
1540 | I2C_SMBUS_QUICK, NULL) >= 0; | ||
1541 | } | ||
1542 | EXPORT_SYMBOL_GPL(i2c_probe_func_quick_read); | ||
1543 | |||
1464 | struct i2c_client * | 1544 | struct i2c_client * |
1465 | i2c_new_probed_device(struct i2c_adapter *adap, | 1545 | i2c_new_probed_device(struct i2c_adapter *adap, |
1466 | struct i2c_board_info *info, | 1546 | struct i2c_board_info *info, |
1467 | unsigned short const *addr_list) | 1547 | unsigned short const *addr_list, |
1548 | int (*probe)(struct i2c_adapter *, unsigned short addr)) | ||
1468 | { | 1549 | { |
1469 | int i; | 1550 | int i; |
1470 | 1551 | ||
1471 | /* Stop here if the bus doesn't support probing */ | 1552 | if (!probe) |
1472 | if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) { | 1553 | probe = i2c_default_probe; |
1473 | dev_err(&adap->dev, "Probing not supported\n"); | ||
1474 | return NULL; | ||
1475 | } | ||
1476 | 1554 | ||
1477 | for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { | 1555 | for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { |
1478 | /* Check address validity */ | 1556 | /* Check address validity */ |
@@ -1490,7 +1568,7 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
1490 | } | 1568 | } |
1491 | 1569 | ||
1492 | /* Test address responsiveness */ | 1570 | /* Test address responsiveness */ |
1493 | if (i2c_default_probe(adap, addr_list[i])) | 1571 | if (probe(adap, addr_list[i])) |
1494 | break; | 1572 | break; |
1495 | } | 1573 | } |
1496 | 1574 | ||
@@ -2002,7 +2080,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
2002 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; | 2080 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; |
2003 | 2081 | ||
2004 | if (adapter->algo->smbus_xfer) { | 2082 | if (adapter->algo->smbus_xfer) { |
2005 | rt_mutex_lock(&adapter->bus_lock); | 2083 | i2c_lock_adapter(adapter); |
2006 | 2084 | ||
2007 | /* Retry automatically on arbitration loss */ | 2085 | /* Retry automatically on arbitration loss */ |
2008 | orig_jiffies = jiffies; | 2086 | orig_jiffies = jiffies; |
@@ -2016,7 +2094,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, | |||
2016 | orig_jiffies + adapter->timeout)) | 2094 | orig_jiffies + adapter->timeout)) |
2017 | break; | 2095 | break; |
2018 | } | 2096 | } |
2019 | rt_mutex_unlock(&adapter->bus_lock); | 2097 | i2c_unlock_adapter(adapter); |
2020 | } else | 2098 | } else |
2021 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, | 2099 | res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, |
2022 | command, protocol, data); | 2100 | command, protocol, data); |