Edit online

关键流程设计

3 Dec 2024
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;
}