diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-01 09:55:16 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-01 09:55:16 -0400 |
commit | e47ef0f1affff3e017d0477b283a26beeb45258a (patch) | |
tree | ae00210c3b875e235c3cea284c8bf44a841a5199 /drivers/spi | |
parent | 823cd0454325509d84dbf8e301c182c8a2711c65 (diff) | |
parent | 1ad849aee5f53353ed88d9cd3d68a51b03a7d44f (diff) |
Merge branch 'spi-fix' into spi-next
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-mpc512x-psc.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 41 | ||||
-rw-r--r-- | drivers/spi/spi.c | 15 |
3 files changed, 33 insertions, 25 deletions
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 89480b281d74..3e490ee7f275 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c | |||
@@ -164,7 +164,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, | |||
164 | 164 | ||
165 | for (i = count; i > 0; i--) { | 165 | for (i = count; i > 0; i--) { |
166 | data = tx_buf ? *tx_buf++ : 0; | 166 | data = tx_buf ? *tx_buf++ : 0; |
167 | if (len == EOFBYTE) | 167 | if (len == EOFBYTE && t->cs_change) |
168 | setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); | 168 | setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); |
169 | out_8(&fifo->txdata_8, data); | 169 | out_8(&fifo->txdata_8, data); |
170 | len--; | 170 | len--; |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 27ff669f0937..a17ca06381ae 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -984,25 +984,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data) | |||
984 | { | 984 | { |
985 | struct s3c64xx_spi_driver_data *sdd = data; | 985 | struct s3c64xx_spi_driver_data *sdd = data; |
986 | struct spi_master *spi = sdd->master; | 986 | struct spi_master *spi = sdd->master; |
987 | unsigned int val; | 987 | unsigned int val, clr = 0; |
988 | 988 | ||
989 | val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); | 989 | val = readl(sdd->regs + S3C64XX_SPI_STATUS); |
990 | 990 | ||
991 | val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | | 991 | if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { |
992 | S3C64XX_SPI_PND_RX_UNDERRUN_CLR | | 992 | clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; |
993 | S3C64XX_SPI_PND_TX_OVERRUN_CLR | | ||
994 | S3C64XX_SPI_PND_TX_UNDERRUN_CLR; | ||
995 | |||
996 | writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); | ||
997 | |||
998 | if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) | ||
999 | dev_err(&spi->dev, "RX overrun\n"); | 993 | dev_err(&spi->dev, "RX overrun\n"); |
1000 | if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) | 994 | } |
995 | if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { | ||
996 | clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; | ||
1001 | dev_err(&spi->dev, "RX underrun\n"); | 997 | dev_err(&spi->dev, "RX underrun\n"); |
1002 | if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) | 998 | } |
999 | if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { | ||
1000 | clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; | ||
1003 | dev_err(&spi->dev, "TX overrun\n"); | 1001 | dev_err(&spi->dev, "TX overrun\n"); |
1004 | if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) | 1002 | } |
1003 | if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { | ||
1004 | clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; | ||
1005 | dev_err(&spi->dev, "TX underrun\n"); | 1005 | dev_err(&spi->dev, "TX underrun\n"); |
1006 | } | ||
1007 | |||
1008 | /* Clear the pending irq by setting and then clearing it */ | ||
1009 | writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); | ||
1010 | writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); | ||
1006 | 1011 | ||
1007 | return IRQ_HANDLED; | 1012 | return IRQ_HANDLED; |
1008 | } | 1013 | } |
@@ -1026,9 +1031,13 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) | |||
1026 | writel(0, regs + S3C64XX_SPI_MODE_CFG); | 1031 | writel(0, regs + S3C64XX_SPI_MODE_CFG); |
1027 | writel(0, regs + S3C64XX_SPI_PACKET_CNT); | 1032 | writel(0, regs + S3C64XX_SPI_PACKET_CNT); |
1028 | 1033 | ||
1029 | /* Clear any irq pending bits */ | 1034 | /* Clear any irq pending bits, should set and clear the bits */ |
1030 | writel(readl(regs + S3C64XX_SPI_PENDING_CLR), | 1035 | val = S3C64XX_SPI_PND_RX_OVERRUN_CLR | |
1031 | regs + S3C64XX_SPI_PENDING_CLR); | 1036 | S3C64XX_SPI_PND_RX_UNDERRUN_CLR | |
1037 | S3C64XX_SPI_PND_TX_OVERRUN_CLR | | ||
1038 | S3C64XX_SPI_PND_TX_UNDERRUN_CLR; | ||
1039 | writel(val, regs + S3C64XX_SPI_PENDING_CLR); | ||
1040 | writel(0, regs + S3C64XX_SPI_PENDING_CLR); | ||
1032 | 1041 | ||
1033 | writel(0, regs + S3C64XX_SPI_SWAP_CFG); | 1042 | writel(0, regs + S3C64XX_SPI_SWAP_CFG); |
1034 | 1043 | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 0cabf1560550..45cb6a9d42c9 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -543,17 +543,16 @@ static void spi_pump_messages(struct kthread_work *work) | |||
543 | /* Lock queue and check for queue work */ | 543 | /* Lock queue and check for queue work */ |
544 | spin_lock_irqsave(&master->queue_lock, flags); | 544 | spin_lock_irqsave(&master->queue_lock, flags); |
545 | if (list_empty(&master->queue) || !master->running) { | 545 | if (list_empty(&master->queue) || !master->running) { |
546 | if (master->busy && master->unprepare_transfer_hardware) { | 546 | if (!master->busy) { |
547 | ret = master->unprepare_transfer_hardware(master); | 547 | spin_unlock_irqrestore(&master->queue_lock, flags); |
548 | if (ret) { | 548 | return; |
549 | spin_unlock_irqrestore(&master->queue_lock, flags); | ||
550 | dev_err(&master->dev, | ||
551 | "failed to unprepare transfer hardware\n"); | ||
552 | return; | ||
553 | } | ||
554 | } | 549 | } |
555 | master->busy = false; | 550 | master->busy = false; |
556 | spin_unlock_irqrestore(&master->queue_lock, flags); | 551 | spin_unlock_irqrestore(&master->queue_lock, flags); |
552 | if (master->unprepare_transfer_hardware && | ||
553 | master->unprepare_transfer_hardware(master)) | ||
554 | dev_err(&master->dev, | ||
555 | "failed to unprepare transfer hardware\n"); | ||
557 | return; | 556 | return; |
558 | } | 557 | } |
559 | 558 | ||