diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi_mpc83xx.c | 115 |
1 files changed, 60 insertions, 55 deletions
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index 273940d3938..e854ac0d413 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c @@ -350,71 +350,76 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) return mpc83xx_spi->count; } -static void mpc83xx_spi_work(struct work_struct *work) +static void mpc83xx_spi_do_one_msg(struct spi_message *m) { - struct mpc83xx_spi *mpc83xx_spi = - container_of(work, struct mpc83xx_spi, work); - - spin_lock_irq(&mpc83xx_spi->lock); - mpc83xx_spi->busy = 1; - while (!list_empty(&mpc83xx_spi->queue)) { - struct spi_message *m; - struct spi_device *spi; - struct spi_transfer *t = NULL; - unsigned cs_change; - int status, nsecs = 50; - - m = container_of(mpc83xx_spi->queue.next, - struct spi_message, queue); - list_del_init(&m->queue); - spin_unlock_irq(&mpc83xx_spi->lock); - - spi = m->spi; - cs_change = 1; - status = 0; - list_for_each_entry(t, &m->transfers, transfer_list) { - if (t->bits_per_word || t->speed_hz) { - /* Don't allow changes if CS is active */ - status = -EINVAL; - - if (cs_change) - status = mpc83xx_spi_setup_transfer(spi, t); - if (status < 0) - break; - } - - if (cs_change) { - mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE); - ndelay(nsecs); - } - cs_change = t->cs_change; - if (t->len) - status = mpc83xx_spi_bufs(spi, t); - if (status) { - status = -EMSGSIZE; + struct spi_device *spi = m->spi; + struct spi_transfer *t; + unsigned int cs_change; + const int nsecs = 50; + int status; + + cs_change = 1; + status = 0; + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->bits_per_word || t->speed_hz) { + /* Don't allow changes if CS is active */ + status = -EINVAL; + + if (cs_change) + status = mpc83xx_spi_setup_transfer(spi, t); + if (status < 0) break; - } - m->actual_length += t->len; - - if (t->delay_usecs) - udelay(t->delay_usecs); + } - if (cs_change) { - ndelay(nsecs); - mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(nsecs); - } + if (cs_change) { + mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE); + ndelay(nsecs); + } + cs_change = t->cs_change; + if (t->len) + status = mpc83xx_spi_bufs(spi, t); + if (status) { + status = -EMSGSIZE; + break; } + m->actual_length += t->len; - m->status = status; - m->complete(m->context); + if (t->delay_usecs) + udelay(t->delay_usecs); - if (status || !cs_change) { + if (cs_change) { ndelay(nsecs); mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); + ndelay(nsecs); } + } + + m->status = status; + m->complete(m->context); + + if (status || !cs_change) { + ndelay(nsecs); + mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE); + } + + mpc83xx_spi_setup_transfer(spi, NULL); +} + +static void mpc83xx_spi_work(struct work_struct *work) +{ + struct mpc83xx_spi *mpc83xx_spi = container_of(work, struct mpc83xx_spi, + work); + + spin_lock_irq(&mpc83xx_spi->lock); + mpc83xx_spi->busy = 1; + while (!list_empty(&mpc83xx_spi->queue)) { + struct spi_message *m = container_of(mpc83xx_spi->queue.next, + struct spi_message, queue); + + list_del_init(&m->queue); + spin_unlock_irq(&mpc83xx_spi->lock); - mpc83xx_spi_setup_transfer(spi, NULL); + mpc83xx_spi_do_one_msg(m); spin_lock_irq(&mpc83xx_spi->lock); } |