tegra-se: Unregister algs support from tegra-se
Amith Ramachandra [Sat, 20 Sep 2014 21:45:12 +0000 (14:45 -0700)]
Owing to lower perf, prefer CPU over SE HW for crypto
operations. However, we may still need SE for save/restore
key context across Lp0 so keep the driver to do this.

Bug 200142359

Change-Id: I16ffaf64400e70615cdb0d4326f5480d172f6be6
Signed-off-by: Amith Ramachandra <aramachan@nvidia.com>
Signed-off-by: Gagan Grover <ggrover@nvidia.com>
Reviewed-on: http://git-master/r/501214
(cherry picked from commit 9bc76d18fe31233e6aad5ab9b142725b9d0a3875)
Reviewed-on: http://git-master/r/539875
Reviewed-by: Dhiren Parmar <dparmar@nvidia.com>
Tested-by: Dhiren Parmar <dparmar@nvidia.com>
Signed-off-by: Gaurav Singh <gauravsingh@nvidia.com>
Reviewed-on: http://git-master/r/822518

arch/arm/configs/tegra12_android_defconfig
drivers/crypto/Kconfig
drivers/crypto/tegra-se.c

index 849e24d..eec3a90 100644 (file)
@@ -640,3 +640,4 @@ CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_TWOFISH=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_DEV_TEGRA_SE=y
+CONFIG_CRYPTO_DEV_TEGRA_SE_NO_ALG_SUPPORT=y
index 1bc5467..e1d5192 100644 (file)
@@ -317,6 +317,12 @@ config CRYPTO_DEV_TEGRA_SE
          acceleration.
 
 trysource "../kernel-t18x/drivers/crypto/Kconfig"
+config CRYPTO_DEV_TEGRA_SE_NO_ALG_SUPPORT
+       bool "Do not register crypto algorithms"
+       depends on CRYPTO_DEV_TEGRA_SE
+       help
+         This option disables registration of crypto algorithms with the kernel.
+         The SE driver has other uses in save restoring context across Lp0.
 
 config CRYPTO_DEV_NX
        bool "Support for IBM Power7+ in-Nest cryptographic acceleration"
index 2fceaf1..9598224 100644 (file)
@@ -2632,38 +2632,6 @@ static struct ahash_alg hash_algs[] = {
        }
 };
 
-static bool is_algo_supported(struct tegra_se_dev *se_dev, const char *algo)
-{
-       if (!strcmp(algo, "ansi_cprng")) {
-               if (se_dev->chipdata->cprng_supported)
-                       return true;
-               else
-                       return false;
-       }
-
-       if (!strcmp(algo, "drbg")) {
-               if (se_dev->chipdata->drbg_supported)
-                       return true;
-               else
-                       return false;
-       }
-
-       if (!strcmp(algo, "rsa512") || !strcmp(algo, "rsa1024") ||
-               !strcmp(algo, "rsa1536") || !strcmp(algo, "rsa2048")) {
-               if (se_dev->chipdata->rsa_supported) {
-                       if ((tegra_get_chipid() == TEGRA_CHIPID_TEGRA21) &&
-                       (tegra_chip_get_revision() == TEGRA_REVISION_A01))
-                               return false;
-                       else
-                               return true;
-               } else {
-                       return false;
-               }
-       }
-
-       return true;
-}
-
 static struct tegra_se_chipdata tegra_se_chipdata = {
        .rsa_supported = false,
        .cprng_supported = true,
@@ -2728,12 +2696,106 @@ static struct of_device_id tegra_se_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_se_of_match);
 
+
+#if defined(CONFIG_CRYPTO_DEV_TEGRA_SE_NO_ALG_SUPPORT)
+static void tegra_se_unregister_algs(struct tegra_se_dev *se_dev,
+                                    int nalgs, int nhash)
+{
+}
+
+static int tegra_se_register_algs(struct tegra_se_dev *se_dev)
+{
+       return 0;
+}
+
+#else
+static bool is_algo_supported(struct tegra_se_dev *se_dev, const char *algo)
+{
+       if (!strcmp(algo, "ansi_cprng")) {
+               if (se_dev->chipdata->cprng_supported)
+                       return true;
+               else
+                       return false;
+       }
+
+       if (!strcmp(algo, "drbg")) {
+               if (se_dev->chipdata->drbg_supported)
+                       return true;
+               else
+                       return false;
+       }
+
+       if (!strcmp(algo, "rsa512") || !strcmp(algo, "rsa1024") ||
+               !strcmp(algo, "rsa1536") || !strcmp(algo, "rsa2048")) {
+               if (se_dev->chipdata->rsa_supported) {
+                       if ((tegra_get_chipid() == TEGRA_CHIPID_TEGRA21) &&
+                       (tegra_chip_get_revision() == TEGRA_REVISION_A01))
+                               return false;
+                       else
+                               return true;
+               } else {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+static void tegra_se_unregister_algs(struct tegra_se_dev *se_dev,
+                                           int nalgs, int nhash)
+{
+       int k;
+
+       for (k = 0; k < nalgs; k++)
+               crypto_unregister_alg(&aes_algs[k]);
+
+       for (k = 0; k < nhash; k++)
+               crypto_unregister_ahash(&hash_algs[k]);
+}
+
+
+static int tegra_se_register_algs(struct tegra_se_dev *se_dev)
+{
+       int err = 0, i = 0, j = 0;
+
+       for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
+               if (is_algo_supported(se_dev, aes_algs[i].cra_name)) {
+                       INIT_LIST_HEAD(&aes_algs[i].cra_list);
+                       err = crypto_register_alg(&aes_algs[i]);
+                       if (err) {
+                               dev_err(se_dev->dev,
+                               "crypto_register_alg failed index[%d]\n", i);
+                               goto err_exit;
+                       }
+               }
+       }
+
+       for (j = 0; j < ARRAY_SIZE(hash_algs); j++) {
+               if (is_algo_supported(se_dev, hash_algs[j].halg.base.cra_name)) {
+                       err = crypto_register_ahash(&hash_algs[j]);
+                       if (err) {
+                               dev_err(se_dev->dev,
+                               "crypto_register_sha alg failed index[%d]\n",
+                               i);
+                               goto err_exit;
+                       }
+               }
+       }
+
+       return 0;
+
+err_exit:
+       tegra_se_unregister_algs(se_dev, i, j);
+       return err;
+}
+#endif
+
 static int tegra_se_probe(struct platform_device *pdev)
 {
        struct tegra_se_dev *se_dev = NULL;
        struct resource *res = NULL;
        const struct of_device_id *match;
-       int err = 0, i = 0, j = 0, k = 0;
+       int err = 0;
 
 #ifdef CONFIG_ARCH_TEGRA_21x_SOC
        if (tegra_bonded_out_dev(BOND_OUT_SE))
@@ -2867,29 +2929,9 @@ static int tegra_se_probe(struct platform_device *pdev)
                goto clean;
        }
 
-       for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
-               if (is_algo_supported(se_dev, aes_algs[i].cra_name)) {
-                       INIT_LIST_HEAD(&aes_algs[i].cra_list);
-                       err = crypto_register_alg(&aes_algs[i]);
-                       if (err) {
-                               dev_err(se_dev->dev,
-                               "crypto_register_alg failed index[%d]\n", i);
-                               goto clean;
-                       }
-               }
-       }
-
-       for (j = 0; j < ARRAY_SIZE(hash_algs); j++) {
-               if (is_algo_supported(se_dev, hash_algs[j].halg.base.cra_name)) {
-                       err = crypto_register_ahash(&hash_algs[j]);
-                       if (err) {
-                               dev_err(se_dev->dev,
-                               "crypto_register_sha alg failed index[%d]\n",
-                               i);
-                               goto clean;
-                       }
-               }
-       }
+       err = tegra_se_register_algs(se_dev);
+       if (err)
+               goto clean;
 
        se_dev->sg_in_buf = dma_alloc_coherent(se_dev->dev,
                DISK_ENCR_BUF_SZ, &se_dev->sg_in_buf_adr,
@@ -2951,11 +2993,6 @@ irq_fail:
        kfree(prev_cfg);
 free_res:
        pm_runtime_disable(se_dev->dev);
-       for (k = 0; k < i; k++)
-               crypto_unregister_alg(&aes_algs[k]);
-
-       for (k = 0; k < j; k++)
-               crypto_unregister_ahash(&hash_algs[j]);
 
        tegra_se_free_ll_buf(se_dev);
 
@@ -2984,7 +3021,6 @@ fail:
 static int tegra_se_remove(struct platform_device *pdev)
 {
        struct tegra_se_dev *se_dev = platform_get_drvdata(pdev);
-       int i;
 
        if (!se_dev)
                return -ENODEV;
@@ -2995,11 +3031,9 @@ static int tegra_se_remove(struct platform_device *pdev)
        if (se_work_q)
                destroy_workqueue(se_work_q);
        free_irq(se_dev->irq, &pdev->dev);
-       for (i = 0; i < ARRAY_SIZE(aes_algs); i++)
-               crypto_unregister_alg(&aes_algs[i]);
-       for (i = 0; i < ARRAY_SIZE(hash_algs); i++)
-               crypto_unregister_ahash(&hash_algs[i]);
 
+       tegra_se_unregister_algs(se_dev, ARRAY_SIZE(aes_algs),
+                                ARRAY_SIZE(hash_algs));
        if (se_dev->enclk)
                clk_put(se_dev->enclk);