summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0030-Add-dump-debug-code-into-I2C-drivers.patch
blob: e984623bae40776c45c6cd0ec3a967c876f0d9db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
From f4c13be7b95899d6eca3fa7ae38224bc9c7d7902 Mon Sep 17 00:00:00 2001
From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
Date: Fri, 29 Jun 2018 11:00:02 -0700
Subject: [PATCH] Add dump debug code into I2C drivers

This commit enables dump debug of master and slave I2C drivers.
This is only for downstream debug purpose so it shouldn't go to
the upstream.

Usage (in case of bus 5 for an example):
echo 5 > /sys/module/i2c_aspeed/parameters/dump_debug_bus_id
echo 1 > /sys/module/i2c_aspeed/parameters/dump_debug
echo 5 > /sys/module/i2c_slave_mqueue/parameters/dump_debug_bus_id
echo 1 > /sys/module/i2c_slave_mqueue/parameters/dump_debug

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
---
 drivers/i2c/busses/i2c-aspeed.c | 25 +++++++++++++++++++++++++
 drivers/i2c/i2c-slave-mqueue.c  | 22 ++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 6c8b38fd6e64..77dbd37b7b51 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -166,6 +166,19 @@ struct aspeed_i2c_bus {
 #endif /* CONFIG_I2C_SLAVE */
 };
 
+static bool dump_debug __read_mostly;
+static int dump_debug_bus_id __read_mostly;
+
+#define I2C_HEX_DUMP(bus, addr, flags, buf, len) \
+	if (dump_debug && bus->adap.nr == dump_debug_bus_id) { \
+		char dump_info[100] = {0,}; \
+		snprintf(dump_info, sizeof(dump_info), \
+			 "%s (bus_id:%d, addr:0x%02x, flags:0x%02x): ", \
+			 __func__, bus->adap.nr, addr, flags); \
+		print_hex_dump(KERN_ERR, dump_info, DUMP_PREFIX_NONE, 16, 1, \
+			       buf, len, true); \
+	}
+
 static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus);
 
 static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
@@ -655,6 +668,7 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
 {
 	struct aspeed_i2c_bus *bus = i2c_get_adapdata(adap);
 	unsigned long time_left, flags;
+	int i;
 
 	spin_lock_irqsave(&bus->lock, flags);
 	bus->cmd_err = 0;
@@ -697,6 +711,11 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
 		return -ETIMEDOUT;
 	}
 
+	for (i = 0; i < num; i++) {
+		I2C_HEX_DUMP(bus, msgs[i].addr, msgs[i].flags,
+			     msgs[i].buf, msgs[i].len);
+	}
+
 	return bus->master_xfer_result;
 }
 
@@ -1064,6 +1083,12 @@ static struct platform_driver aspeed_i2c_bus_driver = {
 };
 module_platform_driver(aspeed_i2c_bus_driver);
 
+module_param_named(dump_debug, dump_debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dump_debug, "debug flag for dump printing");
+module_param_named(dump_debug_bus_id, dump_debug_bus_id, int,
+		   S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dump_debug_bus_id, "bus id for dump debug printing");
+
 MODULE_AUTHOR("Brendan Higgins <brendanhiggins@google.com>");
 MODULE_DESCRIPTION("Aspeed I2C Bus Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/i2c/i2c-slave-mqueue.c b/drivers/i2c/i2c-slave-mqueue.c
index 6014bca0ff2a..4548088e1922 100644
--- a/drivers/i2c/i2c-slave-mqueue.c
+++ b/drivers/i2c/i2c-slave-mqueue.c
@@ -21,6 +21,7 @@ struct mq_msg {
 struct mq_queue {
 	struct bin_attribute	bin;
 	struct kernfs_node	*kn;
+	struct i2c_client	*client;
 
 	spinlock_t		lock; /* spinlock for queue index handling */
 	int			in;
@@ -31,6 +32,18 @@ struct mq_queue {
 	struct mq_msg		*queue;
 };
 
+static bool dump_debug __read_mostly;
+static int dump_debug_bus_id __read_mostly;
+
+#define I2C_HEX_DUMP(client, buf, len) \
+	if (dump_debug && client->adapter->nr == dump_debug_bus_id) { \
+		char dump_info[100] = {0,}; \
+		snprintf(dump_info, sizeof(dump_info), \
+			 "%s (bus_id:%d): ", __func__, client->adapter->nr); \
+		print_hex_dump(KERN_ERR, dump_info, DUMP_PREFIX_NONE, 16, 1, \
+			       buf, len, true); \
+	}
+
 static int i2c_slave_mqueue_callback(struct i2c_client *client,
 				     enum i2c_slave_event event, u8 *val)
 {
@@ -101,6 +114,7 @@ static ssize_t i2c_slave_mqueue_bin_read(struct file *filp,
 		if (msg->len <= count) {
 			ret = msg->len;
 			memcpy(buf, msg->buf, ret);
+			I2C_HEX_DUMP(mq->client, buf, ret);
 		} else {
 			ret = -EOVERFLOW; /* Drop this HUGE one. */
 		}
@@ -131,6 +145,8 @@ static int i2c_slave_mqueue_probe(struct i2c_client *client,
 
 	BUILD_BUG_ON(!is_power_of_2(MQ_QUEUE_SIZE));
 
+	mq->client = client;
+
 	buf = devm_kmalloc_array(dev, MQ_QUEUE_SIZE, MQ_MSGBUF_SIZE,
 				 GFP_KERNEL);
 	if (!buf)
@@ -212,6 +228,12 @@ static struct i2c_driver i2c_slave_mqueue_driver = {
 };
 module_i2c_driver(i2c_slave_mqueue_driver);
 
+module_param_named(dump_debug, dump_debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dump_debug, "debug flag for dump printing");
+module_param_named(dump_debug_bus_id, dump_debug_bus_id, int,
+		   S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dump_debug_bus_id, "bus id for dump debug printing");
+
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>");
 MODULE_DESCRIPTION("I2C slave mode for receiving and queuing messages");
-- 
2.7.4