aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2021-06-25 11:49:23 +0530
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2021-06-30 15:05:55 +0530
commitbaf6c343e661b1e9de13ecd363494dbabeb7aa84 (patch)
treeac85e0c0e4236055a98e475238f9db8a63ec0650 /core
parenta382d1638aaf96371321a177a92286444fceec0d (diff)
downloadskiboot-baf6c343e661b1e9de13ecd363494dbabeb7aa84.zip
skiboot-baf6c343e661b1e9de13ecd363494dbabeb7aa84.tar.gz
skiboot-baf6c343e661b1e9de13ecd363494dbabeb7aa84.tar.bz2
i2c,trace: Add I2C operation trace events
Add support for tracing I2C transactions performed by skiboot. This covers both internally initiated I2C ops and those that requested by the kernel via the OPAL API. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/i2c.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/core/i2c.c b/core/i2c.c
index fd93081..b4313d4 100644
--- a/core/i2c.c
+++ b/core/i2c.c
@@ -13,6 +13,7 @@
#include <timebase.h>
#include <processor.h>
#include <timer.h>
+#include <trace.h>
static LIST_HEAD(i2c_bus_list);
@@ -38,6 +39,34 @@ struct i2c_bus *i2c_find_bus_by_id(uint32_t opal_id)
return NULL;
}
+static inline void i2c_trace_req(struct i2c_request *req, int rc)
+{
+ struct trace_i2c t;
+
+ memset(&t, 0, sizeof(t));
+
+ t.bus = req->bus->opal_id;
+ t.type = req->op | (req->offset_bytes << 4);
+ t.i2c_addr = req->dev_addr;
+ t.smbus_reg = req->offset & 0xffff; // FIXME: log whole offset
+ t.size = req->rw_len;
+ t.rc = rc;
+
+ /* FIXME: trace should not be a union... */
+ trace_add((void *)&t, TRACE_I2C, sizeof(t));
+}
+
+int64_t i2c_queue_req(struct i2c_request *req)
+{
+ int64_t ret = req->bus->queue_req(req);
+
+ i2c_trace_req(req, OPAL_ASYNC_COMPLETION);
+
+ if (!ret)
+ req->req_state = i2c_req_queued;
+ return ret;
+}
+
static void opal_i2c_request_complete(int rc, struct i2c_request *req)
{
uint64_t token = (uint64_t)(unsigned long)req->user_data;
@@ -45,6 +74,8 @@ static void opal_i2c_request_complete(int rc, struct i2c_request *req)
opal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,
cpu_to_be64(token),
cpu_to_be64(rc));
+ i2c_trace_req(req, rc);
+
free(req);
}
@@ -177,6 +208,7 @@ int64_t i2c_request_sync(struct i2c_request *req)
req->req_state = i2c_req_new;
}
+ i2c_trace_req(req, rc);
count = 0;
for (i = 0; i < req->rw_len && count < sizeof(buf); i++) {
count += snprintf(buf+count, sizeof(buf)-count, "%02x",