Commit a97d8efd authored by Linus Torvalds's avatar Linus Torvalds

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
parents 6e041ffc 2a010461
...@@ -9,8 +9,8 @@ i2c adapters present on your system at a given time. i2cdetect is part of ...@@ -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 and a minor device number corresponding to the number assigned as
explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., 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: ...@@ -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: ...@@ -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. ...@@ -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) ...@@ -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 If possible, use the provided i2c_smbus_* methods described below instead
below. 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: ...@@ -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 ...@@ -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 above functions are made available by linking against the libi2c library,
the i2c_smbus_access function, that on its turn calls a specific ioctl which is provided by the i2c-tools project. See:
with the data in a specific format. Read the source code if you https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/.
want to know what happens behind the screens.
Implementation details Implementation details
......
...@@ -707,7 +707,6 @@ config I2C_MPC ...@@ -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 ...@@ -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 ...@@ -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
......
...@@ -86,6 +86,7 @@ struct sprd_i2c { ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
...@@ -280,7 +280,7 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment