[U-Boot] [PATCH 04/13] i2c: mvtwsi: Eliminate flags parameter

Mario Six mario.six at gdsys.cc
Mon Jul 18 10:27:53 CEST 2016


Due to breaking boots from NOR flashes, commit d6b7757 ("i2c: mvtwsi:
Eliminate twsi_control_flags") removed the static global
twsi_control_flags variable, which kept a set of default flags that were
always or'd to the control register when writing. It was replaced with a
flags parameter, which was passed around between the functions that
needed it.

Since the twsi_control_flags variable was used just for the purposes of
a) setting the MVTWSI_CONTROL_TWSIEN on every control register write,
   and
b) setting the MVTWSI_CONTROL_ACK from twsi_i2c_read if needed,
anyway, the added overhead of another variable being passed around is no
longer justified, and we are better off implementing this flag setting
logic locally in the functions that actually write to the control
register.

Therefore, this patch sets MVTWSI_CONTROL_TWSIEN on every control
register write, replaces the twsi_i2c_read's flags parameter with a
ack_flag parameter, which tells the function whether to acknowledge the
read or not, and removes every other instance of the flags variable.
This has the added benefit that now every notion of "global default
flags" is gone, and it's much easier to see which control flags are
actually set at which point in time.

Signed-off-by: Mario Six <mario.six at gdsys.cc>
---
 drivers/i2c/mvtwsi.c | 83 ++++++++++++++++++++++++++--------------------------
 1 file changed, 41 insertions(+), 42 deletions(-)

diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c
index 7b2c611..4a34eab 100644
--- a/drivers/i2c/mvtwsi.c
+++ b/drivers/i2c/mvtwsi.c
@@ -124,6 +124,17 @@ enum mvstwsi_status_values {
 };
 
 /*
+ * enum mvstwsi_ack_flags - Determine whether a read byte should be
+ * acknowledged or not.
+ */
+enum mvtwsi_ack_flags {
+	/* Send NAK after received byte */
+	MVTWSI_READ_NAK = 0,
+	/* Send ACK after received byte */
+	MVTWSI_READ_ACK = 1,
+};
+
+/*
  * MVTWSI controller base
  */
 
@@ -225,14 +236,12 @@ static int twsi_wait(struct i2c_adapter *adap, int expected_status)
  * Assert the START condition, either in a single I2C transaction
  * or inside back-to-back ones (repeated starts).
  */
-static int twsi_start(struct i2c_adapter *adap, int expected_status, u8 *flags)
+static int twsi_start(struct i2c_adapter *adap, int expected_status)
 {
 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
 
-	/* Set TWSIEN */
-	*flags |= MVTWSI_CONTROL_TWSIEN;
 	/* Assert START */
-	writel(*flags | MVTWSI_CONTROL_START |
+	writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_START |
 	       MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
 	/* Wait for controller to process START */
 	return twsi_wait(adap, expected_status);
@@ -241,15 +250,15 @@ static int twsi_start(struct i2c_adapter *adap, int expected_status, u8 *flags)
 /*
  * Send a byte (i2c address or data).
  */
-static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status,
-		     u8 *flags)
+static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status)
 {
 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
 
 	/* Write byte to data register for sending */
 	writel(byte, &twsi->data);
 	/* Clear any pending interrupt -- that will cause sending */
-	writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+	writel(MVTWSI_CONTROL_TWSIEN | MVTWSI_CONTROL_CLEAR_IFLG,
+	       &twsi->control);
 	/* Wait for controller to receive byte, and check ACK */
 	return twsi_wait(adap, expected_status);
 }
@@ -257,18 +266,18 @@ static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status,
 /*
  * Receive a byte.
  */
