public inbox for linux-i2c@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review
@ 2008-09-25  7:16 Tony Lindgren
  2008-09-25  7:16 ` [PATCH 1/8] i2c-omap: Do not use interruptible wait call in omap_i2c_xfer_msg Tony Lindgren
  2008-09-25  7:49 ` [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review Tony Lindgren
  0 siblings, 2 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Tony Lindgren

Hi all,

This series contains pending i2c-omap patches from linux-omap tree
for review.

Looks like we've managed to pile up stuff in the omap tree for this
driver again... Anyways, future patches will be coming straight via
the i2c list.

The first two patches could be pushed as fixes to current -rc series,
but I'm fine with them going in later too.

I've left out some clean-up from the last patch so it won't conflict with
omap ioremp changes that are currently in Russell King's devel
branch.

Regards,

Tony

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] i2c-omap: Do not use interruptible wait call in omap_i2c_xfer_msg
  2008-09-25  7:16 [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review Tony Lindgren
@ 2008-09-25  7:16 ` Tony Lindgren
  2008-09-25  7:16   ` [PATCH 2/8] i2c-omap: Close suspected race between omap_i2c_idle() and omap_i2c_isr() Tony Lindgren
  2008-09-25  7:49 ` [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review Tony Lindgren
  1 sibling, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Jarkko Nikula, Juha Yrjola, Tony Lindgren

From: Jarkko Nikula <jarkko.nikula@nokia.com>

If there is a signal pending and wait_for_completion_interruptible_timeout
terminates with -ERESTARTSYS, we return and disable the i2c clocks in
omap_i2c_xfer.

If we terminate before sending last i2c message with a stop condition, the
bus remains busy and we are not able to send new messages into bus with
successive omap_i2c_xfer calls. Therefore a pending signal is not caught
here and we return only because of timeout or i2c error.

Signed-off-by: Jarkko Nikula <jarkko.nikula@nokia.com>
Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e7eb7bf..cfb76f5 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -328,8 +328,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 		w |= OMAP_I2C_CON_STP;
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
 
-	r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
-						      OMAP_I2C_TIMEOUT);
+	r = wait_for_completion_timeout(&dev->cmd_complete,
+					OMAP_I2C_TIMEOUT);
 	dev->buf_len = 0;
 	if (r < 0)
 		return r;
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/8] i2c-omap: Close suspected race between omap_i2c_idle() and omap_i2c_isr()
  2008-09-25  7:16 ` [PATCH 1/8] i2c-omap: Do not use interruptible wait call in omap_i2c_xfer_msg Tony Lindgren
@ 2008-09-25  7:16   ` Tony Lindgren
  2008-09-25  7:16     ` [PATCH 3/8] i2c-omap: Add high-speed support to omap-i2c Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Paul Walmsley, Tony Lindgren

From: Paul Walmsley <paul@pwsan.com>

omap_i2c_idle() sets an internal flag, "dev->idle", instructing its
ISR to decline interrupts.  It sets this flag before it actually masks
the interrupts on the I2C controller.  This is problematic, since an
I2C interrupt could arrive after dev->idle is set, but before the
interrupt source is masked.  When this happens, Linux disables the I2C
controller's IRQ, causing all future transactions on the bus to fail.

Symptoms, happening on about 7% of boots:

   irq 56: nobody cared (try booting with the "irqpoll" option)
   <warning traceback here>
   Disabling IRQ #56
   i2c_omap i2c_omap.1: controller timed out

In omap_i2c_idle(), this patch sets dev->idle only after the interrupt
mask write to the I2C controller has left the ARM write buffer.
That's probably the major offender.  For additional prophylaxis, in
omap_i2c_unidle(), the patch clears the dev->idle flag before
interrupts are enabled, rather than afterwards.

The patch has survived twenty-two reboots on the 3430SDP here without
wedging I2C1.  Not absolutely dispositive, but promising!

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index cfb76f5..a06ad42 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -181,22 +181,28 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
 	if (dev->iclk != NULL)
 		clk_enable(dev->iclk);
 	clk_enable(dev->fclk);
+	dev->idle = 0;
 	if (dev->iestate)
 		omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
-	dev->idle = 0;
 }
 
 static void omap_i2c_idle(struct omap_i2c_dev *dev)
 {
 	u16 iv;
 
-	dev->idle = 1;
 	dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
 	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
 	if (dev->rev1)
 		iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);	/* Read clears */
 	else
 		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
