]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Nov 2013 00:18:25 +0000 (16:18 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Nov 2013 00:18:25 +0000 (16:18 -0800)
Pull crypto update from Herbert Xu:
 - Made x86 ablk_helper generic for ARM
 - Phase out chainiv in favour of eseqiv (affects IPsec)
 - Fixed aes-cbc IV corruption on s390
 - Added constant-time crypto_memneq which replaces memcmp
 - Fixed aes-ctr in omap-aes
 - Added OMAP3 ROM RNG support
 - Add PRNG support for MSM SoC's
 - Add and use Job Ring API in caam
 - Misc fixes

[ NOTE! This pull request was sent within the merge window, but Herbert
  has some questionable email sending setup that makes him public enemy
  #1 as far as gmail is concerned.  So most of his emails seem to be
  trapped by gmail as spam, resulting in me not seeing them.  - Linus ]

* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (49 commits)
  crypto: s390 - Fix aes-cbc IV corruption
  crypto: omap-aes - Fix CTR mode counter length
  crypto: omap-sham - Add missing modalias
  padata: make the sequence counter an atomic_t
  crypto: caam - Modify the interface layers to use JR API's
  crypto: caam - Add API's to allocate/free Job Rings
  crypto: caam - Add Platform driver for Job Ring
  hwrng: msm - Add PRNG support for MSM SoC's
  ARM: DT: msm: Add Qualcomm's PRNG driver binding document
  crypto: skcipher - Use eseqiv even on UP machines
  crypto: talitos - Simplify key parsing
  crypto: picoxcell - Simplify and harden key parsing
  crypto: ixp4xx - Simplify and harden key parsing
  crypto: authencesn - Simplify key parsing
  crypto: authenc - Export key parsing helper function
  crypto: mv_cesa: remove deprecated IRQF_DISABLED
  hwrng: OMAP3 ROM Random Number Generator support
  crypto: sha256_ssse3 - also test for BMI2
  crypto: mv_cesa - Remove redundant of_match_ptr
  crypto: sahara - Remove redundant of_match_ptr
  ...

13 files changed:
1  2 
arch/arm/mach-tegra/fuse.c
arch/s390/crypto/aes_s390.c
crypto/Kconfig
crypto/Makefile
crypto/asymmetric_keys/rsa.c
drivers/char/hw_random/Kconfig
drivers/char/hw_random/Makefile
drivers/crypto/caam/ctrl.c
drivers/crypto/caam/jr.c
drivers/crypto/ixp4xx_crypto.c
drivers/crypto/omap-sham.c
drivers/crypto/talitos.c
drivers/crypto/tegra-aes.c

index d4639c5066222ea785f3dab068f46874fd52513c,64652b37488627e1a3feea9d7b3224dd7773c7a3..9a4e910c3796154c8fa6c167851a8f6b112265f3
  #include <linux/kernel.h>
  #include <linux/io.h>
  #include <linux/export.h>
 +#include <linux/random.h>
  #include <linux/tegra-soc.h>
  
  #include "fuse.h"
  #include "iomap.h"
  #include "apbio.h"
  
 +/* Tegra20 only */
  #define FUSE_UID_LOW          0x108
  #define FUSE_UID_HIGH         0x10c
 +
 +/* Tegra30 and later */
 +#define FUSE_VENDOR_CODE      0x200
 +#define FUSE_FAB_CODE         0x204
 +#define FUSE_LOT_CODE_0               0x208
 +#define FUSE_LOT_CODE_1               0x20c
 +#define FUSE_WAFER_ID         0x210
 +#define FUSE_X_COORDINATE     0x214
 +#define FUSE_Y_COORDINATE     0x218
 +
  #define FUSE_SKU_INFO         0x110
  
  #define TEGRA20_FUSE_SPARE_BIT                0x200
@@@ -124,51 -112,21 +124,51 @@@ u32 tegra_read_chipid(void
        return readl_relaxed(IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804);
  }
  
 -void tegra_init_fuse(void)
 +static void __init tegra20_fuse_init_randomness(void)
 +{
 +      u32 randomness[2];
 +
 +      randomness[0] = tegra_fuse_readl(FUSE_UID_LOW);
 +      randomness[1] = tegra_fuse_readl(FUSE_UID_HIGH);
 +
 +      add_device_randomness(randomness, sizeof(randomness));
 +}
 +
 +/* Applies to Tegra30 or later */
 +static void __init tegra30_fuse_init_randomness(void)
 +{
 +      u32 randomness[7];
 +
 +      randomness[0] = tegra_fuse_readl(FUSE_VENDOR_CODE);
 +      randomness[1] = tegra_fuse_readl(FUSE_FAB_CODE);
 +      randomness[2] = tegra_fuse_readl(FUSE_LOT_CODE_0);
 +      randomness[3] = tegra_fuse_readl(FUSE_LOT_CODE_1);
 +      randomness[4] = tegra_fuse_readl(FUSE_WAFER_ID);
 +      randomness[5] = tegra_fuse_readl(FUSE_X_COORDINATE);
 +      randomness[6] = tegra_fuse_readl(FUSE_Y_COORDINATE);
 +
 +      add_device_randomness(randomness, sizeof(randomness));
 +}
 +
 +void __init tegra_init_fuse(void)
  {
        u32 id;
 +      u32 randomness[5];
  
        u32 reg = readl(IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
        reg |= 1 << 28;
        writel(reg, IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x48));
  
        reg = tegra_fuse_readl(FUSE_SKU_INFO);
 +      randomness[0] = reg;
        tegra_sku_id = reg & 0xFF;
  
        reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
 +      randomness[1] = reg;
        tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
  
        id = tegra_read_chipid();
 +      randomness[2] = id;
        tegra_chip_id = (id >> 8) & 0xff;
  
        switch (tegra_chip_id) {
  
        tegra_revision = tegra_get_revision(id);
        tegra_init_speedo_data();
 +      randomness[3] = (tegra_cpu_process_id << 16) | tegra_core_process_id;
 +      randomness[4] = (tegra_cpu_speedo_id << 16) | tegra_soc_speedo_id;
 +
 +      add_device_randomness(randomness, sizeof(randomness));
 +      switch (tegra_chip_id) {
 +      case TEGRA20:
 +              tegra20_fuse_init_randomness();
 +      case TEGRA30:
 +      case TEGRA114:
 +      default:
 +              tegra30_fuse_init_randomness();
 +      }
  
        pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
                tegra_revision_name[tegra_revision],
                tegra_sku_id, tegra_cpu_process_id,
                tegra_core_process_id);
  }
- unsigned long long tegra_chip_uid(void)
- {
-       unsigned long long lo, hi;
-       lo = tegra_fuse_readl(FUSE_UID_LOW);
-       hi = tegra_fuse_readl(FUSE_UID_HIGH);
-       return (hi << 32ull) | lo;
- }
- EXPORT_SYMBOL(tegra_chip_uid);
index 46cae138ece2efa3617447d1fccf82fa504d4e7d,2e4b5be31a1bbc2c0dc9b0b3bcb6df91b19d497f..4363528dc8fd013492b2165f6978b5e5226657b1
@@@ -35,7 -35,6 +35,6 @@@ static u8 *ctrblk
  static char keylen_flag;
  
  struct s390_aes_ctx {
-       u8 iv[AES_BLOCK_SIZE];
        u8 key[AES_MAX_KEY_SIZE];
        long enc;
        long dec;
@@@ -441,30 -440,36 +440,36 @@@ static int cbc_aes_set_key(struct crypt
        return aes_set_key(tfm, in_key, key_len);
  }
  
- static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
+ static int cbc_aes_crypt(struct blkcipher_desc *desc, long func,
                         struct blkcipher_walk *walk)
  {
+       struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
        int ret = blkcipher_walk_virt(desc, walk);
        unsigned int nbytes = walk->nbytes;
+       struct {
+               u8 iv[AES_BLOCK_SIZE];
+               u8 key[AES_MAX_KEY_SIZE];
+       } param;
  
        if (!nbytes)
                goto out;
  
-       memcpy(param, walk->iv, AES_BLOCK_SIZE);
+       memcpy(param.iv, walk->iv, AES_BLOCK_SIZE);
+       memcpy(param.key, sctx->key, sctx->key_len);
        do {
                /* only use complete blocks */
                unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
                u8 *out = walk->dst.virt.addr;
                u8 *in = walk->src.virt.addr;
  
-               ret = crypt_s390_kmc(func, param, out, in, n);
+               ret = crypt_s390_kmc(func, &param, out, in, n);
                if (ret < 0 || ret != n)
                        return -EIO;
  
                nbytes &= AES_BLOCK_SIZE - 1;
                ret = blkcipher_walk_done(desc, walk, nbytes);
        } while ((nbytes = walk->nbytes));
-       memcpy(walk->iv, param, AES_BLOCK_SIZE);
+       memcpy(walk->iv, param.iv, AES_BLOCK_SIZE);
  
  out:
        return ret;
@@@ -481,7 -486,7 +486,7 @@@ static int cbc_aes_encrypt(struct blkci
                return fallback_blk_enc(desc, dst, src, nbytes);
  
        blkcipher_walk_init(&walk, dst, src, nbytes);
-       return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
+       return cbc_aes_crypt(desc, sctx->enc, &walk);
  }
  
  static int cbc_aes_decrypt(struct blkcipher_desc *desc,
                return fallback_blk_dec(desc, dst, src, nbytes);
  
        blkcipher_walk_init(&walk, dst, src, nbytes);
-       return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
+       return cbc_aes_crypt(desc, sctx->dec, &walk);
  }
  
  static struct crypto_alg cbc_aes_alg = {
@@@ -725,8 -730,6 +730,8 @@@ static struct crypto_alg xts_aes_alg = 
        }
  };
  
 +static int xts_aes_alg_reg;
 +
  static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
                           unsigned int key_len)
  {
@@@ -848,8 -851,6 +853,8 @@@ static struct crypto_alg ctr_aes_alg = 
        }
  };
  
 +static int ctr_aes_alg_reg;
 +
  static int __init aes_s390_init(void)
  {
        int ret;
                ret = crypto_register_alg(&xts_aes_alg);
                if (ret)
                        goto xts_aes_err;
 +              xts_aes_alg_reg = 1;
        }
  
        if (crypt_s390_func_available(KMCTR_AES_128_ENCRYPT,
                        free_page((unsigned long) ctrblk);
                        goto ctr_aes_err;
                }
 +              ctr_aes_alg_reg = 1;
        }
  
  out:
