diff options
Diffstat (limited to 'drivers/spi/spi-s3c64xx.c')
-rw-r--r-- | drivers/spi/spi-s3c64xx.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index e862ab8853aa..4188b2faac5c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -994,25 +994,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data) | |||
994 | { | 994 | { |
995 | struct s3c64xx_spi_driver_data *sdd = data; | 995 | struct s3c64xx_spi_driver_data *sdd = data; |
996 | struct spi_master *spi = sdd->master; | 996 | struct spi_master *spi = sdd->master; |
997 | unsigned int val; | 997 | unsigned int val, clr = 0; |
998 | 998 | ||
999 | val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); | 999 | val = readl(sdd->regs + S3C64XX_SPI_STATUS); |
1000 | 1000 | ||
1001 | val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | | 1001 | if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { |
1002 | S3C64XX_SPI_PND_RX_UNDERRUN_CLR | | 1002 | clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; |
1003 | S3C64XX_SPI_PND_TX_OVERRUN_CLR | | ||
1004 | S3C64XX_SPI_PND_TX_UNDERRUN_CLR; | ||
1005 | |||
1006 | writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); | ||
1007 | |||
1008 | if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) | ||
1009 | dev_err(&spi->dev, "RX overrun\n"); | 1003 | dev_err(&spi->dev, "RX overrun\n"); |
1010 | if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) | 1004 | } |
1005 | if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { | ||
1006 | clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; | ||
1011 | dev_err(&spi->dev, "RX underrun\n"); | 1007 | dev_err(&spi->dev, "RX underrun\n"); |
1012 | if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) | 1008 | } |
1009 | if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { | ||
1010 | clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; | ||
1013 | dev_err(&spi->dev, "TX overrun\n"); | 1011 | dev_err(&spi->dev, "TX overrun\n"); |
1014 | if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) | 1012 | } |
1013 | if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { | ||
1014 | clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; | ||
1015 | dev_err(&spi->dev, "TX underrun\n"); | 1015 | dev_err(&spi->dev, "TX underrun\n"); |
1016 | } | ||
1017 | |||
1018 | /* Clear the pending irq by setting and then clearing it */ | ||
1019 | writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); | ||
1020 | writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); | ||
1016 | 1021 | ||
1017 | return IRQ_HANDLED; | 1022 | return IRQ_HANDLED; |
1018 | } | 1023 | } |
@@ -1036,9 +1041,13 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) | |||
1036 | writel(0, regs + S3C64XX_SPI_MODE_CFG); | 1041 | writel(0, regs + S3C64XX_SPI_MODE_CFG); |
1037 | writel(0, regs + S3C64XX_SPI_PACKET_CNT); | 1042 | writel(0, regs + S3C64XX_SPI_PACKET_CNT); |
1038 | 1043 | ||
1039 | /* Clear any irq pending bits */ | 1044 | /* Clear any irq pending bits, should set and clear the bits */ |
1040 | writel(readl(regs + S3C64XX_SPI_PENDING_CLR), | 1045 | val = S3C64XX_SPI_PND_RX_OVERRUN_CLR | |
1041 | regs + S3C64XX_SPI_PENDING_CLR); | 1046 | S3C64XX_SPI_PND_RX_UNDERRUN_CLR | |
1047 | S3C64XX_SPI_PND_TX_OVERRUN_CLR | | ||
1048 | S3C64XX_SPI_PND_TX_UNDERRUN_CLR; | ||
1049 | writel(val, regs + S3C64XX_SPI_PENDING_CLR); | ||
1050 | writel(0, regs + S3C64XX_SPI_PENDING_CLR); | ||
1042 | 1051 | ||
1043 | writel(0, regs + S3C64XX_SPI_SWAP_CFG); | 1052 | writel(0, regs + S3C64XX_SPI_SWAP_CFG); |
1044 | 1053 | ||