diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-brcmstb.c | 27 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.h | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 28 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-exynos5.c | 3 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-meson.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mt65xx.c | 9 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-riic.c | 6 | ||||
-rw-r--r-- | drivers/i2c/i2c-mux.c | 2 |
8 files changed, 56 insertions, 22 deletions
diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c index 0652281662a8..78792b4d6437 100644 --- a/drivers/i2c/busses/i2c-brcmstb.c +++ b/drivers/i2c/busses/i2c-brcmstb.c | |||
@@ -465,6 +465,7 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, | |||
465 | u8 *tmp_buf; | 465 | u8 *tmp_buf; |
466 | int len = 0; | 466 | int len = 0; |
467 | int xfersz = brcmstb_i2c_get_xfersz(dev); | 467 | int xfersz = brcmstb_i2c_get_xfersz(dev); |
468 | u32 cond, cond_per_msg; | ||
468 | 469 | ||
469 | if (dev->is_suspended) | 470 | if (dev->is_suspended) |
470 | return -EBUSY; | 471 | return -EBUSY; |
@@ -481,10 +482,11 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, | |||
481 | pmsg->buf ? pmsg->buf[0] : '0', pmsg->len); | 482 | pmsg->buf ? pmsg->buf[0] : '0', pmsg->len); |
482 | 483 | ||
483 | if (i < (num - 1) && (msgs[i + 1].flags & I2C_M_NOSTART)) | 484 | if (i < (num - 1) && (msgs[i + 1].flags & I2C_M_NOSTART)) |
484 | brcmstb_set_i2c_start_stop(dev, ~(COND_START_STOP)); | 485 | cond = ~COND_START_STOP; |
485 | else | 486 | else |
486 | brcmstb_set_i2c_start_stop(dev, | 487 | cond = COND_RESTART | COND_NOSTOP; |
487 | COND_RESTART | COND_NOSTOP); | 488 | |
489 | brcmstb_set_i2c_start_stop(dev, cond); | ||
488 | 490 | ||
489 | /* Send slave address */ | 491 | /* Send slave address */ |
490 | if (!(pmsg->flags & I2C_M_NOSTART)) { | 492 | if (!(pmsg->flags & I2C_M_NOSTART)) { |
@@ -497,13 +499,24 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, | |||
497 | } | 499 | } |
498 | } | 500 | } |
499 | 501 | ||
502 | cond_per_msg = cond; | ||
503 | |||
500 | /* Perform data transfer */ | 504 | /* Perform data transfer */ |
501 | while (len) { | 505 | while (len) { |
502 | bytes_to_xfer = min(len, xfersz); | 506 | bytes_to_xfer = min(len, xfersz); |
503 | 507 | ||
504 | if (len <= xfersz && i == (num - 1)) | 508 | if (len <= xfersz) { |
505 | brcmstb_set_i2c_start_stop(dev, | 509 | if (i == (num - 1)) |
506 | ~(COND_START_STOP)); | 510 | cond_per_msg = cond_per_msg & |
511 | ~(COND_RESTART | COND_NOSTOP); | ||
512 | else | ||
513 | cond_per_msg = cond; | ||
514 | } else { | ||
515 | cond_per_msg = (cond_per_msg & ~COND_RESTART) | | ||
516 | COND_NOSTOP; | ||
517 | } | ||
518 | |||
519 | brcmstb_set_i2c_start_stop(dev, cond_per_msg); | ||
507 | 520 | ||
508 | rc = brcmstb_i2c_xfer_bsc_data(dev, tmp_buf, | 521 | rc = brcmstb_i2c_xfer_bsc_data(dev, tmp_buf, |
509 | bytes_to_xfer, pmsg); | 522 | bytes_to_xfer, pmsg); |
@@ -512,6 +525,8 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter, | |||
512 | 525 | ||
513 | len -= bytes_to_xfer; | 526 | len -= bytes_to_xfer; |
514 | tmp_buf += bytes_to_xfer; | 527 | tmp_buf += bytes_to_xfer; |
528 | |||
529 | cond_per_msg = COND_NOSTART | COND_NOSTOP; | ||
515 | } | 530 | } |
516 | } | 531 | } |
517 | 532 | ||
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index c1db3a5a340f..d9aaf1790e0e 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h | |||
@@ -88,6 +88,7 @@ struct dw_i2c_dev { | |||
88 | void __iomem *base; | 88 | void __iomem *base; |
89 | struct completion cmd_complete; | 89 | struct completion cmd_complete; |
90 | struct clk *clk; | 90 | struct clk *clk; |
91 | struct reset_control *rst; | ||
91 | u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev); | 92 | u32 (*get_clk_rate_khz) (struct dw_i2c_dev *dev); |
92 | struct dw_pci_controller *controller; | 93 | struct dw_pci_controller *controller; |
93 | int cmd_err; | 94 | int cmd_err; |
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 6ce431323125..79c4b4ea0539 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/pm_runtime.h> | 38 | #include <linux/pm_runtime.h> |
39 | #include <linux/property.h> | 39 | #include <linux/property.h> |
40 | #include <linux/io.h> | 40 | #include <linux/io.h> |
41 | #include <linux/reset.h> | ||
41 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
42 | #include <linux/acpi.h> | 43 | #include <linux/acpi.h> |
43 | #include <linux/platform_data/i2c-designware.h> | 44 | #include <linux/platform_data/i2c-designware.h> |
@@ -199,6 +200,14 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) | |||
199 | dev->irq = irq; | 200 | dev->irq = irq; |
200 | platform_set_drvdata(pdev, dev); | 201 | platform_set_drvdata(pdev, dev); |
201 | 202 | ||
203 | dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); | ||
204 | if (IS_ERR(dev->rst)) { | ||
205 | if (PTR_ERR(dev->rst) == -EPROBE_DEFER) | ||
206 | return -EPROBE_DEFER; | ||
207 | } else { | ||
208 | reset_control_deassert(dev->rst); | ||
209 | } | ||
210 | |||
202 | if (pdata) { | 211 | if (pdata) { |
203 | dev->clk_freq = pdata->i2c_scl_freq; | 212 | dev->clk_freq = pdata->i2c_scl_freq; |
204 | } else { | 213 | } else { |
@@ -235,12 +244,13 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) | |||
235 | && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) { | 244 | && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) { |
236 | dev_err(&pdev->dev, | 245 | dev_err(&pdev->dev, |
237 | "Only 100kHz, 400kHz, 1MHz and 3.4MHz supported"); | 246 | "Only 100kHz, 400kHz, 1MHz and 3.4MHz supported"); |
238 | return -EINVAL; | 247 | r = -EINVAL; |
248 | goto exit_reset; | ||
239 | } | 249 | } |
240 | 250 | ||
241 | r = i2c_dw_eval_lock_support(dev); | 251 | r = i2c_dw_eval_lock_support(dev); |
242 | if (r) | 252 | if (r) |
243 | return r; | 253 | goto exit_reset; |
244 | 254 | ||
245 | dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY; | 255 | dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY; |
246 | 256 | ||
@@ -286,10 +296,18 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) | |||
286 | } | 296 | } |
287 | 297 | ||
288 | r = i2c_dw_probe(dev); | 298 | r = i2c_dw_probe(dev); |
289 | if (r && !dev->pm_runtime_disabled) | 299 | if (r) |
290 | pm_runtime_disable(&pdev->dev); | 300 | goto exit_probe; |
291 | 301 | ||
292 | return r; | 302 | return r; |
303 | |||
304 | exit_probe: | ||
305 | if (!dev->pm_runtime_disabled) | ||
306 | pm_runtime_disable(&pdev->dev); | ||
307 | exit_reset: | ||
308 | if (!IS_ERR_OR_NULL(dev->rst)) | ||
309 | reset_control_assert(dev->rst); | ||
310 | return r; | ||
293 | } | 311 | } |
294 | 312 | ||
295 | static int dw_i2c_plat_remove(struct platform_device *pdev) | 313 | static int dw_i2c_plat_remove(struct platform_device *pdev) |
@@ -306,6 +324,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev) | |||
306 | pm_runtime_put_sync(&pdev->dev); | 324 | pm_runtime_put_sync(&pdev->dev); |
307 | if (!dev->pm_runtime_disabled) | 325 | if (!dev->pm_runtime_disabled) |
308 | pm_runtime_disable(&pdev->dev); | 326 | pm_runtime_disable(&pdev->dev); |
327 | if (!IS_ERR_OR_NULL(dev->rst)) | ||
328 | reset_control_assert(dev->rst); | ||
309 | 329 | ||
310 | return 0; | 330 | return 0; |
311 | } | 331 | } |
diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index cbd93ce0661f..736a82472101 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c | |||
@@ -457,7 +457,6 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) | |||
457 | 457 | ||
458 | int_status = readl(i2c->regs + HSI2C_INT_STATUS); | 458 | int_status = readl(i2c->regs + HSI2C_INT_STATUS); |
459 | writel(int_status, i2c->regs + HSI2C_INT_STATUS); | 459 | writel(int_status, i2c->regs + HSI2C_INT_STATUS); |
460 | trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); | ||
461 | 460 | ||
462 | /* handle interrupt related to the transfer status */ | 461 | /* handle interrupt related to the transfer status */ |
463 | if (i2c->variant->hw == HSI2C_EXYNOS7) { | 462 | if (i2c->variant->hw == HSI2C_EXYNOS7) { |
@@ -482,11 +481,13 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id) | |||
482 | goto stop; | 481 | goto stop; |
483 | } | 482 | } |
484 | 483 | ||
484 | trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); | ||
485 | if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) { | 485 | if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) { |
486 | i2c->state = -EAGAIN; | 486 | i2c->state = -EAGAIN; |
487 | goto stop; | 487 | goto stop; |
488 | } | 488 | } |
489 | } else if (int_status & HSI2C_INT_I2C) { | 489 | } else if (int_status & HSI2C_INT_I2C) { |
490 | trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS); | ||
490 | if (trans_status & HSI2C_NO_DEV_ACK) { | 491 | if (trans_status & HSI2C_NO_DEV_ACK) { |
491 | dev_dbg(i2c->dev, "No ACK from device\n"); | 492 | dev_dbg(i2c->dev, "No ACK from device\n"); |
492 | i2c->state = -ENXIO; | 493 | i2c->state = -ENXIO; |
diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c index 2aa61bbbd307..73b97c71a484 100644 --- a/drivers/i2c/busses/i2c-meson.c +++ b/drivers/i2c/busses/i2c-meson.c | |||
@@ -175,7 +175,7 @@ static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len) | |||
175 | wdata1 |= *buf++ << ((i - 4) * 8); | 175 | wdata1 |= *buf++ << ((i - 4) * 8); |
176 | 176 | ||
177 | writel(wdata0, i2c->regs + REG_TOK_WDATA0); | 177 | writel(wdata0, i2c->regs + REG_TOK_WDATA0); |
178 | writel(wdata0, i2c->regs + REG_TOK_WDATA1); | 178 | writel(wdata1, i2c->regs + REG_TOK_WDATA1); |
179 | 179 | ||
180 | dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__, | 180 | dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__, |
181 | wdata0, wdata1, len); | 181 | wdata0, wdata1, len); |
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 4a7d9bc2142b..45d61714c81b 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c | |||
@@ -172,14 +172,6 @@ static const struct i2c_adapter_quirks mt6577_i2c_quirks = { | |||
172 | .max_comb_2nd_msg_len = 31, | 172 | .max_comb_2nd_msg_len = 31, |
173 | }; | 173 | }; |
174 | 174 | ||
175 | static const struct i2c_adapter_quirks mt8173_i2c_quirks = { | ||
176 | .max_num_msgs = 65535, | ||
177 | .max_write_len = 65535, | ||
178 | .max_read_len = 65535, | ||
179 | .max_comb_1st_msg_len = 65535, | ||
180 | .max_comb_2nd_msg_len = 65535, | ||
181 | }; | ||
182 | |||
183 | static const struct mtk_i2c_compatible mt6577_compat = { | 175 | static const struct mtk_i2c_compatible mt6577_compat = { |
184 | .quirks = &mt6577_i2c_quirks, | 176 | .quirks = &mt6577_i2c_quirks, |
185 | .pmic_i2c = 0, | 177 | .pmic_i2c = 0, |
@@ -199,7 +191,6 @@ static const struct mtk_i2c_compatible mt6589_compat = { | |||
199 | }; | 191 | }; |
200 | 192 | ||
201 | static const struct mtk_i2c_compatible mt8173_compat = { | 193 | static const struct mtk_i2c_compatible mt8173_compat = { |
202 | .quirks = &mt8173_i2c_quirks, | ||
203 | .pmic_i2c = 0, | 194 | .pmic_i2c = 0, |
204 | .dcm = 1, | 195 | .dcm = 1, |
205 | .auto_restart = 1, | 196 | .auto_restart = 1, |
diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c index 8f11d347b3ec..c811af4c8d81 100644 --- a/drivers/i2c/busses/i2c-riic.c +++ b/drivers/i2c/busses/i2c-riic.c | |||
@@ -218,8 +218,12 @@ static irqreturn_t riic_tend_isr(int irq, void *data) | |||
218 | } | 218 | } |
219 | 219 | ||
220 | if (riic->is_last || riic->err) { | 220 | if (riic->is_last || riic->err) { |
221 | riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER); | 221 | riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER); |
222 | writeb(ICCR2_SP, riic->base + RIIC_ICCR2); | 222 | writeb(ICCR2_SP, riic->base + RIIC_ICCR2); |
223 | } else { | ||
224 | /* Transfer is complete, but do not send STOP */ | ||
225 | riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER); | ||
226 | complete(&riic->msg_done); | ||
223 | } | 227 | } |
224 | 228 | ||
225 | return IRQ_HANDLED; | 229 | return IRQ_HANDLED; |
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 83768e85a919..2178266bca79 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c | |||
@@ -429,6 +429,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc) | |||
429 | while (muxc->num_adapters) { | 429 | while (muxc->num_adapters) { |
430 | struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters]; | 430 | struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters]; |
431 | struct i2c_mux_priv *priv = adap->algo_data; | 431 | struct i2c_mux_priv *priv = adap->algo_data; |
432 | struct device_node *np = adap->dev.of_node; | ||
432 | 433 | ||
433 | muxc->adapter[muxc->num_adapters] = NULL; | 434 | muxc->adapter[muxc->num_adapters] = NULL; |
434 | 435 | ||
@@ -438,6 +439,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc) | |||
438 | 439 | ||
439 | sysfs_remove_link(&priv->adap.dev.kobj, "mux_device"); | 440 | sysfs_remove_link(&priv->adap.dev.kobj, "mux_device"); |
440 | i2c_del_adapter(adap); | 441 | i2c_del_adapter(adap); |
442 | of_node_put(np); | ||
441 | kfree(priv); | 443 | kfree(priv); |
442 | } | 444 | } |
443 | } | 445 | } |