aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-rcar.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-19 12:50:44 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-19 12:50:44 -0700
commit278f1d0730f4d0acdfc64256ad9b1066d0f3ab57 (patch)
tree27d983de59c4a857650d0472831969e2bf8c8706 /drivers/i2c/busses/i2c-rcar.c
parentMerge tag 'sound-fix-3.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound (diff)
parenti2c: i801: Add Device IDs for Intel Sunrise Point PCH (diff)
downloadlinux-dev-278f1d0730f4d0acdfc64256ad9b1066d0f3ab57.tar.xz
linux-dev-278f1d0730f4d0acdfc64256ad9b1066d0f3ab57.zip
Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang: "Highlights from the I2C subsystem for 3.18: - new drivers for Axxia AM55xx, and Hisilicon hix5hd2 SoC. - designware driver gained AMD support, exynos gained exynos7 support The rest is usual driver stuff. Hopefully no lowlights this time" * 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: i801: Add Device IDs for Intel Sunrise Point PCH i2c: hix5hd2: add i2c controller driver i2c-imx: Disable the clock on probe failure i2c: designware: Add support for AMD I2C controller i2c: designware: Rework probe() to get clock a bit later i2c: designware: Default to fast mode in case of ACPI i2c: axxia: Add I2C driver for AXM55xx i2c: exynos: add support for HSI2C module on Exynos7 i2c: mxs: detect No Slave Ack on SELECT in PIO mode i2c: cros_ec: Remove EC_I2C_FLAG_10BIT i2c: cros-ec-tunnel: Add of match table i2c: rcar: remove sign-compare flaw i2c: ismt: Use minimum descriptor size i2c: imx: Add arbitration lost check i2c: rk3x: Remove unlikely() annotations i2c: rcar: check for no IRQ in rcar_i2c_irq() i2c: rcar: make rcar_i2c_prepare_msg() *void* i2c: rcar: simplify check for last message i2c: designware: add support of platform data to set I2C mode i2c: designware: add support of I2C standard mode
Diffstat (limited to 'drivers/i2c/busses/i2c-rcar.c')
-rw-r--r--drivers/i2c/busses/i2c-rcar.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index e506fcd3ca04..d826e82dd997 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -195,7 +195,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
*/
rate = clk_get_rate(priv->clk);
cdf = rate / 20000000;
- if (cdf >= 1 << cdf_width) {
+ if (cdf >= 1U << cdf_width) {
dev_err(dev, "Input clock %lu too high\n", rate);
return -EIO;
}
@@ -245,7 +245,7 @@ scgd_find:
return 0;
}
-static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
+static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
{
int read = !!rcar_i2c_is_recv(priv);
@@ -253,8 +253,6 @@ static int rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
rcar_i2c_write(priv, ICMSR, 0);
rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
-
- return 0;
}
/*
@@ -365,6 +363,7 @@ static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
{
struct rcar_i2c_priv *priv = ptr;
+ irqreturn_t result = IRQ_HANDLED;
u32 msr;
/*-------------- spin lock -----------------*/
@@ -374,6 +373,10 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
/* Only handle interrupts that are currently enabled */
msr &= rcar_i2c_read(priv, ICMIER);
+ if (!msr) {
+ result = IRQ_NONE;
+ goto exit;
+ }
/* Arbitration lost */
if (msr & MAL) {
@@ -408,10 +411,11 @@ out:
wake_up(&priv->wait);
}
+exit:
spin_unlock(&priv->lock);
/*-------------- spin unlock -----------------*/
- return IRQ_HANDLED;
+ return result;
}
static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
@@ -453,17 +457,14 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
priv->msg = &msgs[i];
priv->pos = 0;
priv->flags = 0;
- if (priv->msg == &msgs[num - 1])
+ if (i == num - 1)
rcar_i2c_flags_set(priv, ID_LAST_MSG);
- ret = rcar_i2c_prepare_msg(priv);
+ rcar_i2c_prepare_msg(priv);
spin_unlock_irqrestore(&priv->lock, flags);
/*-------------- spin unlock -----------------*/
- if (ret < 0)
- break;
-
timeout = wait_event_timeout(priv->wait,
rcar_i2c_flags_has(priv, ID_DONE),
5 * HZ);