@@@ -927,12 -926,9 +932,12 @@@ aes_err
  
  static void __exit aes_s390_fini(void)
  {
 -      crypto_unregister_alg(&ctr_aes_alg);
 -      free_page((unsigned long) ctrblk);
 -      crypto_unregister_alg(&xts_aes_alg);
 +      if (ctr_aes_alg_reg) {
 +              crypto_unregister_alg(&ctr_aes_alg);
 +              free_page((unsigned long) ctrblk);
 +      }
 +      if (xts_aes_alg_reg)
 +              crypto_unregister_alg(&xts_aes_alg);
        crypto_unregister_alg(&cbc_aes_alg);
        crypto_unregister_alg(&ecb_aes_alg);
        crypto_unregister_alg(&aes_alg);
diff --combined crypto/Kconfig
index 4ae5734fb4733bb8e264565867fa6d73d7b11f6b,7c0a4c5de07599c9c2666b1a70e22e3d4bdcce17..7bcb70d216e14b1b811e8924bb15cbf01f5acf80
@@@ -174,9 -174,8 +174,8 @@@ config CRYPTO_TES
        help
          Quick & dirty crypto test module.
  
- config CRYPTO_ABLK_HELPER_X86
+ config CRYPTO_ABLK_HELPER
        tristate
-       depends on X86
        select CRYPTO_CRYPTD
  
  config CRYPTO_GLUE_HELPER_X86
@@@ -695,7 -694,7 +694,7 @@@ config CRYPTO_AES_NI_INTE
        select CRYPTO_AES_X86_64 if 64BIT
        select CRYPTO_AES_586 if !64BIT
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_ALGAPI
        select CRYPTO_GLUE_HELPER_X86 if 64BIT
        select CRYPTO_LRW
@@@ -776,22 -775,6 +775,22 @@@ config CRYPTO_AES_AR
  
          See <http://csrc.nist.gov/encryption/aes/> for more information.
  
 +config CRYPTO_AES_ARM_BS
 +      tristate "Bit sliced AES using NEON instructions"
 +      depends on ARM && KERNEL_MODE_NEON
 +      select CRYPTO_ALGAPI
 +      select CRYPTO_AES_ARM
 +      select CRYPTO_ABLK_HELPER
 +      help
 +        Use a faster and more secure NEON based implementation of AES in CBC,
 +        CTR and XTS modes
 +
 +        Bit sliced AES gives around 45% speedup on Cortex-A15 for CTR mode
 +        and for XTS mode encryption, CBC and XTS mode decryption speedup is
 +        around 25%. (CBC encryption speed is not affected by this driver.)
 +        This implementation does not rely on any lookup tables so it is
 +        believed to be invulnerable to cache timing attacks.
 +
  config CRYPTO_ANUBIS
        tristate "Anubis cipher algorithm"
        select CRYPTO_ALGAPI
@@@ -895,7 -878,7 +894,7 @@@ config CRYPTO_CAMELLIA_AESNI_AVX_X86_6
        depends on CRYPTO
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_CAMELLIA_X86_64
        select CRYPTO_LRW
@@@ -917,7 -900,7 +916,7 @@@ config CRYPTO_CAMELLIA_AESNI_AVX2_X86_6
        depends on CRYPTO
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_CAMELLIA_X86_64
        select CRYPTO_CAMELLIA_AESNI_AVX_X86_64
@@@ -969,7 -952,7 +968,7 @@@ config CRYPTO_CAST5_AVX_X86_6
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_CAST_COMMON
        select CRYPTO_CAST5
        help
@@@ -992,7 -975,7 +991,7 @@@ config CRYPTO_CAST6_AVX_X86_6
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_CAST_COMMON
        select CRYPTO_CAST6
@@@ -1110,7 -1093,7 +1109,7 @@@ config CRYPTO_SERPENT_SSE2_X86_6
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_LRW
@@@ -1132,7 -1115,7 +1131,7 @@@ config CRYPTO_SERPENT_SSE2_58
        depends on X86 && !64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_LRW
@@@ -1154,7 -1137,7 +1153,7 @@@ config CRYPTO_SERPENT_AVX_X86_6
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_LRW
@@@ -1176,7 -1159,7 +1175,7 @@@ config CRYPTO_SERPENT_AVX2_X86_6
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_SERPENT
        select CRYPTO_SERPENT_AVX_X86_64
@@@ -1292,7 -1275,7 +1291,7 @@@ config CRYPTO_TWOFISH_AVX_X86_6
        depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_CRYPTD
-       select CRYPTO_ABLK_HELPER_X86
+       select CRYPTO_ABLK_HELPER
        select CRYPTO_GLUE_HELPER_X86
        select CRYPTO_TWOFISH_COMMON
        select CRYPTO_TWOFISH_X86_64
@@@ -1402,9 -1385,6 +1401,9 @@@ config CRYPTO_USER_API_SKCIPHE
          This option enables the user-spaces interface for symmetric
          key cipher algorithms.
  
 +config CRYPTO_HASH_INFO
 +      bool
 +
  source "drivers/crypto/Kconfig"
  source crypto/asymmetric_keys/Kconfig
  
diff --combined crypto/Makefile
index b3a7e807e08bca306619a3e7250afbc9160fecbe,d6a401c58d17699e77f198a447aa67fd75e71cc4..989c510da8cc98af911976874d6c16db865ee1b3
@@@ -2,8 -2,13 +2,13 @@@
  # Cryptographic API
  #
  
+ # memneq MUST be built with -Os or -O0 to prevent early-return optimizations
+ # that will defeat memneq's actual purpose to prevent timing attacks.
+ CFLAGS_REMOVE_memneq.o := -O1 -O2 -O3
+ CFLAGS_memneq.o := -Os
  obj-$(CONFIG_CRYPTO) += crypto.o
- crypto-y := api.o cipher.o compress.o
+ crypto-y := api.o cipher.o compress.o memneq.o
  
  obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
  
@@@ -83,7 -88,7 +88,7 @@@ obj-$(CONFIG_CRYPTO_ZLIB) += zlib.
  obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
  obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
  obj-$(CONFIG_CRYPTO_CRC32) += crc32.o
 -obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif.o
 +obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
  obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
  obj-$(CONFIG_CRYPTO_LZO) += lzo.o
  obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
@@@ -104,4 -109,4 +109,5 @@@ obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) 
  obj-$(CONFIG_XOR_BLOCKS) += xor.o
  obj-$(CONFIG_ASYNC_CORE) += async_tx/
  obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
 +obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
+ obj-$(CONFIG_CRYPTO_ABLK_HELPER) += ablk_helper.o
index 90a17f59ba2800d197366dbcb0835a9adc598320,1912b9be504356e5880eeb764216f2beff53e296..459cf97a75e2e223798e2cd157a60bf048f01117
@@@ -13,6 -13,7 +13,7 @@@
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/slab.h>
+ #include <crypto/algapi.h>
  #include "public_key.h"
  
  MODULE_LICENSE("GPL");
@@@ -73,13 -74,13 +74,13 @@@ static const struct 
        size_t size;
  } RSA_ASN1_templates[PKEY_HASH__LAST] = {
  #define _(X) { RSA_digest_info_##X, sizeof(RSA_digest_info_##X) }
 -      [PKEY_HASH_MD5]         = _(MD5),
 -      [PKEY_HASH_SHA1]        = _(SHA1),
 -      [PKEY_HASH_RIPE_MD_160] = _(RIPE_MD_160),
 -      [PKEY_HASH_SHA256]      = _(SHA256),
 -      [PKEY_HASH_SHA384]      = _(SHA384),
 -      [PKEY_HASH_SHA512]      = _(SHA512),
 -      [PKEY_HASH_SHA224]      = _(SHA224),
 +      [HASH_ALGO_MD5]         = _(MD5),
 +      [HASH_ALGO_SHA1]        = _(SHA1),
 +      [HASH_ALGO_RIPE_MD_160] = _(RIPE_MD_160),
 +      [HASH_ALGO_SHA256]      = _(SHA256),
 +      [HASH_ALGO_SHA384]      = _(SHA384),
 +      [HASH_ALGO_SHA512]      = _(SHA512),
 +      [HASH_ALGO_SHA224]      = _(SHA224),
  #undef _
  };
  
@@@ -189,12 -190,12 +190,12 @@@ static int RSA_verify(const u8 *H, cons
                }
        }
  
-       if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) {
+       if (crypto_memneq(asn1_template, EM + T_offset, asn1_size) != 0) {
                kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]");
                return -EBADMSG;
        }
  
-       if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) {
+       if (crypto_memneq(H, EM + T_offset + asn1_size, hash_size) != 0) {
                kleave(" = -EKEYREJECTED [EM[T] hash mismatch]");
                return -EKEYREJECTED;
        }
index c206de2951f20f086c099ab69e8a1a48286465be,989ca028d7818e96f91b1082265e3d7e01e7e6db..2f2b08457c673547568187f04863a01947163385
@@@ -165,6 -165,19 +165,19 @@@ config HW_RANDOM_OMA
  
          If unsure, say Y.
  
+ config HW_RANDOM_OMAP3_ROM
+       tristate "OMAP3 ROM Random Number Generator support"
+       depends on HW_RANDOM && ARCH_OMAP3
+       default HW_RANDOM
+       ---help---
+         This driver provides kernel-side support for the Random Number
+         Generator hardware found on OMAP34xx processors.
+         To compile this driver as a module, choose M here: the
+         module will be called omap3-rom-rng.
+         If unsure, say Y.
  config HW_RANDOM_OCTEON
        tristate "Octeon Random Number Generator support"
        depends on HW_RANDOM && CAVIUM_OCTEON_SOC
@@@ -290,19 -303,6 +303,19 @@@ config HW_RANDOM_PSERIE
  
          If unsure, say Y.
  
 +config HW_RANDOM_POWERNV
 +      tristate "PowerNV Random Number Generator support"
 +      depends on HW_RANDOM && PPC_POWERNV
 +      default HW_RANDOM
 +      ---help---
 +        This is the driver for Random Number Generator hardware found
 +        in POWER7+ and above machines for PowerNV platform.
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called powernv-rng.
 +
 +        If unsure, say Y.
 +
  config HW_RANDOM_EXYNOS
        tristate "EXYNOS HW random number generator support"
        depends on HW_RANDOM && HAS_IOMEM && HAVE_CLK
@@@ -327,3 -327,15 +340,15 @@@ config HW_RANDOM_TP
          module will be called tpm-rng.
  
          If unsure, say Y.
+ config HW_RANDOM_MSM
+       tristate "Qualcomm MSM Random Number Generator support"
+       depends on HW_RANDOM && ARCH_MSM
+       ---help---
+         This driver provides kernel-side support for the Random Number
+         Generator hardware found on Qualcomm MSM SoCs.
+         To compile this driver as a module, choose M here. the
+         module will be called msm-rng.
+         If unsure, say Y.
index d7d2435ff7fa8d38cd129d327c59ded717e3682a,32d8e7330b2306427cf4dde1778577de80c90c53..3ae7755a52e706bd8356e8ae5bc660fe8a693767
@@@ -15,6 -15,7 +15,7 @@@ n2-rng-y := n2-drv.o n2-asm.
  obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
  obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
  obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
+ obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o
  obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
  obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
  obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
@@@ -24,7 -25,7 +25,8 @@@ obj-$(CONFIG_HW_RANDOM_NOMADIK) += noma
  obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
  obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
  obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
 +obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
  obj-$(CONFIG_HW_RANDOM_EXYNOS)        += exynos-rng.o
  obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
  obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
+ obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
index bc6d820812b6a73e83c6596caa48ae7d475c315a,52cd6c1b71fc5b7028aad1f99df0532ce1730d14..63fb1af2c43187fe398663869b5877fa16bf8834
@@@ -5,9 -5,6 +5,9 @@@
   * Copyright 2008-2012 Freescale Semiconductor, Inc.
   */
  
 +#include <linux/of_address.h>
 +#include <linux/of_irq.h>
 +
  #include "compat.h"
  #include "regs.h"
  #include "intern.h"
  #include "error.h"
  #include "ctrl.h"
  
- static int caam_remove(struct platform_device *pdev)
- {
-       struct device *ctrldev;
-       struct caam_drv_private *ctrlpriv;
-       struct caam_drv_private_jr *jrpriv;
-       struct caam_full __iomem *topregs;
-       int ring, ret = 0;
-       ctrldev = &pdev->dev;
-       ctrlpriv = dev_get_drvdata(ctrldev);
-       topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
-       /* shut down JobRs */
-       for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
-               ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
-               jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
-               irq_dispose_mapping(jrpriv->irq);
-       }
-       /* Shut down debug views */
- #ifdef CONFIG_DEBUG_FS
-       debugfs_remove_recursive(ctrlpriv->dfs_root);
- #endif
-       /* Unmap controller region */
-       iounmap(&topregs->ctrl);
-       kfree(ctrlpriv->jrdev);
-       kfree(ctrlpriv);
-       return ret;
- }
  /*
   * Descriptor to instantiate RNG State Handle 0 in normal mode and
   * load the JDKEK, TDKEK and TDSK registers
   */
