diff options
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 14 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.h | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 6 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 8 |
5 files changed, 24 insertions, 7 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 21fbb340ad66..c41ca6354fc5 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -383,7 +383,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) | |||
383 | /* Enable the adapter */ | 383 | /* Enable the adapter */ |
384 | __i2c_dw_enable(dev, true); | 384 | __i2c_dw_enable(dev, true); |
385 | 385 | ||
386 | /* Enable interrupts */ | 386 | /* Clear and enable interrupts */ |
387 | i2c_dw_clear_int(dev); | ||
387 | dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); | 388 | dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); |
388 | } | 389 | } |
389 | 390 | ||
@@ -448,8 +449,14 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) | |||
448 | cmd |= BIT(9); | 449 | cmd |= BIT(9); |
449 | 450 | ||
450 | if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { | 451 | if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { |
452 | |||
453 | /* avoid rx buffer overrun */ | ||
454 | if (rx_limit - dev->rx_outstanding <= 0) | ||
455 | break; | ||
456 | |||
451 | dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD); | 457 | dw_writel(dev, cmd | 0x100, DW_IC_DATA_CMD); |
452 | rx_limit--; | 458 | rx_limit--; |
459 | dev->rx_outstanding++; | ||
453 | } else | 460 | } else |
454 | dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD); | 461 | dw_writel(dev, cmd | *buf++, DW_IC_DATA_CMD); |
455 | tx_limit--; buf_len--; | 462 | tx_limit--; buf_len--; |
@@ -502,8 +509,10 @@ i2c_dw_read(struct dw_i2c_dev *dev) | |||
502 | 509 | ||
503 | rx_valid = dw_readl(dev, DW_IC_RXFLR); | 510 | rx_valid = dw_readl(dev, DW_IC_RXFLR); |
504 | 511 | ||
505 | for (; len > 0 && rx_valid > 0; len--, rx_valid--) | 512 | for (; len > 0 && rx_valid > 0; len--, rx_valid--) { |
506 | *buf++ = dw_readl(dev, DW_IC_DATA_CMD); | 513 | *buf++ = dw_readl(dev, DW_IC_DATA_CMD); |
514 | dev->rx_outstanding--; | ||
515 | } | ||
507 | 516 | ||
508 | if (len > 0) { | 517 | if (len > 0) { |
509 | dev->status |= STATUS_READ_IN_PROGRESS; | 518 | dev->status |= STATUS_READ_IN_PROGRESS; |
@@ -561,6 +570,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
561 | dev->msg_err = 0; | 570 | dev->msg_err = 0; |
562 | dev->status = STATUS_IDLE; | 571 | dev->status = STATUS_IDLE; |
563 | dev->abort_source = 0; | 572 | dev->abort_source = 0; |
573 | dev->rx_outstanding = 0; | ||
564 | 574 | ||
565 | ret = i2c_dw_wait_bus_not_busy(dev); | 575 | ret = i2c_dw_wait_bus_not_busy(dev); |
566 | if (ret < 0) | 576 | if (ret < 0) |
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 9c1840ee09c7..e761ad18dd61 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h | |||
@@ -60,6 +60,7 @@ | |||
60 | * @adapter: i2c subsystem adapter node | 60 | * @adapter: i2c subsystem adapter node |
61 | * @tx_fifo_depth: depth of the hardware tx fifo | 61 | * @tx_fifo_depth: depth of the hardware tx fifo |
62 | * @rx_fifo_depth: depth of the hardware rx fifo | 62 | * @rx_fifo_depth: depth of the hardware rx fifo |
63 | * @rx_outstanding: current master-rx elements in tx fifo | ||
63 | */ | 64 | */ |
64 | struct dw_i2c_dev { | 65 | struct dw_i2c_dev { |
65 | struct device *dev; | 66 | struct device *dev; |
@@ -88,6 +89,7 @@ struct dw_i2c_dev { | |||
88 | u32 master_cfg; | 89 | u32 master_cfg; |
89 | unsigned int tx_fifo_depth; | 90 | unsigned int tx_fifo_depth; |
90 | unsigned int rx_fifo_depth; | 91 | unsigned int rx_fifo_depth; |
92 | int rx_outstanding; | ||
91 | }; | 93 | }; |
92 | 94 | ||
93 | #define ACCESS_SWAP 0x00000001 | 95 | #define ACCESS_SWAP 0x00000001 |
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 8ec91335d95a..35b70a1edf57 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -69,6 +69,7 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev) | |||
69 | static const struct acpi_device_id dw_i2c_acpi_match[] = { | 69 | static const struct acpi_device_id dw_i2c_acpi_match[] = { |
70 | { "INT33C2", 0 }, | 70 | { "INT33C2", 0 }, |
71 | { "INT33C3", 0 }, | 71 | { "INT33C3", 0 }, |
72 | { "80860F41", 0 }, | ||
72 | { } | 73 | { } |
73 | }; | 74 | }; |
74 | MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); | 75 | MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index e1cf2e0e1f23..3a6903f63913 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -231,7 +231,11 @@ static const char *i801_feature_names[] = { | |||
231 | 231 | ||
232 | static unsigned int disable_features; | 232 | static unsigned int disable_features; |
233 | module_param(disable_features, uint, S_IRUGO | S_IWUSR); | 233 | module_param(disable_features, uint, S_IRUGO | S_IWUSR); |
234 | MODULE_PARM_DESC(disable_features, "Disable selected driver features"); | 234 | MODULE_PARM_DESC(disable_features, "Disable selected driver features:\n" |
235 | "\t\t 0x01 disable SMBus PEC\n" | ||
236 | "\t\t 0x02 disable the block buffer\n" | ||
237 | "\t\t 0x08 disable the I2C block read functionality\n" | ||
238 | "\t\t 0x10 don't use interrupts "); | ||
235 | 239 | ||
236 | /* Make sure the SMBus host is ready to start transmitting. | 240 | /* Make sure the SMBus host is ready to start transmitting. |
237 | Return 0 if it is, -EBUSY if it is not. */ | 241 | Return 0 if it is, -EBUSY if it is not. */ |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 3bbd65d35a5e..1a3abd6a0bfc 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -252,7 +252,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
252 | writel(drv_data->cntl_bits, | 252 | writel(drv_data->cntl_bits, |
253 | drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); | 253 | drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); |
254 | drv_data->block = 0; | 254 | drv_data->block = 0; |
255 | wake_up_interruptible(&drv_data->waitq); | 255 | wake_up(&drv_data->waitq); |
256 | break; | 256 | break; |
257 | 257 | ||
258 | case MV64XXX_I2C_ACTION_CONTINUE: | 258 | case MV64XXX_I2C_ACTION_CONTINUE: |
@@ -300,7 +300,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
300 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, | 300 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, |
301 | drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); | 301 | drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); |
302 | drv_data->block = 0; | 302 | drv_data->block = 0; |
303 | wake_up_interruptible(&drv_data->waitq); | 303 | wake_up(&drv_data->waitq); |
304 | break; | 304 | break; |
305 | 305 | ||
306 | case MV64XXX_I2C_ACTION_INVALID: | 306 | case MV64XXX_I2C_ACTION_INVALID: |
@@ -315,7 +315,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
315 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, | 315 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, |
316 | drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); | 316 | drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); |
317 | drv_data->block = 0; | 317 | drv_data->block = 0; |
318 | wake_up_interruptible(&drv_data->waitq); | 318 | wake_up(&drv_data->waitq); |
319 | break; | 319 | break; |
320 | } | 320 | } |
321 | } | 321 | } |
@@ -381,7 +381,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) | |||
381 | unsigned long flags; | 381 | unsigned long flags; |
382 | char abort = 0; | 382 | char abort = 0; |
383 | 383 | ||
384 | time_left = wait_event_interruptible_timeout(drv_data->waitq, | 384 | time_left = wait_event_timeout(drv_data->waitq, |
385 | !drv_data->block, drv_data->adapter.timeout); | 385 | !drv_data->block, drv_data->adapter.timeout); |
386 | 386 | ||
387 | spin_lock_irqsave(&drv_data->lock, flags); | 387 | spin_lock_irqsave(&drv_data->lock, flags); |