diff options
author | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-05-24 11:21:03 +0200 |
---|---|---|
committer | Alejandro Gonzalez <alex.gonzalez@digi.com> | 2010-05-24 11:25:23 +0200 |
commit | 82e36c9848fb95f971fd85e123e61b2baa94906f (patch) | |
tree | 2bcb0bbcf96bc4ea7c38efb6b250014133c76699 /drivers | |
parent | 66ba72a7fe15ad33d442ae007bfc6eee1359800d (diff) |
SPI: Fix half duplex lock
When a NULL TX pointer is passed to perform a half duplex read, the
transfer locks in the RX interrupt handler.
Signed-off-by: Alejandro Gonzalez <alex.gonzalez@digi.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/mxc_spi.c | 31 | ||||
-rw-r--r-- | drivers/spi/spidev.c | 6 |
2 files changed, 16 insertions, 21 deletions
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index 8ec90134769b..97f4d47b4d8b 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -722,36 +722,31 @@ static irqreturn_t mxc_spi_isr(int irq, void *dev_id) /* Read the interrupt status register to determine the source */ status = __raw_readl(master_drv_data->stat_addr); do { - u32 rx_tmp = - __raw_readl(master_drv_data->base + MXC_CSPIRXDATA); - + u32 rx_tmp = __raw_readl(master_drv_data->base + MXC_CSPIRXDATA); if (master_drv_data->transfer.rx_buf) - master_drv_data->transfer.rx_get(master_drv_data, - rx_tmp); + master_drv_data->transfer.rx_get(master_drv_data,rx_tmp); + (master_drv_data->transfer.count)--; (master_drv_data->transfer.rx_count)--; + ret = IRQ_HANDLED; + if (pass_counter-- == 0) { break; } + status = __raw_readl(master_drv_data->stat_addr); - } while (status & - (1 << - (MXC_CSPISTAT_RR + - master_drv_data->spi_ver_def->int_status_dif))); + } while (status & (1 << (MXC_CSPISTAT_RR + + master_drv_data->spi_ver_def->int_status_dif))); if (master_drv_data->transfer.rx_count) return ret; - if (master_drv_data->transfer.count) { - if (master_drv_data->transfer.tx_buf) { - u32 count = (master_drv_data->transfer.count > - fifo_size) ? fifo_size : - master_drv_data->transfer.count; - master_drv_data->transfer.rx_count = count; - spi_put_tx_data(master_drv_data->base, count, - master_drv_data); - } + if (master_drv_data->transfer.count ) { + u32 count = (master_drv_data->transfer.count > fifo_size) ? + fifo_size : master_drv_data->transfer.count; + master_drv_data->transfer.rx_count = count; + spi_put_tx_data(master_drv_data->base, count, master_drv_data); } else { complete(&master_drv_data->xfer_done); } diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 606e7a40a8da..5c3783b45954 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -267,15 +267,15 @@ static int spidev_message(struct spidev_data *spidev, k_tmp->delay_usecs = u_tmp->delay_usecs; k_tmp->speed_hz = u_tmp->speed_hz; #ifdef VERBOSE - dev_dbg(&spi->dev, + dev_dbg(&msg.spi->dev, " xfer len %zd %s%s%s%dbits %u usec %uHz\n", u_tmp->len, u_tmp->rx_buf ? "rx " : "", u_tmp->tx_buf ? "tx " : "", u_tmp->cs_change ? "cs " : "", - u_tmp->bits_per_word ? : spi->bits_per_word, + u_tmp->bits_per_word ? : msg.spi->bits_per_word, u_tmp->delay_usecs, - u_tmp->speed_hz ? : spi->max_speed_hz); + u_tmp->speed_hz ? : msg.spi->max_speed_hz); #endif spi_message_add_tail(k_tmp, &msg); } |