[linux-yocto] [PATCH 06/17] i2c: axxia: Fix broken smbus block read

2014-07-09 Thread Charlie Paul
From: Anders Berg 

Changed the initial transfer size on block reads from 1 to
I2C_SMBUS_BLOCK_MAX. The size is adjusted when the first byte (block
length) is received. Having the initial size set to 1 could cause the
controller to stop the transfer after the block length byte, if the
transfer length register wasn't updated in time.

Signed-off-by: Anders Berg 
---
 drivers/i2c/busses/i2c-axxia.c |   16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index e965793..15d5f0d 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -271,15 +271,18 @@ axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev)
while (0 < bytes_to_transfer--) {
int c = readl(&idev->regs->mst_data);
if (idev->msg_xfrd == 0 && i2c_m_recv_len(msg)) {
-   if (c == 0 || c > I2C_SMBUS_BLOCK_MAX) {
+   /*
+* Check length byte for SMBus block read
+*/
+   if (c <= 0) {
idev->msg_err = -EPROTO;
i2c_int_disable(idev, ~0);
-   dev_err(idev->dev,
-   "invalid SMBus block size (%d)\n", c);
complete(&idev->msg_complete);
break;
+   } else if (c > I2C_SMBUS_BLOCK_MAX) {
+   c = I2C_SMBUS_BLOCK_MAX;
}
-   msg->len += c;
+   msg->len = 1 + c;
writel(msg->len, &idev->regs->mst_rx_xfer);
}
msg->buf[idev->msg_xfrd++] = c;
@@ -402,7 +405,10 @@ axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct 
i2c_msg *msg)
/* TX 0 bytes */
writel(0, &idev->regs->mst_tx_xfer);
/* RX # bytes */
-   writel(msg->len, &idev->regs->mst_rx_xfer);
+   if (i2c_m_recv_len(msg))
+   writel(I2C_SMBUS_BLOCK_MAX, &idev->regs->mst_rx_xfer);
+   else
+   writel(msg->len, &idev->regs->mst_rx_xfer);
} else {
/* TX # bytes */
writel(msg->len, &idev->regs->mst_tx_xfer);
-- 
1.7.9.5

-- 
___
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto


[linux-yocto] [PATCH 06/17] i2c: axxia: Fix broken smbus block read

2014-07-08 Thread Charlie Paul
From: Anders Berg 

Changed the initial transfer size on block reads from 1 to
I2C_SMBUS_BLOCK_MAX. The size is adjusted when the first byte (block
length) is received. Having the initial size set to 1 could cause the
controller to stop the transfer after the block length byte, if the
transfer length register wasn't updated in time.

Signed-off-by: Anders Berg 
---
 drivers/i2c/busses/i2c-axxia.c |   16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index e965793..15d5f0d 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -271,15 +271,18 @@ axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev)
while (0 < bytes_to_transfer--) {
int c = readl(&idev->regs->mst_data);
if (idev->msg_xfrd == 0 && i2c_m_recv_len(msg)) {
-   if (c == 0 || c > I2C_SMBUS_BLOCK_MAX) {
+   /*
+* Check length byte for SMBus block read
+*/
+   if (c <= 0) {
idev->msg_err = -EPROTO;
i2c_int_disable(idev, ~0);
-   dev_err(idev->dev,
-   "invalid SMBus block size (%d)\n", c);
complete(&idev->msg_complete);
break;
+   } else if (c > I2C_SMBUS_BLOCK_MAX) {
+   c = I2C_SMBUS_BLOCK_MAX;
}
-   msg->len += c;
+   msg->len = 1 + c;
writel(msg->len, &idev->regs->mst_rx_xfer);
}
msg->buf[idev->msg_xfrd++] = c;
@@ -402,7 +405,10 @@ axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct 
i2c_msg *msg)
/* TX 0 bytes */
writel(0, &idev->regs->mst_tx_xfer);
/* RX # bytes */
-   writel(msg->len, &idev->regs->mst_rx_xfer);
+   if (i2c_m_recv_len(msg))
+   writel(I2C_SMBUS_BLOCK_MAX, &idev->regs->mst_rx_xfer);
+   else
+   writel(msg->len, &idev->regs->mst_rx_xfer);
} else {
/* TX # bytes */
writel(msg->len, &idev->regs->mst_tx_xfer);
-- 
1.7.9.5

-- 
___
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto