diff options
author | Oliver O'Halloran <oohall@gmail.com> | 2018-05-21 11:29:23 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.ibm.com> | 2018-05-22 02:50:56 -0500 |
commit | ac6059026442f0da98293f800aa002271d579097 (patch) | |
tree | 26a9f4b2c833b3ea5070426b26beca14d0894d8e /hw/p8-i2c.c | |
parent | 0181eea27db16871580cfb4eeed78ebb3b61c9b1 (diff) | |
download | skiboot-ac6059026442f0da98293f800aa002271d579097.zip skiboot-ac6059026442f0da98293f800aa002271d579097.tar.gz skiboot-ac6059026442f0da98293f800aa002271d579097.tar.bz2 |
p8-i2c: Allow a per-port default timeout
Add support for setting a default timeout for the I2C port to the
device-tree. This is consumed by skiboot.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'hw/p8-i2c.c')
-rw-r--r-- | hw/p8-i2c.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c index d029854..5f49f72 100644 --- a/hw/p8-i2c.c +++ b/hw/p8-i2c.c @@ -192,7 +192,6 @@ struct p8_i2c_master { uint64_t start_time; /* Request start time */ uint64_t last_update; uint64_t poll_interval; /* Polling interval */ - uint64_t byte_timeout; /* Timeout per byte */ uint64_t xscom_base; /* xscom base of i2cm */ uint32_t fifo_size; /* Maximum size of FIFO */ uint32_t chip_id; /* Chip the i2cm sits on */ @@ -225,6 +224,7 @@ struct p8_i2c_master_port { struct p8_i2c_master *master; uint32_t port_num; uint32_t bit_rate_div; /* Divisor to set bus speed*/ + uint64_t byte_timeout; /* Timeout per byte */ struct list_node link; }; @@ -1287,7 +1287,7 @@ static int p8_i2c_start_request(struct p8_i2c_master *master, /* If we don't have a user-set timeout then use the master's default */ if (!request->timeout) - request->timeout = master->byte_timeout; + request->timeout = port->byte_timeout; /* Start the timeout */ p8_i2c_reset_timeout(master, req); @@ -1608,7 +1608,7 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type) struct dt_node *i2cm_port; struct p8_i2c_master *master; struct list_head *chip_list; - uint64_t ex_stat; + uint64_t ex_stat, default_timeout; static bool irq_printed; int64_t rc; @@ -1717,7 +1717,12 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type) list_add_tail(chip_list, &master->link); max_bus_speed = 0; + default_timeout = master->irq_ok ? + I2C_TIMEOUT_IRQ_MS : + I2C_TIMEOUT_POLL_MS; + dt_for_each_child(i2cm, i2cm_port) { + uint64_t timeout_ms; uint32_t speed; port->port_num = dt_prop_get_u32(i2cm_port, "reg"); @@ -1733,6 +1738,11 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type) port->bus.free_req = p8_i2c_free_request; port->bus.set_req_timeout = p8_i2c_set_request_timeout; port->bus.run_req = p8_i2c_run_request; + + timeout_ms = dt_prop_get_u32_def(i2cm_port, "timeout-ms", + default_timeout); + port->byte_timeout = msecs_to_tb(timeout_ms); + i2c_add_bus(&port->bus); list_add_tail(&master->ports, &port->link); @@ -1752,10 +1762,6 @@ static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type) * poll_interval is that interval. */ 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); } void p8_i2c_init(void) |