- static void build_instantiation_desc(u32 *desc)
+ static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
  {
-       u32 *jump_cmd;
+       u32 *jump_cmd, op_flags;
  
        init_job_desc(desc, 0);
  
+       op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+                       (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
        /* INIT RNG in non-test mode */
-       append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
-                        OP_ALG_AS_INIT);
+       append_operation(desc, op_flags);
+       if (!handle && do_sk) {
+               /*
+                * For SH0, Secure Keys must be generated as well
+                */
+               /* wait for done */
+               jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
+               set_jump_tgt_here(desc, jump_cmd);
+               /*
+                * load 1 to clear written reg:
+                * resets the done interrrupt and returns the RNG to idle.
+                */
+               append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+               /* Initialize State Handle  */
+               append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+                                OP_ALG_AAI_RNG4_SK);
+       }
  
-       /* wait for done */
-       jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
-       set_jump_tgt_here(desc, jump_cmd);
+       append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
+ }
  
-       /*
-        * load 1 to clear written reg:
-        * resets the done interrupt and returns the RNG to idle.
-        */
-       append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+ /* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
+ static void build_deinstantiation_desc(u32 *desc, int handle)
+ {
+       init_job_desc(desc, 0);
  
-       /* generate secure keys (non-test) */
+       /* Uninstantiate State Handle 0 */
        append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
-                        OP_ALG_RNG4_SK);
+                        (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);
+       append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
  }
  
- static int instantiate_rng(struct device *ctrldev)
+ /*
+  * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
+  *                      the software (no JR/QI used).
+  * @ctrldev - pointer to device
+  * @status - descriptor status, after being run
+  *
+  * Return: - 0 if no error occurred
+  *       - -ENODEV if the DECO couldn't be acquired
+  *       - -EAGAIN if an error occurred while executing the descriptor
+  */
+ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
+                                       u32 *status)
  {
        struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
        struct caam_full __iomem *topregs;
        unsigned int timeout = 100000;
-       u32 *desc;
-       int i, ret = 0;
-       desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA);
-       if (!desc) {
-               dev_err(ctrldev, "can't allocate RNG init descriptor memory\n");
-               return -ENOMEM;
-       }
-       build_instantiation_desc(desc);
+       u32 deco_dbg_reg, flags;
+       int i;
  
        /* Set the bit to request direct access to DECO0 */
        topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
  
        if (!timeout) {
                dev_err(ctrldev, "failed to acquire DECO 0\n");
-               ret = -EIO;
-               goto out;
+               clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
+               return -ENODEV;
        }
  
        for (i = 0; i < desc_len(desc); i++)
-               topregs->deco.descbuf[i] = *(desc + i);
+               wr_reg32(&topregs->deco.descbuf[i], *(desc + i));
  
-       wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR);
+       flags = DECO_JQCR_WHL;
+       /*
+        * If the descriptor length is longer than 4 words, then the
+        * FOUR bit in JRCTRL register must be set.
+        */
+       if (desc_len(desc) >= 4)
+               flags |= DECO_JQCR_FOUR;
+       /* Instruct the DECO to execute it */
+       wr_reg32(&topregs->deco.jr_ctl_hi, flags);
  
        timeout = 10000000;
-       while ((rd_reg32(&topregs->deco.desc_dbg) & DECO_DBG_VALID) &&
-                                                                --timeout)
+       do {
+               deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg);
+               /*
+                * If an error occured in the descriptor, then
+                * the DECO status field will be set to 0x0D
+                */
+               if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
+                   DESC_DBG_DECO_STAT_HOST_ERR)
+                       break;
                cpu_relax();
+       } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
  
-       if (!timeout) {
-               dev_err(ctrldev, "failed to instantiate RNG\n");
-               ret = -EIO;
-       }
+       *status = rd_reg32(&topregs->deco.op_status_hi) &
+                 DECO_OP_STATUS_HI_ERR_MASK;
  
+       /* Mark the DECO as free */
        clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
- out:
+       if (!timeout)
+               return -EAGAIN;
+       return 0;
+ }
+ /*
+  * instantiate_rng - builds and executes a descriptor on DECO0,
+  *                 which initializes the RNG block.
+  * @ctrldev - pointer to device
+  * @state_handle_mask - bitmask containing the instantiation status
+  *                    for the RNG4 state handles which exist in
+  *                    the RNG4 block: 1 if it's been instantiated
+  *                    by an external entry, 0 otherwise.
+  * @gen_sk  - generate data to be loaded into the JDKEK, TDKEK and TDSK;
+  *          Caution: this can be done only once; if the keys need to be
+  *          regenerated, a POR is required
+  *
+  * Return: - 0 if no error occurred
+  *       - -ENOMEM if there isn't enough memory to allocate the descriptor
+  *       - -ENODEV if DECO0 couldn't be acquired
+  *       - -EAGAIN if an error occurred when executing the descriptor
+  *          f.i. there was a RNG hardware error due to not "good enough"
+  *          entropy being aquired.
+  */
+ static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
+                          int gen_sk)
+ {
+       struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+       struct caam_full __iomem *topregs;
+       struct rng4tst __iomem *r4tst;
+       u32 *desc, status, rdsta_val;
+       int ret = 0, sh_idx;
+       topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+       r4tst = &topregs->ctrl.r4tst[0];
+       desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
+       if (!desc)
+               return -ENOMEM;
+       for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+               /*
+                * If the corresponding bit is set, this state handle
+                * was initialized by somebody else, so it's left alone.
+                */
+               if ((1 << sh_idx) & state_handle_mask)
+                       continue;
+               /* Create the descriptor for instantiating RNG State Handle */
+               build_instantiation_desc(desc, sh_idx, gen_sk);
+               /* Try to run it through DECO0 */
+               ret = run_descriptor_deco0(ctrldev, desc, &status);
+               /*
+                * If ret is not 0, or descriptor status is not 0, then
+                * something went wrong. No need to try the next state
+                * handle (if available), bail out here.
+                * Also, if for some reason, the State Handle didn't get
+                * instantiated although the descriptor has finished
+                * without any error (HW optimizations for later
+                * CAAM eras), then try again.
+                */
+               rdsta_val =
+                       rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IFMASK;
+               if (status || !(rdsta_val & (1 << sh_idx)))
+                       ret = -EAGAIN;
+               if (ret)
+                       break;
+               dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
+               /* Clear the contents before recreating the descriptor */
+               memset(desc, 0x00, CAAM_CMD_SZ * 7);
+       }
        kfree(desc);
        return ret;
  }
  
  /*
-  * By default, the TRNG runs for 200 clocks per sample;
-  * 1600 clocks per sample generates better entropy.
+  * deinstantiate_rng - builds and executes a descriptor on DECO0,
+  *                   which deinitializes the RNG block.
+  * @ctrldev - pointer to device
+  * @state_handle_mask - bitmask containing the instantiation status
+  *                    for the RNG4 state handles which exist in
+  *                    the RNG4 block: 1 if it's been instantiated
+  *
+  * Return: - 0 if no error occurred
+  *       - -ENOMEM if there isn't enough memory to allocate the descriptor
+  *       - -ENODEV if DECO0 couldn't be acquired
+  *       - -EAGAIN if an error occurred when executing the descriptor
   */
