aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-at91.c32
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c3
-rw-r--r--drivers/i2c/busses/i2c-rcar.c37
-rw-r--r--drivers/i2c/busses/i2c-rk3x.c4
4 files changed, 62 insertions, 14 deletions
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 79a68999a696..917d54588d95 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -101,6 +101,7 @@ struct at91_twi_dev {
101 unsigned twi_cwgr_reg; 101 unsigned twi_cwgr_reg;
102 struct at91_twi_pdata *pdata; 102 struct at91_twi_pdata *pdata;
103 bool use_dma; 103 bool use_dma;
104 bool recv_len_abort;
104 struct at91_twi_dma dma; 105 struct at91_twi_dma dma;
105}; 106};
106 107
@@ -267,12 +268,24 @@ static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
267 *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff; 268 *dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff;
268 --dev->buf_len; 269 --dev->buf_len;
269 270
271 /* return if aborting, we only needed to read RHR to clear RXRDY*/
272 if (dev->recv_len_abort)
273 return;
274
270 /* handle I2C_SMBUS_BLOCK_DATA */ 275 /* handle I2C_SMBUS_BLOCK_DATA */
271 if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) { 276 if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) {
272 dev->msg->flags &= ~I2C_M_RECV_LEN; 277 /* ensure length byte is a valid value */
273 dev->buf_len += *dev->buf; 278 if (*dev->buf <= I2C_SMBUS_BLOCK_MAX && *dev->buf > 0) {
274 dev->msg->len = dev->buf_len + 1; 279 dev->msg->flags &= ~I2C_M_RECV_LEN;
275 dev_dbg(dev->dev, "received block length %d\n", dev->buf_len); 280 dev->buf_len += *dev->buf;
281 dev->msg->len = dev->buf_len + 1;
282 dev_dbg(dev->dev, "received block length %d\n",
283 dev->buf_len);
284 } else {
285 /* abort and send the stop by reading one more byte */
286 dev->recv_len_abort = true;
287 dev->buf_len = 1;
288 }
276 } 289 }
277 290
278 /* send stop if second but last byte has been read */ 291 /* send stop if second but last byte has been read */
@@ -421,8 +434,8 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
421 } 434 }
422 } 435 }
423 436
424 ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, 437 ret = wait_for_completion_io_timeout(&dev->cmd_complete,
425 dev->adapter.timeout); 438 dev->adapter.timeout);
426 if (ret == 0) { 439 if (ret == 0) {
427 dev_err(dev->dev, "controller timed out\n"); 440 dev_err(dev->dev, "controller timed out\n");
428 at91_init_twi_bus(dev); 441 at91_init_twi_bus(dev);
@@ -444,6 +457,12 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
444 ret = -EIO; 457 ret = -EIO;
445 goto error; 458 goto error;
446 } 459 }
460 if (dev->recv_len_abort) {
461 dev_err(dev->dev, "invalid smbus block length recvd\n");
462 ret = -EPROTO;
463 goto error;
464 }
465
447 dev_dbg(dev->dev, "transfer complete\n"); 466 dev_dbg(dev->dev, "transfer complete\n");
448 467
449 return 0; 468 return 0;
@@ -500,6 +519,7 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
500 dev->buf_len = m_start->len; 519 dev->buf_len = m_start->len;
501 dev->buf = m_start->buf; 520 dev->buf = m_start->buf;
502 dev->msg = m_start; 521 dev->msg = m_start;
522 dev->recv_len_abort = false;
503 523
504 ret = at91_do_twi_transfer(dev); 524 ret = at91_do_twi_transfer(dev);
505 525
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 6dc5ded86f62..2f64273d3f2b 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -746,8 +746,7 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
746 } 746 }
747 tclk = clk_get_rate(drv_data->clk); 747 tclk = clk_get_rate(drv_data->clk);
748 748
749 rc = of_property_read_u32(np, "clock-frequency", &bus_freq); 749 if (of_property_read_u32(np, "clock-frequency", &bus_freq))
750 if (rc)
751 bus_freq = 100000; /* 100kHz by default */ 750 bus_freq = 100000; /* 100kHz by default */
752 751
753 if (!mv64xxx_find_baud_factors(bus_freq, tclk, 752 if (!mv64xxx_find_baud_factors(bus_freq, tclk,
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index f3c7139dfa25..1cc146cfc1f3 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -34,6 +34,7 @@
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/pm_runtime.h> 35#include <linux/pm_runtime.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/spinlock.h>
37 38
38/* register offsets */ 39/* register offsets */
39#define ICSCR 0x00 /* slave ctrl */ 40#define ICSCR 0x00 /* slave ctrl */
@@ -95,6 +96,7 @@ struct rcar_i2c_priv {
95 struct i2c_msg *msg; 96 struct i2c_msg *msg;
96 struct clk *clk; 97 struct clk *clk;
97 98
99 spinlock_t lock;
98 wait_queue_head_t wait; 100 wait_queue_head_t wait;
99 101
100 int pos; 102 int pos;
@@ -365,20 +367,20 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
365 struct rcar_i2c_priv *priv = ptr; 367 struct rcar_i2c_priv *priv = ptr;
366 u32 msr; 368 u32 msr;
367 369
370 /*-------------- spin lock -----------------*/
371 spin_lock(&priv->lock);
372
368 msr = rcar_i2c_read(priv, ICMSR); 373 msr = rcar_i2c_read(priv, ICMSR);
369 374
375 /* Only handle interrupts that are currently enabled */
376 msr &= rcar_i2c_read(priv, ICMIER);
377
370 /* Arbitration lost */ 378 /* Arbitration lost */
371 if (msr & MAL) { 379 if (msr & MAL) {
372 rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST)); 380 rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST));
373 goto out; 381 goto out;
374 } 382 }
375 383
376 /* Stop */
377 if (msr & MST) {
378 rcar_i2c_flags_set(priv, ID_DONE);
379 goto out;
380 }
381
382 /* Nack */ 384 /* Nack */
383 if (msr & MNR) { 385 if (msr & MNR) {
384 /* go to stop phase */ 386 /* go to stop phase */
@@ -388,6 +390,12 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
388 goto out; 390 goto out;
389 } 391 }
390 392
393 /* Stop */
394 if (msr & MST) {
395 rcar_i2c_flags_set(priv, ID_DONE);
396 goto out;
397 }
398
391 if (rcar_i2c_is_recv(priv)) 399 if (rcar_i2c_is_recv(priv))
392 rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); 400 rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr));
393 else 401 else
@@ -400,6 +408,9 @@ out:
400 wake_up(&priv->wait); 408 wake_up(&priv->wait);
401 } 409 }
402 410
411 spin_unlock(&priv->lock);
412 /*-------------- spin unlock -----------------*/
413
403 return IRQ_HANDLED; 414 return IRQ_HANDLED;
404} 415}
405 416
@@ -409,14 +420,21 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
409{ 420{
410 struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); 421 struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
411 struct device *dev = rcar_i2c_priv_to_dev(priv); 422 struct device *dev = rcar_i2c_priv_to_dev(priv);
423 unsigned long flags;
412 int i, ret, timeout; 424 int i, ret, timeout;
413 425
414 pm_runtime_get_sync(dev); 426 pm_runtime_get_sync(dev);
415 427
428 /*-------------- spin lock -----------------*/
429 spin_lock_irqsave(&priv->lock, flags);
430
416 rcar_i2c_init(priv); 431 rcar_i2c_init(priv);
417 /* start clock */ 432 /* start clock */
418 rcar_i2c_write(priv, ICCCR, priv->icccr); 433 rcar_i2c_write(priv, ICCCR, priv->icccr);
419 434
435 spin_unlock_irqrestore(&priv->lock, flags);
436 /*-------------- spin unlock -----------------*/
437
420 ret = rcar_i2c_bus_barrier(priv); 438 ret = rcar_i2c_bus_barrier(priv);
421 if (ret < 0) 439 if (ret < 0)
422 goto out; 440 goto out;
@@ -428,6 +446,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
428 break; 446 break;
429 } 447 }
430 448
449 /*-------------- spin lock -----------------*/
450 spin_lock_irqsave(&priv->lock, flags);
451
431 /* init each data */ 452 /* init each data */
432 priv->msg = &msgs[i]; 453 priv->msg = &msgs[i];
433 priv->pos = 0; 454 priv->pos = 0;
@@ -437,6 +458,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
437 458
438 ret = rcar_i2c_prepare_msg(priv); 459 ret = rcar_i2c_prepare_msg(priv);
439 460
461 spin_unlock_irqrestore(&priv->lock, flags);
462 /*-------------- spin unlock -----------------*/
463
440 if (ret < 0) 464 if (ret < 0)
441 break; 465 break;
442 466
@@ -540,6 +564,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
540 564
541 irq = platform_get_irq(pdev, 0); 565 irq = platform_get_irq(pdev, 0);
542 init_waitqueue_head(&priv->wait); 566 init_waitqueue_head(&priv->wait);
567 spin_lock_init(&priv->lock);
543 568
544 adap = &priv->adap; 569 adap = &priv->adap;
545 adap->nr = pdev->id; 570 adap->nr = pdev->id;
diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
index 69e11853e8bf..e637c32ae517 100644
--- a/drivers/i2c/busses/i2c-rk3x.c
+++ b/drivers/i2c/busses/i2c-rk3x.c
@@ -323,6 +323,10 @@ static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
323 /* ack interrupt */ 323 /* ack interrupt */
324 i2c_writel(i2c, REG_INT_MBRF, REG_IPD); 324 i2c_writel(i2c, REG_INT_MBRF, REG_IPD);
325 325
326 /* Can only handle a maximum of 32 bytes at a time */
327 if (len > 32)
328 len = 32;
329
326 /* read the data from receive buffer */ 330 /* read the data from receive buffer */
327 for (i = 0; i < len; ++i) { 331 for (i = 0; i < len; ++i) {
328 if (i % 4 == 0) 332 if (i % 4 == 0)