Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 Apr 2018 17:06:16 +0000 (10:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 Apr 2018 17:06:16 +0000 (10:06 -0700)
Pull i2c fixes from Wolfram Sang:

 - two driver fixes

 - better parameter check for the core

 - Documentation updates

 - part of a tree-wide HAS_DMA cleanup

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: sprd: Fix the i2c count issue
  i2c: sprd: Prevent i2c accesses after suspend is called
  i2c: dev: prevent ZERO_SIZE_PTR deref in i2cdev_ioctl_rdwr()
  Documentation/i2c: adopt kernel commenting style in examples
  Documentation/i2c: sync docs with current state of i2c-tools
  Documentation/i2c: whitespace cleanup
  i2c: Remove depends on HAS_DMA in case of platform dependency

Documentation/i2c/dev-interface
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-sprd.c
drivers/i2c/i2c-dev.c

index d04e6e4964ee7f88387f2e0e9ce3803b96d4ae18..fbed645ccd7563e90e86796d13cae7cfa7329748 100644 (file)
@@ -9,8 +9,8 @@ i2c adapters present on your system at a given time. i2cdetect is part of
 the i2c-tools package.
 
 I2C device files are character device files with major device number 89
-and a minor device number corresponding to the number assigned as 
-explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., 
+and a minor device number corresponding to the number assigned as
+explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ...,
 i2c-10, ...). All 256 minor device numbers are reserved for i2c.
 
 
@@ -23,11 +23,6 @@ First, you need to include these two headers:
   #include <linux/i2c-dev.h>
   #include <i2c/smbus.h>
 
-(Please note that there are two files named "i2c-dev.h" out there. One is
-distributed with the Linux kernel and the other one is included in the
-source tree of i2c-tools. They used to be different in content but since 2012
-they're identical. You should use "linux/i2c-dev.h").
-
 Now, you have to decide which adapter you want to access. You should
 inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this.
 Adapter numbers are assigned somewhat dynamically, so you can not
@@ -38,7 +33,7 @@ Next thing, open the device file, as follows:
   int file;
   int adapter_nr = 2; /* probably dynamically determined */
   char filename[20];
-  
+
   snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
   file = open(filename, O_RDWR);
   if (file < 0) {
@@ -72,8 +67,10 @@ the device supports them. Both are illustrated below.
     /* res contains the read word */
   }
 
-  /* Using I2C Write, equivalent of 
-     i2c_smbus_write_word_data(file, reg, 0x6543) */
+  /*
+   * Using I2C Write, equivalent of
+   * i2c_smbus_write_word_data(file, reg, 0x6543)
+   */
   buf[0] = reg;
   buf[1] = 0x43;
   buf[2] = 0x65;
@@ -140,14 +137,14 @@ ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
   set in each message, overriding the values set with the above ioctl's.
 
 ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)
-  Not meant to be called  directly; instead, use the access functions
-  below.
+  If possible, use the provided i2c_smbus_* methods described below instead
+  of issuing direct ioctls.
 
 You can do plain i2c transactions by using read(2) and write(2) calls.
 You do not need to pass the address byte; instead, set it through
 ioctl I2C_SLAVE before you try to access the device.
 
-You can do SMBus level transactions (see documentation file smbus-protocol 
+You can do SMBus level transactions (see documentation file smbus-protocol
 for details) through the following functions:
   __s32 i2c_smbus_write_quick(int file, __u8 value);
   __s32 i2c_smbus_read_byte(int file);
@@ -158,7 +155,7 @@ for details) through the following functions:
   __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
   __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
   __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
-  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, 
+  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
                                    __u8 *values);
 All these transactions return -1 on failure; you can read errno to see
 what happened. The 'write' transactions return 0 on success; the
@@ -166,10 +163,9 @@ what happened. The 'write' transactions return 0 on success; the
 returns the number of values read. The block buffers need not be longer
 than 32 bytes.
 
-The above functions are all inline functions, that resolve to calls to
-the i2c_smbus_access function, that on its turn calls a specific ioctl
-with the data in a specific format. Read the source code if you
-want to know what happens behind the screens.
+The above functions are made available by linking against the libi2c library,
+which is provided by the i2c-tools project.  See:
+https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/.
 
 
 Implementation details