+	/*
+	 * The wmb() is to ensure that the I2C interrupt mask write
+	 * reaches the I2C controller before the dev->idle store
+	 * occurs.
+	 */
+	wmb();
+	dev->idle = 1;
 	clk_disable(dev->fclk);
 	if (dev->iclk != NULL)
 		clk_disable(dev->iclk);
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/8] i2c-omap: Add high-speed support to omap-i2c
  2008-09-25  7:16   ` [PATCH 2/8] i2c-omap: Close suspected race between omap_i2c_idle() and omap_i2c_isr() Tony Lindgren
@ 2008-09-25  7:16     ` Tony Lindgren
  2008-09-25  7:16       ` [PATCH 4/8] i2c-omap: FIFO handling support and broken hw workaround for i2c-omap Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Syed Mohammed Khasim, Tony Lindgren

From: Syed Mohammed Khasim <x0khasim@ti.com>

Omap2430 has additional support for high-speed I2C.

This patch moves I2C speed parameter (from module) to platform data.
Also added basic High Speed support based on I2C bus speed.

This patch is tested for high speed I2C (with TWL4030 Keypad) and works as
expected.

Signed-off-by: Syed Mohammed Khasim  <x0khasim@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |  111 +++++++++++++++++++++++++++++-----------
 1 files changed, 80 insertions(+), 31 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a06ad42..0d30790 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -83,6 +83,7 @@
 /* I2C Configuration Register (OMAP_I2C_CON): */
 #define OMAP_I2C_CON_EN		(1 << 15)	/* I2C module enable */
 #define OMAP_I2C_CON_BE		(1 << 14)	/* Big endian mode */
+#define OMAP_I2C_CON_OPMODE	(1 << 12)	/* High Speed support */
 #define OMAP_I2C_CON_STB	(1 << 11)	/* Start byte mode (master) */
 #define OMAP_I2C_CON_MST	(1 << 10)	/* Master/slave mode */
 #define OMAP_I2C_CON_TRX	(1 << 9)	/* TX/RX mode (master only) */
@@ -91,6 +92,10 @@
 #define OMAP_I2C_CON_STP	(1 << 1)	/* Stop cond (master only) */
 #define OMAP_I2C_CON_STT	(1 << 0)	/* Start condition (master) */
 
+/* I2C SCL time value when Master */
+#define OMAP_I2C_SCLL_HSSCLL	8
+#define OMAP_I2C_SCLH_HSSCLH	8
+
 /* I2C System Test Register (OMAP_I2C_SYSTEST): */
 #ifdef DEBUG
 #define OMAP_I2C_SYSTEST_ST_EN		(1 << 15)	/* System test enable */
@@ -109,12 +114,6 @@
 /* I2C System Configuration Register (OMAP_I2C_SYSC): */
 #define OMAP_I2C_SYSC_SRST		(1 << 1)	/* Soft Reset */
 
-/* REVISIT: Use platform_data instead of module parameters */
-/* Fast Mode = 400 kHz, Standard = 100 kHz */
-static int clock = 100; /* Default: 100 kHz */
-module_param(clock, int, 0);
-MODULE_PARM_DESC(clock, "Set I2C clock in kHz: 400=fast mode (default == 100)");
-
 struct omap_i2c_dev {
 	struct device		*dev;
 	void __iomem		*base;		/* virtual */
@@ -123,6 +122,7 @@ struct omap_i2c_dev {
 	struct clk		*fclk;		/* Functional clock */
 	struct completion	cmd_complete;
 	struct resource		*ioarea;
+	u32			speed;		/* Speed of bus in Khz */
 	u16			cmd_err;
 	u8			*buf;
 	size_t			buf_len;
@@ -152,17 +152,28 @@ static int omap_i2c_get_clocks(struct omap_i2c_dev *dev)
 			return -ENODEV;
 		}
 	}
-
-	dev->fclk = clk_get(dev->dev, "i2c_fck");
-	if (IS_ERR(dev->fclk)) {
-		if (dev->iclk != NULL) {
-			clk_put(dev->iclk);
-			dev->iclk = NULL;
+	/* For I2C operations on 2430 we need 96Mhz clock */
+	if (cpu_is_omap2430()) {
+		dev->fclk = clk_get(dev->dev, "i2chs_fck");
+		if (IS_ERR(dev->fclk)) {
+			if (dev->iclk != NULL) {
+				clk_put(dev->iclk);
+				dev->iclk = NULL;
+			}
+			dev->fclk = NULL;
+			return -ENODEV;
+		}
+	} else {
+		dev->fclk = clk_get(dev->dev, "i2c_fck");
+		if (IS_ERR(dev->fclk)) {
+			if (dev->iclk != NULL) {
+				clk_put(dev->iclk);
+				dev->iclk = NULL;
+			}
+			dev->fclk = NULL;
+			return -ENODEV;
 		}
-		dev->fclk = NULL;
-		return -ENODEV;
 	}
-
 	return 0;
 }
 
@@ -210,9 +221,11 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
 
 static int omap_i2c_init(struct omap_i2c_dev *dev)
 {
-	u16 psc = 0;
+	u16 psc = 0, scll = 0, sclh = 0;
+	u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
 	unsigned long fclk_rate = 12000000;
 	unsigned long timeout;
+	unsigned long internal_clk = 0;
 
 	if (!dev->rev1) {
 		omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, OMAP_I2C_SYSC_SRST);
@@ -255,18 +268,47 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 			psc = fclk_rate / 12000000;
 	}
 
+	if (cpu_is_omap2430()) {
+
+		/* HSI2C controller internal clk rate should be 19.2 Mhz */
+		internal_clk = 19200;
+		fclk_rate = clk_get_rate(dev->fclk) / 1000;
+
+		/* Compute prescaler divisor */
+		psc = fclk_rate / internal_clk;
+		psc = psc - 1;
+
+		/* If configured for High Speed */
+		if (dev->speed > 400) {
+			/* For first phase of HS mode */
+			fsscll = internal_clk / (400 * 2) - 6;
+			fssclh = internal_clk / (400 * 2) - 6;
+
+			/* For second phase of HS mode */
+			hsscll = fclk_rate / (dev->speed * 2) - 6;
+			hssclh = fclk_rate / (dev->speed * 2) - 6;
+		} else {
+			/* To handle F/S modes */
+			fsscll = internal_clk / (dev->speed * 2) - 6;
+			fssclh = internal_clk / (dev->speed * 2) - 6;
+		}
+		scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll;
+		sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh;
+	} else {
+		/* Program desired operating rate */
+		fclk_rate /= (psc + 1) * 1000;
+		if (psc > 2)
+			psc = 2;
+		scll = fclk_rate / (dev->speed * 2) - 7 + psc;
+		sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
+	}
+
 	/* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
 	omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
 
-	/* Program desired operating rate */
-	fclk_rate /= (psc + 1) * 1000;
-	if (psc > 2)
-		psc = 2;
-
-	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG,
-			   fclk_rate / (clock * 2) - 7 + psc);
-	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG,
-			   fclk_rate / (clock * 2) - 7 + psc);
+	/* SCL low and high time values */
+	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
+	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
 
 	/* Take the I2C module out of reset: */
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
@@ -326,6 +368,11 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 	dev->cmd_err = 0;
 
 	w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
+
+	/* High speed configuration */
+	if (dev->speed > 400)
+		w |= OMAP_I2C_CON_OPMODE;
+
 	if (msg->flags & I2C_M_TEN)
 		w |= OMAP_I2C_CON_XA;
 	if (!(msg->flags & I2C_M_RD))
@@ -562,6 +609,7 @@ omap_i2c_probe(struct platform_device *pdev)
 	struct i2c_adapter	*adap;
 	struct resource		*mem, *irq, *ioarea;
 	int r;
+	u32 *speed = NULL;
 
 	/* NOTE: driver uses the static register mapping */
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -582,17 +630,18 @@ omap_i2c_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	if (clock > 200)
-		clock = 400;	/* Fast mode */
-	else
-		clock = 100;	/* Standard mode */
-
 	dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
 	if (!dev) {
 		r = -ENOMEM;
 		goto err_release_region;
 	}
 
+	if (pdev->dev.platform_data != NULL)
+		speed = (u32 *) pdev->dev.platform_data;
+	else
+		*speed = 100; /* Defualt speed */
+
+	dev->speed = *speed;
 	dev->dev = &pdev->dev;
 	dev->irq = irq->start;
 	dev->base = (void __iomem *) IO_ADDRESS(mem->start);
@@ -618,7 +667,7 @@ omap_i2c_probe(struct platform_device *pdev)
 	}
 	r = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
 	dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n",
-		 pdev->id, r >> 4, r & 0xf, clock);
+		 pdev->id, r >> 4, r & 0xf, dev->speed);
 
 	adap = &dev->adapter;
 	i2c_set_adapdata(adap, dev);
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/8] i2c-omap: FIFO handling support and broken hw workaround for i2c-omap
  2008-09-25  7:16     ` [PATCH 3/8] i2c-omap: Add high-speed support to omap-i2c Tony Lindgren
