diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-28 19:06:16 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-28 19:06:16 +0200 |
commit | a97d8efd9d350bd9c6cf13689c7cc09049b42acd (patch) | |
tree | 6159a9faa50938c01cab75fd0bab4313a9c92247 /drivers | |
parent | Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert... (diff) | |
parent | i2c: sprd: Fix the i2c count issue (diff) | |
download | linux-a97d8efd9d350bd9c6cf13689c7cc09049b42acd.tar.xz linux-a97d8efd9d350bd9c6cf13689c7cc09049b42acd.zip |
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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/Kconfig | 3 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-sprd.c | 22 | ||||
-rw-r--r-- | drivers/i2c/i2c-dev.c | 2 |
3 files changed, 19 insertions, 8 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c4865b08d7fb..8d21b9825d71 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -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 diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c index 25fcc3c1e32b..4053259bccb8 100644 --- a/drivers/i2c/busses/i2c-sprd.c +++ b/drivers/i2c/busses/i2c-sprd.c @@ -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); } diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 036a03f0d0a6..1667b6e7674f 100644 --- a/drivers/i2c/i2c-dev.c +++ b/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_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; |