aboutsummaryrefslogtreecommitdiff
path: root/hw/p8-i2c.c
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2016-11-24 16:06:51 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-11-24 16:47:16 +1100
commit6c077e9ed08c7af7db56ef6f334d204f78e6de8d (patch)
treebbdbfc64d5cff3a163da3b6f1409dfa60c870261 /hw/p8-i2c.c
parenta5761fb4585520983716d17fdb33f04891cf0479 (diff)
downloadskiboot-6c077e9ed08c7af7db56ef6f334d204f78e6de8d.zip
skiboot-6c077e9ed08c7af7db56ef6f334d204f78e6de8d.tar.gz
skiboot-6c077e9ed08c7af7db56ef6f334d204f78e6de8d.tar.bz2
p8i2c: Use calculated poll_interval when booting OPAL
Otherwise we'd default to 2seconds (TIMER_POLL) during boot on chips with a functional i2c interrupt, leading to slow i2c during boot (or hitting timeouts instead). Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/p8-i2c.c')
-rw-r--r--hw/p8-i2c.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c
index 12a4d1a..faaf6ed 100644
--- a/hw/p8-i2c.c
+++ b/hw/p8-i2c.c
@@ -870,7 +870,7 @@ static int p8_i2c_start_request(struct p8_i2c_master *master,
struct p8_i2c_master_port *port;
struct p8_i2c_request *request =
container_of(req, struct p8_i2c_request, req);
- uint64_t cmd, now;
+ uint64_t cmd, now, poll_interval;
int64_t rc, tbytes;
DBG("Starting req %d len=%d addr=%02x (offset=%x)\n",
@@ -975,7 +975,11 @@ static int p8_i2c_start_request(struct p8_i2c_master *master,
/* Run a poll timer for boot cases or non-working interrupts
* cases
*/
- now = schedule_timer(&master->poller, master->poll_interval);
+ if (!opal_booting() && master->irq_ok)
+ poll_interval = TIMER_POLL;
+ else
+ poll_interval = master->poll_interval;
+ now = schedule_timer(&master->poller, poll_interval);
/* Calculate and start timeout */
if (request->timeout) {
@@ -1428,15 +1432,14 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
port++;
}
- /* If we have no interrupt, calculate a poll interval,
- * otherwise just use a TIMER_POLL timer which will tick
- * on OPAL pollers only (which allows us to operate
- * during boot before interrupts are functional etc...
+ /* When at runtime and we have the i2c irq, we just use it
+ * (see p8_i2c_start_request), but in the situation where
+ * one of those isn't the case (e.g. during boot), we need
+ * a better poll interval to efficiently crank the i2c machine.
+ * poll_interval is that interval.
*/
- if (master->irq_ok)
- master->poll_interval = TIMER_POLL;
- else
- master->poll_interval = p8_i2c_get_poll_interval(max_bus_speed);
+ master->poll_interval = (max_bus_speed) ? p8_i2c_get_poll_interval(max_bus_speed) : TIMER_POLL;
+
master->byte_timeout = master->irq_ok ?
msecs_to_tb(I2C_TIMEOUT_IRQ_MS) :
msecs_to_tb(I2C_TIMEOUT_POLL_MS);