- static void kick_trng(struct platform_device *pdev)
+ static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask)
+ {
+       u32 *desc, status;
+       int sh_idx, ret = 0;
+       desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
+       if (!desc)
+               return -ENOMEM;
+       for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+               /*
+                * If the corresponding bit is set, then it means the state
+                * handle was initialized by us, and thus it needs to be
+                * deintialized as well
+                */
+               if ((1 << sh_idx) & state_handle_mask) {
+                       /*
+                        * Create the descriptor for deinstantating this state
+                        * handle
+                        */
+                       build_deinstantiation_desc(desc, sh_idx);
+                       /* Try to run it through DECO0 */
+                       ret = run_descriptor_deco0(ctrldev, desc, &status);
+                       if (ret || status) {
+                               dev_err(ctrldev,
+                                       "Failed to deinstantiate RNG4 SH%d\n",
+                                       sh_idx);
+                               break;
+                       }
+                       dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx);
+               }
+       }
+       kfree(desc);
+       return ret;
+ }
+ static int caam_remove(struct platform_device *pdev)
+ {
+       struct device *ctrldev;
+       struct caam_drv_private *ctrlpriv;
+       struct caam_full __iomem *topregs;
+       int ring, ret = 0;
+       ctrldev = &pdev->dev;
+       ctrlpriv = dev_get_drvdata(ctrldev);
+       topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+       /* Remove platform devices for JobRs */
+       for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
+               if (ctrlpriv->jrpdev[ring])
+                       of_device_unregister(ctrlpriv->jrpdev[ring]);
+       }
+       /* De-initialize RNG state handles initialized by this driver. */
+       if (ctrlpriv->rng4_sh_init)
+               deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
+       /* Shut down debug views */
+ #ifdef CONFIG_DEBUG_FS
+       debugfs_remove_recursive(ctrlpriv->dfs_root);
+ #endif
+       /* Unmap controller region */
+       iounmap(&topregs->ctrl);
+       kfree(ctrlpriv->jrpdev);
+       kfree(ctrlpriv);
+       return ret;
+ }
+ /*
+  * kick_trng - sets the various parameters for enabling the initialization
+  *           of the RNG4 block in CAAM
+  * @pdev - pointer to the platform device
+  * @ent_delay - Defines the length (in system clocks) of each entropy sample.
+  */
+ static void kick_trng(struct platform_device *pdev, int ent_delay)
  {
        struct device *ctrldev = &pdev->dev;
        struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
  
        /* put RNG4 into program mode */
        setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
-       /* 1600 clocks per sample */
+       /*
+        * Performance-wise, it does not make sense to
+        * set the delay to a value that is lower
+        * than the last one that worked (i.e. the state handles
+        * were instantiated properly. Thus, instead of wasting
+        * time trying to set the values controlling the sample
+        * frequency, the function simply returns.
+        */
+       val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
+             >> RTSDCTL_ENT_DLY_SHIFT;
+       if (ent_delay <= val) {
+               /* put RNG4 into run mode */
+               clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
+               return;
+       }
        val = rd_reg32(&r4tst->rtsdctl);
-       val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT);
+       val = (val & ~RTSDCTL_ENT_DLY_MASK) |
+             (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
        wr_reg32(&r4tst->rtsdctl, val);
-       /* min. freq. count */
-       wr_reg32(&r4tst->rtfrqmin, 400);
-       /* max. freq. count */
-       wr_reg32(&r4tst->rtfrqmax, 6400);
+       /* min. freq. count, equal to 1/4 of the entropy sample length */
+       wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
+       /* max. freq. count, equal to 8 times the entropy sample length */
+       wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
        /* put RNG4 into run mode */
        clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
  }
@@@ -193,7 -383,7 +386,7 @@@ EXPORT_SYMBOL(caam_get_era)
  /* Probe routine for CAAM top (controller) level */
  static int caam_probe(struct platform_device *pdev)
  {
-       int ret, ring, rspec;
+       int ret, ring, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
        u64 caam_id;
        struct device *dev;
        struct device_node *nprop, *np;
        topregs = (struct caam_full __iomem *)ctrl;
  
        /* Get the IRQ of the controller (for security violations only) */
 -      ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL);
 +      ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0);
  
        /*
         * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
                        rspec++;
        }
  
-       ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
-       if (ctrlpriv->jrdev == NULL) {
+       ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec,
+                                                               GFP_KERNEL);
+       if (ctrlpriv->jrpdev == NULL) {
                iounmap(&topregs->ctrl);
                return -ENOMEM;
        }
        ring = 0;
        ctrlpriv->total_jobrs = 0;
        for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
-               caam_jr_probe(pdev, np, ring);
+               ctrlpriv->jrpdev[ring] =
+                               of_platform_device_create(np, NULL, dev);
+               if (!ctrlpriv->jrpdev[ring]) {
+                       pr_warn("JR%d Platform device creation error\n", ring);
+                       continue;
+               }
                ctrlpriv->total_jobrs++;
                ring++;
        }
        if (!ring) {
                for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") {
-                       caam_jr_probe(pdev, np, ring);
+                       ctrlpriv->jrpdev[ring] =
+                               of_platform_device_create(np, NULL, dev);
+                       if (!ctrlpriv->jrpdev[ring]) {
+                               pr_warn("JR%d Platform device creation error\n",
+                                       ring);
+                               continue;
+                       }
                        ctrlpriv->total_jobrs++;
                        ring++;
                }
  
        /*
         * If SEC has RNG version >= 4 and RNG state handle has not been
-        * already instantiated ,do RNG instantiation
+        * already instantiateddo RNG instantiation
         */
-       if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
-           !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
-               kick_trng(pdev);
-               ret = instantiate_rng(dev);
+       if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4) {
+               ctrlpriv->rng4_sh_init =
+                       rd_reg32(&topregs->ctrl.r4tst[0].rdsta);
+               /*
+                * If the secure keys (TDKEK, JDKEK, TDSK), were already
+                * generated, signal this to the function that is instantiating
+                * the state handles. An error would occur if RNG4 attempts
+                * to regenerate these keys before the next POR.
+                */
+               gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
+               ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
+               do {
+                       int inst_handles =
+                               rd_reg32(&topregs->ctrl.r4tst[0].rdsta) &
+                                                               RDSTA_IFMASK;
+                       /*
+                        * If either SH were instantiated by somebody else
+                        * (e.g. u-boot) then it is assumed that the entropy
+                        * parameters are properly set and thus the function
+                        * setting these (kick_trng(...)) is skipped.
+                        * Also, if a handle was instantiated, do not change
+                        * the TRNG parameters.
+                        */
+                       if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+                               kick_trng(pdev, ent_delay);
+                               ent_delay += 400;
+                       }
+                       /*
+                        * if instantiate_rng(...) fails, the loop will rerun
+                        * and the kick_trng(...) function will modfiy the
+                        * upper and lower limits of the entropy sampling
+                        * interval, leading to a sucessful initialization of
+                        * the RNG.
+                        */
+                       ret = instantiate_rng(dev, inst_handles,
+                                             gen_sk);
+               } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
                if (ret) {
+                       dev_err(dev, "failed to instantiate RNG");
                        caam_remove(pdev);
                        return ret;
                }
+               /*
+                * Set handles init'ed by this module as the complement of the
+                * already initialized ones
+                */
+               ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;
  
                /* Enable RDB bit so that RNG works faster */
                setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);
diff --combined drivers/crypto/caam/jr.c
index bdb786d5a5e5b0216b968a833592d8aef7c96d8d,636bb53125abb4ec9b2db615dd130c02cec3ada7..d23356d20e1ca430e5993aaf77b88b39b82fe651
   * Copyright 2008-2012 Freescale Semiconductor, Inc.
   */
  
 +#include <linux/of_irq.h>
 +
  #include "compat.h"
  #include "regs.h"
  #include "jr.h"
  #include "desc.h"
  #include "intern.h"
  