@ 2008-09-25  7:16       ` Tony Lindgren
  2008-09-25  7:16         ` [PATCH 5/8] i2c-omap: Add support on 34xx Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Nishanth Menon, Jason P Marini, Tony Lindgren

From: Nishanth Menon <menon.nishanth@gmail.com>

Based on an earlier patch from Nishant Menon:

- Transfers can use FIFO on FIFO capable devices
- Prevents errors for HSI2C if FIFO is not used
- Implemented errenous handling of STT-STP handling on SDP2430

Also merged in is a fix from Jaron Marini to fix occasional i2c
hang if OMAP_I2C_CON_STT remains asserted.

Signed-off-by: Jason P Marini <jason.marini@gmail.com>
Signed-off-by: Nishanth Menon <menon.nishanth@gmail.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |  186 ++++++++++++++++++++++++++++++++---------
 1 files changed, 146 insertions(+), 40 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0d30790..6cd4d54 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -55,8 +55,11 @@
 #define OMAP_I2C_SCLL_REG		0x34
 #define OMAP_I2C_SCLH_REG		0x38
 #define OMAP_I2C_SYSTEST_REG		0x3c
+#define OMAP_I2C_BUFSTAT_REG		0x40
 
 /* I2C Interrupt Enable Register (OMAP_I2C_IE): */
+#define OMAP_I2C_IE_XDR		(1 << 14)	/* TX Buffer drain int enable */
+#define OMAP_I2C_IE_RDR		(1 << 13)	/* RX Buffer drain int enable */
 #define OMAP_I2C_IE_XRDY	(1 << 4)	/* TX data ready int enable */
 #define OMAP_I2C_IE_RRDY	(1 << 3)	/* RX data ready int enable */
 #define OMAP_I2C_IE_ARDY	(1 << 2)	/* Access ready int enable */
@@ -64,7 +67,8 @@
 #define OMAP_I2C_IE_AL		(1 << 0)	/* Arbitration lost int ena */
 
 /* I2C Status Register (OMAP_I2C_STAT): */
