aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c67
1 files changed, 64 insertions, 3 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 5fb80b8962a2..7c7f4b856bad 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -48,10 +48,13 @@
48#include <linux/rwsem.h> 48#include <linux/rwsem.h>
49#include <linux/pm_runtime.h> 49#include <linux/pm_runtime.h>
50#include <linux/acpi.h> 50#include <linux/acpi.h>
51#include <linux/jump_label.h>
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52 53
53#include "i2c-core.h" 54#include "i2c-core.h"
54 55
56#define CREATE_TRACE_POINTS
57#include <trace/events/i2c.h>
55 58
56/* core_lock protects i2c_adapter_idr, and guarantees 59/* core_lock protects i2c_adapter_idr, and guarantees
57 that device detection, deletion of detected devices, and attach_adapter 60 that device detection, deletion of detected devices, and attach_adapter
@@ -62,6 +65,18 @@ static DEFINE_IDR(i2c_adapter_idr);
62static struct device_type i2c_client_type; 65static struct device_type i2c_client_type;
63static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); 66static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
64 67
68static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE;
69
70void i2c_transfer_trace_reg(void)
71{
72 static_key_slow_inc(&i2c_trace_msg);
73}
74
75void i2c_transfer_trace_unreg(void)
76{
77 static_key_slow_dec(&i2c_trace_msg);
78}
79
65/* ------------------------------------------------------------------------- */ 80/* ------------------------------------------------------------------------- */
66 81
67static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, 82static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
@@ -1686,6 +1701,7 @@ static void __exit i2c_exit(void)
1686 class_compat_unregister(i2c_adapter_compat_class); 1701 class_compat_unregister(i2c_adapter_compat_class);
1687#endif 1702#endif
1688 bus_unregister(&i2c_bus_type); 1703 bus_unregister(&i2c_bus_type);
1704 tracepoint_synchronize_unregister();
1689} 1705}
1690 1706
1691/* We must initialize early, because some subsystems register i2c drivers 1707/* We must initialize early, because some subsystems register i2c drivers
@@ -1716,6 +1732,19 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1716 unsigned long orig_jiffies; 1732 unsigned long orig_jiffies;
1717 int ret, try; 1733 int ret, try;
1718 1734
1735 /* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets
1736 * enabled. This is an efficient way of keeping the for-loop from
1737 * being executed when not needed.
1738 */
1739 if (static_key_false(&i2c_trace_msg)) {
1740 int i;
1741 for (i = 0; i < num; i++)
1742 if (msgs[i].flags & I2C_M_RD)
1743 trace_i2c_read(adap, &msgs[i], i);
1744 else
1745 trace_i2c_write(adap, &msgs[i], i);
1746 }
1747
1719 /* Retry automatically on arbitration loss */ 1748 /* Retry automatically on arbitration loss */
1720 orig_jiffies = jiffies; 1749 orig_jiffies = jiffies;
1721 for (ret = 0, try = 0; try <= adap->retries; try++) { 1750 for (ret = 0, try = 0; try <= adap->retries; try++) {
@@ -1726,6 +1755,14 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1726 break; 1755 break;
1727 } 1756 }
1728 1757
1758 if (static_key_false(&i2c_trace_msg)) {
1759 int i;
1760 for (i = 0; i < ret; i++)
1761 if (msgs[i].flags & I2C_M_RD)
1762 trace_i2c_reply(adap, &msgs[i], i);
1763 trace_i2c_result(adap, i, ret);
1764 }
1765
1729 return ret; 1766 return ret;
1730} 1767}
1731EXPORT_SYMBOL(__i2c_transfer); 1768EXPORT_SYMBOL(__i2c_transfer);
@@ -1941,6 +1978,13 @@ static int i2c_detect_address(struct i2c_client *temp_client,
1941 struct i2c_client *client; 1978 struct i2c_client *client;
1942 1979
1943 /* Detection succeeded, instantiate the device */ 1980 /* Detection succeeded, instantiate the device */
1981 if (adapter->class & I2C_CLASS_DEPRECATED)
1982 dev_warn(&adapter->dev,
1983 "This adapter will soon drop class based instantiation of devices. "
1984 "Please make sure client 0x%02x gets instantiated by other means. "
1985 "Check 'Documentation/i2c/instantiating-devices' for details.\n",
1986 info.addr);
1987
1944 dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n", 1988 dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
1945 info.type, info.addr); 1989 info.type, info.addr);
1946 client = i2c_new_device(adapter, &info); 1990 client = i2c_new_device(adapter, &info);
@@ -2521,6 +2565,14 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
2521 int try; 2565 int try;
2522 s32 res; 2566 s32 res;
2523 2567
2568 /* If enabled, the following two tracepoints are conditional on
2569 * read_write and protocol.
2570 */
2571 trace_smbus_write(adapter, addr, flags, read_write,
2572 command, protocol, data);
2573 trace_smbus_read(adapter, addr, flags, read_write,
2574 command, protocol);
2575
2524 flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB; 2576 flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;
2525 2577
2526 if (adapter->algo->smbus_xfer) { 2578 if (adapter->algo->smbus_xfer) {
@@ -2541,15 +2593,24 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
2541 i2c_unlock_adapter(adapter); 2593 i2c_unlock_adapter(adapter);
2542 2594
2543 if (res != -EOPNOTSUPP || !adapter->algo->master_xfer) 2595 if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)
2544 return res; 2596 goto trace;
2545 /* 2597 /*
2546 * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't 2598 * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't
2547 * implement native support for the SMBus operation. 2599 * implement native support for the SMBus operation.
2548 */ 2600 */
2549 } 2601 }
2550 2602
2551 return i2c_smbus_xfer_emulated(adapter, addr, flags, read_write, 2603 res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
2552 command, protocol, data); 2604 command, protocol, data);
2605
2606trace:
2607 /* If enabled, the reply tracepoint is conditional on read_write. */
2608 trace_smbus_reply(adapter, addr, flags, read_write,
2609 command, protocol, data);
2610 trace_smbus_result(adapter, addr, flags, read_write,
2611 command, protocol, res);
2612
2613 return res;
2553} 2614}
2554EXPORT_SYMBOL(i2c_smbus_xfer); 2615EXPORT_SYMBOL(i2c_smbus_xfer);
2555 2616