Commit 91bfe298 authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Wolfram Sang

Revert "i2c: rcar: remove spinlock"

This reverts commit 150b8be3.

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: default avatarSergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Cc: stable@vger.kernel.org # 3.16+
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 75b81f33
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h>
/* register offsets */ /* register offsets */
#define ICSCR 0x00 /* slave ctrl */ #define ICSCR 0x00 /* slave ctrl */
...@@ -95,6 +96,7 @@ struct rcar_i2c_priv { ...@@ -95,6 +96,7 @@ struct rcar_i2c_priv {
struct i2c_msg *msg; struct i2c_msg *msg;
struct clk *clk; struct clk *clk;
spinlock_t lock;
wait_queue_head_t wait; wait_queue_head_t wait;
int pos; int pos;
...@@ -365,6 +367,9 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) ...@@ -365,6 +367,9 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
struct rcar_i2c_priv *priv = ptr; struct rcar_i2c_priv *priv = ptr;
u32 msr; u32 msr;
/*-------------- spin lock -----------------*/
spin_lock(&priv->lock);
msr = rcar_i2c_read(priv, ICMSR); msr = rcar_i2c_read(priv, ICMSR);
/* Only handle interrupts that are currently enabled */ /* Only handle interrupts that are currently enabled */
...@@ -403,6 +408,9 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) ...@@ -403,6 +408,9 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
wake_up(&priv->wait); wake_up(&priv->wait);
} }
spin_unlock(&priv->lock);
/*-------------- spin unlock -----------------*/
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -412,14 +420,21 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, ...@@ -412,14 +420,21 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
{ {
struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
struct device *dev = rcar_i2c_priv_to_dev(priv); struct device *dev = rcar_i2c_priv_to_dev(priv);
unsigned long flags;
int i, ret, timeout; int i, ret, timeout;
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
/*-------------- spin lock -----------------*/
spin_lock_irqsave(&priv->lock, flags);
rcar_i2c_init(priv); rcar_i2c_init(priv);
/* start clock */ /* start clock */
rcar_i2c_write(priv, ICCCR, priv->icccr); rcar_i2c_write(priv, ICCCR, priv->icccr);
spin_unlock_irqrestore(&priv->lock, flags);
/*-------------- spin unlock -----------------*/
ret = rcar_i2c_bus_barrier(priv); ret = rcar_i2c_bus_barrier(priv);
if (ret < 0) if (ret < 0)
goto out; goto out;
...@@ -431,6 +446,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, ...@@ -431,6 +446,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
break; break;
} }
/*-------------- spin lock -----------------*/
spin_lock_irqsave(&priv->lock, flags);
/* init each data */ /* init each data */
priv->msg = &msgs[i]; priv->msg = &msgs[i];
priv->pos = 0; priv->pos = 0;
...@@ -440,6 +458,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, ...@@ -440,6 +458,9 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
ret = rcar_i2c_prepare_msg(priv); ret = rcar_i2c_prepare_msg(priv);
spin_unlock_irqrestore(&priv->lock, flags);
/*-------------- spin unlock -----------------*/
if (ret < 0) if (ret < 0)
break; break;
...@@ -543,6 +564,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) ...@@ -543,6 +564,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
init_waitqueue_head(&priv->wait); init_waitqueue_head(&priv->wait);
spin_lock_init(&priv->lock);
adap = &priv->adap; adap = &priv->adap;
adap->nr = pdev->id; adap->nr = pdev->id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment