[Skiboot] [PATCH 11/22] hw/p8-i2c: Set poll interval from the current port

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Fri Jun 25 16:19:26 AEST 2021


From: Oliver O'Halloran <oohall at gmail.com>

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 at gmail.com>
---
 hw/p8-i2c.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/hw/p8-i2c.c b/hw/p8-i2c.c
index adefa2781..53f2c2ede 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;
 };
 
@@ -1016,7 +1017,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",
@@ -1151,10 +1152,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)
@@ -1441,7 +1442,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;
@@ -1546,7 +1547,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 :
@@ -1558,8 +1558,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;
@@ -1580,14 +1579,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)
-- 
2.31.1



More information about the Skiboot mailing list