summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAlejandro Gonzalez <alex.gonzalez@digi.com>2010-05-24 11:21:03 +0200
committerAlejandro Gonzalez <alex.gonzalez@digi.com>2010-05-24 11:25:23 +0200
commit82e36c9848fb95f971fd85e123e61b2baa94906f (patch)
tree2bcb0bbcf96bc4ea7c38efb6b250014133c76699 /drivers
parent66ba72a7fe15ad33d442ae007bfc6eee1359800d (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.c31
-rw-r--r--drivers/spi/spidev.c6
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);
}