Browse Source

Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

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
Linus Torvalds 7 years ago
parent
commit
a97d8efd9d

+ 14 - 18
Documentation/i2c/dev-interface

@@ -9,8 +9,8 @@ i2c adapters present on your system at a given time. i2cdetect is part of
 the i2c-tools package.
 the i2c-tools package.
 
 
 I2C device files are character device files with major device number 89
 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.
 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 <linux/i2c-dev.h>
   #include <i2c/smbus.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
 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.
 inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this.
 Adapter numbers are assigned somewhat dynamically, so you can not
 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 file;
   int adapter_nr = 2; /* probably dynamically determined */
   int adapter_nr = 2; /* probably dynamically determined */
   char filename[20];
   char filename[20];
-  
+
   snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
   snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
   file = open(filename, O_RDWR);
   file = open(filename, O_RDWR);
   if (file < 0) {
   if (file < 0) {
@@ -72,8 +67,10 @@ the device supports them. Both are illustrated below.
     /* res contains the read word */
     /* 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[0] = reg;
   buf[1] = 0x43;
   buf[1] = 0x43;
   buf[2] = 0x65;
   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.
   set in each message, overriding the values set with the above ioctl's.
 
 
 ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)
 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 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
 You do not need to pass the address byte; instead, set it through
 ioctl I2C_SLAVE before you try to access the device.
 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:
 for details) through the following functions:
   __s32 i2c_smbus_write_quick(int file, __u8 value);
   __s32 i2c_smbus_write_quick(int file, __u8 value);
   __s32 i2c_smbus_read_byte(int file);
   __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_write_word_data(int file, __u8 command, __u16 value);
   __s32 i2c_smbus_process_call(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_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);
                                    __u8 *values);
 All these transactions return -1 on failure; you can read errno to see
 All these transactions return -1 on failure; you can read errno to see
 what happened. The 'write' transactions return 0 on success; the
 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
 returns the number of values read. The block buffers need not be longer
 than 32 bytes.
 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
 Implementation details

+ 0 - 3
drivers/i2c/busses/Kconfig

@@ -707,7 +707,6 @@ config I2C_MPC
 config I2C_MT65XX
 config I2C_MT65XX
 	tristate "MediaTek I2C adapter"
 	tristate "MediaTek I2C adapter"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 	depends on ARCH_MEDIATEK || COMPILE_TEST
-	depends on HAS_DMA
 	help
 	help
 	  This selects the MediaTek(R) Integrated Inter Circuit bus driver
 	  This selects the MediaTek(R) Integrated Inter Circuit bus driver
 	  for MT65xx and MT81xx.
 	  for MT65xx and MT81xx.
@@ -885,7 +884,6 @@ config I2C_SH7760
 
 
 config I2C_SH_MOBILE
 config I2C_SH_MOBILE
 	tristate "SuperH Mobile I2C Controller"
 	tristate "SuperH Mobile I2C Controller"
-	depends on HAS_DMA
 	depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST
 	depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST
 	help
 	help
 	  If you say yes to this option, support will be included for the
 	  If you say yes to this option, support will be included for the
@@ -1098,7 +1096,6 @@ config I2C_XLP9XX
 
 
 config I2C_RCAR
 config I2C_RCAR
 	tristate "Renesas R-Car I2C Controller"
 	tristate "Renesas R-Car I2C Controller"
-	depends on HAS_DMA
 	depends on ARCH_RENESAS || COMPILE_TEST
 	depends on ARCH_RENESAS || COMPILE_TEST
 	select I2C_SLAVE
 	select I2C_SLAVE
 	help
 	help

+ 18 - 4
drivers/i2c/busses/i2c-sprd.c

@@ -86,6 +86,7 @@ struct sprd_i2c {
 	u32 count;
 	u32 count;
 	int irq;
 	int irq;
 	int err;
 	int err;
+	bool is_suspended;
 };
 };
 
 
 static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count)
 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;
 	struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
 	int im, ret;
 	int im, ret;
 
 
+	if (i2c_dev->is_suspended)
+		return -EBUSY;
+
 	ret = pm_runtime_get_sync(i2c_dev->dev);
 	ret = pm_runtime_get_sync(i2c_dev->dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		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 sprd_i2c *i2c_dev = dev_id;
 	struct i2c_msg *msg = i2c_dev->msg;
 	struct i2c_msg *msg = i2c_dev->msg;
 	bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
 	bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
-	u32 i2c_count = readl(i2c_dev->base + I2C_COUNT);
 	u32 i2c_tran;
 	u32 i2c_tran;
 
 
 	if (msg->flags & I2C_M_RD)
 	if (msg->flags & I2C_M_RD)
 		i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
 		i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
 	else
 	else
-		i2c_tran = i2c_count;
+		i2c_tran = i2c_dev->count;
 
 
 	/*
 	/*
 	 * If we got one ACK from slave when writing data, and we did not
 	 * 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 sprd_i2c *i2c_dev = dev_id;
 	struct i2c_msg *msg = i2c_dev->msg;
 	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);
 	bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
 	u32 i2c_tran;
 	u32 i2c_tran;
 
 
 	if (msg->flags & I2C_M_RD)
 	if (msg->flags & I2C_M_RD)
 		i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
 		i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
 	else
 	else
-		i2c_tran = i2c_count;
+		i2c_tran = i2c_dev->count;
 
 
 	/*
 	/*
 	 * If we did not get one ACK from slave when writing data, then we
 	 * 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)
 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);
 	return pm_runtime_force_suspend(pdev);
 }
 }
 
 
 static int __maybe_unused sprd_i2c_resume_noirq(struct device *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);
 	return pm_runtime_force_resume(pdev);
 }
 }
 
 

+ 1 - 1
drivers/i2c/i2c-dev.c

@@ -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_RECV_LEN) {
 			if (!(msgs[i].flags & I2C_M_RD) ||
 			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] +
 			    msgs[i].len < msgs[i].buf[0] +
 					     I2C_SMBUS_BLOCK_MAX) {
 					     I2C_SMBUS_BLOCK_MAX) {
 				res = -EINVAL;
 				res = -EINVAL;