Merge branch 'spi-fix' into spi-next
This commit is contained in:
commit
e47ef0f1af
@ -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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user