关键流程设计
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;
}