]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/crypto/mv_cesa.c
ARM: Orion: fix driver probe error handling with respect to clk
[karo-tx-linux.git] / drivers / crypto / mv_cesa.c
index e6ecc5f2394387efcdfa3b112edd83ac88591509..a4faa893199c822dc4d69bc5001b5432314b4509 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/clk.h>
 #include <crypto/internal/hash.h>
 #include <crypto/sha.h>
 
@@ -79,6 +80,7 @@ struct crypto_priv {
        void __iomem *reg;
        void __iomem *sram;
        int irq;
+       struct clk *clk;
        struct task_struct *queue_th;
 
        /* the lock protects queue and eng_st */
@@ -1053,6 +1055,12 @@ static int mv_probe(struct platform_device *pdev)
        if (ret)
                goto err_thread;
 
+       /* Not all platforms can gate the clock, so it is not
+          an error if the clock does not exists. */
+       cp->clk = clk_get(&pdev->dev, NULL);
+       if (!IS_ERR(cp->clk))
+               clk_prepare_enable(cp->clk);
+
        writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK);
        writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG);
        writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0);
@@ -1090,6 +1098,10 @@ err_unreg_ecb:
        crypto_unregister_alg(&mv_aes_alg_ecb);
 err_irq:
        free_irq(irq, cp);
+       if (!IS_ERR(cp->clk)) {
+               clk_disable_unprepare(cp->clk);
+               clk_put(cp->clk);
+       }
 err_thread:
        kthread_stop(cp->queue_th);
 err_unmap_sram:
@@ -1118,6 +1130,12 @@ static int mv_remove(struct platform_device *pdev)
        memset(cp->sram, 0, cp->sram_size);
        iounmap(cp->sram);
        iounmap(cp->reg);
+
+       if (!IS_ERR(cp->clk)) {
+               clk_disable_unprepare(cp->clk);
+               clk_put(cp->clk);
+       }
+
        kfree(cp);
        cpg = NULL;
        return 0;