|
@@ -984,25 +984,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
|
|
|
{
|
|
|
struct s3c64xx_spi_driver_data *sdd = data;
|
|
|
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 |
|
|
|
- S3C64XX_SPI_PND_RX_UNDERRUN_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)
|
|
|
+ if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) {
|
|
|
+ clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR;
|
|
|
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");
|
|
|
- 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");
|
|
|
- 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");
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 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;
|
|
|
}
|
|
@@ -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_PACKET_CNT);
|
|
|
|
|
|
- /* Clear any irq pending bits */
|
|
|
- writel(readl(regs + S3C64XX_SPI_PENDING_CLR),
|
|
|
- regs + S3C64XX_SPI_PENDING_CLR);
|
|
|
+ /* Clear any irq pending bits, should set and clear the bits */
|
|
|
+ val = S3C64XX_SPI_PND_RX_OVERRUN_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);
|
|
|
|