关键流程设计
初始化
aic_spienc_probe(); |-> drvdata->base = devm_platform_ioremap_resource(pdev, 0); |-> irq = platform_get_irq(pdev, 0); |-> devm_request_threaded_irq(dev, irq, aic_spienc_irq_handler, aic_spienc_irq_thread, IRQF_ONESHOT, dev_name(dev), drvdata); |-> drvdata->clk = devm_clk_get(dev, NULL); |-> clk_prepare_enable(drvdata->clk); |-> devm_reset_control_get(dev, NULL); |-> platform_set_drvdata(pdev, drvdata); |-> crypto_register_skcipher(&spienc_alg.alg); // 注册算法
加解密配置
aic_spienc_encrypt(req);
|-> aic_spienc_xcrypt(req);
    |-> aic_spienc_attach_bus(drvdata, ivinfo->spi_id);
    |-> writel(ivinfo->addr, (drvdata->base + SPIE_REG_ADDR));
    |-> writel(ivinfo->cpos, (drvdata->base + SPIE_REG_CPOS));
    |-> writel(clen, (drvdata->base + SPIE_REG_CLEN));
    |-> writel(tweak, (drvdata->base + SPIE_REG_TWEAK));
            解密流程相同。
中断流程
当中断发生时,首先在 irq handler 中读取并保存状态寄存器:
static irqreturn_t aic_spienc_irq_handler(int irq, void *arg)
{
    struct aic_spienc_drvdata *drvdata = arg;
    drvdata->irq_sts = readl(drvdata->base + SPIE_REG_ISR);
    return IRQ_WAKE_THREAD;
}
            然后唤醒对应的处理线程进行处理:
        static irqreturn_t aic_spienc_irq_thread(int irq, void *arg)
{
    struct aic_spienc_drvdata *drvdata = arg;
    struct crypto_async_request *base;
    int err = 0;
    u32 val = 0;
    if (drvdata->irq_sts & SPIE_INTR_ENC_DEC_FIN_MSK) {
        if (drvdata->irq_sts & SPIE_INTR_ALL_EMP_MSK)
            err = AIC_SPIENC_ALL_FF;
        base = &drvdata->req->base;
        base->complete(base, err);
        /* Stop it */
        val = readl((drvdata->base + SPIE_REG_CTL));
        val &= ~SPIE_START_MSK;
        writel(val, (drvdata->base + SPIE_REG_CTL));
        /* Clear interrupts */
        drvdata->irq_sts = 0;
        writel(SPIE_INTR_ALL_MSK, (drvdata->base + SPIE_REG_ISR));
    }
    return IRQ_HANDLED;
}