forked from luck/tmp_suning_uos_patched
i2c: pxa: re-arrange functions to flow better
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> Signed-off-by: Wolfram Sang <wsa@kernel.org>
This commit is contained in:
parent
8de32da283
commit
1ae49a15ee
|
@ -326,7 +326,6 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
|
|||
#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)
|
||||
{
|
||||
|
@ -741,34 +740,6 @@ static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
|
|||
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.
|
||||
|
@ -797,140 +768,6 @@ static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
|
|||
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.
|
||||
*/
|
||||
|
@ -1137,6 +974,71 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
|
|||
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)
|
||||
{
|
||||
|
@ -1174,6 +1076,103 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
|
|||
#endif
|
||||
};
|
||||
|
||||
/* 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,
|
||||
|
|
Loading…
Reference in New Issue
Block a user