-#define OMAP_I2C_STAT_SBD	(1 << 15)	/* Single byte data */
+#define OMAP_I2C_STAT_XDR	(1 << 14)	/* TX Buffer draining */
+#define OMAP_I2C_STAT_RDR	(1 << 13)	/* RX Buffer draining */
 #define OMAP_I2C_STAT_BB	(1 << 12)	/* Bus busy */
 #define OMAP_I2C_STAT_ROVR	(1 << 11)	/* Receive overrun */
 #define OMAP_I2C_STAT_XUDF	(1 << 10)	/* Transmit underflow */
@@ -78,12 +82,14 @@
 
 /* I2C Buffer Configuration Register (OMAP_I2C_BUF): */
 #define OMAP_I2C_BUF_RDMA_EN	(1 << 15)	/* RX DMA channel enable */
+#define OMAP_I2C_BUF_RXFIF_CLR	(1 << 14)	/* RX FIFO Clear */
 #define OMAP_I2C_BUF_XDMA_EN	(1 << 7)	/* TX DMA channel enable */
+#define OMAP_I2C_BUF_TXFIF_CLR	(1 << 6)	/* TX FIFO Clear */
 
 /* I2C Configuration Register (OMAP_I2C_CON): */
 #define OMAP_I2C_CON_EN		(1 << 15)	/* I2C module enable */
 #define OMAP_I2C_CON_BE		(1 << 14)	/* Big endian mode */
-#define OMAP_I2C_CON_OPMODE	(1 << 12)	/* High Speed support */
+#define OMAP_I2C_CON_OPMODE_HS	(1 << 12)	/* High Speed support */
 #define OMAP_I2C_CON_STB	(1 << 11)	/* Start byte mode (master) */
 #define OMAP_I2C_CON_MST	(1 << 10)	/* Master/slave mode */
 #define OMAP_I2C_CON_TRX	(1 << 9)	/* TX/RX mode (master only) */
@@ -127,7 +133,12 @@ struct omap_i2c_dev {
 	u8			*buf;
 	size_t			buf_len;
 	struct i2c_adapter	adapter;
+	u8			fifo_size;	/* use as flag and value
+						 * fifo_size==0 implies no fifo
+						 * if set, should be trsh+1
+						 */
 	unsigned		rev1:1;
+	unsigned		b_hw:1;		/* bad h/w fixes */
 	unsigned		idle:1;
 	u16			iestate;	/* Saved interrupt register */
 };
@@ -310,6 +321,14 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
 
+	if (dev->fifo_size)
+		/* Note: setup required fifo size - 1 */
+		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
+					(dev->fifo_size - 1) << 8 | /* RTRSH */
+					OMAP_I2C_BUF_RXFIF_CLR |
+					(dev->fifo_size - 1) | /* XTRSH */
+					OMAP_I2C_BUF_TXFIF_CLR);
+
 	/* Take the I2C module out of reset: */
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
 
@@ -317,7 +336,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
 			   (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
 			    OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
-			    OMAP_I2C_IE_AL));
+			    OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
+				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
 	return 0;
 }
 
@@ -364,6 +384,11 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
 	omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
 
+	/* Clear the FIFO Buffers */
+	w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
+	w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
+	omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w);
+
 	init_completion(&dev->cmd_complete);
 	dev->cmd_err = 0;
 
@@ -371,16 +396,37 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
 	/* High speed configuration */
 	if (dev->speed > 400)
-		w |= OMAP_I2C_CON_OPMODE;
+		w |= OMAP_I2C_CON_OPMODE_HS;
 
 	if (msg->flags & I2C_M_TEN)
 		w |= OMAP_I2C_CON_XA;
 	if (!(msg->flags & I2C_M_RD))
 		w |= OMAP_I2C_CON_TRX;
-	if (stop)
+	if (!dev->b_hw && stop)
 		w |= OMAP_I2C_CON_STP;
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
 
+	/*
+	 * Don't write stt and stp together on some hardware
+	 */
+	if (dev->b_hw && stop) {
+		u16 con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG);
+		while (con & OMAP_I2C_CON_STT) {
+			con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG);
+
+			/* Let the user know if i2c is in a bad state */
+			if (time_after(jiffies, delay)) {
+				dev_err(dev->dev, "controller timed out "
+				"waiting for start condition to finish\n");
+				return -ETIMEDOUT;
+			}
+			cpu_relax();
+		}
+
+		w |= OMAP_I2C_CON_STP;
+		w &= ~OMAP_I2C_CON_STT;
+		omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
+	}
 	r = wait_for_completion_timeout(&dev->cmd_complete,
 					OMAP_I2C_TIMEOUT);
 	dev->buf_len = 0;
@@ -525,7 +571,7 @@ omap_i2c_isr(int this_irq, void *dev_id)
 	struct omap_i2c_dev *dev = dev_id;
 	u16 bits;
 	u16 stat, w;
-	int count = 0;
+	int err, count = 0;
 
 	if (dev->idle)
 		return IRQ_NONE;
@@ -540,39 +586,92 @@ omap_i2c_isr(int this_irq, void *dev_id)
 
 		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
 
-		if (stat & OMAP_I2C_STAT_ARDY) {
-			omap_i2c_complete_cmd(dev, 0);
-			continue;
+		err = 0;
+		if (stat & OMAP_I2C_STAT_NACK) {
+			err |= OMAP_I2C_STAT_NACK;
+			omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
+					   OMAP_I2C_CON_STP);
 		}
