Run tested: ath79, ipq40xx Build tested: ath79, ipq40xx Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
		
			
				
	
	
		
			381 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			381 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From: Russell King <rmk+kernel@armlinux.org.uk>
 | 
						|
Bcc: linux@mail.armlinux.org.uk
 | 
						|
Cc: linux-i2c@vger.kernel.org
 | 
						|
Subject: [PATCH 04/17] i2c: pxa: re-arrange functions to flow better
 | 
						|
MIME-Version: 1.0
 | 
						|
Content-Disposition: inline
 | 
						|
Content-Transfer-Encoding: 8bit
 | 
						|
Content-Type: text/plain; charset="utf-8"
 | 
						|
 | 
						|
Re-arrange the PXA I2C code to avoid forward declarations, and keep
 | 
						|
similar functionality (e.g. the non-IRQ mode support) together. This
 | 
						|
improves code readability.
 | 
						|
 | 
						|
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
 | 
						|
---
 | 
						|
 drivers/i2c/busses/i2c-pxa.c | 325 +++++++++++++++++------------------
 | 
						|
 1 file changed, 162 insertions(+), 163 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/i2c/busses/i2c-pxa.c
 | 
						|
+++ b/drivers/i2c/busses/i2c-pxa.c
 | 
						|
@@ -326,7 +326,6 @@ static void i2c_pxa_scream_blue_murder(s
 | 
						|
 #endif /* ifdef DEBUG / else */
 | 
						|
 
 | 
						|
 static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
 | 
						|
-static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
 | 
						|
 
 | 
						|
 static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
 | 
						|
 {
 | 
						|
@@ -697,34 +696,6 @@ static inline void i2c_pxa_stop_message(
 | 
						|
 	writel(icr, _ICR(i2c));
 | 
						|
 }
 | 
						|
 
 | 
						|
-static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
 | 
						|
-{
 | 
						|
-	/* make timeout the same as for interrupt based functions */
 | 
						|
-	long timeout = 2 * DEF_TIMEOUT;
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * Wait for the bus to become free.
 | 
						|
-	 */
 | 
						|
-	while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
 | 
						|
-		udelay(1000);
 | 
						|
-		show_state(i2c);
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	if (timeout < 0) {
 | 
						|
-		show_state(i2c);
 | 
						|
-		dev_err(&i2c->adap.dev,
 | 
						|
-			"i2c_pxa: timeout waiting for bus free\n");
 | 
						|
-		return I2C_RETRY;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * Set master mode.
 | 
						|
-	 */
 | 
						|
-	writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
 | 
						|
-
 | 
						|
-	return 0;
 | 
						|
-}
 | 
						|
-
 | 
						|
 /*
 | 
						|
  * PXA I2C send master code
 | 
						|
  * 1. Load master code to IDBR and send it.
 | 
						|
@@ -753,140 +724,6 @@ static int i2c_pxa_send_mastercode(struc
 | 
						|
 	return (timeout == 0) ? I2C_RETRY : 0;
 | 
						|
 }
 | 
						|
 
 | 
						|
-static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
 | 
						|
-			       struct i2c_msg *msg, int num)
 | 
						|
-{
 | 
						|
-	unsigned long timeout = 500000; /* 5 seconds */
 | 
						|
-	int ret = 0;
 | 
						|
-
 | 
						|
-	ret = i2c_pxa_pio_set_master(i2c);
 | 
						|
-	if (ret)
 | 
						|
-		goto out;
 | 
						|
-
 | 
						|
-	i2c->msg = msg;
 | 
						|
-	i2c->msg_num = num;
 | 
						|
-	i2c->msg_idx = 0;
 | 
						|
-	i2c->msg_ptr = 0;
 | 
						|
-	i2c->irqlogidx = 0;
 | 
						|
-
 | 
						|
-	i2c_pxa_start_message(i2c);
 | 
						|
-
 | 
						|
-	while (i2c->msg_num > 0 && --timeout) {
 | 
						|
-		i2c_pxa_handler(0, i2c);
 | 
						|
-		udelay(10);
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	i2c_pxa_stop_message(i2c);
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * We place the return code in i2c->msg_idx.
 | 
						|
-	 */
 | 
						|
-	ret = i2c->msg_idx;
 | 
						|
-
 | 
						|
-out:
 | 
						|
-	if (timeout == 0) {
 | 
						|
-		i2c_pxa_scream_blue_murder(i2c, "timeout");
 | 
						|
-		ret = I2C_RETRY;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	return ret;
 | 
						|
-}
 | 
						|
-
 | 
						|
-/*
 | 
						|
- * We are protected by the adapter bus mutex.
 | 
						|
- */
 | 
						|
-static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
 | 
						|
-{
 | 
						|
-	long timeout;
 | 
						|
-	int ret;
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * Wait for the bus to become free.
 | 
						|
-	 */
 | 
						|
-	ret = i2c_pxa_wait_bus_not_busy(i2c);
 | 
						|
-	if (ret) {
 | 
						|
-		dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
 | 
						|
-		goto out;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * Set master mode.
 | 
						|
-	 */
 | 
						|
-	ret = i2c_pxa_set_master(i2c);
 | 
						|
-	if (ret) {
 | 
						|
-		dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
 | 
						|
-		goto out;
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	if (i2c->high_mode) {
 | 
						|
-		ret = i2c_pxa_send_mastercode(i2c);
 | 
						|
-		if (ret) {
 | 
						|
-			dev_err(&i2c->adap.dev, "i2c_pxa_send_mastercode timeout\n");
 | 
						|
-			goto out;
 | 
						|
-			}
 | 
						|
-	}
 | 
						|
-
 | 
						|
-	spin_lock_irq(&i2c->lock);
 | 
						|
-
 | 
						|
-	i2c->msg = msg;
 | 
						|
-	i2c->msg_num = num;
 | 
						|
-	i2c->msg_idx = 0;
 | 
						|
-	i2c->msg_ptr = 0;
 | 
						|
-	i2c->irqlogidx = 0;
 | 
						|
-
 | 
						|
-	i2c_pxa_start_message(i2c);
 | 
						|
-
 | 
						|
-	spin_unlock_irq(&i2c->lock);
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * The rest of the processing occurs in the interrupt handler.
 | 
						|
-	 */
 | 
						|
-	timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
 | 
						|
-	i2c_pxa_stop_message(i2c);
 | 
						|
-
 | 
						|
-	/*
 | 
						|
-	 * We place the return code in i2c->msg_idx.
 | 
						|
-	 */
 | 
						|
-	ret = i2c->msg_idx;
 | 
						|
-
 | 
						|
-	if (!timeout && i2c->msg_num) {
 | 
						|
-		i2c_pxa_scream_blue_murder(i2c, "timeout");
 | 
						|
-		ret = I2C_RETRY;
 | 
						|
-	}
 | 
						|
-
 | 
						|
- out:
 | 
						|
-	return ret;
 | 
						|
-}
 | 
						|
-
 | 
						|
-static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
 | 
						|
-			    struct i2c_msg msgs[], int num)
 | 
						|
-{
 | 
						|
-	struct pxa_i2c *i2c = adap->algo_data;
 | 
						|
-	int ret, i;
 | 
						|
-
 | 
						|
-	/* If the I2C controller is disabled we need to reset it
 | 
						|
-	  (probably due to a suspend/resume destroying state). We do
 | 
						|
-	  this here as we can then avoid worrying about resuming the
 | 
						|
-	  controller before its users. */
 | 
						|
-	if (!(readl(_ICR(i2c)) & ICR_IUE))
 | 
						|
-		i2c_pxa_reset(i2c);
 | 
						|
-
 | 
						|
-	for (i = adap->retries; i >= 0; i--) {
 | 
						|
-		ret = i2c_pxa_do_pio_xfer(i2c, msgs, num);
 | 
						|
-		if (ret != I2C_RETRY)
 | 
						|
-			goto out;
 | 
						|
-
 | 
						|
-		if (i2c_debug)
 | 
						|
-			dev_dbg(&adap->dev, "Retrying transmission\n");
 | 
						|
-		udelay(100);
 | 
						|
-	}
 | 
						|
-	i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
 | 
						|
-	ret = -EREMOTEIO;
 | 
						|
- out:
 | 
						|
-	i2c_pxa_set_slave(i2c, ret);
 | 
						|
-	return ret;
 | 
						|
-}
 | 
						|
-
 | 
						|
 /*
 | 
						|
  * i2c_pxa_master_complete - complete the message and wake up.
 | 
						|
  */
 | 
						|
@@ -1093,6 +930,71 @@ static irqreturn_t i2c_pxa_handler(int t
 | 
						|
 	return IRQ_HANDLED;
 | 
						|
 }
 | 
						|
 
 | 
						|
+/*
 | 
						|
+ * We are protected by the adapter bus mutex.
 | 
						|
+ */
 | 
						|
+static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
 | 
						|
+{
 | 
						|
+	long timeout;
 | 
						|
+	int ret;
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Wait for the bus to become free.
 | 
						|
+	 */
 | 
						|
+	ret = i2c_pxa_wait_bus_not_busy(i2c);
 | 
						|
+	if (ret) {
 | 
						|
+		dev_err(&i2c->adap.dev, "i2c_pxa: timeout waiting for bus free\n");
 | 
						|
+		goto out;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Set master mode.
 | 
						|
+	 */
 | 
						|
+	ret = i2c_pxa_set_master(i2c);
 | 
						|
+	if (ret) {
 | 
						|
+		dev_err(&i2c->adap.dev, "i2c_pxa_set_master: error %d\n", ret);
 | 
						|
+		goto out;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (i2c->high_mode) {
 | 
						|
+		ret = i2c_pxa_send_mastercode(i2c);
 | 
						|
+		if (ret) {
 | 
						|
+			dev_err(&i2c->adap.dev, "i2c_pxa_send_mastercode timeout\n");
 | 
						|
+			goto out;
 | 
						|
+			}
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	spin_lock_irq(&i2c->lock);
 | 
						|
+
 | 
						|
+	i2c->msg = msg;
 | 
						|
+	i2c->msg_num = num;
 | 
						|
+	i2c->msg_idx = 0;
 | 
						|
+	i2c->msg_ptr = 0;
 | 
						|
+	i2c->irqlogidx = 0;
 | 
						|
+
 | 
						|
+	i2c_pxa_start_message(i2c);
 | 
						|
+
 | 
						|
+	spin_unlock_irq(&i2c->lock);
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * The rest of the processing occurs in the interrupt handler.
 | 
						|
+	 */
 | 
						|
+	timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
 | 
						|
+	i2c_pxa_stop_message(i2c);
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * We place the return code in i2c->msg_idx.
 | 
						|
+	 */
 | 
						|
+	ret = i2c->msg_idx;
 | 
						|
+
 | 
						|
+	if (!timeout && i2c->msg_num) {
 | 
						|
+		i2c_pxa_scream_blue_murder(i2c, "timeout");
 | 
						|
+		ret = I2C_RETRY;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+ out:
 | 
						|
+	return ret;
 | 
						|
+}
 | 
						|
 
 | 
						|
 static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 | 
						|
 {
 | 
						|
@@ -1126,6 +1028,103 @@ static const struct i2c_algorithm i2c_px
 | 
						|
 	.functionality	= i2c_pxa_functionality,
 | 
						|
 };
 | 
						|
 
 | 
						|
+/* Non-interrupt mode support */
 | 
						|
+static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
 | 
						|
+{
 | 
						|
+	/* make timeout the same as for interrupt based functions */
 | 
						|
+	long timeout = 2 * DEF_TIMEOUT;
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Wait for the bus to become free.
 | 
						|
+	 */
 | 
						|
+	while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
 | 
						|
+		udelay(1000);
 | 
						|
+		show_state(i2c);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	if (timeout < 0) {
 | 
						|
+		show_state(i2c);
 | 
						|
+		dev_err(&i2c->adap.dev,
 | 
						|
+			"i2c_pxa: timeout waiting for bus free\n");
 | 
						|
+		return I2C_RETRY;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Set master mode.
 | 
						|
+	 */
 | 
						|
+	writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
 | 
						|
+
 | 
						|
+	return 0;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
 | 
						|
+			       struct i2c_msg *msg, int num)
 | 
						|
+{
 | 
						|
+	unsigned long timeout = 500000; /* 5 seconds */
 | 
						|
+	int ret = 0;
 | 
						|
+
 | 
						|
+	ret = i2c_pxa_pio_set_master(i2c);
 | 
						|
+	if (ret)
 | 
						|
+		goto out;
 | 
						|
+
 | 
						|
+	i2c->msg = msg;
 | 
						|
+	i2c->msg_num = num;
 | 
						|
+	i2c->msg_idx = 0;
 | 
						|
+	i2c->msg_ptr = 0;
 | 
						|
+	i2c->irqlogidx = 0;
 | 
						|
+
 | 
						|
+	i2c_pxa_start_message(i2c);
 | 
						|
+
 | 
						|
+	while (i2c->msg_num > 0 && --timeout) {
 | 
						|
+		i2c_pxa_handler(0, i2c);
 | 
						|
+		udelay(10);
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	i2c_pxa_stop_message(i2c);
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * We place the return code in i2c->msg_idx.
 | 
						|
+	 */
 | 
						|
+	ret = i2c->msg_idx;
 | 
						|
+
 | 
						|
+out:
 | 
						|
+	if (timeout == 0) {
 | 
						|
+		i2c_pxa_scream_blue_murder(i2c, "timeout");
 | 
						|
+		ret = I2C_RETRY;
 | 
						|
+	}
 | 
						|
+
 | 
						|
+	return ret;
 | 
						|
+}
 | 
						|
+
 | 
						|
+static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
 | 
						|
+			    struct i2c_msg msgs[], int num)
 | 
						|
+{
 | 
						|
+	struct pxa_i2c *i2c = adap->algo_data;
 | 
						|
+	int ret, i;
 | 
						|
+
 | 
						|
+	/* If the I2C controller is disabled we need to reset it
 | 
						|
+	  (probably due to a suspend/resume destroying state). We do
 | 
						|
+	  this here as we can then avoid worrying about resuming the
 | 
						|
+	  controller before its users. */
 | 
						|
+	if (!(readl(_ICR(i2c)) & ICR_IUE))
 | 
						|
+		i2c_pxa_reset(i2c);
 | 
						|
+
 | 
						|
+	for (i = adap->retries; i >= 0; i--) {
 | 
						|
+		ret = i2c_pxa_do_pio_xfer(i2c, msgs, num);
 | 
						|
+		if (ret != I2C_RETRY)
 | 
						|
+			goto out;
 | 
						|
+
 | 
						|
+		if (i2c_debug)
 | 
						|
+			dev_dbg(&adap->dev, "Retrying transmission\n");
 | 
						|
+		udelay(100);
 | 
						|
+	}
 | 
						|
+	i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
 | 
						|
+	ret = -EREMOTEIO;
 | 
						|
+ out:
 | 
						|
+	i2c_pxa_set_slave(i2c, ret);
 | 
						|
+	return ret;
 | 
						|
+}
 | 
						|
+
 | 
						|
 static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
 | 
						|
 	.master_xfer	= i2c_pxa_pio_xfer,
 | 
						|
 	.functionality	= i2c_pxa_functionality,
 |