index c4865b08d7fb9e3b194dba2830b837fe6ab17819..8d21b9825d71764dc950a47dec4a3bc3dc102e25 100644 (file)
@@ -707,7 +707,6 @@ config I2C_MPC
 config I2C_MT65XX
        tristate "MediaTek I2C adapter"
        depends on ARCH_MEDIATEK || COMPILE_TEST
-       depends on HAS_DMA
        help
          This selects the MediaTek(R) Integrated Inter Circuit bus driver
          for MT65xx and MT81xx.
@@ -885,7 +884,6 @@ config I2C_SH7760
 
 config I2C_SH_MOBILE
        tristate "SuperH Mobile I2C Controller"
-       depends on HAS_DMA
        depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST
        help
          If you say yes to this option, support will be included for the
@@ -1098,7 +1096,6 @@ config I2C_XLP9XX
 
 config I2C_RCAR
        tristate "Renesas R-Car I2C Controller"
-       depends on HAS_DMA
        depends on ARCH_RENESAS || COMPILE_TEST
        select I2C_SLAVE
        help
index 25fcc3c1e32bf3d9a41fa345982039fb234dbcbd..4053259bccb8d704d9d386287086841690174844 100644 (file)
@@ -86,6 +86,7 @@ struct sprd_i2c {
        u32 count;
        int irq;
        int err;
+       bool is_suspended;
 };
 
 static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count)
@@ -283,6 +284,9 @@ static int sprd_i2c_master_xfer(struct i2c_adapter *i2c_adap,
        struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
        int im, ret;
 
+       if (i2c_dev->is_suspended)
+               return -EBUSY;
+
        ret = pm_runtime_get_sync(i2c_dev->dev);
        if (ret < 0)
                return ret;
@@ -364,13 +368,12 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
        struct sprd_i2c *i2c_dev = dev_id;
        struct i2c_msg *msg = i2c_dev->msg;
        bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
-       u32 i2c_count = readl(i2c_dev->base + I2C_COUNT);
        u32 i2c_tran;
 
        if (msg->flags & I2C_M_RD)
                i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
        else
-               i2c_tran = i2c_count;
+               i2c_tran = i2c_dev->count;
 
        /*
         * If we got one ACK from slave when writing data, and we did not
@@ -408,14 +411,13 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
 {
        struct sprd_i2c *i2c_dev = dev_id;
        struct i2c_msg *msg = i2c_dev->msg;
-       u32 i2c_count = readl(i2c_dev->base + I2C_COUNT);
        bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
        u32 i2c_tran;
 
        if (msg->flags & I2C_M_RD)
                i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
        else
-               i2c_tran = i2c_count;
+               i2c_tran = i2c_dev->count;
 
        /*
         * If we did not get one ACK from slave when writing data, then we
@@ -586,11 +588,23 @@ static int sprd_i2c_remove(struct platform_device *pdev)
 
 static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev)
 {
+       struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
+
+       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_dev->is_suspended = true;
+       i2c_unlock_adapter(&i2c_dev->adap);
+
        return pm_runtime_force_suspend(pdev);
 }
 
 static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev)
 {
+       struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
+
+       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_dev->is_suspended = false;
+       i2c_unlock_adapter(&i2c_dev->adap);
+
        return pm_runtime_force_resume(pdev);
 }
 
index 036a03f0d0a6866001d0badd11cb9b30516ca5de..1667b6e7674f4a0439befcd544d74753e41d43f3 100644 (file)
@@ -280,7 +280,7 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
                 */
                if (msgs[i].flags & I2C_M_RECV_LEN) {
                        if (!(msgs[i].flags & I2C_M_RD) ||
-                           msgs[i].buf[0] < 1 ||
+                           msgs[i].len < 1 || msgs[i].buf[0] < 1 ||
                            msgs[i].len < msgs[i].buf[0] +
                                             I2C_SMBUS_BLOCK_MAX) {
                                res = -EINVAL;