-		if (stat & OMAP_I2C_STAT_RRDY) {
-			w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-			if (dev->buf_len) {
-				*dev->buf++ = w;
-				dev->buf_len--;
+		if (stat & OMAP_I2C_STAT_AL) {
+			dev_err(dev->dev, "Arbitration lost\n");
+			err |= OMAP_I2C_STAT_AL;
+		}
+		if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
+					OMAP_I2C_STAT_AL))
+			omap_i2c_complete_cmd(dev, err);
+		if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
+			u8 num_bytes = 1;
+			if (dev->fifo_size)
+				if (stat & OMAP_I2C_STAT_RRDY)
+					num_bytes = dev->fifo_size;
+				else
+					num_bytes = omap_i2c_read_reg(dev,
+							OMAP_I2C_BUFSTAT_REG);
+			while (num_bytes) {
+				num_bytes--;
+				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
 				if (dev->buf_len) {
-					*dev->buf++ = w >> 8;
+					*dev->buf++ = w;
 					dev->buf_len--;
+					/* Data reg from 2430 is 8 bit wide */
+					if (!cpu_is_omap2430() {
+						if (dev->buf_len) {
+							*dev->buf++ = w >> 8;
+							dev->buf_len--;
+						}
+					}
+				} else {
+					if (stat & OMAP_I2C_STAT_RRDY)
+						dev_err(dev->dev,
+							"RRDY IRQ while no data"
+								" requested\n");
+					if (stat & OMAP_I2C_STAT_RDR)
+						dev_err(dev->dev,
+							"RDR IRQ while no data"
+								" requested\n");
+					break;
 				}
-			} else
-				dev_err(dev->dev, "RRDY IRQ while no data "
-						"requested\n");
-			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
+			}
+			omap_i2c_ack_stat(dev,
+				stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
 			continue;
 		}
-		if (stat & OMAP_I2C_STAT_XRDY) {
-			w = 0;
-			if (dev->buf_len) {
-				w = *dev->buf++;
-				dev->buf_len--;
+		if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
+			u8 num_bytes = 1;
+			if (dev->fifo_size)
+				if (stat & OMAP_I2C_STAT_XRDY)
+					num_bytes = dev->fifo_size;
+				else
+					num_bytes = omap_i2c_read_reg(dev,
+							OMAP_I2C_BUFSTAT_REG);
+			while (num_bytes) {
+				num_bytes--;
+				w = 0;
 				if (dev->buf_len) {
-					w |= *dev->buf++ << 8;
+					w = *dev->buf++;
 					dev->buf_len--;
+					/* Data reg from  2430 is 8 bit wide */
+					if (!cpu_is_omap2430() {
+						if (dev->buf_len) {
+							w |= *dev->buf++ << 8;
+							dev->buf_len--;
+						}
+					}
+				} else {
+					if (stat & OMAP_I2C_STAT_XRDY)
+						dev_err(dev->dev,
+							"XRDY IRQ while no "
+							"data to send\n");
+					if (stat & OMAP_I2C_STAT_XDR)
+						dev_err(dev->dev,
+							"XDR IRQ while no "
+							"data to send\n");
+					break;
 				}
-			} else
-				dev_err(dev->dev, "XRDY IRQ while no "
-					"data to send\n");
-			omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
-			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
+				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+			}
+			omap_i2c_ack_stat(dev,
+				stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
 			continue;
 		}
 		if (stat & OMAP_I2C_STAT_ROVR) {
@@ -580,18 +679,9 @@ omap_i2c_isr(int this_irq, void *dev_id)
 			dev->cmd_err |= OMAP_I2C_STAT_ROVR;
 		}
 		if (stat & OMAP_I2C_STAT_XUDF) {
-			dev_err(dev->dev, "Transmit overflow\n");
+			dev_err(dev->dev, "Transmit underflow\n");
 			dev->cmd_err |= OMAP_I2C_STAT_XUDF;
 		}
-		if (stat & OMAP_I2C_STAT_NACK) {
-			omap_i2c_complete_cmd(dev, OMAP_I2C_STAT_NACK);
-			omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
-					   OMAP_I2C_CON_STP);
-		}
-		if (stat & OMAP_I2C_STAT_AL) {
-			dev_err(dev->dev, "Arbitration lost\n");
-			omap_i2c_complete_cmd(dev, OMAP_I2C_STAT_AL);
-		}
 	}
 
 	return count ? IRQ_HANDLED : IRQ_NONE;
@@ -655,6 +745,22 @@ omap_i2c_probe(struct platform_device *pdev)
 	if (cpu_is_omap15xx())
 		dev->rev1 = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) < 0x20;
 