-static int twsi_recv(struct i2c_adapter *adap, u8 *byte, u8 *flags)
+static int twsi_recv(struct i2c_adapter *adap, u8 *byte, int ack_flag)
 {
 	struct mvtwsi_registers *twsi = twsi_get_base(adap);
-	int expected_status, status;
+	int expected_status, status, control;
 
-	/* Compute expected status based on ACK bit in passed control flags */
-	if (*flags & MVTWSI_CONTROL_ACK)
-		expected_status = MVTWSI_STATUS_DATA_R_ACK;
-	else
-		expected_status = MVTWSI_STATUS_DATA_R_NAK;
+	/* Compute expected status based on passed ACK flag */
+	expected_status = ack_flag ? MVTWSI_STATUS_DATA_R_ACK :
+			  MVTWSI_STATUS_DATA_R_NAK;
 	/* Acknowledge *previous state*, and launch receive */
-	writel(*flags | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
+	control = MVTWSI_CONTROL_TWSIEN;
+	control |= ack_flag == MVTWSI_READ_ACK ? MVTWSI_CONTROL_ACK : 0;
+	writel(control | MVTWSI_CONTROL_CLEAR_IFLG, &twsi->control);
 	/* Wait for controller to receive byte, and assert ACK or NAK */
 	status = twsi_wait(adap, expected_status);
 	/* If we did receive the expected byte, store it */
@@ -378,7 +387,7 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
  * Expected address status will derive from direction bit (bit 0) in addr.
  */
 static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
-		     u8 addr, u8 *flags)
+		     u8 addr)
 {
 	int status, expected_addr_status;
 
@@ -389,11 +398,10 @@ static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
 	else /* Writing */
 		expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK;
 	/* Assert START */
-	status = twsi_start(adap, expected_start_status, flags);
+	status = twsi_start(adap, expected_start_status);
 	/* Send out the address if the start went well */
 	if (status == 0)
-		status = twsi_send(adap, addr, expected_addr_status,
-				   flags);
+		status = twsi_send(adap, addr, expected_addr_status);
 	/* Return 0, or the status of the first failure */
 	return status;
 }
@@ -404,14 +412,13 @@ static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
 static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip)
 {
 	u8 dummy_byte;
-	u8 flags = 0;
 	int status;
 
 	/* Begin i2c read */
-	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1, &flags);
+	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1);
 	/* Dummy read was accepted: receive byte, but NAK it. */
 	if (status == 0)
-		status = twsi_recv(adap, &dummy_byte, &flags);
+		status = twsi_recv(adap, &dummy_byte, MVTWSI_READ_NAK);
 	/* Stop transaction */
 	twsi_stop(adap, 0);
 	/* Return 0, or the status of the first failure */
@@ -430,29 +437,23 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 			int alen, uchar *data, int length)
 {
 	int status;
-	u8 flags = 0;
 
 	/* Begin i2c write to send the address bytes */
-	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
+	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
 	/* Send address bytes */
 	while ((status == 0) && alen--)
 		status = twsi_send(adap, addr >> (8*alen),
-			MVTWSI_STATUS_DATA_W_ACK, &flags);
+			MVTWSI_STATUS_DATA_W_ACK);
 	/* Begin i2c read to receive data bytes */
 	if (status == 0)
 		status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
-				   (chip << 1) | 1, &flags);
-	/* Prepare ACK if at least one byte must be received */
-	if (length > 0)
-		flags |= MVTWSI_CONTROL_ACK;
-	/* Receive actual data bytes */
-	while ((status == 0) && length--) {
-		/* Set NAK if we if we have nothing more to read */
-		if (length == 0)
-			flags &= ~MVTWSI_CONTROL_ACK;
-		/* Read current byte */
-		status = twsi_recv(adap, data++, &flags);
-	}
+				   (chip << 1) | 1);
+	/* Receive actual data bytes; set NAK if we if we have nothing more to
+	 * read */
+	while ((status == 0) && length--)
+		status = twsi_recv(adap, data++,
+				   length > 0 ?
+				   MVTWSI_READ_ACK : MVTWSI_READ_NAK);
 	/* Stop transaction */
 	status = twsi_stop(adap, status);
 	/* Return 0, or the status of the first failure */
@@ -466,19 +467,17 @@ static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 			int alen, uchar *data, int length)
 {
 	int status;
-	u8 flags = 0;
 
 	/* Begin i2c write to send first the address bytes, then the
 	 * data bytes */
-	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1), &flags);
+	status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1));
 	/* Send address bytes */
 	while ((status == 0) && alen--)
 		status = twsi_send(adap, addr >> (8*alen),
-			MVTWSI_STATUS_DATA_W_ACK, &flags);
+			MVTWSI_STATUS_DATA_W_ACK);
 	/* Send data bytes */
 	while ((status == 0) && (length-- > 0))
-		status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK,
-				   &flags);
+		status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK);
 	/* Stop transaction */
 	status = twsi_stop(adap, status);
 	/* Return 0, or the status of the first failure */
-- 
2.9.0



More information about the U-Boot mailing list