[PATCH 1/5] i2c-i801: hwpec and check_pre cleanups

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Corey Minyard <cminyard@xxxxxxxxxx>

Add an "xact_extra" variable and use it to carry the PEC enable and
interrupt flags .

Also move i801_check_pre() to i801_access()  That consolidates it to
one call, and there's no point in doing all the work if the hardware
isn't ready.

Signed-off-by: Corey Minyard <cminyard@xxxxxxxxxx>
---
 drivers/i2c/busses/i2c-i801.c | 51 ++++++++++++++++++++++---------------------
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index f62d697..62cf1e5 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -230,6 +230,7 @@ struct i801_priv {
 	/* isr processing */
 	wait_queue_head_t waitq;
 	u8 status;
+	u8 xact_extra; /* Used to set INTREN if irqs enabled, and HWPEC */
 
 	/* Command state used by isr for byte-by-byte block transactions */
 	u8 cmd;
@@ -401,13 +402,13 @@ static int i801_transaction(struct i801_priv *priv, int xact)
 	int result;
 	const struct i2c_adapter *adap = &priv->adapter;
 
-	result = i801_check_pre(priv);
-	if (result < 0)
-		return result;
+	/*
+	 * the current contents of SMBHSTCNT can be overwritten, since PEC,
+	 * SMBSCMD are passed in xact
+	 */
+	outb_p(xact | priv->xact_extra | SMBHSTCNT_START,  SMBHSTCNT(priv));
 
 	if (priv->features & FEATURE_IRQ) {
-		outb_p(xact | SMBHSTCNT_INTREN | SMBHSTCNT_START,
-		       SMBHSTCNT(priv));
 		result = wait_event_timeout(priv->waitq,
 					    (status = priv->status),
 					    adap->timeout);
@@ -420,17 +421,13 @@ static int i801_transaction(struct i801_priv *priv, int xact)
 		return i801_check_post(priv, status);
 	}
 
-	/* the current contents of SMBHSTCNT can be overwritten, since PEC,
-	 * SMBSCMD are passed in xact */
-	outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
-
 	status = i801_wait_intr(priv);
 	return i801_check_post(priv, status);
 }
 
 static int i801_block_transaction_by_block(struct i801_priv *priv,
 					   union i2c_smbus_data *data,
-					   char read_write, int hwpec)
+					   char read_write)
 {
 	int i, len;
 	int status;
@@ -445,8 +442,7 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
 			outb_p(data->block[i+1], SMBBLKDAT(priv));
 	}
 
-	status = i801_transaction(priv, I801_BLOCK_DATA |
-				  (hwpec ? SMBHSTCNT_PEC_EN : 0));
+	status = i801_transaction(priv, I801_BLOCK_DATA);
 	if (status)
 		return status;
 
@@ -553,8 +549,7 @@ static irqreturn_t i801_isr(int irq, void *dev_id)
  */
 static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
 					       union i2c_smbus_data *data,
-					       char read_write, int command,
-					       int hwpec)
+					       char read_write, int command)
 {
 	int i, len;
 	int smbcmd;
@@ -562,10 +557,6 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
 	int result;
 	const struct i2c_adapter *adap = &priv->adapter;
 
-	result = i801_check_pre(priv);
-	if (result < 0)
-		return result;
-
 	len = data->block[0];
 
 	if (read_write == I2C_SMBUS_WRITE) {
@@ -583,7 +574,7 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
 		priv->is_read = (read_write == I2C_SMBUS_READ);
 		if (len == 1 && priv->is_read)
 			smbcmd |= SMBHSTCNT_LAST_BYTE;
-		priv->cmd = smbcmd | SMBHSTCNT_INTREN;
+		priv->cmd = smbcmd | priv->xact_extra;
 		priv->len = len;
 		priv->count = 0;
 		priv->data = &data->block[1];
@@ -691,13 +682,15 @@ static int i801_block_transaction(struct i801_priv *priv,
 	   doesn't mention this limitation. */
 	if ((priv->features & FEATURE_BLOCK_BUFFER)
 	 && command != I2C_SMBUS_I2C_BLOCK_DATA
-	 && i801_set_block_buffer_mode(priv) == 0)
+	 && i801_set_block_buffer_mode(priv) == 0) {
+		if (hwpec)
+			priv->xact_extra |= SMBHSTCNT_PEC_EN;
 		result = i801_block_transaction_by_block(priv, data,
-							 read_write, hwpec);
-	else
+							 read_write);
+	} else
 		result = i801_block_transaction_byte_by_byte(priv, data,
 							     read_write,
-							     command, hwpec);
+							     command);
 
 	if (command == I2C_SMBUS_I2C_BLOCK_DATA
 	 && read_write == I2C_SMBUS_WRITE) {
@@ -716,6 +709,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
 	int block = 0;
 	int ret, xact = 0;
 	struct i801_priv *priv = i2c_get_adapdata(adap);
+	int result;
 
 	hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
 		&& size != I2C_SMBUS_QUICK
@@ -776,11 +770,17 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
 		return -EOPNOTSUPP;
 	}
 
-	if (hwpec)	/* enable/disable hardware PEC */
+	result = i801_check_pre(priv);
+	if (result < 0)
+		return result;
+
+	if (hwpec) {	/* enable/disable hardware PEC */
 		outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
-	else
+	} else {
 		outb_p(inb_p(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
 		       SMBAUXCTL(priv));
+		priv->xact_extra &= ~SMBHSTCNT_PEC_EN;
+	}
 
 	if (block)
 		ret = i801_block_transaction(priv, data, read_write, size,
@@ -1381,6 +1381,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	}
 
 	if (priv->features & FEATURE_IRQ) {
+		priv->xact_extra |= SMBHSTCNT_INTREN;
 		init_waitqueue_head(&priv->waitq);
 
 		err = devm_request_irq(&dev->dev, dev->irq, i801_isr,
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux