Title: [6648] branches/2009R1/drivers/i2c/busses/i2c-bfin-twi.c: More replace timeout timer with wait_for_completion_timeout
Revision
6648
Author
sonicz
Date
2009-06-11 04:26:47 -0500 (Thu, 11 Jun 2009)

Log Message

More replace timeout timer with wait_for_completion_timeout

1. retry i2c transfer according to user defined parameter retires in
struct i2c_adapter.
2. wait timeout based on user defined parameter timeout in struct
i2c_adapter.
3. wake up i2c transfer process in each twi interrupt.

Modified Paths

Diff

Modified: branches/2009R1/drivers/i2c/busses/i2c-bfin-twi.c (6647 => 6648)


--- branches/2009R1/drivers/i2c/busses/i2c-bfin-twi.c	2009-06-11 09:26:06 UTC (rev 6647)
+++ branches/2009R1/drivers/i2c/busses/i2c-bfin-twi.c	2009-06-11 09:26:47 UTC (rev 6648)
@@ -23,8 +23,6 @@
 #include <asm/portmux.h>
 #include <asm/irq.h>
 
-#define POLL_TIMEOUT       (20 * HZ)
-
 /* SMBus mode*/
 #define TWI_I2C_MODE_STANDARD		1
 #define TWI_I2C_MODE_STANDARDSUB	2
@@ -165,16 +163,13 @@
 			write_INT_MASK(iface, 0);
 			write_MASTER_CTL(iface, 0);
 			SSYNC();
-			/* If it is a quick transfer, only address bug no data,
+			/* If it is a quick transfer, only address without data,
 			 * not an err, return 1.
+			 * If address is acknowledged return 1.
 			 */
-			if (iface->writeNum == 0 && (mast_stat & BUFRDERR))
+			if ((iface->writeNum == 0 && (mast_stat & BUFRDERR))
+				|| !(mast_stat & ANAK))
 				iface->result = 1;
-			/* If address not acknowledged return -1,
-			 * else return 0.
-			 */
-			else if (!(mast_stat & ANAK))
-				iface->result = 0;
 		}
 		complete(&iface->complete);
 		return;
@@ -246,9 +241,9 @@
 			write_INT_MASK(iface, 0);
 			write_MASTER_CTL(iface, 0);
 			SSYNC();
-			complete(&iface->complete);
 		}
 	}
+	complete(&iface->complete);
 }
 
 /* Interrupt handler */
@@ -264,9 +259,9 @@
 }
 
 /*
- * Generic i2c master transfer entrypoint
+ * One i2c master transfer
  */
-static int bfin_twi_master_xfer(struct i2c_adapter *adap,
+static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
 				struct i2c_msg *msgs, int num)
 {
 	struct bfin_twi_iface *iface = adap->algo_data;
@@ -338,23 +333,41 @@
 		((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
 	SSYNC();
 
-	if (!wait_for_completion_timeout(&iface->complete,
-		jiffies + POLL_TIMEOUT))
-		iface->result = -1;
+	while (!iface->result) {
+		if (!wait_for_completion_timeout(&iface->complete,
+			jiffies + adap->timeout*HZ))
+			iface->result = -1;
+	}
 
-	rc = iface->result;
+	if (iface->result == 1)
+		rc = iface->cur_msg + 1;
+	else
+		rc = iface->result;
 
-	if (rc == 1)
-		return num;
-	else
-		return rc;
+	return rc;
 }
 
 /*
- * SMBus type transfer entrypoint
+ * Generic i2c master transfer entrypoint
  */
+static int bfin_twi_master_xfer(struct i2c_adapter *adap,
+				struct i2c_msg *msgs, int num)
+{
+	int i, ret = 0;
 
-int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+	for (i = 0; i < adap->retries; i++) {
+		ret = bfin_twi_do_master_xfer(adap, msgs, num);
+		if (ret > 0)
+			break;
+	}
+
+	return ret;
+}
+
+/*
+ * One I2C SMBus transfer
+ */
+int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
 			unsigned short flags, char read_write,
 			u8 command, int size, union i2c_smbus_data *data)
 {
@@ -527,9 +540,11 @@
 	}
 	SSYNC();
 
-	if (!wait_for_completion_timeout(&iface->complete,
-		jiffies + POLL_TIMEOUT))
-		iface->result = -1;
+	while (!iface->result) {
+		if (!wait_for_completion_timeout(&iface->complete,
+			jiffies + adap->timeout*HZ))
+			iface->result = -1;
+	}
 
 	rc = (iface->result >= 0) ? 0 : -1;
 
@@ -537,6 +552,25 @@
 }
 
 /*
+ * Generic I2C SMBus transfer entrypoint
+ */
+int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+			unsigned short flags, char read_write,
+			u8 command, int size, union i2c_smbus_data *data)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < adap->retries; i++) {
+		ret = bfin_twi_do_smbus_xfer(adap, addr, flags,
+			read_write, command, size, data);
+		if (ret == 0)
+			break;
+	}
+
+	return ret;
+}
+
+/*
  * Return what the adapter supports
  */
 static u32 bfin_twi_functionality(struct i2c_adapter *adap)
@@ -635,6 +669,8 @@
 	p_adap->algo_data = iface;
 	p_adap->class = I2C_CLASS_ALL;
 	p_adap->dev.parent = &pdev->dev;
+	p_adap->timeout = 1;
+	p_adap->retries = 3;
 
 	rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");
 	if (rc) {
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to