Edit online

关键流程设计

31 Jan 2024
Read time: 2 minute(s)

初始化

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