diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-11-24 16:06:51 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-11-24 17:14:55 +1100 |
commit | f176f5cc8e2899cb9997ab6cf556719050a9c737 (patch) | |
tree | 82f2425b08e4059f02e713062e9f92c80424be89 | |
parent | 0a4733a7ef18a9eeaeacad93d7978ba5d5e290fa (diff) | |
download | skiboot-f176f5cc8e2899cb9997ab6cf556719050a9c737.zip skiboot-f176f5cc8e2899cb9997ab6cf556719050a9c737.tar.gz skiboot-f176f5cc8e2899cb9997ab6cf556719050a9c737.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>
(cherry picked from commit 6c077e9ed08c7af7db56ef6f334d204f78e6de8d)
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | hw/p8-i2c.c | 23 | ||||
-rw-r--r-- | include/skiboot.h | 5 |
2 files changed, 18 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); diff --git a/include/skiboot.h b/include/skiboot.h index 97bdce7..3f7c077 100644 --- a/include/skiboot.h +++ b/include/skiboot.h @@ -86,6 +86,11 @@ struct debug_descriptor { }; extern struct debug_descriptor debug_descriptor; +static inline bool opal_booting(void) +{ + return !(debug_descriptor.state_flags & OPAL_BOOT_COMPLETE); +} + /* Console logging */ #define PR_EMERG 0 #define PR_ALERT 1 |