Commit e47ef0f1 authored by Mark Brown's avatar Mark Brown

Merge branch 'spi-fix' into spi-next

parents 823cd045 1ad849ae
...@@ -164,7 +164,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, ...@@ -164,7 +164,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi,
for (i = count; i > 0; i--) { for (i = count; i > 0; i--) {
data = tx_buf ? *tx_buf++ : 0; data = tx_buf ? *tx_buf++ : 0;
if (len == EOFBYTE) if (len == EOFBYTE && t->cs_change)
setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF);
out_8(&fifo->txdata_8, data); out_8(&fifo->txdata_8, data);
len--; len--;
......
...@@ -984,25 +984,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data) ...@@ -984,25 +984,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
{ {
struct s3c64xx_spi_driver_data *sdd = data; struct s3c64xx_spi_driver_data *sdd = data;
struct spi_master *spi = sdd->master; struct spi_master *spi = sdd->master;
unsigned int val; unsigned int val, clr = 0;
val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); val = readl(sdd->regs + S3C64XX_SPI_STATUS);
val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) {
S3C64XX_SPI_PND_RX_UNDERRUN_CLR | clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR;
S3C64XX_SPI_PND_TX_OVERRUN_CLR |
S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR);
if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR)
dev_err(&spi->dev, "RX overrun\n"); dev_err(&spi->dev, "RX overrun\n");
if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) }
if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) {
clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR;
dev_err(&spi->dev, "RX underrun\n"); dev_err(&spi->dev, "RX underrun\n");
if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) }
if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) {
clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR;
dev_err(&spi->dev, "TX overrun\n"); dev_err(&spi->dev, "TX overrun\n");
if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) }
if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) {
clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
dev_err(&spi->dev, "TX underrun\n"); dev_err(&spi->dev, "TX underrun\n");
}
/* Clear the pending irq by setting and then clearing it */
writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR);
writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -1026,9 +1031,13 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) ...@@ -1026,9 +1031,13 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
writel(0, regs + S3C64XX_SPI_MODE_CFG); writel(0, regs + S3C64XX_SPI_MODE_CFG);
writel(0, regs + S3C64XX_SPI_PACKET_CNT); writel(0, regs + S3C64XX_SPI_PACKET_CNT);
/* Clear any irq pending bits */ /* Clear any irq pending bits, should set and clear the bits */
writel(readl(regs + S3C64XX_SPI_PENDING_CLR), val = S3C64XX_SPI_PND_RX_OVERRUN_CLR |
regs + S3C64XX_SPI_PENDING_CLR); S3C64XX_SPI_PND_RX_UNDERRUN_CLR |
S3C64XX_SPI_PND_TX_OVERRUN_CLR |
S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
writel(val, regs + S3C64XX_SPI_PENDING_CLR);
writel(0, regs + S3C64XX_SPI_PENDING_CLR);
writel(0, regs + S3C64XX_SPI_SWAP_CFG); writel(0, regs + S3C64XX_SPI_SWAP_CFG);
......
...@@ -543,17 +543,16 @@ static void spi_pump_messages(struct kthread_work *work) ...@@ -543,17 +543,16 @@ static void spi_pump_messages(struct kthread_work *work)
/* Lock queue and check for queue work */ /* Lock queue and check for queue work */
spin_lock_irqsave(&master->queue_lock, flags); spin_lock_irqsave(&master->queue_lock, flags);
if (list_empty(&master->queue) || !master->running) { if (list_empty(&master->queue) || !master->running) {
if (master->busy && master->unprepare_transfer_hardware) { if (!master->busy) {
ret = master->unprepare_transfer_hardware(master); spin_unlock_irqrestore(&master->queue_lock, flags);
if (ret) { return;
spin_unlock_irqrestore(&master->queue_lock, flags);
dev_err(&master->dev,
"failed to unprepare transfer hardware\n");
return;
}
} }
master->busy = false; master->busy = false;
spin_unlock_irqrestore(&master->queue_lock, flags); spin_unlock_irqrestore(&master->queue_lock, flags);
if (master->unprepare_transfer_hardware &&
master->unprepare_transfer_hardware(master))
dev_err(&master->dev,
"failed to unprepare transfer hardware\n");
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment