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