+ struct jr_driver_data {
+       /* List of Physical JobR's with the Driver */
+       struct list_head        jr_list;
+       spinlock_t              jr_alloc_lock;  /* jr_list lock */
+ } ____cacheline_aligned;
+ static struct jr_driver_data driver_data;
+ static int caam_reset_hw_jr(struct device *dev)
+ {
+       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+       unsigned int timeout = 100000;
+       /*
+        * mask interrupts since we are going to poll
+        * for reset completion status
+        */
+       setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+       /* initiate flush (required prior to reset) */
+       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+       while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
+               JRINT_ERR_HALT_INPROGRESS) && --timeout)
+               cpu_relax();
+       if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
+           JRINT_ERR_HALT_COMPLETE || timeout == 0) {
+               dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
+               return -EIO;
+       }
+       /* initiate reset */
+       timeout = 100000;
+       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+       while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
+               cpu_relax();
+       if (timeout == 0) {
+               dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
+               return -EIO;
+       }
+       /* unmask interrupts */
+       clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+       return 0;
+ }
+ /*
+  * Shutdown JobR independent of platform property code
+  */
+ int caam_jr_shutdown(struct device *dev)
+ {
+       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+       dma_addr_t inpbusaddr, outbusaddr;
+       int ret;
+       ret = caam_reset_hw_jr(dev);
+       tasklet_kill(&jrp->irqtask);
+       /* Release interrupt */
+       free_irq(jrp->irq, dev);
+       /* Free rings */
+       inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
+       outbusaddr = rd_reg64(&jrp->rregs->outring_base);
+       dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
+                         jrp->inpring, inpbusaddr);
+       dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
+                         jrp->outring, outbusaddr);
+       kfree(jrp->entinfo);
+       return ret;
+ }
+ static int caam_jr_remove(struct platform_device *pdev)
+ {
+       int ret;
+       struct device *jrdev;
+       struct caam_drv_private_jr *jrpriv;
+       jrdev = &pdev->dev;
+       jrpriv = dev_get_drvdata(jrdev);
+       /*
+        * Return EBUSY if job ring already allocated.
+        */
+       if (atomic_read(&jrpriv->tfm_count)) {
+               dev_err(jrdev, "Device is busy\n");
+               return -EBUSY;
+       }
+       /* Remove the node from Physical JobR list maintained by driver */
+       spin_lock(&driver_data.jr_alloc_lock);
+       list_del(&jrpriv->list_node);
+       spin_unlock(&driver_data.jr_alloc_lock);
+       /* Release ring */
+       ret = caam_jr_shutdown(jrdev);
+       if (ret)
+               dev_err(jrdev, "Failed to shut down job ring\n");
+       irq_dispose_mapping(jrpriv->irq);
+       return ret;
+ }
  /* Main per-ring interrupt handler */
  static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
  {
@@@ -127,6 -232,59 +234,59 @@@ static void caam_jr_dequeue(unsigned lo
        clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
  }
  
+ /**
+  * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
+  *
+  * returns :  pointer to the newly allocated physical
+  *          JobR dev can be written to if successful.
+  **/
+ struct device *caam_jr_alloc(void)
+ {
+       struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL;
+       struct device *dev = NULL;
+       int min_tfm_cnt = INT_MAX;
+       int tfm_cnt;
+       spin_lock(&driver_data.jr_alloc_lock);
+       if (list_empty(&driver_data.jr_list)) {
+               spin_unlock(&driver_data.jr_alloc_lock);
+               return ERR_PTR(-ENODEV);
+       }
+       list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) {
+               tfm_cnt = atomic_read(&jrpriv->tfm_count);
+               if (tfm_cnt < min_tfm_cnt) {
+                       min_tfm_cnt = tfm_cnt;
+                       min_jrpriv = jrpriv;
+               }
+               if (!min_tfm_cnt)
+                       break;
+       }
+       if (min_jrpriv) {
+               atomic_inc(&min_jrpriv->tfm_count);
+               dev = min_jrpriv->dev;
+       }
+       spin_unlock(&driver_data.jr_alloc_lock);
+       return dev;
+ }
+ EXPORT_SYMBOL(caam_jr_alloc);
+ /**
+  * caam_jr_free() - Free the Job Ring
+  * @rdev     - points to the dev that identifies the Job ring to
+  *             be released.
+  **/
+ void caam_jr_free(struct device *rdev)
+ {
+       struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev);
+       atomic_dec(&jrpriv->tfm_count);
+ }
+ EXPORT_SYMBOL(caam_jr_free);
  /**
   * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
   * -EBUSY if the queue is full, -EIO if it cannot map the caller's
@@@ -207,46 -365,6 +367,6 @@@ int caam_jr_enqueue(struct device *dev
  }
  EXPORT_SYMBOL(caam_jr_enqueue);
  
- static int caam_reset_hw_jr(struct device *dev)
- {
-       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
-       unsigned int timeout = 100000;
-       /*
-        * mask interrupts since we are going to poll
-        * for reset completion status
-        */
-       setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
-       /* initiate flush (required prior to reset) */
-       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
-       while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
-               JRINT_ERR_HALT_INPROGRESS) && --timeout)
-               cpu_relax();
-       if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
-           JRINT_ERR_HALT_COMPLETE || timeout == 0) {
-               dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
-               return -EIO;
-       }
-       /* initiate reset */
-       timeout = 100000;
-       wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
-       while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
-               cpu_relax();
-       if (timeout == 0) {
-               dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
-               return -EIO;
-       }
-       /* unmask interrupts */
-       clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
-       return 0;
- }
  /*
   * Init JobR independent of platform property detection
   */
@@@ -262,7 -380,7 +382,7 @@@ static int caam_jr_init(struct device *
  
        /* Connect job ring interrupt handler. */
        error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
-                           "caam-jobr", dev);
+                           dev_name(dev), dev);
        if (error) {
                dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
                        jrp->ridx, jrp->irq);
        return 0;
  }
  
- /*
-  * Shutdown JobR independent of platform property code
-  */
- int caam_jr_shutdown(struct device *dev)
- {
-       struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
-       dma_addr_t inpbusaddr, outbusaddr;
-       int ret;
-       ret = caam_reset_hw_jr(dev);
-       tasklet_kill(&jrp->irqtask);
-       /* Release interrupt */
-       free_irq(jrp->irq, dev);
-       /* Free rings */
-       inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
-       outbusaddr = rd_reg64(&jrp->rregs->outring_base);
-       dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
-                         jrp->inpring, inpbusaddr);
-       dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
-                         jrp->outring, outbusaddr);
-       kfree(jrp->entinfo);
-       of_device_unregister(jrp->jr_pdev);
-       return ret;
- }
  
  /*
-  * Probe routine for each detected JobR subsystem. It assumes that
-  * property detection was picked up externally.
+  * Probe routine for each detected JobR subsystem.
   */
- int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
-                 int ring)
+ static int caam_jr_probe(struct platform_device *pdev)
  {
-       struct device *ctrldev, *jrdev;
-       struct platform_device *jr_pdev;
-       struct caam_drv_private *ctrlpriv;
+       struct device *jrdev;
+       struct device_node *nprop;
+       struct caam_job_ring __iomem *ctrl;
        struct caam_drv_private_jr *jrpriv;
-       u32 *jroffset;
+       static int total_jobrs;
        int error;
  
-       ctrldev = &pdev->dev;
-       ctrlpriv = dev_get_drvdata(ctrldev);
+       jrdev = &pdev->dev;
        jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
                         GFP_KERNEL);
-       if (jrpriv == NULL) {
-               dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
-                       ring);
+       if (!jrpriv)
                return -ENOMEM;
-       }
-       jrpriv->parentdev = ctrldev; /* point back to parent */
-       jrpriv->ridx = ring; /* save ring identity relative to detection */
  
-       /*
-        * Derive a pointer to the detected JobRs regs
-        * Driver has already iomapped the entire space, we just
-        * need to add in the offset to this JobR. Don't know if I
-        * like this long-term, but it'll run
-        */
-       jroffset = (u32 *)of_get_property(np, "reg", NULL);
-       jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
-                                                        + *jroffset);
+       dev_set_drvdata(jrdev, jrpriv);
  
-       /* Build a local dev for each detected queue */
-       jr_pdev = of_platform_device_create(np, NULL, ctrldev);
-       if (jr_pdev == NULL) {
-               kfree(jrpriv);
-               return -EINVAL;
+       /* save ring identity relative to detection */
+       jrpriv->ridx = total_jobrs++;
+       nprop = pdev->dev.of_node;
+       /* Get configuration properties from device tree */
+       /* First, get register page */
+       ctrl = of_iomap(nprop, 0);
+       if (!ctrl) {
+               dev_err(jrdev, "of_iomap() failed\n");
+               return -ENOMEM;
        }
  
-       jrpriv->jr_pdev = jr_pdev;
-       jrdev = &jr_pdev->dev;
-       dev_set_drvdata(jrdev, jrpriv);
-       ctrlpriv->jrdev[ring] = jrdev;
+       jrpriv->rregs = (struct caam_job_ring __force *)ctrl;
  
        if (sizeof(dma_addr_t) == sizeof(u64))
-               if (of_device_is_compatible(np, "fsl,sec-v5.0-job-ring"))
+               if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring"))
                        dma_set_mask(jrdev, DMA_BIT_MASK(40));
                else
                        dma_set_mask(jrdev, DMA_BIT_MASK(36));
                dma_set_mask(jrdev, DMA_BIT_MASK(32));
  
        /* Identify the interrupt */
-       jrpriv->irq = irq_of_parse_and_map(np, 0);
 -      jrpriv->irq = of_irq_to_resource(nprop, 0, NULL);
++      jrpriv->irq = irq_of_parse_and_map(nprop, 0);
  
        /* Now do the platform independent part */
        error = caam_jr_init(jrdev); /* now turn on hardware */
        if (error) {
-               of_device_unregister(jr_pdev);
                kfree(jrpriv);
                return error;
        }
  
-       return error;
+       jrpriv->dev = jrdev;
+       spin_lock(&driver_data.jr_alloc_lock);
+       list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
+       spin_unlock(&driver_data.jr_alloc_lock);
+       atomic_set(&jrpriv->tfm_count, 0);
+       return 0;
+ }
+ static struct of_device_id caam_jr_match[] = {
+       {
+               .compatible = "fsl,sec-v4.0-job-ring",
+       },
+       {
+               .compatible = "fsl,sec4.0-job-ring",
+       },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, caam_jr_match);
+ static struct platform_driver caam_jr_driver = {
+       .driver = {
+               .name = "caam_jr",
+               .owner = THIS_MODULE,
+               .of_match_table = caam_jr_match,
+       },
+       .probe       = caam_jr_probe,
+       .remove      = caam_jr_remove,
+ };
+ static int __init jr_driver_init(void)
+ {
+       spin_lock_init(&driver_data.jr_alloc_lock);
+       INIT_LIST_HEAD(&driver_data.jr_list);
+       return platform_driver_register(&caam_jr_driver);
+ }
+ static void __exit jr_driver_exit(void)
+ {
+       platform_driver_unregister(&caam_jr_driver);
  }
