summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0030-Add-dump-debug-code-into-I2C-drivers.patch
blob: b735ab38b8e942635d7f3ec5dc79a4ed9f26517d (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
143
144
145
146
147
148
149
150
151
From 577b65960842f4098cdfc85a311261477c051d84 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  | 24 ++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index d11b2ea97259..506d867b43d9 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 ret;
+	int i;
 
 	spin_lock_irqsave(&bus->lock, flags);
 	bus->cmd_err = 0;
@@ -694,6 +708,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;
 }
 
@@ -1061,6 +1080,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..0140c0dc4c03 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,19 @@ 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, addr:0x%02x): ", \
+			 __func__, client->adapter->nr, client->addr); \
+		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)
 {
@@ -49,6 +63,7 @@ static int i2c_slave_mqueue_callback(struct i2c_client *client,
 	case I2C_SLAVE_WRITE_RECEIVED:
 		if (msg->len < MQ_MSGBUF_SIZE) {
 			msg->buf[msg->len++] = *val;
+			I2C_HEX_DUMP(client, val, 1);
 		} else {
 			dev_err(&client->dev, "message is truncated!\n");
 			mq->truncated = 1;
@@ -101,6 +116,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 +147,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 +230,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