[RFC 2/2] i2c-intel-mid: Implement software fragment

    There is a problem when xfer size > FIFO buffer size

    Implement software fragment in host bus driver

    So that I2C slave device driver need not to do modify

 

 

diff -ruN a/drivers/i2c/busses/i2c-intel-mid.c 
b/drivers/i2c/busses/i2c-intel-mid.c

--- a/drivers/i2c/busses/i2c-intel-mid.c      2010-11-23 10:12:51.950754000 
+0800

+++ b/drivers/i2c/busses/i2c-intel-mid.c    2010-11-23 10:15:11.119068000 +0800

@@ -59,6 +59,11 @@

 /* Currently, pre-define it as 32-byte; it is safe for all CPU stepping */

 #define I2C_FIFO_SIZE       32

 

+/* There is a problem when xfer size > FIFO buffer size */

+/* Implement software fragment in host bus driver */

+/* So that I2C slave device driver need not to do modify */

+#define I2C_XFER_FRAGMENT

+

 /**

  * struct intel_mid_i2c_private        - per device I²C context

  * @adap: core i2c layer adapter information

@@ -84,8 +89,12 @@

       int speed;

       struct completion complete;

       int abort;

+#ifdef I2C_XFER_FRAGMENT

+      int xfer_buf_len; /* xfer buffer length */

+#else

       u8 *rx_buf;

       int rx_buf_len;

+#endif

       enum mid_i2c_status status;

       struct i2c_msg *msg;

       enum platform_enum platform;

@@ -548,6 +557,13 @@

       readl(i2c->base + IC_CLR_INTR);

       writel(0x0044, i2c->base + IC_INTR_MASK);

 

+#ifdef I2C_XFER_FRAGMENT

+      /* set xfer_buf_len as xfer_read length */

+      i2c->xfer_buf_len = length;

+      /* set receive FIFO threshold */

+      writel((uint16_t)(length - 1), i2c->base + IC_RX_TL);

+#endif

+

       i2c->status = STATUS_READ_START;

 

       while (i--)

@@ -724,6 +740,11 @@

 {

       struct intel_mid_i2c_private *i2c = i2c_get_adapdata(adap);

       int i, err = 0;

+#ifdef I2C_XFER_FRAGMENT

+      u16 len;

+      u8 *buf;

+      u16 xfer_len;

+#endif

 

       /* if number of messages equal 0*/

       if (num == 0)

@@ -764,6 +785,36 @@

       for (i = 0; i < num; i++) {

               i2c->msg = pmsg;

               i2c->status = STATUS_IDLE;

+#ifdef I2C_XFER_FRAGMENT

+              if (pmsg->len && pmsg->buf) {

+                      len = pmsg->len;

+                      buf = pmsg->buf;

+                      xfer_len = 0;

+

+                      while (len && buf) {

+                              if (len >= I2C_FIFO_SIZE)

+                                      xfer_len = I2C_FIFO_SIZE;

+                              else

+                                      xfer_len = len;

+

+                              if (pmsg->flags & I2C_M_RD) {

+                                      dev_dbg(&adap->dev, "I2C_M_RD\n");

+                                      err = xfer_read(adap, buf, xfer_len);

+                              } else {

+                                      dev_dbg(&adap->dev, "I2C_M_WR\n");

+                                      err = xfer_write(adap, buf, xfer_len);

+                              }

+                              if (err < 0)

+                                      goto err_1;

+

+                              len -= xfer_len;

+                              if (len)

+                                      buf += xfer_len;

+                              else /* len == 0 */

+                                      break;

+                      }

+              }

+#else

               /* Read or Write */

               if (pmsg->flags & I2C_M_RD) {

                       dev_dbg(&adap->dev, "I2C_M_RD\n");

@@ -774,6 +825,7 @@

               }

               if (err < 0)

                       break;

+#endif

               dev_dbg(&adap->dev, "msg[%d] transfer complete\n", i);

               pmsg++;           /* next message */

       }

@@ -844,6 +896,14 @@

 static void i2c_isr_read(struct intel_mid_i2c_private *i2c)

 {

       struct i2c_msg *msg = i2c->msg;

+#ifdef I2C_XFER_FRAGMENT

+      u32 len = i2c->xfer_buf_len;

+      u8 *buf = msg->buf;

+

+      while (len--)

+              *buf++ = readl(i2c->base + IC_DATA_CMD);

+      i2c->status = STATUS_READ_SUCCESS;

+#else

       int rx_num;

       u32 len;

       u8 *buf;

@@ -870,6 +930,7 @@

               i2c->rx_buf = buf;

       } else

               i2c->status = STATUS_READ_SUCCESS;

+#endif

 

       return;

 }

@@ -906,7 +967,10 @@

       }

 

       if (stat & TX_EMPTY) {

+#ifndef I2C_XFER_FRAGMENT

+              /* if IC_TX_TL == 0, TFE of IC_STATUS is always 1 */

               if (readl(i2c->base + IC_STATUS) & 0x4)

+#endif

                       i2c->status = STATUS_WRITE_SUCCESS;

       }

 

@@ -1014,7 +1078,11 @@

       mrst->base = base;

       mrst->speed = STANDARD;

       mrst->abort = 0;

+#ifdef I2C_XFER_FRAGMENT

+      mrst->xfer_buf_len = 0;

+#else

       mrst->rx_buf_len = 0;

+#endif

       mrst->status = STATUS_IDLE;

 

       pci_set_drvdata(dev, mrst);

 

Attachment: 2_Implement_software_fragment.patch
Description: 2_Implement_software_fragment.patch

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to