diff options
Diffstat (limited to 'drivers')
| -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 89480b281d7..3e490ee7f27 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,  		for (i = count; i > 0; i--) {  			data = tx_buf ? *tx_buf++ : 0; -			if (len == EOFBYTE) +			if (len == EOFBYTE && t->cs_change)  				setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF);  			out_8(&fifo->txdata_8, data);  			len--; diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 27ff669f093..a17ca06381a 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)  {  	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); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 0cabf156055..45cb6a9d42c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -543,17 +543,16 @@ static void spi_pump_messages(struct kthread_work *work)  	/* Lock queue and check for queue work */  	spin_lock_irqsave(&master->queue_lock, flags);  	if (list_empty(&master->queue) || !master->running) { -		if (master->busy && master->unprepare_transfer_hardware) { -			ret = master->unprepare_transfer_hardware(master); -			if (ret) { -				spin_unlock_irqrestore(&master->queue_lock, flags); -				dev_err(&master->dev, -					"failed to unprepare transfer hardware\n"); -				return; -			} +		if (!master->busy) { +			spin_unlock_irqrestore(&master->queue_lock, flags); +			return;  		}  		master->busy = false;  		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;  	}  |