diff options
Diffstat (limited to 'drivers/spi/spi-bitbang.c')
-rw-r--r-- | drivers/spi/spi-bitbang.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index aef59b1a15f7..a63d7da3bfe2 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -69,7 +69,7 @@ static unsigned bitbang_txrx_8( unsigned ns, struct spi_transfer *t ) { - unsigned bits = t->bits_per_word ? : spi->bits_per_word; + unsigned bits = t->bits_per_word; unsigned count = t->len; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; @@ -95,7 +95,7 @@ static unsigned bitbang_txrx_16( unsigned ns, struct spi_transfer *t ) { - unsigned bits = t->bits_per_word ? : spi->bits_per_word; + unsigned bits = t->bits_per_word; unsigned count = t->len; const u16 *tx = t->tx_buf; u16 *rx = t->rx_buf; @@ -121,7 +121,7 @@ static unsigned bitbang_txrx_32( unsigned ns, struct spi_transfer *t ) { - unsigned bits = t->bits_per_word ? : spi->bits_per_word; + unsigned bits = t->bits_per_word; unsigned count = t->len; const u32 *tx = t->tx_buf; u32 *rx = t->rx_buf; @@ -260,11 +260,11 @@ static void bitbang_work(struct work_struct *work) struct spi_bitbang *bitbang = container_of(work, struct spi_bitbang, work); unsigned long flags; + struct spi_message *m, *_m; spin_lock_irqsave(&bitbang->lock, flags); bitbang->busy = 1; - while (!list_empty(&bitbang->queue)) { - struct spi_message *m; + list_for_each_entry_safe(m, _m, &bitbang->queue, queue) { struct spi_device *spi; unsigned nsecs; struct spi_transfer *t = NULL; @@ -273,9 +273,7 @@ static void bitbang_work(struct work_struct *work) int status; int do_setup = -1; - m = container_of(bitbang->queue.next, struct spi_message, - queue); - list_del_init(&m->queue); + list_del(&m->queue); spin_unlock_irqrestore(&bitbang->lock, flags); /* FIXME this is made-up ... the correct value is known to @@ -346,17 +344,14 @@ static void bitbang_work(struct work_struct *work) if (t->delay_usecs) udelay(t->delay_usecs); - if (!cs_change) - continue; - if (t->transfer_list.next == &m->transfers) - break; - - /* sometimes a short mid-message deselect of the chip - * may be needed to terminate a mode or command - */ - ndelay(nsecs); - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(nsecs); + if (cs_change && !list_is_last(&t->transfer_list, &m->transfers)) { + /* sometimes a short mid-message deselect of the chip + * may be needed to terminate a mode or command + */ + ndelay(nsecs); + bitbang->chipselect(spi, BITBANG_CS_INACTIVE); + ndelay(nsecs); + } } m->status = status; @@ -432,40 +427,41 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer); */ int spi_bitbang_start(struct spi_bitbang *bitbang) { - int status; + struct spi_master *master = bitbang->master; + int status; - if (!bitbang->master || !bitbang->chipselect) + if (!master || !bitbang->chipselect) return -EINVAL; INIT_WORK(&bitbang->work, bitbang_work); spin_lock_init(&bitbang->lock); INIT_LIST_HEAD(&bitbang->queue); - if (!bitbang->master->mode_bits) - bitbang->master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; + if (!master->mode_bits) + master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags; - if (!bitbang->master->transfer) - bitbang->master->transfer = spi_bitbang_transfer; + if (!master->transfer) + master->transfer = spi_bitbang_transfer; if (!bitbang->txrx_bufs) { bitbang->use_dma = 0; bitbang->txrx_bufs = spi_bitbang_bufs; - if (!bitbang->master->setup) { + if (!master->setup) { if (!bitbang->setup_transfer) bitbang->setup_transfer = spi_bitbang_setup_transfer; - bitbang->master->setup = spi_bitbang_setup; - bitbang->master->cleanup = spi_bitbang_cleanup; + master->setup = spi_bitbang_setup; + master->cleanup = spi_bitbang_cleanup; } - } else if (!bitbang->master->setup) + } else if (!master->setup) return -EINVAL; - if (bitbang->master->transfer == spi_bitbang_transfer && + if (master->transfer == spi_bitbang_transfer && !bitbang->setup_transfer) return -EINVAL; /* this task is the only thing to touch the SPI bits */ bitbang->busy = 0; bitbang->workqueue = create_singlethread_workqueue( - dev_name(bitbang->master->dev.parent)); + dev_name(master->dev.parent)); if (bitbang->workqueue == NULL) { status = -EBUSY; goto err1; @@ -474,7 +470,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) /* driver may get busy before register() returns, especially * if someone registered boardinfo for devices */ - status = spi_register_master(bitbang->master); + status = spi_register_master(master); if (status < 0) goto err2; |