diff mbox series

[07/10] hw/p8-i2c: Set poll interval from the current port

Message ID 20201012025314.1070230-7-oohall@gmail.com
State New
Headers show
Series [01/10] external/trace: Fall back to read() | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (f901fcafae14d38e29f1cc11440086ee678785d0)
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot fail Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present

Commit Message

Oliver O'Halloran Oct. 12, 2020, 2:53 a.m. UTC
The rate at which we need to poll the master depends on the speed of the
bus. Faster I2C buses will require more frequent polling so it doesn't
make a whole lot of sense to set this on a per-master basis. This patch
sets the master's polling interval to a per-port setting calculated
from the port speed.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 hw/p8-i2c.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c
index 78f1e7e32932..f01cbe8a0870 100644
--- a/hw/p8-i2c.c
+++ b/hw/p8-i2c.c
@@ -234,6 +234,7 @@  struct p8_i2c_master_port {
 	uint32_t		port_num;
 	uint32_t		bit_rate_div;	/* Divisor to set bus speed*/
 	uint64_t		byte_timeout;	/* Timeout per byte */
+	uint64_t		poll_interval;	/* Polling interval */
 	struct list_node	link;
 };
 
@@ -1017,7 +1018,7 @@  static int p8_i2c_start_request(struct p8_i2c_master *master,
 				struct i2c_request *req)
 {
 	struct p8_i2c_master_port *port;
-	uint64_t cmd, poll_interval;
+	uint64_t cmd;
 	int64_t rc;
 
 	DBG("Starting req %d len=%d addr=%02x (offset=%x)\n",
@@ -1152,10 +1153,10 @@  static int p8_i2c_start_request(struct p8_i2c_master *master,
 	 * cases
 	 */
 	if (!opal_booting() && master->irq_ok)
-		poll_interval = TIMER_POLL;
+		master->poll_interval = TIMER_POLL;
 	else
-		poll_interval = master->poll_interval;
-	schedule_timer(&master->poller, poll_interval);
+		master->poll_interval = port->poll_interval;
+	schedule_timer(&master->poller, master->poll_interval);
 
 	/* If we don't have a user-set timeout then use the master's default */
 	if (!req->timeout)
@@ -1442,7 +1443,7 @@  static void p8_i2c_add_bus_prop(struct p8_i2c_master_port *port)
 static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
 {
 	struct p8_i2c_master_port *port;
-	uint32_t lb_freq, count, max_bus_speed;
+	uint32_t lb_freq, count;
 	struct dt_node *i2cm_port;
 	struct p8_i2c_master *master;
 	struct list_head *chip_list;
@@ -1547,7 +1548,6 @@  static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
 
 	/* Add master to chip's list */
 	list_add_tail(chip_list, &master->link);
-	max_bus_speed = 0;
 
 	default_timeout = master->irq_ok ?
 		I2C_TIMEOUT_IRQ_MS :
@@ -1559,8 +1559,7 @@  static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
 		port->port_num = dt_prop_get_u32(i2cm_port, "reg");
 		port->master = master;
 		speed = dt_prop_get_u32(i2cm_port, "bus-frequency");
-		if (speed > max_bus_speed)
-			max_bus_speed = speed;
+		port->poll_interval = p8_i2c_get_poll_interval(speed);
 		port->bit_rate_div =
 			p8_i2c_get_bit_rate_divisor(lb_freq, speed);
 		port->bus.dt_node = i2cm_port;
@@ -1581,14 +1580,6 @@  static void p8_i2c_init_one(struct dt_node *i2cm, enum p8_i2c_master_type type)
 					  "ibm,port-name"), speed/1000);
 		port++;
 	}
-
-	/* 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.
-	 */
-	master->poll_interval = (max_bus_speed) ? p8_i2c_get_poll_interval(max_bus_speed) : TIMER_POLL;
 }
 
 void p8_i2c_init(void)