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; }
/* * 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; }