diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-11-23 16:45:59 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-11-24 16:47:16 +1100 |
commit | 441ddb9b4719a092bbbf81fcf775632f282a3fca (patch) | |
tree | 437302f687eb23d881e59013e62464956533b622 /libstb | |
parent | 2981a7bfc9dc3b1b642a868b09a75d011c49063a (diff) | |
download | skiboot-441ddb9b4719a092bbbf81fcf775632f282a3fca.zip skiboot-441ddb9b4719a092bbbf81fcf775632f282a3fca.tar.gz skiboot-441ddb9b4719a092bbbf81fcf775632f282a3fca.tar.bz2 |
i2c: Add i2c_run_req() to crank the state machine for a request
Doing everything asynchronously is brilliant, it's exactly what we
want to do.
Except... the tpm driver wants to do things synchronously, which isn't
so cool.
For reasons that are not yet completely known, we spend an awful lot of
time in the main thread *not* running pollers (potentially seconds), which
doesn't bode well for I2C timeouts.
Since the TPM measure is done in a secondary thread, we do *not* run pollers
there either (as of 323c8aeb54bd4e0b9004091fcbb4a9daeda2f576 - which is
roughly as of skiboot 2.1.1).
But we still need to crank the i2c state machine, so we introduce a call
to do just that. It will return how long the poll interval should be, so
that we can time_wait() for a more appropriate time for whatever i2c
implementation is sitting behind things.
Without this, it was "easy" to get to a situation where the i2c state machine
wasn't cranked at all, and you'd hit the i2c timeout (for the issued operation)
before the poller to crank i2c was ever called.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Tested-by: Claudio Carvalho <cclaudio@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'libstb')
-rw-r--r-- | libstb/drivers/tpm_i2c_interface.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/libstb/drivers/tpm_i2c_interface.c b/libstb/drivers/tpm_i2c_interface.c index ba0c5a8..4d136fd 100644 --- a/libstb/drivers/tpm_i2c_interface.c +++ b/libstb/drivers/tpm_i2c_interface.c @@ -57,6 +57,7 @@ int tpm_i2c_request_send(int tpm_bus_id, int tpm_dev_addr, int read_write, int rc, waited, retries, timeout; struct i2c_request *req; struct i2c_bus *bus; + uint64_t time_to_wait = 0; bus = i2c_find_bus_by_id(tpm_bus_id); if (!bus) { @@ -106,9 +107,12 @@ int tpm_i2c_request_send(int tpm_bus_id, int tpm_dev_addr, int read_write, i2c_queue_req(req); do { - time_wait_ms(REQ_COMPLETE_POLLING); - waited += REQ_COMPLETE_POLLING; - } while (waited < timeout && rc == 1); + 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; + } while (tb_to_msecs(waited) < timeout && rc == 1); if (rc == OPAL_I2C_NACK_RCVD) continue; @@ -117,10 +121,10 @@ int tpm_i2c_request_send(int tpm_bus_id, int tpm_dev_addr, int read_write, break; } - DBG("%s tpm req op=%x offset=%x buf=%016llx buflen=%d delay=%d/%d," + DBG("%s tpm 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, waited, timeout, rc); + *(uint64_t*) buf, req->rw_len, tb_to_msecs(waited), timeout, rc); i2c_free_req(req); if (rc) |