summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2019-03-26 19:18:18 +1100
committerStewart Smith <stewart@linux.ibm.com>2019-03-28 15:24:13 +1100
commit319e7d935f1354f317f32816293ade0dfd827b81 (patch)
tree33062251a9fc4bace5264a068228b12873330e10 /core
parentd290b244efbc03c9a89e858a57b7a91186dcf364 (diff)
downloadtalos-skiboot-319e7d935f1354f317f32816293ade0dfd827b81.tar.gz
talos-skiboot-319e7d935f1354f317f32816293ade0dfd827b81.zip
core/i2c: split i2c_request_send()
Split the i2c_request_send() method into two methods: i2c_request_send() which allocates and populates and i2c_request structure, and i2c_request_sync() which take a request structure and blocks until it completes. This allows code that allocates a i2c_request structure elsewhere to make use of the existing busy-wait and request retry logic. Fix the return types to use int64_t while we're here since these are returning OPAL_API error codes. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/i2c.c97
1 files changed, 53 insertions, 44 deletions
diff --git a/core/i2c.c b/core/i2c.c
index e78b6b61..07303e75 100644
--- a/core/i2c.c
+++ b/core/i2c.c
@@ -140,6 +140,56 @@ opal_call(OPAL_I2C_REQUEST, opal_i2c_request, 3);
#define MAX_NACK_RETRIES 2
#define REQ_COMPLETE_POLLING 5 /* Check if req is complete
in 5ms interval */
+int64_t i2c_request_sync(struct i2c_request *req)
+{
+ uint64_t timer_period = msecs_to_tb(5), timer_count;
+ uint64_t time_to_wait = 0;
+ int64_t rc, waited, retries;
+
+ for (retries = 0; retries <= MAX_NACK_RETRIES; retries++) {
+ waited = 0;
+ timer_count = 0;
+
+ i2c_queue_req(req);
+
+ do {
+ time_to_wait = i2c_run_req(req);
+ if (!time_to_wait)
+ time_to_wait = REQ_COMPLETE_POLLING;
+ time_wait(time_to_wait);
+ waited += time_to_wait;
+ timer_count += time_to_wait;
+ if (timer_count > timer_period) {
+ /*
+ * The above request may be relying on
+ * timers to complete, yet there may
+ * not be called, especially during
+ * opal init. We could be looping here
+ * forever. So explicitly check the
+ * timers once in a while
+ */
+ check_timers(false);
+ timer_count = 0;
+ }
+ } while (req->req_state != i2c_req_done);
+
+ lwsync();
+ rc = req->result;
+
+ /* retry on NACK, otherwise exit */
+ if (rc != OPAL_I2C_NACK_RCVD)
+ break;
+ req->req_state = i2c_req_new;
+ }
+
+ prlog(PR_DEBUG, "I2C: %s req op=%x offset=%x buf=%016llx buflen=%d "
+ "delay=%lu/%lld rc=%lld\n",
+ (rc) ? "!!!!" : "----", req->op, req->offset,
+ *(uint64_t*) req->rw_buf, req->rw_len, tb_to_msecs(waited), req->timeout, rc);
+
+ return rc;
+}
+
/**
* i2c_request_send - send request to i2c bus synchronously
* @bus_id: i2c bus id
@@ -155,15 +205,13 @@ opal_call(OPAL_I2C_REQUEST, opal_i2c_request, 3);
*
* Returns: Zero on success otherwise a negative error code
*/
-int i2c_request_send(int bus_id, int dev_addr, int read_write,
+int64_t i2c_request_send(int bus_id, int dev_addr, int read_write,
uint32_t offset, uint32_t offset_bytes, void* buf,
size_t buflen, int timeout)
{
- int rc, waited, retries;
struct i2c_request *req;
struct i2c_bus *bus;
- uint64_t time_to_wait = 0;
- uint64_t timer_period = msecs_to_tb(5), timer_count;
+ int64_t rc;
bus = i2c_find_bus_by_id(bus_id);
if (!bus) {
@@ -197,46 +245,7 @@ int i2c_request_send(int bus_id, int dev_addr, int read_write,
req->rw_len = buflen;
req->timeout = timeout;
- for (retries = 0; retries <= MAX_NACK_RETRIES; retries++) {
- waited = 0;
- timer_count = 0;
-
- i2c_queue_req(req);
-
- do {
- time_to_wait = i2c_run_req(req);
- if (!time_to_wait)
- time_to_wait = REQ_COMPLETE_POLLING;
- time_wait(time_to_wait);
- waited += time_to_wait;
- timer_count += time_to_wait;
- if (timer_count > timer_period) {
- /*
- * The above request may be relying on
- * timers to complete, yet there may
- * not be called, especially during
- * opal init. We could be looping here
- * forever. So explicitly check the
- * timers once in a while
- */
- check_timers(false);
- timer_count = 0;
- }
- } while (req->req_state != i2c_req_done);
-
- lwsync();
- rc = req->result;
-
- /* retry on NACK, otherwise exit */
- if (rc != OPAL_I2C_NACK_RCVD)
- break;
- req->req_state = i2c_req_new;
- }
-
- prlog(PR_DEBUG, "I2C: %s req op=%x offset=%x buf=%016llx buflen=%d "
- "delay=%lu/%d rc=%d\n",
- (rc) ? "!!!!" : "----", req->op, req->offset,
- *(uint64_t*) buf, req->rw_len, tb_to_msecs(waited), timeout, rc);
+ rc = i2c_request_sync(req);
free(req);
if (rc)
OpenPOWER on IntegriCloud