+ module_init(jr_driver_init);
+ module_exit(jr_driver_exit);
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("FSL CAAM JR request backend");
+ MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
index 214357e12dc0b5469bb3c9daae5904ef3a618845,153f73c12d3e7895dfdaa078543d801238536fa8..9dd6e01eac33050b8304c5f8758440e7286606f2
@@@ -218,9 -218,23 +218,9 @@@ static dma_addr_t crypt_phys
  
  static int support_aes = 1;
  
 -static void dev_release(struct device *dev)
 -{
 -      return;
 -}
 -
  #define DRIVER_NAME "ixp4xx_crypto"
 -static struct platform_device pseudo_dev = {
 -      .name = DRIVER_NAME,
 -      .id   = 0,
 -      .num_resources = 0,
 -      .dev  = {
 -              .coherent_dma_mask = DMA_BIT_MASK(32),
 -              .release = dev_release,
 -      }
 -};
  
 -static struct device *dev = &pseudo_dev.dev;
 +static struct platform_device *pdev;
  
  static inline dma_addr_t crypt_virt2phys(struct crypt_ctl *virt)
  {
@@@ -249,7 -263,6 +249,7 @@@ static inline const struct ix_hash_alg
  
  static int setup_crypt_desc(void)
  {
 +      struct device *dev = &pdev->dev;
        BUILD_BUG_ON(sizeof(struct crypt_ctl) != 64);
        crypt_virt = dma_alloc_coherent(dev,
                        NPE_QLEN * sizeof(struct crypt_ctl),
@@@ -350,7 -363,6 +350,7 @@@ static void finish_scattered_hmac(struc
  
  static void one_packet(dma_addr_t phys)
  {
 +      struct device *dev = &pdev->dev;
        struct crypt_ctl *crypt;
        struct ixp_ctx *ctx;
        int failed;
@@@ -420,7 -432,7 +420,7 @@@ static void crypto_done_action(unsigne
        tasklet_schedule(&crypto_done_tasklet);
  }
  
 -static int init_ixp_crypto(void)
 +static int init_ixp_crypto(struct device *dev)
  {
        int ret = -ENODEV;
        u32 msg[2] = { 0, 0 };
@@@ -507,7 -519,7 +507,7 @@@ err
        return ret;
  }
  
 -static void release_ixp_crypto(void)
 +static void release_ixp_crypto(struct device *dev)
  {
        qmgr_disable_irq(RECV_QID);
        tasklet_kill(&crypto_done_tasklet);
@@@ -874,7 -886,6 +874,7 @@@ static int ablk_perform(struct ablkciph
        enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
        struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
        struct buffer_desc src_hook;
 +      struct device *dev = &pdev->dev;
        gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
                                GFP_KERNEL : GFP_ATOMIC;
  
@@@ -999,7 -1010,6 +999,7 @@@ static int aead_perform(struct aead_req
        unsigned int cryptlen;
        struct buffer_desc *buf, src_hook;
        struct aead_ctx *req_ctx = aead_request_ctx(req);
 +      struct device *dev = &pdev->dev;
        gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
                                GFP_KERNEL : GFP_ATOMIC;
  
@@@ -1149,32 -1159,24 +1149,24 @@@ static int aead_setkey(struct crypto_ae
                        unsigned int keylen)
  {
        struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
-       struct rtattr *rta = (struct rtattr *)key;
-       struct crypto_authenc_key_param *param;
+       struct crypto_authenc_keys keys;
  
-       if (!RTA_OK(rta, keylen))
-               goto badkey;
-       if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-               goto badkey;
-       if (RTA_PAYLOAD(rta) < sizeof(*param))
+       if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
                goto badkey;
  
-       param = RTA_DATA(rta);
-       ctx->enckey_len = be32_to_cpu(param->enckeylen);
-       key += RTA_ALIGN(rta->rta_len);
-       keylen -= RTA_ALIGN(rta->rta_len);
+       if (keys.authkeylen > sizeof(ctx->authkey))
+               goto badkey;
  
-       if (keylen < ctx->enckey_len)
+       if (keys.enckeylen > sizeof(ctx->enckey))
                goto badkey;
  
-       ctx->authkey_len = keylen - ctx->enckey_len;
-       memcpy(ctx->enckey, key + ctx->authkey_len, ctx->enckey_len);
-       memcpy(ctx->authkey, key, ctx->authkey_len);
+       memcpy(ctx->authkey, keys.authkey, keys.authkeylen);
+       memcpy(ctx->enckey, keys.enckey, keys.enckeylen);
+       ctx->authkey_len = keys.authkeylen;
+       ctx->enckey_len = keys.enckeylen;
  
        return aead_setup(tfm, crypto_aead_authsize(tfm));
  badkey:
-       ctx->enckey_len = 0;
        crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
        return -EINVAL;
  }
@@@ -1408,30 -1410,20 +1400,30 @@@ static struct ixp_alg ixp4xx_algos[] = 
  } };
  
  #define IXP_POSTFIX "-ixp4xx"
 +
 +static const struct platform_device_info ixp_dev_info __initdata = {
 +      .name           = DRIVER_NAME,
 +      .id             = 0,
 +      .dma_mask       = DMA_BIT_MASK(32),
 +};
 +
  static int __init ixp_module_init(void)
  {
        int num = ARRAY_SIZE(ixp4xx_algos);
 -      int i,err ;
 +      int i, err ;
  
 -      if (platform_device_register(&pseudo_dev))
 -              return -ENODEV;
 +      pdev = platform_device_register_full(&ixp_dev_info);
 +      if (IS_ERR(pdev))
 +              return PTR_ERR(pdev);
 +
 +      dev = &pdev->dev;
  
        spin_lock_init(&desc_lock);
        spin_lock_init(&emerg_lock);
  
 -      err = init_ixp_crypto();
 +      err = init_ixp_crypto(&pdev->dev);
        if (err) {
 -              platform_device_unregister(&pseudo_dev);
 +              platform_device_unregister(pdev);
                return err;
        }
        for (i=0; i< num; i++) {
@@@ -1495,8 -1487,8 +1487,8 @@@ static void __exit ixp_module_exit(void
                if (ixp4xx_algos[i].registered)
                        crypto_unregister_alg(&ixp4xx_algos[i].crypto);
        }
 -      release_ixp_crypto();
 -      platform_device_unregister(&pseudo_dev);
 +      release_ixp_crypto(&pdev->dev);
 +      platform_device_unregister(pdev);
  }
  
  module_init(ixp_module_init);
index e28104b4aab08ce20a9c1bbf26aefdb45778379a,236db0a44105257974d0dc73e38b93d1f3380b6b..e45aaaf0db3069d5c99cef88664dfdc62a87d434
@@@ -1818,7 -1818,7 +1818,7 @@@ static int omap_sham_get_res_of(struct 
                goto err;
        }
  
 -      dd->irq = of_irq_to_resource(node, 0, NULL);
 +      dd->irq = irq_of_parse_and_map(node, 0);
        if (!dd->irq) {
                dev_err(dev, "can't translate OF irq value\n");
                err = -EINVAL;
@@@ -2033,3 -2033,4 +2033,4 @@@ module_platform_driver(omap_sham_driver
  MODULE_DESCRIPTION("OMAP SHA1/MD5 hw acceleration support.");
  MODULE_LICENSE("GPL v2");
  MODULE_AUTHOR("Dmitry Kasatkin");
+ MODULE_ALIAS("platform:omap-sham");
diff --combined drivers/crypto/talitos.c
index 6cd0e603858321dd678b45ad74dda8f6746fba97,f6f7c681073e8b9132afa81c70a7af58cf3f8360..905de4427e7c4d1630604db45ffa2ba158983918
@@@ -32,8 -32,6 +32,8 @@@
  #include <linux/interrupt.h>
  #include <linux/crypto.h>
  #include <linux/hw_random.h>
 +#include <linux/of_address.h>
 +#include <linux/of_irq.h>
  #include <linux/of_platform.h>
  #include <linux/dma-mapping.h>
  #include <linux/io.h>
@@@ -673,39 -671,20 +673,20 @@@ static int aead_setkey(struct crypto_ae
                       const u8 *key, unsigned int keylen)
  {
        struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
-       struct rtattr *rta = (void *)key;
-       struct crypto_authenc_key_param *param;
-       unsigned int authkeylen;
-       unsigned int enckeylen;
-       if (!RTA_OK(rta, keylen))
-               goto badkey;
-       if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-               goto badkey;
+       struct crypto_authenc_keys keys;
  
-       if (RTA_PAYLOAD(rta) < sizeof(*param))
+       if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
                goto badkey;
  
-       param = RTA_DATA(rta);
-       enckeylen = be32_to_cpu(param->enckeylen);
-       key += RTA_ALIGN(rta->rta_len);
-       keylen -= RTA_ALIGN(rta->rta_len);
-       if (keylen < enckeylen)
-               goto badkey;
-       authkeylen = keylen - enckeylen;
-       if (keylen > TALITOS_MAX_KEY_SIZE)
+       if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
                goto badkey;
  
-       memcpy(&ctx->key, key, keylen);
+       memcpy(ctx->key, keys.authkey, keys.authkeylen);
+       memcpy(&ctx->key[keys.authkeylen], keys.enckey, keys.enckeylen);
  
-       ctx->keylen = keylen;
-       ctx->enckeylen = enckeylen;
-       ctx->authkeylen = authkeylen;
+       ctx->keylen = keys.authkeylen + keys.enckeylen;
+       ctx->enckeylen = keys.enckeylen;
+       ctx->authkeylen = keys.authkeylen;
  
        return 0;
  
index fa05e3c329bdd44a522a922a1d12e87a54393309,d8c7a132fea467e9d38bd842f40b5cde55c6ed8b..060eecc5dbc31b24bf0c05301b37192da7e36dff
@@@ -27,6 -27,8 +27,8 @@@
   * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   */
  
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/errno.h>
@@@ -199,8 -201,6 +201,6 @@@ static void aes_workqueue_handler(struc
  static DECLARE_WORK(aes_work, aes_workqueue_handler);
  static struct workqueue_struct *aes_wq;
  
- extern unsigned long long tegra_chip_uid(void);
  static inline u32 aes_readl(struct tegra_aes_dev *dd, u32 offset)
  {
        return readl(dd->io_base + offset);
@@@ -268,7 -268,7 +268,7 @@@ static int aes_start_crypt(struct tegra
        aes_writel(dd, value, TEGRA_AES_SECURE_INPUT_SELECT);
  
        aes_writel(dd, out_addr, TEGRA_AES_SECURE_DEST_ADDR);
 -      INIT_COMPLETION(dd->op_complete);
 +      reinit_completion(&dd->op_complete);
  
        for (i = 0; i < AES_HW_MAX_ICQ_LENGTH - 1; i++) {
                do {
@@@ -713,13 -713,12 +713,12 @@@ static int tegra_aes_rng_reset(struct c
        struct tegra_aes_dev *dd = aes_dev;
        struct tegra_aes_ctx *ctx = &rng_ctx;
        struct tegra_aes_slot *key_slot;
-       struct timespec ts;
        int ret = 0;
-       u64 nsec, tmp[2];
+       u8 tmp[16]; /* 16 bytes = 128 bits of entropy */
        u8 *dt;
  
        if (!ctx || !dd) {
-               dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n",
+               pr_err("ctx=0x%x, dd=0x%x\n",
                        (unsigned int)ctx, (unsigned int)dd);
                return -EINVAL;
        }
        if (dd->ivlen >= (2 * DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) {
                dt = dd->iv + DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128;
        } else {
-               getnstimeofday(&ts);
-               nsec = timespec_to_ns(&ts);
-               do_div(nsec, 1000);
-               nsec ^= dd->ctr << 56;
-               dd->ctr++;
-               tmp[0] = nsec;
-               tmp[1] = tegra_chip_uid();
-               dt = (u8 *)tmp;
+               get_random_bytes(tmp, sizeof(tmp));
+               dt = tmp;
        }
        memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ);
  
@@@ -804,7 -797,7 +797,7 @@@ static int tegra_aes_cra_init(struct cr
        return 0;
  }
  
- void tegra_aes_cra_exit(struct crypto_tfm *tfm)
static void tegra_aes_cra_exit(struct crypto_tfm *tfm)
  {
        struct tegra_aes_ctx *ctx =
                crypto_ablkcipher_ctx((struct crypto_ablkcipher *)tfm);
@@@ -924,7 -917,7 +917,7 @@@ static int tegra_aes_probe(struct platf
        }
  
        /* Initialize the vde clock */
-       dd->aes_clk = clk_get(dev, "vde");
+       dd->aes_clk = devm_clk_get(dev, "vde");
        if (IS_ERR(dd->aes_clk)) {
                dev_err(dev, "iclock intialization failed.\n");
                err = -ENODEV;
@@@ -1033,8 -1026,6 +1026,6 @@@ out
        if (dd->buf_out)
                dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
                        dd->buf_out, dd->dma_buf_out);
-       if (!IS_ERR(dd->aes_clk))
-               clk_put(dd->aes_clk);
        if (aes_wq)
                destroy_workqueue(aes_wq);
        spin_lock(&list_lock);
@@@ -1068,7 -1059,6 +1059,6 @@@ static int tegra_aes_remove(struct plat
                          dd->buf_in, dd->dma_buf_in);
        dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
                          dd->buf_out, dd->dma_buf_out);
-       clk_put(dd->aes_clk);
        aes_dev = NULL;
  
        return 0;