in sahara.c [1360:1512]
static int sahara_probe(struct platform_device *pdev)
{
struct sahara_dev *dev;
u32 version;
int irq;
int err;
int i;
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->device = &pdev->dev;
platform_set_drvdata(pdev, dev);
/* Get the base address */
dev->regs_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dev->regs_base))
return PTR_ERR(dev->regs_base);
/* Get the IRQ */
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
err = devm_request_irq(&pdev->dev, irq, sahara_irq_handler,
0, dev_name(&pdev->dev), dev);
if (err) {
dev_err(&pdev->dev, "failed to request irq\n");
return err;
}
/* clocks */
dev->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
if (IS_ERR(dev->clk_ipg)) {
dev_err(&pdev->dev, "Could not get ipg clock\n");
return PTR_ERR(dev->clk_ipg);
}
dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
if (IS_ERR(dev->clk_ahb)) {
dev_err(&pdev->dev, "Could not get ahb clock\n");
return PTR_ERR(dev->clk_ahb);
}
/* Allocate HW descriptors */
dev->hw_desc[0] = dmam_alloc_coherent(&pdev->dev,
SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
&dev->hw_phys_desc[0], GFP_KERNEL);
if (!dev->hw_desc[0]) {
dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
return -ENOMEM;
}
dev->hw_desc[1] = dev->hw_desc[0] + 1;
dev->hw_phys_desc[1] = dev->hw_phys_desc[0] +
sizeof(struct sahara_hw_desc);
/* Allocate space for iv and key */
dev->key_base = dmam_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
&dev->key_phys_base, GFP_KERNEL);
if (!dev->key_base) {
dev_err(&pdev->dev, "Could not allocate memory for key\n");
return -ENOMEM;
}
dev->iv_base = dev->key_base + AES_KEYSIZE_128;
dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128;
/* Allocate space for context: largest digest + message length field */
dev->context_base = dmam_alloc_coherent(&pdev->dev,
SHA256_DIGEST_SIZE + 4,
&dev->context_phys_base, GFP_KERNEL);
if (!dev->context_base) {
dev_err(&pdev->dev, "Could not allocate memory for MDHA context\n");
return -ENOMEM;
}
/* Allocate space for HW links */
dev->hw_link[0] = dmam_alloc_coherent(&pdev->dev,
SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
&dev->hw_phys_link[0], GFP_KERNEL);
if (!dev->hw_link[0]) {
dev_err(&pdev->dev, "Could not allocate hw links\n");
return -ENOMEM;
}
for (i = 1; i < SAHARA_MAX_HW_LINK; i++) {
dev->hw_phys_link[i] = dev->hw_phys_link[i - 1] +
sizeof(struct sahara_hw_link);
dev->hw_link[i] = dev->hw_link[i - 1] + 1;
}
crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH);
mutex_init(&dev->queue_mutex);
dev_ptr = dev;
dev->kthread = kthread_run(sahara_queue_manage, dev, "sahara_crypto");
if (IS_ERR(dev->kthread)) {
return PTR_ERR(dev->kthread);
}
init_completion(&dev->dma_completion);
err = clk_prepare_enable(dev->clk_ipg);
if (err)
return err;
err = clk_prepare_enable(dev->clk_ahb);
if (err)
goto clk_ipg_disable;
version = sahara_read(dev, SAHARA_REG_VERSION);
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx27-sahara")) {
if (version != SAHARA_VERSION_3)
err = -ENODEV;
} else if (of_device_is_compatible(pdev->dev.of_node,
"fsl,imx53-sahara")) {
if (((version >> 8) & 0xff) != SAHARA_VERSION_4)
err = -ENODEV;
version = (version >> 8) & 0xff;
}
if (err == -ENODEV) {
dev_err(&pdev->dev, "SAHARA version %d not supported\n",
version);
goto err_algs;
}
dev->version = version;
sahara_write(dev, SAHARA_CMD_RESET | SAHARA_CMD_MODE_BATCH,
SAHARA_REG_CMD);
sahara_write(dev, SAHARA_CONTROL_SET_THROTTLE(0) |
SAHARA_CONTROL_SET_MAXBURST(8) |
SAHARA_CONTROL_RNG_AUTORSD |
SAHARA_CONTROL_ENABLE_INT,
SAHARA_REG_CONTROL);
err = sahara_register_algs(dev);
if (err)
goto err_algs;
dev_info(&pdev->dev, "SAHARA version %d initialized\n", version);
return 0;
err_algs:
kthread_stop(dev->kthread);
dev_ptr = NULL;
clk_disable_unprepare(dev->clk_ahb);
clk_ipg_disable:
clk_disable_unprepare(dev->clk_ipg);
return err;
}