+	if (cpu_is_omap2430()) {
+		u16 s;
+
+		/* Set up the fifo size - Get total size */
+		s = (omap_i2c_read_reg(dev, OMAP_I2C_BUFSTAT_REG) >> 14) & 0x3;
+		dev->fifo_size = 0x8 << s;
+
+		/*
+		 * Set up notification threshold as half the total available
+		 * size. This is to ensure that we can handle the status on int
+		 * call back latencies.
+		 */
+		dev->fifo_size = (dev->fifo_size / 2);
+		dev->b_hw = 1; /* Enable hardware fixes */
+	}
+
 	/* reset ASAP, clearing any IRQs */
 	omap_i2c_init(dev);
 
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/8] i2c-omap: Add support on 34xx
  2008-09-25  7:16       ` [PATCH 4/8] i2c-omap: FIFO handling support and broken hw workaround for i2c-omap Tony Lindgren
@ 2008-09-25  7:16         ` Tony Lindgren
  2008-09-25  7:16           ` [PATCH 6/8] i2c-omap: Mark init-only functions as __init Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Chandra shekhar, Tony Lindgren

From: Chandra shekhar <x0044955@ti.com>

Signed-off-by: chandra shekhar <x0044955@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6cd4d54..fdebf96 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -156,7 +156,7 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
 
 static int omap_i2c_get_clocks(struct omap_i2c_dev *dev)
 {
-	if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
+	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
 		dev->iclk = clk_get(dev->dev, "i2c_ick");
 		if (IS_ERR(dev->iclk)) {
 			dev->iclk = NULL;
@@ -279,7 +279,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 			psc = fclk_rate / 12000000;
 	}
 
-	if (cpu_is_omap2430()) {
+	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 
 		/* HSI2C controller internal clk rate should be 19.2 Mhz */
 		internal_clk = 19200;
@@ -614,7 +614,8 @@ omap_i2c_isr(int this_irq, void *dev_id)
 					*dev->buf++ = w;
 					dev->buf_len--;
 					/* Data reg from 2430 is 8 bit wide */
-					if (!cpu_is_omap2430() {
+					if (!cpu_is_omap2430() &&
+							!cpu_is_omap34xx()) {
 						if (dev->buf_len) {
 							*dev->buf++ = w >> 8;
 							dev->buf_len--;
@@ -651,7 +652,8 @@ omap_i2c_isr(int this_irq, void *dev_id)
 					w = *dev->buf++;
 					dev->buf_len--;
 					/* Data reg from  2430 is 8 bit wide */
-					if (!cpu_is_omap2430() {
+					if (!cpu_is_omap2430() &&
+							!cpu_is_omap34xx()) {
 						if (dev->buf_len) {
 							w |= *dev->buf++ << 8;
 							dev->buf_len--;
@@ -745,7 +747,7 @@ omap_i2c_probe(struct platform_device *pdev)
 	if (cpu_is_omap15xx())
 		dev->rev1 = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) < 0x20;
 
-	if (cpu_is_omap2430()) {
+	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 		u16 s;
 
 		/* Set up the fifo size - Get total size */
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] i2c-omap: Mark init-only functions as __init
  2008-09-25  7:16         ` [PATCH 5/8] i2c-omap: Add support on 34xx Tony Lindgren
@ 2008-09-25  7:16           ` Tony Lindgren
  2008-09-25  7:16             ` [PATCH 7/8] i2c-omap: Don't compile in OMAP15xx I2C ISR for non-OMAP15xx builds Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Paul Walmsley, Tony Lindgren

From: Paul Walmsley <paul@pwsan.com>

Mark functions called only at init time as __init.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index fdebf96..52ecddd 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -154,7 +154,7 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
 	return __raw_readw(i2c_dev->base + reg);
 }
 
-static int omap_i2c_get_clocks(struct omap_i2c_dev *dev)
+static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
 {
 	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
 		dev->iclk = clk_get(dev->dev, "i2c_ick");
@@ -694,7 +694,7 @@ static const struct i2c_algorithm omap_i2c_algo = {
 	.functionality	= omap_i2c_func,
 };
 
-static int
+static int __init
 omap_i2c_probe(struct platform_device *pdev)
 {
 	struct omap_i2c_dev	*dev;
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/8] i2c-omap: Don't compile in OMAP15xx I2C ISR for non-OMAP15xx builds
  2008-09-25  7:16           ` [PATCH 6/8] i2c-omap: Mark init-only functions as __init Tony Lindgren
@ 2008-09-25  7:16             ` Tony Lindgren
  2008-09-25  7:16               ` [PATCH 8/8] i2c-omap: Clean-up i2c-omap Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Paul Walmsley, Tony Lindgren

From: Paul Walmsley <paul@pwsan.com>

Skip compiling OMAP15xx I2C ISR for non-OMAP15xx builds.  Saves 400 bytes
of text for most OMAP builds.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 52ecddd..9ac64c7 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -510,6 +510,9 @@ omap_i2c_ack_stat(struct omap_i2c_dev *dev, u16 stat)
 	omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
 }
 
+/* rev1 devices are apparently only on some 15xx */
+#ifdef CONFIG_ARCH_OMAP15XX
+
 static irqreturn_t
 omap_i2c_rev1_isr(int this_irq, void *dev_id)
 {
@@ -564,6 +567,9 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id)
 
 	return IRQ_HANDLED;
 }
+#else
+#define omap_i2c_rev1_isr		0
+#endif
 
 static irqreturn_t
 omap_i2c_isr(int this_irq, void *dev_id)
@@ -840,14 +846,14 @@ static struct platform_driver omap_i2c_driver = {
 };
 
 /* I2C may be needed to bring up other drivers */
-static int __init
+static int __devinit
 omap_i2c_init_driver(void)
 {
 	return platform_driver_register(&omap_i2c_driver);
 }
 subsys_initcall(omap_i2c_init_driver);
 
-static void __exit omap_i2c_exit_driver(void)
+static void __devexit omap_i2c_exit_driver(void)
 {
 	platform_driver_unregister(&omap_i2c_driver);
 }
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 8/8] i2c-omap: Clean-up i2c-omap
  2008-09-25  7:16             ` [PATCH 7/8] i2c-omap: Don't compile in OMAP15xx I2C ISR for non-OMAP15xx builds Tony Lindgren
@ 2008-09-25  7:16               ` Tony Lindgren
  2008-09-25  7:27                 ` [PATCH 8/8] i2c-omap: Clean-up i2c-omap, v2 Tony Lindgren
  0 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:16 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Tony Lindgren

Minor checkpatch and formatting clean-up. Also update copyrights.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |   31 ++++++++++++++++++-------------
 1 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9ac64c7..0c5d101 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -2,13 +2,15 @@
  * TI OMAP I2C master mode driver
  *
  * Copyright (C) 2003 MontaVista Software, Inc.
- * Copyright (C) 2004 Texas Instruments.
- *
- * Updated to work with multiple I2C interfaces on 24xx by
- * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
  * Copyright (C) 2005 Nokia Corporation
+ * Copyright (C) 2004 - 2007 Texas Instruments.
  *
- * Cleaned up by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Originally written by MontaVista Software, Inc.
+ * Additional contributions by:
+ *	Tony Lindgren <tony@atomide.com>
+ *	Imre Deak <imre.deak@nokia.com>
+ *	Juha Yrjölä <juha.yrjola@nokia.com>
+ *	Syed Khasim <x0khasim@ti.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,8 +35,7 @@
 #include <linux/completion.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -215,7 +216,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
 	dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
 	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
 	if (dev->rev1)
-		iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);	/* Read clears */
+		iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
 	else
 		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
 	/*
@@ -334,9 +335,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 
 	/* Enable interrupts */
 	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
