Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "i2c: rcar: remove spinlock"

This reverts commit 150b8be3cda54412ad7b54f5392b513b25c0aaa7.

The I2C core's per-adapter locks can't protect from IRQs, so the driver still
needs a spinlock to protect the register accesses.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Cc: stable@vger.kernel.org # 3.16+
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Sergei Shtylyov and committed by
Wolfram Sang
91bfe298 75b81f33

+22
+22
drivers/i2c/busses/i2c-rcar.c
··· 34 34 #include <linux/platform_device.h> 35 35 #include <linux/pm_runtime.h> 36 36 #include <linux/slab.h> 37 + #include <linux/spinlock.h> 37 38 38 39 /* register offsets */ 39 40 #define ICSCR 0x00 /* slave ctrl */ ··· 96 95 struct i2c_msg *msg; 97 96 struct clk *clk; 98 97 98 + spinlock_t lock; 99 99 wait_queue_head_t wait; 100 100 101 101 int pos; ··· 367 365 struct rcar_i2c_priv *priv = ptr; 368 366 u32 msr; 369 367 368 + /*-------------- spin lock -----------------*/ 369 + spin_lock(&priv->lock); 370 + 370 371 msr = rcar_i2c_read(priv, ICMSR); 371 372 372 373 /* Only handle interrupts that are currently enabled */ ··· 408 403 wake_up(&priv->wait); 409 404 } 410 405 406 + spin_unlock(&priv->lock); 407 + /*-------------- spin unlock -----------------*/ 408 + 411 409 return IRQ_HANDLED; 412 410 } 413 411 ··· 420 412 { 421 413 struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); 422 414 struct device *dev = rcar_i2c_priv_to_dev(priv); 415 + unsigned long flags; 423 416 int i, ret, timeout; 424 417 425 418 pm_runtime_get_sync(dev); 426 419 420 + /*-------------- spin lock -----------------*/ 421 + spin_lock_irqsave(&priv->lock, flags); 422 + 427 423 rcar_i2c_init(priv); 428 424 /* start clock */ 429 425 rcar_i2c_write(priv, ICCCR, priv->icccr); 426 + 427 + spin_unlock_irqrestore(&priv->lock, flags); 428 + /*-------------- spin unlock -----------------*/ 430 429 431 430 ret = rcar_i2c_bus_barrier(priv); 432 431 if (ret < 0) ··· 446 431 break; 447 432 } 448 433 434 + /*-------------- spin lock -----------------*/ 435 + spin_lock_irqsave(&priv->lock, flags); 436 + 449 437 /* init each data */ 450 438 priv->msg = &msgs[i]; 451 439 priv->pos = 0; ··· 457 439 rcar_i2c_flags_set(priv, ID_LAST_MSG); 458 440 459 441 ret = rcar_i2c_prepare_msg(priv); 442 + 443 + spin_unlock_irqrestore(&priv->lock, flags); 444 + /*-------------- spin unlock -----------------*/ 460 445 461 446 if (ret < 0) 462 447 break; ··· 564 543 565 544 irq = platform_get_irq(pdev, 0); 566 545 init_waitqueue_head(&priv->wait); 546 + spin_lock_init(&priv->lock); 567 547 568 548 adap = &priv->adap; 569 549 adap->nr = pdev->id;