summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-davinci.c2
-rw-r--r--drivers/i2c/busses/i2c-stm32f7.c6
-rw-r--r--drivers/i2c/busses/i2c-tegra.c19
-rw-r--r--drivers/i2c/busses/i2c-virtio.c2
-rw-r--r--drivers/i2c/i2c-core-acpi.c1
-rw-r--r--drivers/i2c/i2c-core-base.c3
-rw-r--r--drivers/i2c/i2c-core-smbus.c13
-rw-r--r--drivers/i2c/i2c-dev.c9
-rw-r--r--drivers/i2c/i2c-slave-testunit.c4
-rw-r--r--drivers/i2c/i2c-stub.c5
10 files changed, 42 insertions, 22 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index a773ba082321..66c23535656b 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -117,7 +117,7 @@
/* timeout for pm runtime autosuspend */
#define DAVINCI_I2C_PM_TIMEOUT 1000 /* ms */
-#define DAVINCI_I2C_DEFAULT_BUS_FREQ 100
+#define DAVINCI_I2C_DEFAULT_BUS_FREQ 100000
struct davinci_i2c_dev {
struct device *dev;
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index 70cb5822bf17..53d9df70ebe4 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -895,8 +895,6 @@ static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
f7_msg->result = 0;
f7_msg->stop = (i2c_dev->msg_id >= i2c_dev->msg_num - 1);
- reinit_completion(&i2c_dev->complete);
-
cr1 = readl_relaxed(base + STM32F7_I2C_CR1);
cr2 = readl_relaxed(base + STM32F7_I2C_CR2);
@@ -1728,6 +1726,8 @@ static int stm32f7_i2c_xfer_core(struct i2c_adapter *i2c_adap,
if (ret)
goto pm_free;
+ reinit_completion(&i2c_dev->complete);
+
stm32f7_i2c_xfer_msg(i2c_dev, msgs);
if (!i2c_dev->atomic)
@@ -2253,7 +2253,7 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)",
&res->start);
adap->owner = THIS_MODULE;
- adap->timeout = 2 * HZ;
+ adap->timeout = 8 * HZ;
adap->retries = 3;
adap->algo = &stm32f7_i2c_algo;
adap->dev.parent = &pdev->dev;
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 9fd5ade774a0..479a1667e88d 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -589,25 +589,22 @@ static int tegra_i2c_mutex_lock(struct tegra_i2c_dev *i2c_dev)
return ret;
}
-static int tegra_i2c_mutex_unlock(struct tegra_i2c_dev *i2c_dev)
+static void tegra_i2c_mutex_unlock(struct tegra_i2c_dev *i2c_dev)
{
unsigned int reg = i2c_dev->hw->regs->sw_mutex;
u32 val, id;
if (!i2c_dev->hw->has_mutex)
- return 0;
+ return;
val = readl(i2c_dev->base + reg);
id = FIELD_GET(I2C_SW_MUTEX_GRANT, val);
- if (id && id != I2C_SW_MUTEX_ID_CCPLEX) {
- dev_warn(i2c_dev->dev, "unable to unlock mutex, mutex is owned by: %u\n", id);
- return -EPERM;
- }
+ if (WARN(id && id != I2C_SW_MUTEX_ID_CCPLEX,
+ "unable to unlock mutex, mutex is owned by: %u\n", id))
+ return;
writel(0, i2c_dev->base + reg);
-
- return 0;
}
static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
@@ -1666,8 +1663,10 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
}
ret = tegra_i2c_mutex_lock(i2c_dev);
- if (ret)
+ if (ret) {
+ pm_runtime_put(i2c_dev->dev);
return ret;
+ }
for (i = 0; i < num; i++) {
enum msg_end_type end_type = MSG_END_STOP;
@@ -1698,7 +1697,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
break;
}
- ret = tegra_i2c_mutex_unlock(i2c_dev);
+ tegra_i2c_mutex_unlock(i2c_dev);
pm_runtime_put(i2c_dev->dev);
return ret ?: i;
diff --git a/drivers/i2c/busses/i2c-virtio.c b/drivers/i2c/busses/i2c-virtio.c
index 7b0b0bff8000..5da6fef92bec 100644
--- a/drivers/i2c/busses/i2c-virtio.c
+++ b/drivers/i2c/busses/i2c-virtio.c
@@ -222,6 +222,8 @@ static int virtio_i2c_probe(struct virtio_device *vdev)
*/
ACPI_COMPANION_SET(&vi->adap.dev, ACPI_COMPANION(vdev->dev.parent));
+ virtio_device_ready(vdev);
+
ret = i2c_add_adapter(&vi->adap);
if (ret)
virtio_i2c_del_vqs(vdev);
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index 2cbd31f77667..28c0e4884a7f 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -371,6 +371,7 @@ static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = {
* a 400KHz frequency. The root cause of the issue is not known.
*/
{ "DLL0945", 0 },
+ { "ELAN0678", 0 },
{ "ELAN06FA", 0 },
{}
};
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 9c46147e3506..a2132d70fb36 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -445,8 +445,7 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
bri->set_scl = set_scl_gpio_value;
if (bri->sda_gpiod) {
bri->get_sda = get_sda_gpio_value;
- /* FIXME: add proper flag instead of '0' once available */
- if (gpiod_get_direction(bri->sda_gpiod) == 0)
+ if (gpiod_get_direction(bri->sda_gpiod) == GPIO_LINE_DIRECTION_OUT)
bri->set_sda = set_sda_gpio_value;
}
} else if (bri->recover_bus == i2c_generic_scl_recovery) {
diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c
index 71eb1ef56f0c..fa63bee0b345 100644
--- a/drivers/i2c/i2c-core-smbus.c
+++ b/drivers/i2c/i2c-core-smbus.c
@@ -353,6 +353,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter *adapter, u16 addr,
&& size != I2C_SMBUS_I2C_BLOCK_DATA);
msgbuf0[0] = command;
+ msgbuf1[0] = 0;
switch (size) {
case I2C_SMBUS_QUICK:
msg[0].len = 0;
@@ -566,6 +567,18 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
if (res)
return res;
+ /* Reject invalid caller-supplied block lengths before any
+ * tracepoint or native smbus_xfer callback runs.
+ */
+ if (data &&
+ (protocol == I2C_SMBUS_I2C_BLOCK_DATA ||
+ protocol == I2C_SMBUS_BLOCK_PROC_CALL ||
+ (protocol == I2C_SMBUS_BLOCK_DATA &&
+ read_write == I2C_SMBUS_WRITE)) &&
+ (data->block[0] == 0 ||
+ data->block[0] > I2C_SMBUS_BLOCK_MAX))
+ return -EINVAL;
+
/* If enabled, the following two tracepoints are conditional on
* read_write and protocol.
*/
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 7bbe0263411e..ccaac5e29f90 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -487,12 +487,13 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
client->adapter->retries = arg;
break;
case I2C_TIMEOUT:
- if (arg > INT_MAX)
+ /*
+ * For historical reasons, user-space sets the timeout value in
+ * units of 10 ms.
+ */
+ if (arg > INT_MAX / 10)
return -EINVAL;
- /* For historical reasons, user-space sets the timeout
- * value in units of 10 ms.
- */
client->adapter->timeout = msecs_to_jiffies(arg * 10);
break;
default:
diff --git a/drivers/i2c/i2c-slave-testunit.c b/drivers/i2c/i2c-slave-testunit.c
index 6de4307050dd..871c58461ebc 100644
--- a/drivers/i2c/i2c-slave-testunit.c
+++ b/drivers/i2c/i2c-slave-testunit.c
@@ -15,7 +15,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/slab.h>
-#include <linux/workqueue.h> /* FIXME: is system_long_wq the best choice? */
+#include <linux/workqueue.h>
#define TU_VERSION_MAX_LENGTH 128
@@ -124,7 +124,7 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
case I2C_SLAVE_STOP:
if (tu->reg_idx == TU_NUM_REGS) {
set_bit(TU_FLAG_IN_PROCESS, &tu->flags);
- queue_delayed_work(system_long_wq, &tu->worker,
+ queue_delayed_work(system_dfl_long_wq, &tu->worker,
msecs_to_jiffies(10 * tu->regs[TU_REG_DELAY]));
}
diff --git a/drivers/i2c/i2c-stub.c b/drivers/i2c/i2c-stub.c
index fbb0db41b10e..04314e3ed24c 100644
--- a/drivers/i2c/i2c-stub.c
+++ b/drivers/i2c/i2c-stub.c
@@ -214,6 +214,11 @@ static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags,
* We ignore banks here, because banked chips don't use I2C
* block transfers
*/
+ if (data->block[0] == 0 ||
+ data->block[0] > I2C_SMBUS_BLOCK_MAX) {
+ ret = -EINVAL;
+ break;
+ }
if (data->block[0] > 256 - command) /* Avoid overrun */
data->block[0] = 256 - command;
len = data->block[0];