关键流程设计
Read time: 1 minute(s)
初始化流程
aic_spi_probe(); |-> irq = platform_get_irq(pdev, 0); |-> ctlr = spi_alloc_master(&pdev->dev, sizeof(struct aic_spi)); |-> platform_set_drvdata(pdev, ctlr); |-> aicspi->dma_rx = dma_request_slave_channel(aicspi->dev, "rx"); |-> aicspi->dma_tx = dma_request_slave_channel(aicspi->dev, "tx"); |-> request_irq(aicspi->irq, aic_spi_handle_irq, 0, aicspi->dev_name, aicspi); |-> spi_register_controller(ctlr);
中断流程
SPI 控制器驱动中的中断处理并不复杂,当中断发生时,首先在 irq handler 中读取相关状态寄存器,
然后判断如何处理:
static irqreturn_t aic_spi_handle_irq(int irq, void *dev_id) { ... spi_ctlr_pending_irq_clr(status, base_addr); /* master mode, Transfer Complete Interrupt */ if (status & ISR_BIT_TC) { ... spi_ctlr_irq_disable(ISR_BIT_TC | ISR_BIT_ERRS, base_addr); spi_finalize_current_transfer(aicspi->ctlr); // 传输完成,通知调用者 ... return IRQ_HANDLED; } else if (status & ISR_BIT_ERRS) { ... spi_ctlr_irq_disable(ISR_BIT_TC | ISR_BIT_ERRS, base_addr); spi_ctlr_soft_reset(base_addr); // 传输出错,reset 控制器 spi_finalize_current_transfer(aicspi->ctlr); ... return IRQ_HANDLED; } ... return IRQ_NONE; }