Beispiel #1
0
static irqreturn_t nuc970_spi0_irq(int irq, void *dev)
{
	struct nuc970_spi *hw = dev;
	unsigned int status, i, offset;
	unsigned int count = hw->count;
    
    hw->count += hw->pdata->txnum+1;

    if (hw->rx) {
        for(i=0, offset=0; i<hw->pdata->txnum+1 ;i++,offset+=4)
            hw_rx(hw, __raw_readl(hw->regs + REG_RX0 + offset), count++);
    }
    
    count = hw->count;
    if (count < hw->len) {
        for(i=0, offset=0; i<hw->pdata->txnum+1 ;i++,offset+=4) {
            __raw_writel(hw_tx(hw, count++), hw->regs + REG_TX0 + offset);
        }
        nuc970_spi0_gobusy(hw);
    } else {
        complete(&hw->done);
    }

    status = __raw_readl(hw->regs + REG_CNTRL);
	__raw_writel(status, hw->regs + REG_CNTRL);

    return IRQ_HANDLED;
}
Beispiel #2
0
/*
 * s3c6410_spi_interrupt  - spi fifo interrupt handler
 * @irq    : interrupt number
 * @dev    : device instance
 *
 * spi fifo interrupt handler
 */
static irqreturn_t s3c6410_spi_irq(int irq, void *dev)
{
	struct s3c6410_spi *hw = dev;
	unsigned int pend = readl(hw->regs + S3C_SPI_STATUS);
	unsigned int w_tmp;
	unsigned int r_tmp;
	int err = 0;

	spin_lock(&hw->lock);

	if(pend & SPI_STUS_RX_OVERRUN_ERR)
	{
		printk("spi%d: RX FIFO overrun error\n", hw->id);
		writel(SPI_PND_RX_OVERRUN_CLR, hw->regs + S3C_PENDING_CLR);
		err = 1;
	}
	if(pend & SPI_STUS_RX_UNDERRUN_ERR)
	{
		printk("spi%d: RX FIFO underrun error\n", hw->id);
		writel(SPI_PND_RX_UNDERRUN_CLR, hw->regs + S3C_PENDING_CLR);
		err = 1;
	}
	if(pend & SPI_STUS_TX_OVERRUN_ERR)
	{
		printk("spi%d: TX FIFO overrun error\n", hw->id);
		writel(SPI_PND_TX_OVERRUN_CLR, hw->regs + S3C_PENDING_CLR);
		err = 1;
	}
	if(pend & SPI_STUS_TX_UNDERRUN_ERR)
	{
		printk("spi%d: TX FIFO underrun error\n", hw->id);
		writel(SPI_PND_TX_UNDERRUN_CLR, hw->regs + S3C_PENDING_CLR);
		err = 1;
	}

	if(err)
	{
		complete(&hw->done);
		return IRQ_HANDLED;
	}
	
	if((pend & SPI_STUS_TX_FIFORDY) && (hw->tx_done < hw->len))
	{
		w_tmp = hw_tx(hw);
        writel(w_tmp, hw->regs + S3C_SPI_TX_DATA);
		udelay(30);
		
		hw->flag = 1;
	    hw->tx_done++;
	}
	
	if(pend & (SPI_STUS_RX_FIFOLVL)) 
	{
		r_tmp = readl(hw->regs + S3C_SPI_RX_DATA);
        hw_rx(hw, r_tmp);
		hw->flag = 0;
		hw->rx_done++;
	}

	if(hw->rx_done == hw->len && hw->tx_done == hw->len)
	{
		writel(SPI_INT_ALL_DISABLE, hw->regs + S3C_SPI_INT_EN);
		udelay(30);
		complete(&hw->done);
	}
	
	spin_unlock(&hw->lock);

	return IRQ_HANDLED;
}