Changeset 42807


Ignore:
Timestamp:
2014-10-06T22:05:13+02:00 (3 years ago)
Author:
blogic
Message:

ralink: various i2c fixes

the driver did not handle all states correctly causing a deadlock of the i2c hw block.

Signed-off-by: Ing.Michele Mogioni <michele.mogioni@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/ramips/patches-3.14/0052-i2c-MIPS-adds-ralink-I2C-driver.patch

    r42463 r42807  
    1414 create mode 100644 drivers/i2c/busses/i2c-ralink.c 
    1515 
    16 --- /dev/null 
    17 +++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt 
     16Index: linux-3.14.18/Documentation/devicetree/bindings/i2c/i2c-ralink.txt 
     17=================================================================== 
     18--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     19+++ linux-3.14.18/Documentation/devicetree/bindings/i2c/i2c-ralink.txt  2014-10-06 14:28:14.296590159 +0200 
    1820@@ -0,0 +1,27 @@ 
    1921+I2C for Ralink platforms 
     
    4446+       }; 
    4547+}; 
    46 --- a/drivers/i2c/busses/Kconfig 
    47 +++ b/drivers/i2c/busses/Kconfig 
    48 @@ -659,6 +659,10 @@ config I2C_RIIC 
     48Index: linux-3.14.18/drivers/i2c/busses/Kconfig 
     49=================================================================== 
     50--- linux-3.14.18.orig/drivers/i2c/busses/Kconfig       2014-09-06 01:34:59.000000000 +0200 
     51+++ linux-3.14.18/drivers/i2c/busses/Kconfig    2014-10-06 14:28:14.296590159 +0200 
     52@@ -659,6 +659,10 @@ 
    4953          This driver can also be built as a module.  If so, the module 
    5054          will be called i2c-riic. 
     
    5761        bool 
    5862        help 
    59 --- a/drivers/i2c/busses/Makefile 
    60 +++ b/drivers/i2c/busses/Makefile 
    61 @@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX)         += i2c-pnx.o 
     63Index: linux-3.14.18/drivers/i2c/busses/Makefile 
     64=================================================================== 
     65--- linux-3.14.18.orig/drivers/i2c/busses/Makefile      2014-09-06 01:34:59.000000000 +0200 
     66+++ linux-3.14.18/drivers/i2c/busses/Makefile   2014-10-06 14:28:14.296590159 +0200 
     67@@ -63,6 +63,7 @@ 
    6268 obj-$(CONFIG_I2C_PUV3)         += i2c-puv3.o 
    6369 obj-$(CONFIG_I2C_PXA)          += i2c-pxa.o 
     
    6773 obj-$(CONFIG_I2C_S3C2410)      += i2c-s3c2410.o 
    6874 obj-$(CONFIG_I2C_S6000)                += i2c-s6000.o 
    69 --- /dev/null 
    70 +++ b/drivers/i2c/busses/i2c-ralink.c 
    71 @@ -0,0 +1,271 @@ 
     75Index: linux-3.14.18/drivers/i2c/busses/i2c-ralink.c 
     76=================================================================== 
     77--- /dev/null   1970-01-01 00:00:00.000000000 +0000 
     78+++ linux-3.14.18/drivers/i2c/busses/i2c-ralink.c       2014-10-06 15:53:32.416500362 +0200 
     79@@ -0,0 +1,298 @@ 
    7280+/* 
    7381+ * drivers/i2c/busses/i2c-ralink.c 
    7482+ * 
    7583+ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com> 
     84+ * 
     85+ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus. 
     86+ * (C) 2014 Sittisak <sittisaks@hotmail.com> 
    7687+ * 
    7788+ * This software is licensed under the terms of the GNU General Public 
     
    97108+#include <linux/i2c.h> 
    98109+#include <linux/io.h> 
     110+#include <linux/of_i2c.h> 
    99111+#include <linux/err.h> 
    100112+ 
     
    120132+#define I2C_ADDRDIS            BIT(1) 
    121133+ 
    122 +#define I2C_RETRY              0x400 
     134+#define I2C_RETRY              0x1000 
    123135+ 
    124136+#define CLKDIV_VALUE           200 // clock rate is 40M, 40M / (200*2) = 100k (standard i2c bus rate). 
     
    140152+{ 
    141153+       return ioread32(membase + reg); 
     154+} 
     155+ 
     156+static inline int rt_i2c_get_ack(void) 
     157+{ 
     158+        return (rt_i2c_r32(REG_STATUS_REG) & I2C_ACKERR) ? -EIO : 0; 
    142159+} 
    143160+ 
     
    151168+       } while(!(rt_i2c_r32(REG_STATUS_REG) & I2C_DATARDY)); 
    152169+ 
    153 +       return (retries < 0); 
     170+       return (retries < 0) ? -ETIMEDOUT : 0; 
    154171+} 
    155172+ 
     
    175192+       } while(!(rt_i2c_r32(REG_STATUS_REG) & I2C_SDOEMPTY)); 
    176193+ 
    177 +       return (retries < 0); 
     194+       return (retries < 0) ? -ETIMEDOUT : 0; 
    178195+} 
    179196+ 
     
    183200+       int nblock = msg->len / READ_BLOCK; 
    184201+        int rem = msg->len % READ_BLOCK; 
    185 + 
     202+       int ret = 0; 
     203+       /*printk("i2c handle msg len:%d\n",msg->len);*/ 
    186204+       if (msg->flags & I2C_M_TEN) { 
    187205+               printk("10 bits addr not supported\n"); 
     
    191209+       if (msg->flags & I2C_M_RD) { 
    192210+               for (i = 0; i < nblock; i++) { 
    193 +                       rt_i2c_wait_idle(); 
     211+                       if (rt_i2c_wait_idle()) { 
     212+                                   printk("i2c-read line busy\n"); 
     213+                           return -ETIMEDOUT; 
     214+                       } 
    194215+                       rt_i2c_w32(READ_BLOCK - 1, REG_BYTECNT_REG); 
    195216+                       rt_i2c_w32(READ_CMD, REG_STARTXFR_REG); 
    196217+                       for (j = 0; j < READ_BLOCK; j++) { 
    197 +                               if (rt_i2c_wait_rx_done()) 
    198 +                                       return -1; 
     218+                               if (rt_i2c_wait_rx_done()<0) ret = rt_i2c_wait_rx_done(); 
     219+                                if (rt_i2c_get_ack()<0)      ret = rt_i2c_get_ack(); 
    199220+                               msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG); 
    200221+                       } 
    201222+               } 
    202223+ 
    203 +               rt_i2c_wait_idle(); 
     224+               if (rt_i2c_wait_idle()) { 
     225+                       printk("i2c-read line busy\n"); 
     226+                       return -ETIMEDOUT; 
     227+               } 
     228+               if (rem){ 
    204229+               rt_i2c_w32(rem - 1, REG_BYTECNT_REG); 
    205230+               rt_i2c_w32(READ_CMD, REG_STARTXFR_REG); 
     231+               } 
    206232+               for (i = 0; i < rem; i++) { 
    207 +                       if (rt_i2c_wait_rx_done()) 
    208 +                               return -1; 
     233+                       if (rt_i2c_wait_rx_done()<0) ret = rt_i2c_wait_rx_done(); 
     234+                        if (rt_i2c_get_ack()     <0) ret = rt_i2c_get_ack(); 
     235+ 
    209236+                       msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG); 
    210237+               } 
    211238+       } else { 
    212 +               rt_i2c_wait_idle(); 
     239+               if (rt_i2c_wait_idle()) { 
     240+                       printk("i2c-write line busy\n"); 
     241+                       return -ETIMEDOUT; 
     242+               } 
    213243+               rt_i2c_w32(msg->len - 1, REG_BYTECNT_REG); 
    214244+               for (i = 0; i < msg->len; i++) { 
    215245+                       rt_i2c_w32(msg->buf[i], REG_DATAOUT_REG); 
    216246+                       rt_i2c_w32(WRITE_CMD, REG_STARTXFR_REG); 
    217 +                       if (rt_i2c_wait_tx_done()) 
    218 +                               return -1; 
    219 +               } 
    220 +       } 
    221 + 
    222 +       return 0; 
     247+ 
     248+                       if (rt_i2c_wait_tx_done()<0) ret = rt_i2c_wait_tx_done(); 
     249+                        if (rt_i2c_get_ack()<0)      ret = rt_i2c_get_ack(); 
     250+ 
     251+ 
     252+               } 
     253+       } 
     254+ 
     255+       return ret; 
    223256+} 
    224257+ 
     
    229262+ 
    230263+       if (rt_i2c_wait_idle()) { 
    231 +               printk("i2c transfer failed\n"); 
    232 +               return 0; 
     264+               printk("i2c-master_xfer line busy\n"); 
     265+               return -ETIMEDOUT; 
    233266+       } 
    234267+ 
     
    239272+       rt_i2c_w32(CLKDIV_VALUE, REG_CLKDIV_REG); 
    240273+ 
    241 +       for (i = 0; i < n && !ret; i++) 
     274+       for (i = 0; i < n && !ret; i++) { 
    242275+               ret = rt_i2c_handle_msg(a, &m[i]); 
    243276+ 
    244 +       if (ret) { 
    245 +               printk("i2c transfer failed\n"); 
    246 +               return 0; 
     277+               if (ret < 0) { 
     278+                       return ret; 
     279+               } 
    247280+       } 
    248281+ 
     
    292325+       if (ret) 
    293326+               return ret; 
     327+ 
     328+       of_i2c_register_devices(adapter); 
    294329+ 
    295330+       platform_set_drvdata(pdev, adapter); 
Note: See TracChangeset for help on using the changeset viewer.