-			   (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
-			    OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
-			    OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
+			(OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+			OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
+			OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
 				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
 	return 0;
 }
@@ -402,8 +403,10 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 		w |= OMAP_I2C_CON_XA;
 	if (!(msg->flags & I2C_M_RD))
 		w |= OMAP_I2C_CON_TRX;
+
 	if (!dev->b_hw && stop)
 		w |= OMAP_I2C_CON_STP;
+
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
 
 	/*
@@ -475,7 +478,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 
 	omap_i2c_unidle(dev);
 
-	if ((r = omap_i2c_wait_for_bb(dev)) < 0)
+	r = omap_i2c_wait_for_bb(dev)
+	if (r < 0)
 		goto out;
 
 	for (i = 0; i < num; i++) {
@@ -745,7 +749,8 @@ omap_i2c_probe(struct platform_device *pdev)
 	dev->base = (void __iomem *) IO_ADDRESS(mem->start);
 	platform_set_drvdata(pdev, dev);
 
-	if ((r = omap_i2c_get_clocks(dev)) != 0)
+	r = omap_i2c_get_clocks(dev)
+	if (r != 0)
 		goto err_free_mem;
 
 	omap_i2c_unidle(dev);
-- 
1.5.6.rc3.21.g8c6b5

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 8/8] i2c-omap: Clean-up i2c-omap, v2
  2008-09-25  7:16               ` [PATCH 8/8] i2c-omap: Clean-up i2c-omap Tony Lindgren
@ 2008-09-25  7:27                 ` Tony Lindgren
  0 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:27 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap

[-- Attachment #1: Type: text/plain, Size: 226 bytes --]

* Tony Lindgren <tony@atomide.com> [080925 10:18]:
> Minor checkpatch and formatting clean-up. Also update copyrights.

Oops, left out the last hunk too to avoid merge conflicts, here's an
updated version of this patch.

Tony

[-- Attachment #2: 0008-i2c-omap-Clean-up-i2c-omap.patch --]
[-- Type: text/x-diff, Size: 3108 bytes --]

>From a50275a85a81be007c74293b5519c3cbb01f6fa5 Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Thu, 25 Sep 2008 10:23:55 +0300
Subject: [PATCH] i2c-omap: Clean-up i2c-omap

Minor checkpatch and formatting clean-up. Also update copyrights.

Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |   28 ++++++++++++++++------------
 1 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9ac64c7..3dc608c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -2,13 +2,15 @@
  * TI OMAP I2C master mode driver
  *
  * Copyright (C) 2003 MontaVista Software, Inc.
- * Copyright (C) 2004 Texas Instruments.
- *
- * Updated to work with multiple I2C interfaces on 24xx by
- * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
  * Copyright (C) 2005 Nokia Corporation
+ * Copyright (C) 2004 - 2007 Texas Instruments.
  *
- * Cleaned up by Juha Yrjölä <juha.yrjola@nokia.com>
+ * Originally written by MontaVista Software, Inc.
+ * Additional contributions by:
+ *	Tony Lindgren <tony@atomide.com>
+ *	Imre Deak <imre.deak@nokia.com>
+ *	Juha Yrjölä <juha.yrjola@nokia.com>
+ *	Syed Khasim <x0khasim@ti.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,8 +35,7 @@
 #include <linux/completion.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -215,7 +216,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
 	dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
 	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
 	if (dev->rev1)
-		iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);	/* Read clears */
+		iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
 	else
 		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
 	/*
@@ -334,9 +335,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 
 	/* Enable interrupts */
 	omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
-			   (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
-			    OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
-			    OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
+			(OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+			OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
+			OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
 				(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
 	return 0;
 }
@@ -402,8 +403,10 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 		w |= OMAP_I2C_CON_XA;
 	if (!(msg->flags & I2C_M_RD))
 		w |= OMAP_I2C_CON_TRX;
+
 	if (!dev->b_hw && stop)
 		w |= OMAP_I2C_CON_STP;
+
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
 
 	/*
@@ -475,7 +478,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 
 	omap_i2c_unidle(dev);
 
-	if ((r = omap_i2c_wait_for_bb(dev)) < 0)
+	r = omap_i2c_wait_for_bb(dev)
+	if (r < 0)
 		goto out;
 
 	for (i = 0; i < num; i++) {
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review
  2008-09-25  7:16 [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review Tony Lindgren
  2008-09-25  7:16 ` [PATCH 1/8] i2c-omap: Do not use interruptible wait call in omap_i2c_xfer_msg Tony Lindgren
@ 2008-09-25  7:49 ` Tony Lindgren
  1 sibling, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:49 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap

* Tony Lindgren <tony@atomide.com> [080925 10:16]:
> Hi all,
> 
> This series contains pending i2c-omap patches from linux-omap tree
> for review.
> 
> Looks like we've managed to pile up stuff in the omap tree for this
> driver again... Anyways, future patches will be coming straight via
> the i2c list.
> 
> The first two patches could be pushed as fixes to current -rc series,
> but I'm fine with them going in later too.
> 
> I've left out some clean-up from the last patch so it won't conflict with
> omap ioremp changes that are currently in Russell King's devel
> branch.

Grr, I'll repost the whole series. There was a compile error in one of
the patches.

Tony

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] i2c-omap: Do not use interruptible wait call in omap_i2c_xfer_msg
  2008-09-25  7:53 [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review, v2 Tony Lindgren
@ 2008-09-25  7:53 ` Tony Lindgren
  0 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-09-25  7:53 UTC (permalink / raw)
  To: i2c; +Cc: linux-omap, Jarkko Nikula, Juha Yrjola, Tony Lindgren

From: Jarkko Nikula <jarkko.nikula@nokia.com>

If there is a signal pending and wait_for_completion_interruptible_timeout
terminates with -ERESTARTSYS, we return and disable the i2c clocks in
omap_i2c_xfer.

If we terminate before sending last i2c message with a stop condition, the
bus remains busy and we are not able to send new messages into bus with
successive omap_i2c_xfer calls. Therefore a pending signal is not caught
here and we return only because of timeout or i2c error.

Signed-off-by: Jarkko Nikula <jarkko.nikula@nokia.com>
Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/i2c/busses/i2c-omap.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e7eb7bf..cfb76f5 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -328,8 +328,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 		w |= OMAP_I2C_CON_STP;
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
 
-	r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
-						      OMAP_I2C_TIMEOUT);
+	r = wait_for_completion_timeout(&dev->cmd_complete,
+					OMAP_I2C_TIMEOUT);
 	dev->buf_len = 0;
 	if (r < 0)
 		return r;
-- 
1.5.6.rc3.21.g8c6b5


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2008-09-25  7:53 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-25  7:16 [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review Tony Lindgren
2008-09-25  7:16 ` [PATCH 1/8] i2c-omap: Do not use interruptible wait call in omap_i2c_xfer_msg Tony Lindgren
2008-09-25  7:16   ` [PATCH 2/8] i2c-omap: Close suspected race between omap_i2c_idle() and omap_i2c_isr() Tony Lindgren
2008-09-25  7:16     ` [PATCH 3/8] i2c-omap: Add high-speed support to omap-i2c Tony Lindgren
2008-09-25  7:16       ` [PATCH 4/8] i2c-omap: FIFO handling support and broken hw workaround for i2c-omap Tony Lindgren
2008-09-25  7:16         ` [PATCH 5/8] i2c-omap: Add support on 34xx Tony Lindgren
2008-09-25  7:16           ` [PATCH 6/8] i2c-omap: Mark init-only functions as __init Tony Lindgren
2008-09-25  7:16             ` [PATCH 7/8] i2c-omap: Don't compile in OMAP15xx I2C ISR for non-OMAP15xx builds Tony Lindgren
2008-09-25  7:16               ` [PATCH 8/8] i2c-omap: Clean-up i2c-omap Tony Lindgren
2008-09-25  7:27                 ` [PATCH 8/8] i2c-omap: Clean-up i2c-omap, v2 Tony Lindgren
2008-09-25  7:49 ` [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review Tony Lindgren
  -- strict thread matches above, loose matches on Subject: below --
2008-09-25  7:53 [PATCH 0/8] Updates for i2c-omap from linux-omap tree for review, v2 Tony Lindgren
2008-09-25  7:53 ` [PATCH 1/8] i2c-omap: Do not use interruptible wait call in omap_i2c_xfer_msg Tony Lindgren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox