| 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, |