kernel: bump 4.14 to 4.14.125 (FS#2305 FS#2297)
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.14 / 820-sec-support-layerscape.patch
index ff0fe8daa4b820a08e61df64a15e4655b020ded8..95e6894b93fa58c57dd4d5e4013b6bd29eaf7213 100644 (file)
@@ -1,59 +1,69 @@
-From 936d5f485f2ff837cdd7d49839771bd3367e8b92 Mon Sep 17 00:00:00 2001
+From ba8e92b322a3763880fdc4d19e9c7085f5504be7 Mon Sep 17 00:00:00 2001
 From: Biwen Li <biwen.li@nxp.com>
-Date: Tue, 30 Oct 2018 18:28:03 +0800
-Subject: [PATCH 37/40] sec: support layerscape
+Date: Tue, 23 Apr 2019 17:41:43 +0800
+Subject: [PATCH] sec: support layerscape
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
 This is an integrated patch of sec for layerscape
 
 Signed-off-by: Alex Porosanu <alexandru.porosanu@nxp.com>
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
+Signed-off-by: Carmen Iorga <carmen.iorga@nxp.com>
 Signed-off-by: Cristian Stoica <cristian.stoica@nxp.com>
 Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com>
 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
 Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
-Signed-off-by: Horia Geantă horia.geanta@nxp.com
+Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
 Signed-off-by: Radu Alexe <radu.alexe@nxp.com>
 Signed-off-by: Tudor Ambarus <tudor-dan.ambarus@nxp.com>
 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
-Signed-off-by: Biwen Li <biwen.li@nxp.com>
 ---
  crypto/Kconfig                      |   20 +
  crypto/Makefile                     |    1 +
+ crypto/chacha20poly1305.c           |    2 -
  crypto/tcrypt.c                     |   27 +-
  crypto/testmgr.c                    |  244 ++
  crypto/testmgr.h                    |  219 ++
- crypto/tls.c                        |  607 +++
+ crypto/tls.c                        |  607 ++++
  drivers/crypto/Makefile             |    2 +-
- drivers/crypto/caam/Kconfig         |   57 +-
- drivers/crypto/caam/Makefile        |   10 +-
- drivers/crypto/caam/caamalg.c       |  131 +-
- drivers/crypto/caam/caamalg_desc.c  |  761 +++-
- drivers/crypto/caam/caamalg_desc.h  |   47 +-
- drivers/crypto/caam/caamalg_qi.c    |  927 ++++-
- drivers/crypto/caam/caamalg_qi2.c   | 5691 +++++++++++++++++++++++++++
- drivers/crypto/caam/caamalg_qi2.h   |  274 ++
- drivers/crypto/caam/caamhash.c      |  132 +-
+ drivers/crypto/caam/Kconfig         |   85 +-
+ drivers/crypto/caam/Makefile        |   26 +-
+ drivers/crypto/caam/caamalg.c       |  468 +++-
+ drivers/crypto/caam/caamalg_desc.c  |  903 +++++-
+ drivers/crypto/caam/caamalg_desc.h  |   52 +-
+ drivers/crypto/caam/caamalg_qi.c    | 1060 ++++++-
+ drivers/crypto/caam/caamalg_qi2.c   | 5843 +++++++++++++++++++++++++++++++++++
+ drivers/crypto/caam/caamalg_qi2.h   |  276 ++
+ drivers/crypto/caam/caamhash.c      |  192 +-
  drivers/crypto/caam/caamhash_desc.c |  108 +
  drivers/crypto/caam/caamhash_desc.h |   49 +
- drivers/crypto/caam/compat.h        |    2 +
- drivers/crypto/caam/ctrl.c          |   23 +-
- drivers/crypto/caam/desc.h          |   62 +-
- drivers/crypto/caam/desc_constr.h   |   52 +-
- drivers/crypto/caam/dpseci.c        |  865 ++++
- drivers/crypto/caam/dpseci.h        |  433 ++
+ drivers/crypto/caam/caampkc.c       |   52 +-
+ drivers/crypto/caam/caamrng.c       |   52 +-
+ drivers/crypto/caam/compat.h        |    4 +
+ drivers/crypto/caam/ctrl.c          |  194 +-
+ drivers/crypto/caam/desc.h          |   89 +-
+ drivers/crypto/caam/desc_constr.h   |   59 +-
+ drivers/crypto/caam/dpseci.c        |  865 ++++++
+ drivers/crypto/caam/dpseci.h        |  433 +++
  drivers/crypto/caam/dpseci_cmd.h    |  287 ++
- drivers/crypto/caam/error.c         |   75 +-
+ drivers/crypto/caam/error.c         |   81 +-
  drivers/crypto/caam/error.h         |    6 +-
- drivers/crypto/caam/intern.h        |    1 +
- drivers/crypto/caam/jr.c            |   42 +
+ drivers/crypto/caam/intern.h        |  102 +-
+ drivers/crypto/caam/jr.c            |   84 +
  drivers/crypto/caam/jr.h            |    2 +
  drivers/crypto/caam/key_gen.c       |   30 -
  drivers/crypto/caam/key_gen.h       |   30 +
- drivers/crypto/caam/qi.c            |   85 +-
+ drivers/crypto/caam/qi.c            |  134 +-
  drivers/crypto/caam/qi.h            |    2 +-
- drivers/crypto/caam/regs.h          |    2 +
+ drivers/crypto/caam/regs.h          |   76 +-
  drivers/crypto/caam/sg_sw_qm.h      |   46 +-
  drivers/crypto/talitos.c            |    8 +
- 37 files changed, 11006 insertions(+), 354 deletions(-)
+ include/crypto/chacha20.h           |    1 +
+ 41 files changed, 12088 insertions(+), 733 deletions(-)
  create mode 100644 crypto/tls.c
  create mode 100644 drivers/crypto/caam/caamalg_qi2.c
  create mode 100644 drivers/crypto/caam/caamalg_qi2.h
@@ -102,6 +112,17 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  obj-$(CONFIG_CRYPTO_LZO) += lzo.o
  obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
  obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
+--- a/crypto/chacha20poly1305.c
++++ b/crypto/chacha20poly1305.c
+@@ -22,8 +22,6 @@
+ #include "internal.h"
+-#define CHACHAPOLY_IV_SIZE    12
+-
+ struct chachapoly_instance_ctx {
+       struct crypto_skcipher_spawn chacha;
+       struct crypto_ahash_spawn poly;
 --- a/crypto/tcrypt.c
 +++ b/crypto/tcrypt.c
 @@ -76,7 +76,7 @@ static char *check[] = {
@@ -1316,9 +1337,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o
 --- a/drivers/crypto/caam/Kconfig
 +++ b/drivers/crypto/caam/Kconfig
-@@ -1,7 +1,11 @@
+@@ -1,7 +1,17 @@
 +config CRYPTO_DEV_FSL_CAAM_COMMON
 +      tristate
++
++config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
++      tristate
++
++config CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC
++      tristate
 +
  config CRYPTO_DEV_FSL_CAAM
 -      tristate "Freescale CAAM-Multicore driver backend"
@@ -1329,7 +1356,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        help
          Enables the driver module for Freescale's Cryptographic Accelerator
          and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).
-@@ -12,9 +16,16 @@ config CRYPTO_DEV_FSL_CAAM
+@@ -12,9 +22,16 @@ config CRYPTO_DEV_FSL_CAAM
          To compile this driver as a module, choose M here: the module
          will be called caam.
  
@@ -1347,7 +1374,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        default y
        help
          Enables the driver module for Job Rings which are part of
-@@ -25,9 +36,10 @@ config CRYPTO_DEV_FSL_CAAM_JR
+@@ -25,9 +42,10 @@ config CRYPTO_DEV_FSL_CAAM_JR
          To compile this driver as a module, choose M here: the module
          will be called caam_jr.
  
@@ -1359,7 +1386,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        range 2 9
        default "9"
        help
-@@ -45,7 +57,6 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE
+@@ -45,7 +63,6 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE
  
  config CRYPTO_DEV_FSL_CAAM_INTC
        bool "Job Ring interrupt coalescing"
@@ -1367,50 +1394,83 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        help
          Enable the Job Ring's interrupt coalescing feature.
  
-@@ -75,7 +86,6 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THL
+@@ -74,9 +91,9 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THL
+         threshold. Range is 1-65535.
  
  config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
-       tristate "Register algorithm implementations with the Crypto API"
+-      tristate "Register algorithm implementations with the Crypto API"
 -      depends on CRYPTO_DEV_FSL_CAAM_JR
++      bool "Register algorithm implementations with the Crypto API"
        default y
++      select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
        select CRYPTO_AEAD
        select CRYPTO_AUTHENC
-@@ -90,7 +100,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
+       select CRYPTO_BLKCIPHER
+@@ -85,13 +102,11 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
+         scatterlist crypto API (such as the linux native IPSec
+         stack) to the SEC4 via job ring.
  
+-        To compile this as a module, choose M here: the module
+-        will be called caamalg.
+-
  config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
-       tristate "Queue Interface as Crypto API backend"
+-      tristate "Queue Interface as Crypto API backend"
 -      depends on CRYPTO_DEV_FSL_CAAM_JR && FSL_DPAA && NET
++      bool "Queue Interface as Crypto API backend"
 +      depends on FSL_SDK_DPA && NET
        default y
++      select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
        select CRYPTO_AUTHENC
        select CRYPTO_BLKCIPHER
-@@ -107,7 +117,6 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
+       help
+@@ -102,36 +117,26 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI
+         assigned to the kernel should also be more than the number of
+         job rings.
  
+-        To compile this as a module, choose M here: the module
+-        will be called caamalg_qi.
+-
  config CRYPTO_DEV_FSL_CAAM_AHASH_API
-       tristate "Register hash algorithm implementations with Crypto API"
+-      tristate "Register hash algorithm implementations with Crypto API"
 -      depends on CRYPTO_DEV_FSL_CAAM_JR
++      bool "Register hash algorithm implementations with Crypto API"
        default y
++      select CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC
        select CRYPTO_HASH
        help
-@@ -119,7 +128,6 @@ config CRYPTO_DEV_FSL_CAAM_AHASH_API
+         Selecting this will offload ahash for users of the
+         scatterlist crypto API to the SEC4 via job ring.
  
+-        To compile this as a module, choose M here: the module
+-        will be called caamhash.
+-
  config CRYPTO_DEV_FSL_CAAM_PKC_API
-         tristate "Register public key cryptography implementations with Crypto API"
+-        tristate "Register public key cryptography implementations with Crypto API"
 -        depends on CRYPTO_DEV_FSL_CAAM_JR
++        bool "Register public key cryptography implementations with Crypto API"
          default y
          select CRYPTO_RSA
          help
-@@ -131,7 +139,6 @@ config CRYPTO_DEV_FSL_CAAM_PKC_API
+           Selecting this will allow SEC Public key support for RSA.
+           Supported cryptographic primitives: encryption, decryption,
+           signature and verification.
+-          To compile this as a module, choose M here: the module
+-          will be called caam_pkc.
  
  config CRYPTO_DEV_FSL_CAAM_RNG_API
-       tristate "Register caam device for hwrng API"
+-      tristate "Register caam device for hwrng API"
 -      depends on CRYPTO_DEV_FSL_CAAM_JR
++      bool "Register caam device for hwrng API"
        default y
        select CRYPTO_RNG
        select HW_RANDOM
-@@ -142,13 +149,31 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API
-         To compile this as a module, choose M here: the module
-         will be called caamrng.
+@@ -139,16 +144,24 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API
+         Selecting this will register the SEC4 hardware rng to
+         the hw_random API for suppying the kernel entropy pool.
+-        To compile this as a module, choose M here: the module
+-        will be called caamrng.
++endif # CRYPTO_DEV_FSL_CAAM_JR
  
 -config CRYPTO_DEV_FSL_CAAM_DEBUG
 -      bool "Enable debug output in CAAM driver"
@@ -1418,14 +1478,17 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 -      help
 -        Selecting this will enable printing of various debug
 -        information in the CAAM driver.
-+endif # CRYPTO_DEV_FSL_CAAM_JR
-+
 +endif # CRYPTO_DEV_FSL_CAAM
-+
+-config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
+-      def_tristate (CRYPTO_DEV_FSL_CAAM_CRYPTO_API || \
+-                    CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI)
 +config CRYPTO_DEV_FSL_DPAA2_CAAM
 +      tristate "QorIQ DPAA2 CAAM (DPSECI) driver"
 +      depends on FSL_MC_DPIO
 +      select CRYPTO_DEV_FSL_CAAM_COMMON
++      select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
++      select CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC
 +      select CRYPTO_BLKCIPHER
 +      select CRYPTO_AUTHENC
 +      select CRYPTO_AEAD
@@ -1437,16 +1500,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +
 +        To compile this as a module, choose M here: the module
 +        will be called dpaa2_caam.
- config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC
-       def_tristate (CRYPTO_DEV_FSL_CAAM_CRYPTO_API || \
--                    CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI)
-+                    CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI || \
-+                    CRYPTO_DEV_FSL_DPAA2_CAAM)
-+
-+config CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC
-+      def_tristate (CRYPTO_DEV_FSL_CAAM_AHASH_API || \
-+                    CRYPTO_DEV_FSL_DPAA2_CAAM)
 --- a/drivers/crypto/caam/Makefile
 +++ b/drivers/crypto/caam/Makefile
 @@ -6,19 +6,27 @@ ifeq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG
@@ -1458,21 +1511,30 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON) += error.o
  obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
  obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
+-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
+-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
  obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
-+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
- obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caam_pkc.o
- caam-objs := ctrl.o
+-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
+-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
+-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caam_pkc.o
+-
+-caam-objs := ctrl.o
 -caam_jr-objs := jr.o key_gen.o error.o
-+caam_jr-objs := jr.o key_gen.o
- caam_pkc-y := caampkc.o pkc_desc.o
+-caam_pkc-y := caampkc.o pkc_desc.o
++obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o
++
++caam-y := ctrl.o
++caam_jr-y := jr.o key_gen.o
++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o
++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o
++
++caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o
  ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),)
        ccflags-y += -DCONFIG_CAAM_QI
-       caam-objs += qi.o
+-      caam-objs += qi.o
  endif
 +
 +obj-$(CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM) += dpaa2_caam.o
@@ -1480,7 +1542,16 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +dpaa2_caam-y    := caamalg_qi2.o dpseci.o
 --- a/drivers/crypto/caam/caamalg.c
 +++ b/drivers/crypto/caam/caamalg.c
-@@ -108,6 +108,7 @@ struct caam_ctx {
+@@ -71,6 +71,8 @@
+ #define AUTHENC_DESC_JOB_IO_LEN               (AEAD_DESC_JOB_IO_LEN + \
+                                        CAAM_CMD_SZ * 5)
++#define CHACHAPOLY_DESC_JOB_IO_LEN    (AEAD_DESC_JOB_IO_LEN + CAAM_CMD_SZ * 6)
++
+ #define DESC_MAX_USED_BYTES           (CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN)
+ #define DESC_MAX_USED_LEN             (DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
+@@ -108,6 +110,7 @@ struct caam_ctx {
        dma_addr_t sh_desc_dec_dma;
        dma_addr_t sh_desc_givenc_dma;
        dma_addr_t key_dma;
@@ -1488,7 +1559,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        struct device *jrdev;
        struct alginfo adata;
        struct alginfo cdata;
-@@ -118,6 +119,7 @@ static int aead_null_set_sh_desc(struct
+@@ -118,6 +121,7 @@ static int aead_null_set_sh_desc(struct
  {
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
        struct device *jrdev = ctx->jrdev;
@@ -1496,7 +1567,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        u32 *desc;
        int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
                        ctx->adata.keylen_pad;
-@@ -136,9 +138,10 @@ static int aead_null_set_sh_desc(struct
+@@ -136,9 +140,10 @@ static int aead_null_set_sh_desc(struct
  
        /* aead_encrypt shared descriptor */
        desc = ctx->sh_desc_enc;
@@ -1509,7 +1580,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        /*
         * Job Descriptor and Shared Descriptors
-@@ -154,9 +157,10 @@ static int aead_null_set_sh_desc(struct
+@@ -154,9 +159,10 @@ static int aead_null_set_sh_desc(struct
  
        /* aead_decrypt shared descriptor */
        desc = ctx->sh_desc_dec;
@@ -1522,7 +1593,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        return 0;
  }
-@@ -168,6 +172,7 @@ static int aead_set_sh_desc(struct crypt
+@@ -168,6 +174,7 @@ static int aead_set_sh_desc(struct crypt
        unsigned int ivsize = crypto_aead_ivsize(aead);
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
        struct device *jrdev = ctx->jrdev;
@@ -1530,7 +1601,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        u32 ctx1_iv_off = 0;
        u32 *desc, *nonce = NULL;
        u32 inl_mask;
-@@ -234,9 +239,9 @@ static int aead_set_sh_desc(struct crypt
+@@ -234,9 +241,9 @@ static int aead_set_sh_desc(struct crypt
        desc = ctx->sh_desc_enc;
        cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
                               ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
@@ -1542,7 +1613,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  skip_enc:
        /*
-@@ -266,9 +271,9 @@ skip_enc:
+@@ -266,9 +273,9 @@ skip_enc:
        desc = ctx->sh_desc_dec;
        cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
                               ctx->authsize, alg->caam.geniv, is_rfc3686,
@@ -1554,7 +1625,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        if (!alg->caam.geniv)
                goto skip_givenc;
-@@ -300,9 +305,9 @@ skip_enc:
+@@ -300,9 +307,9 @@ skip_enc:
        desc = ctx->sh_desc_enc;
        cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
                                  ctx->authsize, is_rfc3686, nonce,
@@ -1566,7 +1637,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  skip_givenc:
        return 0;
-@@ -323,6 +328,7 @@ static int gcm_set_sh_desc(struct crypto
+@@ -323,6 +330,7 @@ static int gcm_set_sh_desc(struct crypto
  {
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
        struct device *jrdev = ctx->jrdev;
@@ -1574,7 +1645,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        u32 *desc;
        int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
                        ctx->cdata.keylen;
-@@ -344,9 +350,9 @@ static int gcm_set_sh_desc(struct crypto
+@@ -344,9 +352,9 @@ static int gcm_set_sh_desc(struct crypto
        }
  
        desc = ctx->sh_desc_enc;
@@ -1586,7 +1657,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        /*
         * Job Descriptor and Shared Descriptors
-@@ -361,9 +367,9 @@ static int gcm_set_sh_desc(struct crypto
+@@ -361,9 +369,9 @@ static int gcm_set_sh_desc(struct crypto
        }
  
        desc = ctx->sh_desc_dec;
@@ -1598,7 +1669,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        return 0;
  }
-@@ -382,6 +388,7 @@ static int rfc4106_set_sh_desc(struct cr
+@@ -382,6 +390,7 @@ static int rfc4106_set_sh_desc(struct cr
  {
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
        struct device *jrdev = ctx->jrdev;
@@ -1606,7 +1677,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        u32 *desc;
        int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
                        ctx->cdata.keylen;
-@@ -403,9 +410,10 @@ static int rfc4106_set_sh_desc(struct cr
+@@ -403,9 +412,10 @@ static int rfc4106_set_sh_desc(struct cr
        }
  
        desc = ctx->sh_desc_enc;
@@ -1619,7 +1690,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        /*
         * Job Descriptor and Shared Descriptors
-@@ -420,9 +428,10 @@ static int rfc4106_set_sh_desc(struct cr
+@@ -420,9 +430,10 @@ static int rfc4106_set_sh_desc(struct cr
        }
  
        desc = ctx->sh_desc_dec;
@@ -1632,7 +1703,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        return 0;
  }
-@@ -442,6 +451,7 @@ static int rfc4543_set_sh_desc(struct cr
+@@ -442,6 +453,7 @@ static int rfc4543_set_sh_desc(struct cr
  {
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
        struct device *jrdev = ctx->jrdev;
@@ -1640,7 +1711,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        u32 *desc;
        int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
                        ctx->cdata.keylen;
-@@ -463,9 +473,10 @@ static int rfc4543_set_sh_desc(struct cr
+@@ -463,9 +475,10 @@ static int rfc4543_set_sh_desc(struct cr
        }
  
        desc = ctx->sh_desc_enc;
@@ -1653,7 +1724,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        /*
         * Job Descriptor and Shared Descriptors
-@@ -480,9 +491,10 @@ static int rfc4543_set_sh_desc(struct cr
+@@ -480,9 +493,10 @@ static int rfc4543_set_sh_desc(struct cr
        }
  
        desc = ctx->sh_desc_dec;
@@ -1666,7 +1737,67 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        return 0;
  }
-@@ -503,6 +515,7 @@ static int aead_setkey(struct crypto_aea
+@@ -498,11 +512,67 @@ static int rfc4543_setauthsize(struct cr
+       return 0;
+ }
++static int chachapoly_set_sh_desc(struct crypto_aead *aead)
++{
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++      struct device *jrdev = ctx->jrdev;
++      unsigned int ivsize = crypto_aead_ivsize(aead);
++      u32 *desc;
++
++      if (!ctx->cdata.keylen || !ctx->authsize)
++              return 0;
++
++      desc = ctx->sh_desc_enc;
++      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
++                             ctx->authsize, true, false);
++      dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
++                                 desc_bytes(desc), ctx->dir);
++
++      desc = ctx->sh_desc_dec;
++      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
++                             ctx->authsize, false, false);
++      dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
++                                 desc_bytes(desc), ctx->dir);
++
++      return 0;
++}
++
++static int chachapoly_setauthsize(struct crypto_aead *aead,
++                                unsigned int authsize)
++{
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++
++      if (authsize != POLY1305_DIGEST_SIZE)
++              return -EINVAL;
++
++      ctx->authsize = authsize;
++      return chachapoly_set_sh_desc(aead);
++}
++
++static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
++                           unsigned int keylen)
++{
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++      unsigned int ivsize = crypto_aead_ivsize(aead);
++      unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
++
++      if (keylen != CHACHA20_KEY_SIZE + saltlen) {
++              crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
++              return -EINVAL;
++      }
++
++      ctx->cdata.key_virt = key;
++      ctx->cdata.keylen = keylen - saltlen;
++
++      return chachapoly_set_sh_desc(aead);
++}
++
+ static int aead_setkey(struct crypto_aead *aead,
+                              const u8 *key, unsigned int keylen)
  {
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
        struct device *jrdev = ctx->jrdev;
@@ -1674,7 +1805,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        struct crypto_authenc_keys keys;
        int ret = 0;
  
-@@ -517,6 +530,27 @@ static int aead_setkey(struct crypto_aea
+@@ -517,6 +587,27 @@ static int aead_setkey(struct crypto_aea
                       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
  #endif
  
@@ -1702,7 +1833,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
                            keys.authkeylen, CAAM_MAX_KEY_SIZE -
                            keys.enckeylen);
-@@ -527,12 +561,14 @@ static int aead_setkey(struct crypto_aea
+@@ -527,12 +618,14 @@ static int aead_setkey(struct crypto_aea
        /* postpend encryption key to auth split key */
        memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
        dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
@@ -1718,7 +1849,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        ctx->cdata.keylen = keys.enckeylen;
        return aead_set_sh_desc(aead);
  badkey:
-@@ -552,7 +588,7 @@ static int gcm_setkey(struct crypto_aead
+@@ -552,7 +645,7 @@ static int gcm_setkey(struct crypto_aead
  #endif
  
        memcpy(ctx->key, key, keylen);
@@ -1727,7 +1858,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        ctx->cdata.keylen = keylen;
  
        return gcm_set_sh_desc(aead);
-@@ -580,7 +616,7 @@ static int rfc4106_setkey(struct crypto_
+@@ -580,7 +673,7 @@ static int rfc4106_setkey(struct crypto_
         */
        ctx->cdata.keylen = keylen - 4;
        dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
@@ -1736,7 +1867,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        return rfc4106_set_sh_desc(aead);
  }
  
-@@ -606,7 +642,7 @@ static int rfc4543_setkey(struct crypto_
+@@ -606,7 +699,7 @@ static int rfc4543_setkey(struct crypto_
         */
        ctx->cdata.keylen = keylen - 4;
        dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
@@ -1745,7 +1876,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        return rfc4543_set_sh_desc(aead);
  }
  
-@@ -658,21 +694,21 @@ static int ablkcipher_setkey(struct cryp
+@@ -658,21 +751,21 @@ static int ablkcipher_setkey(struct cryp
        cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
                                     ctx1_iv_off);
        dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
@@ -1770,7 +1901,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        return 0;
  }
-@@ -701,13 +737,13 @@ static int xts_ablkcipher_setkey(struct
+@@ -701,13 +794,13 @@ static int xts_ablkcipher_setkey(struct
        desc = ctx->sh_desc_enc;
        cnstr_shdsc_xts_ablkcipher_encap(desc, &ctx->cdata);
        dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
@@ -1786,7 +1917,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        return 0;
  }
-@@ -987,9 +1023,6 @@ static void init_aead_job(struct aead_re
+@@ -987,9 +1080,6 @@ static void init_aead_job(struct aead_re
                append_seq_out_ptr(desc, dst_dma,
                                   req->assoclen + req->cryptlen - authsize,
                                   out_options);
@@ -1796,7 +1927,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  }
  
  static void init_gcm_job(struct aead_request *req,
-@@ -1004,6 +1037,7 @@ static void init_gcm_job(struct aead_req
+@@ -1004,6 +1094,7 @@ static void init_gcm_job(struct aead_req
        unsigned int last;
  
        init_aead_job(req, edesc, all_contig, encrypt);
@@ -1804,7 +1935,48 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        /* BUG This should not be specific to generic GCM. */
        last = 0;
-@@ -1030,6 +1064,7 @@ static void init_authenc_job(struct aead
+@@ -1021,6 +1112,40 @@ static void init_gcm_job(struct aead_req
+       /* End of blank commands */
+ }
++static void init_chachapoly_job(struct aead_request *req,
++                              struct aead_edesc *edesc, bool all_contig,
++                              bool encrypt)
++{
++      struct crypto_aead *aead = crypto_aead_reqtfm(req);
++      unsigned int ivsize = crypto_aead_ivsize(aead);
++      unsigned int assoclen = req->assoclen;
++      u32 *desc = edesc->hw_desc;
++      u32 ctx_iv_off = 4;
++
++      init_aead_job(req, edesc, all_contig, encrypt);
++
++      if (ivsize != CHACHAPOLY_IV_SIZE) {
++              /* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */
++              ctx_iv_off += 4;
++
++              /*
++               * The associated data comes already with the IV but we need
++               * to skip it when we authenticate or encrypt...
++               */
++              assoclen -= ivsize;
++      }
++
++      append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen);
++
++      /*
++       * For IPsec load the IV further in the same register.
++       * For RFC7539 simply load the 12 bytes nonce in a single operation
++       */
++      append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB |
++                         LDST_SRCDST_BYTE_CONTEXT |
++                         ctx_iv_off << LDST_OFFSET_SHIFT);
++}
++
+ static void init_authenc_job(struct aead_request *req,
+                            struct aead_edesc *edesc,
+                            bool all_contig, bool encrypt)
+@@ -1030,6 +1155,7 @@ static void init_authenc_job(struct aead
                                                 struct caam_aead_alg, aead);
        unsigned int ivsize = crypto_aead_ivsize(aead);
        struct caam_ctx *ctx = crypto_aead_ctx(aead);
@@ -1812,7 +1984,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
                               OP_ALG_AAI_CTR_MOD128);
        const bool is_rfc3686 = alg->caam.rfc3686;
-@@ -1053,6 +1088,15 @@ static void init_authenc_job(struct aead
+@@ -1053,6 +1179,15 @@ static void init_authenc_job(struct aead
  
        init_aead_job(req, edesc, all_contig, encrypt);
  
@@ -1828,7 +2000,176 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
                append_load_as_imm(desc, req->iv, ivsize,
                                   LDST_CLASS_1_CCB |
-@@ -3204,9 +3248,11 @@ struct caam_crypto_alg {
+@@ -1225,8 +1360,16 @@ static struct aead_edesc *aead_edesc_all
+               }
+       }
++      /*
++       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
++       * the end of the table by allocating more S/G entries.
++       */
+       sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
+-      sec4_sg_len += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
++      if (mapped_dst_nents > 1)
++              sec4_sg_len += ALIGN(mapped_dst_nents, 4);
++      else
++              sec4_sg_len = ALIGN(sec4_sg_len, 4);
++
+       sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
+       /* allocate space for base edesc and hw desc commands, link tables */
+@@ -1307,6 +1450,72 @@ static int gcm_encrypt(struct aead_reque
+       return ret;
+ }
++static int chachapoly_encrypt(struct aead_request *req)
++{
++      struct aead_edesc *edesc;
++      struct crypto_aead *aead = crypto_aead_reqtfm(req);
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++      struct device *jrdev = ctx->jrdev;
++      bool all_contig;
++      u32 *desc;
++      int ret;
++
++      edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
++                               true);
++      if (IS_ERR(edesc))
++              return PTR_ERR(edesc);
++
++      desc = edesc->hw_desc;
++
++      init_chachapoly_job(req, edesc, all_contig, true);
++      print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
++                           DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
++                           1);
++
++      ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
++      if (!ret) {
++              ret = -EINPROGRESS;
++      } else {
++              aead_unmap(jrdev, edesc, req);
++              kfree(edesc);
++      }
++
++      return ret;
++}
++
++static int chachapoly_decrypt(struct aead_request *req)
++{
++      struct aead_edesc *edesc;
++      struct crypto_aead *aead = crypto_aead_reqtfm(req);
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++      struct device *jrdev = ctx->jrdev;
++      bool all_contig;
++      u32 *desc;
++      int ret;
++
++      edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
++                               false);
++      if (IS_ERR(edesc))
++              return PTR_ERR(edesc);
++
++      desc = edesc->hw_desc;
++
++      init_chachapoly_job(req, edesc, all_contig, false);
++      print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
++                           DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
++                           1);
++
++      ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
++      if (!ret) {
++              ret = -EINPROGRESS;
++      } else {
++              aead_unmap(jrdev, edesc, req);
++              kfree(edesc);
++      }
++
++      return ret;
++}
++
+ static int ipsec_gcm_encrypt(struct aead_request *req)
+ {
+       if (req->assoclen < 8)
+@@ -1494,7 +1703,25 @@ static struct ablkcipher_edesc *ablkciph
+       sec4_sg_ents = 1 + mapped_src_nents;
+       dst_sg_idx = sec4_sg_ents;
+-      sec4_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
++
++      /*
++       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
++       * the end of the table by allocating more S/G entries. Logic:
++       * if (src != dst && output S/G)
++       *      pad output S/G, if needed
++       * else if (src == dst && S/G)
++       *      overlapping S/Gs; pad one of them
++       * else if (input S/G) ...
++       *      pad input S/G, if needed
++       */
++      if (mapped_dst_nents > 1)
++              sec4_sg_ents += ALIGN(mapped_dst_nents, 4);
++      else if ((req->src == req->dst) && (mapped_src_nents > 1))
++              sec4_sg_ents = max(ALIGN(sec4_sg_ents, 4),
++                                 1 + ALIGN(mapped_src_nents, 4));
++      else
++              sec4_sg_ents = ALIGN(sec4_sg_ents, 4);
++
+       sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
+       /*
+@@ -3196,6 +3423,50 @@ static struct caam_aead_alg driver_aeads
+                       .geniv = true,
+               },
+       },
++      {
++              .aead = {
++                      .base = {
++                              .cra_name = "rfc7539(chacha20,poly1305)",
++                              .cra_driver_name = "rfc7539-chacha20-poly1305-"
++                                                 "caam",
++                              .cra_blocksize = 1,
++                      },
++                      .setkey = chachapoly_setkey,
++                      .setauthsize = chachapoly_setauthsize,
++                      .encrypt = chachapoly_encrypt,
++                      .decrypt = chachapoly_decrypt,
++                      .ivsize = CHACHAPOLY_IV_SIZE,
++                      .maxauthsize = POLY1305_DIGEST_SIZE,
++              },
++              .caam = {
++                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
++                                         OP_ALG_AAI_AEAD,
++                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
++                                         OP_ALG_AAI_AEAD,
++              },
++      },
++      {
++              .aead = {
++                      .base = {
++                              .cra_name = "rfc7539esp(chacha20,poly1305)",
++                              .cra_driver_name = "rfc7539esp-chacha20-"
++                                                 "poly1305-caam",
++                              .cra_blocksize = 1,
++                      },
++                      .setkey = chachapoly_setkey,
++                      .setauthsize = chachapoly_setauthsize,
++                      .encrypt = chachapoly_encrypt,
++                      .decrypt = chachapoly_decrypt,
++                      .ivsize = 8,
++                      .maxauthsize = POLY1305_DIGEST_SIZE,
++              },
++              .caam = {
++                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
++                                         OP_ALG_AAI_AEAD,
++                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
++                                         OP_ALG_AAI_AEAD,
++              },
++      },
+ };
+ struct caam_crypto_alg {
+@@ -3204,9 +3475,11 @@ struct caam_crypto_alg {
        struct caam_alg_entry caam;
  };
  
@@ -1841,7 +2182,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        ctx->jrdev = caam_jr_alloc();
        if (IS_ERR(ctx->jrdev)) {
-@@ -3214,10 +3260,16 @@ static int caam_init_common(struct caam_
+@@ -3214,10 +3487,16 @@ static int caam_init_common(struct caam_
                return PTR_ERR(ctx->jrdev);
        }
  
@@ -1859,7 +2200,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (dma_mapping_error(ctx->jrdev, dma_addr)) {
                dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
                caam_jr_free(ctx->jrdev);
-@@ -3245,7 +3297,7 @@ static int caam_cra_init(struct crypto_t
+@@ -3245,7 +3524,7 @@ static int caam_cra_init(struct crypto_t
                 container_of(alg, struct caam_crypto_alg, crypto_alg);
        struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
  
@@ -1868,7 +2209,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  }
  
  static int caam_aead_init(struct crypto_aead *tfm)
-@@ -3255,14 +3307,15 @@ static int caam_aead_init(struct crypto_
+@@ -3255,14 +3534,15 @@ static int caam_aead_init(struct crypto_
                 container_of(alg, struct caam_aead_alg, aead);
        struct caam_ctx *ctx = crypto_aead_ctx(tfm);
  
@@ -1886,6 +2227,166 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        caam_jr_free(ctx->jrdev);
  }
  
+@@ -3276,7 +3556,7 @@ static void caam_aead_exit(struct crypto
+       caam_exit_common(crypto_aead_ctx(tfm));
+ }
+-static void __exit caam_algapi_exit(void)
++void caam_algapi_exit(void)
+ {
+       struct caam_crypto_alg *t_alg, *n;
+@@ -3355,56 +3635,52 @@ static void caam_aead_alg_init(struct ca
+       alg->exit = caam_aead_exit;
+ }
+-static int __init caam_algapi_init(void)
++int caam_algapi_init(struct device *ctrldev)
+ {
+-      struct device_node *dev_node;
+-      struct platform_device *pdev;
+-      struct device *ctrldev;
+-      struct caam_drv_private *priv;
++      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
+       int i = 0, err = 0;
+-      u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
++      u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
+       unsigned int md_limit = SHA512_DIGEST_SIZE;
+       bool registered = false;
+-      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+-      if (!dev_node) {
+-              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+-              if (!dev_node)
+-                      return -ENODEV;
+-      }
+-
+-      pdev = of_find_device_by_node(dev_node);
+-      if (!pdev) {
+-              of_node_put(dev_node);
+-              return -ENODEV;
+-      }
+-
+-      ctrldev = &pdev->dev;
+-      priv = dev_get_drvdata(ctrldev);
+-      of_node_put(dev_node);
+-
+-      /*
+-       * If priv is NULL, it's probably because the caam driver wasn't
+-       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+-       */
+-      if (!priv)
+-              return -ENODEV;
+-
+-
+       INIT_LIST_HEAD(&alg_list);
+       /*
+        * Register crypto algorithms the device supports.
+        * First, detect presence and attributes of DES, AES, and MD blocks.
+        */
+-      cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
+-      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+-      des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
+-      aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
+-      md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++      if (priv->era < 10) {
++              u32 cha_vid, cha_inst;
++
++              cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
++              aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
++              md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++
++              cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
++              des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
++                         CHA_ID_LS_DES_SHIFT;
++              aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
++              md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++              ccha_inst = 0;
++              ptha_inst = 0;
++      } else {
++              u32 aesa, mdha;
++
++              aesa = rd_reg32(&priv->ctrl->vreg.aesa);
++              mdha = rd_reg32(&priv->ctrl->vreg.mdha);
++
++              aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
++              md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
++
++              des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
++              aes_inst = aesa & CHA_VER_NUM_MASK;
++              md_inst = mdha & CHA_VER_NUM_MASK;
++              ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
++              ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
++      }
+       /* If MD is present, limit digest size based on LP256 */
+-      if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
++      if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
+               md_limit = SHA256_DIGEST_SIZE;
+       for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
+@@ -3426,10 +3702,10 @@ static int __init caam_algapi_init(void)
+                * Check support for AES modes not available
+                * on LP devices.
+                */
+-              if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
+-                      if ((alg->class1_alg_type & OP_ALG_AAI_MASK) ==
+-                           OP_ALG_AAI_XTS)
+-                              continue;
++              if (aes_vid == CHA_VER_VID_AES_LP &&
++                  (alg->class1_alg_type & OP_ALG_AAI_MASK) ==
++                  OP_ALG_AAI_XTS)
++                      continue;
+               t_alg = caam_alg_alloc(alg);
+               if (IS_ERR(t_alg)) {
+@@ -3468,21 +3744,28 @@ static int __init caam_algapi_init(void)
+               if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
+                               continue;
++              /* Skip CHACHA20 algorithms if not supported by device */
++              if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst)
++                      continue;
++
++              /* Skip POLY1305 algorithms if not supported by device */
++              if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
++                      continue;
++
+               /*
+                * Check support for AES algorithms not available
+                * on LP devices.
+                */
+-              if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
+-                      if (alg_aai == OP_ALG_AAI_GCM)
+-                              continue;
++              if (aes_vid  == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
++                      continue;
+               /*
+                * Skip algorithms requiring message digests
+                * if MD or MD size is not supported by device.
+                */
+-              if (c2_alg_sel &&
+-                  (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
+-                              continue;
++              if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 &&
++                  (!md_inst || t_alg->aead.maxauthsize > md_limit))
++                      continue;
+               caam_aead_alg_init(t_alg);
+@@ -3502,10 +3785,3 @@ static int __init caam_algapi_init(void)
+       return err;
+ }
+-
+-module_init(caam_algapi_init);
+-module_exit(caam_algapi_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("FSL CAAM support for crypto API");
+-MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
 --- a/drivers/crypto/caam/caamalg_desc.c
 +++ b/drivers/crypto/caam/caamalg_desc.c
 @@ -45,16 +45,16 @@ static inline void append_dec_op1(u32 *d
@@ -2881,6 +3382,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        /* assoclen + cryptlen = seqinlen */
        append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
  
+@@ -931,7 +1507,7 @@ void cnstr_shdsc_rfc4543_encap(u32 * con
+       read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
+                                   (0x6 << MOVE_LEN_SHIFT));
+       write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
+-                                   (0x8 << MOVE_LEN_SHIFT));
++                                   (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
+       /* Will read assoclen + cryptlen bytes */
+       append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 @@ -966,10 +1542,13 @@ EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap)
   * @desc: pointer to buffer used for descriptor construction
   * @cdata: pointer to block cipher transform definitions
@@ -2915,47 +3425,215 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        /* assoclen + cryptlen = seqoutlen */
        append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
  
-@@ -1075,7 +1666,7 @@ void cnstr_shdsc_ablkcipher_encap(u32 *
-       /* Load nonce into CONTEXT1 reg */
-       if (is_rfc3686) {
--              u8 *nonce = cdata->key_virt + cdata->keylen;
-+              const u8 *nonce = cdata->key_virt + cdata->keylen;
-               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
-                                  LDST_CLASS_IND_CCB |
-@@ -1140,7 +1731,7 @@ void cnstr_shdsc_ablkcipher_decap(u32 *
-       /* Load nonce into CONTEXT1 reg */
-       if (is_rfc3686) {
--              u8 *nonce = cdata->key_virt + cdata->keylen;
-+              const u8 *nonce = cdata->key_virt + cdata->keylen;
-               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
-                                  LDST_CLASS_IND_CCB |
-@@ -1209,7 +1800,7 @@ void cnstr_shdsc_ablkcipher_givencap(u32
-       /* Load Nonce into CONTEXT1 reg */
-       if (is_rfc3686) {
--              u8 *nonce = cdata->key_virt + cdata->keylen;
-+              const u8 *nonce = cdata->key_virt + cdata->keylen;
-               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
-                                  LDST_CLASS_IND_CCB |
---- a/drivers/crypto/caam/caamalg_desc.h
-+++ b/drivers/crypto/caam/caamalg_desc.h
-@@ -17,6 +17,9 @@
- #define DESC_QI_AEAD_DEC_LEN          (DESC_AEAD_DEC_LEN + 3 * CAAM_CMD_SZ)
- #define DESC_QI_AEAD_GIVENC_LEN               (DESC_AEAD_GIVENC_LEN + 3 * CAAM_CMD_SZ)
+@@ -1001,7 +1592,7 @@ void cnstr_shdsc_rfc4543_decap(u32 * con
+       read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
+                                   (0x6 << MOVE_LEN_SHIFT));
+       write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
+-                                   (0x8 << MOVE_LEN_SHIFT));
++                                   (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
  
-+#define DESC_TLS_BASE                 (4 * CAAM_CMD_SZ)
-+#define DESC_TLS10_ENC_LEN            (DESC_TLS_BASE + 29 * CAAM_CMD_SZ)
-+
- /* Note: Nonce is counted in cdata.keylen */
- #define DESC_AEAD_CTR_RFC3686_LEN     (4 * CAAM_CMD_SZ)
+       /* Will read assoclen + cryptlen bytes */
+       append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
+@@ -1035,6 +1626,138 @@ void cnstr_shdsc_rfc4543_decap(u32 * con
+ }
+ EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
  
-@@ -27,14 +30,20 @@
- #define DESC_GCM_BASE                 (3 * CAAM_CMD_SZ)
++/**
++ * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
++ *                          IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
++ *                          descriptor (non-protocol).
++ * @desc: pointer to buffer used for descriptor construction
++ * @cdata: pointer to block cipher transform definitions
++ *         Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
++ *         OP_ALG_AAI_AEAD.
++ * @adata: pointer to authentication transform definitions
++ *         Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
++ *         OP_ALG_AAI_AEAD.
++ * @ivsize: initialization vector size
++ * @icvsize: integrity check value (ICV) size (truncated or full)
++ * @encap: true if encapsulation, false if decapsulation
++ * @is_qi: true when called from caam/qi
++ */
++void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
++                          struct alginfo *adata, unsigned int ivsize,
++                          unsigned int icvsize, const bool encap,
++                          const bool is_qi)
++{
++      u32 *key_jump_cmd, *wait_cmd;
++      u32 nfifo;
++      const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
++
++      /* Note: Context registers are saved. */
++      init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
++
++      /* skip key loading if they are loaded due to sharing */
++      key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
++                                 JUMP_COND_SHRD);
++
++      append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
++                        CLASS_1 | KEY_DEST_CLASS_REG);
++
++      /* For IPsec load the salt from keymat in the context register */
++      if (is_ipsec)
++              append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
++                                 LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
++                                 4 << LDST_OFFSET_SHIFT);
++
++      set_jump_tgt_here(desc, key_jump_cmd);
++
++      /* Class 2 and 1 operations: Poly & ChaCha */
++      if (encap) {
++              append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
++                               OP_ALG_ENCRYPT);
++              append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
++                               OP_ALG_ENCRYPT);
++      } else {
++              append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
++                               OP_ALG_DECRYPT | OP_ALG_ICV_ON);
++              append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
++                               OP_ALG_DECRYPT);
++      }
++
++      if (is_qi) {
++              u32 *wait_load_cmd;
++              u32 ctx1_iv_off = is_ipsec ? 8 : 4;
++
++              /* REG3 = assoclen */
++              append_seq_load(desc, 4, LDST_CLASS_DECO |
++                              LDST_SRCDST_WORD_DECO_MATH3 |
++                              4 << LDST_OFFSET_SHIFT);
++
++              wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
++                                          JUMP_COND_CALM | JUMP_COND_NCP |
++                                          JUMP_COND_NOP | JUMP_COND_NIP |
++                                          JUMP_COND_NIFP);
++              set_jump_tgt_here(desc, wait_load_cmd);
++
++              append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
++                              LDST_SRCDST_BYTE_CONTEXT |
++                              ctx1_iv_off << LDST_OFFSET_SHIFT);
++      }
++
++      /*
++       * MAGIC with NFIFO
++       * Read associated data from the input and send them to class1 and
++       * class2 alignment blocks. From class1 send data to output fifo and
++       * then write it to memory since we don't need to encrypt AD.
++       */
++      nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
++              NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
++      append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
++                          LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
++
++      append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
++      append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
++      append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
++                           FIFOLD_CLASS_CLASS1 | LDST_VLF);
++      append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
++                      MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
++      append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
++
++      /* IPsec - copy IV at the output */
++      if (is_ipsec)
++              append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
++                                    0x2 << 25);
++
++      wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
++                             JUMP_COND_NOP | JUMP_TEST_ALL);
++      set_jump_tgt_here(desc, wait_cmd);
++
++      if (encap) {
++              /* Read and write cryptlen bytes */
++              append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
++              append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
++                              CAAM_CMD_SZ);
++              aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
++
++              /* Write ICV */
++              append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
++                               LDST_SRCDST_BYTE_CONTEXT);
++      } else {
++              /* Read and write cryptlen bytes */
++              append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
++              append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
++                              CAAM_CMD_SZ);
++              aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
++
++              /* Load ICV for verification */
++              append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
++                                   FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
++      }
++
++      print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
++                           DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
++                           1);
++}
++EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
++
+ /*
+  * For ablkcipher encrypt and decrypt, read from req->src and
+  * write to req->dst
+@@ -1053,7 +1776,8 @@ static inline void ablkcipher_append_src
+  * @desc: pointer to buffer used for descriptor construction
+  * @cdata: pointer to block cipher transform definitions
+  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
+- *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
++ *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
++ *                                - OP_ALG_ALGSEL_CHACHA20
+  * @ivsize: initialization vector size
+  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
+  * @ctx1_iv_off: IV offset in CONTEXT1 register
+@@ -1075,7 +1799,7 @@ void cnstr_shdsc_ablkcipher_encap(u32 *
+       /* Load nonce into CONTEXT1 reg */
+       if (is_rfc3686) {
+-              u8 *nonce = cdata->key_virt + cdata->keylen;
++              const u8 *nonce = cdata->key_virt + cdata->keylen;
+               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
+                                  LDST_CLASS_IND_CCB |
+@@ -1118,7 +1842,8 @@ EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_enc
+  * @desc: pointer to buffer used for descriptor construction
+  * @cdata: pointer to block cipher transform definitions
+  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
+- *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
++ *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
++ *                                - OP_ALG_ALGSEL_CHACHA20
+  * @ivsize: initialization vector size
+  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
+  * @ctx1_iv_off: IV offset in CONTEXT1 register
+@@ -1140,7 +1865,7 @@ void cnstr_shdsc_ablkcipher_decap(u32 *
+       /* Load nonce into CONTEXT1 reg */
+       if (is_rfc3686) {
+-              u8 *nonce = cdata->key_virt + cdata->keylen;
++              const u8 *nonce = cdata->key_virt + cdata->keylen;
+               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
+                                  LDST_CLASS_IND_CCB |
+@@ -1209,7 +1934,7 @@ void cnstr_shdsc_ablkcipher_givencap(u32
+       /* Load Nonce into CONTEXT1 reg */
+       if (is_rfc3686) {
+-              u8 *nonce = cdata->key_virt + cdata->keylen;
++              const u8 *nonce = cdata->key_virt + cdata->keylen;
+               append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
+                                  LDST_CLASS_IND_CCB |
+--- a/drivers/crypto/caam/caamalg_desc.h
++++ b/drivers/crypto/caam/caamalg_desc.h
+@@ -17,6 +17,9 @@
+ #define DESC_QI_AEAD_DEC_LEN          (DESC_AEAD_DEC_LEN + 3 * CAAM_CMD_SZ)
+ #define DESC_QI_AEAD_GIVENC_LEN               (DESC_AEAD_GIVENC_LEN + 3 * CAAM_CMD_SZ)
++#define DESC_TLS_BASE                 (4 * CAAM_CMD_SZ)
++#define DESC_TLS10_ENC_LEN            (DESC_TLS_BASE + 29 * CAAM_CMD_SZ)
++
+ /* Note: Nonce is counted in cdata.keylen */
+ #define DESC_AEAD_CTR_RFC3686_LEN     (4 * CAAM_CMD_SZ)
+@@ -27,14 +30,20 @@
+ #define DESC_GCM_BASE                 (3 * CAAM_CMD_SZ)
  #define DESC_GCM_ENC_LEN              (DESC_GCM_BASE + 16 * CAAM_CMD_SZ)
  #define DESC_GCM_DEC_LEN              (DESC_GCM_BASE + 12 * CAAM_CMD_SZ)
 +#define DESC_QI_GCM_ENC_LEN           (DESC_GCM_ENC_LEN + 6 * CAAM_CMD_SZ)
@@ -2975,7 +3653,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  #define DESC_ABLKCIPHER_BASE          (3 * CAAM_CMD_SZ)
  #define DESC_ABLKCIPHER_ENC_LEN               (DESC_ABLKCIPHER_BASE + \
-@@ -43,46 +52,62 @@
+@@ -43,46 +52,67 @@
                                         15 * CAAM_CMD_SZ)
  
  void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
@@ -3046,6 +3724,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 -                             unsigned int icvsize);
 +                             unsigned int ivsize, unsigned int icvsize,
 +                             const bool is_qi);
++
++void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
++                          struct alginfo *adata, unsigned int ivsize,
++                          unsigned int icvsize, const bool encap,
++                          const bool is_qi);
  
  void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata,
                                  unsigned int ivsize, const bool is_rfc3686,
@@ -3131,7 +3814,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              memcpy(ctx->key, keys.authkey, keys.authkeylen);
 +              memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
 +                     keys.enckeylen);
-+              dma_sync_single_for_device(jrdev, ctx->key_dma,
++              dma_sync_single_for_device(jrdev->parent, ctx->key_dma,
 +                                         ctx->adata.keylen_pad +
 +                                         keys.enckeylen, ctx->dir);
 +              goto skip_split_key;
@@ -3695,7 +4378,34 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        }
  
        edesc = container_of(drv_req, typeof(*edesc), drv_req);
-@@ -785,6 +1319,260 @@ static int aead_decrypt(struct aead_requ
+@@ -647,9 +1181,24 @@ static struct aead_edesc *aead_edesc_all
+       /*
+        * Create S/G table: req->assoclen, [IV,] req->src [, req->dst].
+        * Input is not contiguous.
++       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
++       * the end of the table by allocating more S/G entries. Logic:
++       * if (src != dst && output S/G)
++       *      pad output S/G, if needed
++       * else if (src == dst && S/G)
++       *      overlapping S/Gs; pad one of them
++       * else if (input S/G) ...
++       *      pad input S/G, if needed
+        */
+-      qm_sg_ents = 1 + !!ivsize + mapped_src_nents +
+-                   (mapped_dst_nents > 1 ? mapped_dst_nents : 0);
++      qm_sg_ents = 1 + !!ivsize + mapped_src_nents;
++      if (mapped_dst_nents > 1)
++              qm_sg_ents += ALIGN(mapped_dst_nents, 4);
++      else if ((req->src == req->dst) && (mapped_src_nents > 1))
++              qm_sg_ents = max(ALIGN(qm_sg_ents, 4),
++                               1 + !!ivsize + ALIGN(mapped_src_nents, 4));
++      else
++              qm_sg_ents = ALIGN(qm_sg_ents, 4);
++
+       sg_table = &edesc->sgt[0];
+       qm_sg_bytes = qm_sg_ents * sizeof(*sg_table);
+       if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize >
+@@ -785,6 +1334,260 @@ static int aead_decrypt(struct aead_requ
        return aead_crypt(req, false);
  }
  
@@ -3956,7 +4666,33 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  static void ablkcipher_done(struct caam_drv_req *drv_req, u32 status)
  {
        struct ablkcipher_edesc *edesc;
-@@ -1308,6 +2096,61 @@ static struct caam_alg_template driver_a
+@@ -900,7 +1703,24 @@ static struct ablkcipher_edesc *ablkciph
+       qm_sg_ents = 1 + mapped_src_nents;
+       dst_sg_idx = qm_sg_ents;
+-      qm_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
++      /*
++       * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
++       * the end of the table by allocating more S/G entries. Logic:
++       * if (src != dst && output S/G)
++       *      pad output S/G, if needed
++       * else if (src == dst && S/G)
++       *      overlapping S/Gs; pad one of them
++       * else if (input S/G) ...
++       *      pad input S/G, if needed
++       */
++      if (mapped_dst_nents > 1)
++              qm_sg_ents += ALIGN(mapped_dst_nents, 4);
++      else if ((req->src == req->dst) && (mapped_src_nents > 1))
++              qm_sg_ents = max(ALIGN(qm_sg_ents, 4),
++                               1 + ALIGN(mapped_src_nents, 4));
++      else
++              qm_sg_ents = ALIGN(qm_sg_ents, 4);
++
+       qm_sg_bytes = qm_sg_ents * sizeof(struct qm_sg_entry);
+       if (unlikely(offsetof(struct ablkcipher_edesc, sgt) + qm_sg_bytes +
+                    ivsize > CAAM_QI_MEMCACHE_SIZE)) {
+@@ -1308,6 +2128,61 @@ static struct caam_alg_template driver_a
  };
  
  static struct caam_aead_alg driver_aeads[] = {
@@ -4018,7 +4754,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        /* single-pass ipsec_esp descriptor */
        {
                .aead = {
-@@ -2118,6 +2961,26 @@ static struct caam_aead_alg driver_aeads
+@@ -2118,6 +2993,26 @@ static struct caam_aead_alg driver_aeads
                        .geniv = true,
                }
        },
@@ -4045,7 +4781,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  };
  
  struct caam_crypto_alg {
-@@ -2126,9 +2989,20 @@ struct caam_crypto_alg {
+@@ -2126,9 +3021,21 @@ struct caam_crypto_alg {
        struct caam_alg_entry caam;
  };
  
@@ -4054,6 +4790,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                         bool uses_dkp)
  {
        struct caam_drv_private *priv;
++      struct device *dev;
 +      /* Digest sizes for MD5, SHA1, SHA-224, SHA-256, SHA-384, SHA-512 */
 +      static const u8 digest_size[] = {
 +              MD5_DIGEST_SIZE,
@@ -4067,27 +4804,36 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        /*
         * distribute tfms across job rings to ensure in-order
-@@ -2140,8 +3014,14 @@ static int caam_init_common(struct caam_
+@@ -2140,10 +3047,19 @@ static int caam_init_common(struct caam_
                return PTR_ERR(ctx->jrdev);
        }
  
+-      ctx->key_dma = dma_map_single(ctx->jrdev, ctx->key, sizeof(ctx->key),
+-                                    DMA_TO_DEVICE);
+-      if (dma_mapping_error(ctx->jrdev, ctx->key_dma)) {
+-              dev_err(ctx->jrdev, "unable to map key\n");
 +      priv = dev_get_drvdata(ctx->jrdev->parent);
-+      if (priv->era >= 6 && uses_dkp)
++      if (priv->era >= 6 && uses_dkp) {
 +              ctx->dir = DMA_BIDIRECTIONAL;
-+      else
++              dev = ctx->jrdev->parent;
++      } else {
 +              ctx->dir = DMA_TO_DEVICE;
++              dev = ctx->jrdev;
++      }
 +
-       ctx->key_dma = dma_map_single(ctx->jrdev, ctx->key, sizeof(ctx->key),
--                                    DMA_TO_DEVICE);
++      ctx->key_dma = dma_map_single(dev, ctx->key, sizeof(ctx->key),
 +                                    ctx->dir);
-       if (dma_mapping_error(ctx->jrdev, ctx->key_dma)) {
-               dev_err(ctx->jrdev, "unable to map key\n");
++      if (dma_mapping_error(dev, ctx->key_dma)) {
++              dev_err(dev, "unable to map key\n");
                caam_jr_free(ctx->jrdev);
-@@ -2152,7 +3032,22 @@ static int caam_init_common(struct caam_
+               return -ENOMEM;
+       }
+@@ -2152,8 +3068,23 @@ static int caam_init_common(struct caam_
        ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
        ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
  
 -      priv = dev_get_drvdata(ctx->jrdev->parent);
+-      ctx->qidev = priv->qidev;
 +      if (ctx->adata.algtype) {
 +              op_id = (ctx->adata.algtype & OP_ALG_ALGSEL_SUBMASK)
 +                              >> OP_ALG_ALGSEL_SHIFT;
@@ -4104,10 +4850,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              ctx->authsize = 0;
 +      }
 +
-       ctx->qidev = priv->qidev;
++      ctx->qidev = ctx->jrdev->parent;
  
        spin_lock_init(&ctx->lock);
-@@ -2170,7 +3065,7 @@ static int caam_cra_init(struct crypto_t
+       ctx->drv_ctx[ENCRYPT] = NULL;
+@@ -2170,7 +3101,7 @@ static int caam_cra_init(struct crypto_t
                                                        crypto_alg);
        struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
  
@@ -4116,7 +4863,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  }
  
  static int caam_aead_init(struct crypto_aead *tfm)
-@@ -2180,7 +3075,9 @@ static int caam_aead_init(struct crypto_
+@@ -2180,17 +3111,25 @@ static int caam_aead_init(struct crypto_
                                                      aead);
        struct caam_ctx *ctx = crypto_aead_ctx(tfm);
  
@@ -4127,31 +4874,162 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  }
  
  static void caam_exit_common(struct caam_ctx *ctx)
-@@ -2189,8 +3086,7 @@ static void caam_exit_common(struct caam
+ {
++      struct device *dev;
++
+       caam_drv_ctx_rel(ctx->drv_ctx[ENCRYPT]);
        caam_drv_ctx_rel(ctx->drv_ctx[DECRYPT]);
        caam_drv_ctx_rel(ctx->drv_ctx[GIVENCRYPT]);
  
 -      dma_unmap_single(ctx->jrdev, ctx->key_dma, sizeof(ctx->key),
 -                       DMA_TO_DEVICE);
-+      dma_unmap_single(ctx->jrdev, ctx->key_dma, sizeof(ctx->key), ctx->dir);
++      if (ctx->dir == DMA_BIDIRECTIONAL)
++              dev = ctx->jrdev->parent;
++      else
++              dev = ctx->jrdev;
++
++      dma_unmap_single(dev, ctx->key_dma, sizeof(ctx->key), ctx->dir);
  
        caam_jr_free(ctx->jrdev);
  }
-@@ -2315,6 +3211,11 @@ static int __init caam_qi_algapi_init(vo
-       if (!priv || !priv->qi_present)
-               return -ENODEV;
+@@ -2206,7 +3145,7 @@ static void caam_aead_exit(struct crypto
+ }
  
-+      if (caam_dpaa2) {
-+              dev_info(ctrldev, "caam/qi frontend driver not suitable for DPAA 2.x, aborting...\n");
-+              return -ENODEV;
-+      }
-+
+ static struct list_head alg_list;
+-static void __exit caam_qi_algapi_exit(void)
++void caam_qi_algapi_exit(void)
+ {
+       struct caam_crypto_alg *t_alg, *n;
+       int i;
+@@ -2282,53 +3221,48 @@ static void caam_aead_alg_init(struct ca
+       alg->exit = caam_aead_exit;
+ }
+-static int __init caam_qi_algapi_init(void)
++int caam_qi_algapi_init(struct device *ctrldev)
+ {
+-      struct device_node *dev_node;
+-      struct platform_device *pdev;
+-      struct device *ctrldev;
+-      struct caam_drv_private *priv;
++      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
+       int i = 0, err = 0;
+-      u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
++      u32 aes_vid, aes_inst, des_inst, md_vid, md_inst;
+       unsigned int md_limit = SHA512_DIGEST_SIZE;
+       bool registered = false;
+-      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+-      if (!dev_node) {
+-              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+-              if (!dev_node)
+-                      return -ENODEV;
+-      }
+-
+-      pdev = of_find_device_by_node(dev_node);
+-      of_node_put(dev_node);
+-      if (!pdev)
+-              return -ENODEV;
+-
+-      ctrldev = &pdev->dev;
+-      priv = dev_get_drvdata(ctrldev);
+-
+-      /*
+-       * If priv is NULL, it's probably because the caam driver wasn't
+-       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+-       */
+-      if (!priv || !priv->qi_present)
+-              return -ENODEV;
+-
        INIT_LIST_HEAD(&alg_list);
  
        /*
+        * Register crypto algorithms the device supports.
+        * First, detect presence and attributes of DES, AES, and MD blocks.
+        */
+-      cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
+-      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+-      des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
+-      aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
+-      md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++      if (priv->era < 10) {
++              u32 cha_vid, cha_inst;
++
++              cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
++              aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
++              md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++
++              cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
++              des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
++                         CHA_ID_LS_DES_SHIFT;
++              aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
++              md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++      } else {
++              u32 aesa, mdha;
++
++              aesa = rd_reg32(&priv->ctrl->vreg.aesa);
++              mdha = rd_reg32(&priv->ctrl->vreg.mdha);
++
++              aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
++              md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
++
++              des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
++              aes_inst = aesa & CHA_VER_NUM_MASK;
++              md_inst = mdha & CHA_VER_NUM_MASK;
++      }
+       /* If MD is present, limit digest size based on LP256 */
+-      if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
++      if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
+               md_limit = SHA256_DIGEST_SIZE;
+       for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
+@@ -2349,14 +3283,14 @@ static int __init caam_qi_algapi_init(vo
+               t_alg = caam_alg_alloc(alg);
+               if (IS_ERR(t_alg)) {
+                       err = PTR_ERR(t_alg);
+-                      dev_warn(priv->qidev, "%s alg allocation failed\n",
++                      dev_warn(ctrldev, "%s alg allocation failed\n",
+                                alg->driver_name);
+                       continue;
+               }
+               err = crypto_register_alg(&t_alg->crypto_alg);
+               if (err) {
+-                      dev_warn(priv->qidev, "%s alg registration failed\n",
++                      dev_warn(ctrldev, "%s alg registration failed\n",
+                                t_alg->crypto_alg.cra_driver_name);
+                       kfree(t_alg);
+                       continue;
+@@ -2388,8 +3322,7 @@ static int __init caam_qi_algapi_init(vo
+                * Check support for AES algorithms not available
+                * on LP devices.
+                */
+-              if (((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP) &&
+-                  (alg_aai == OP_ALG_AAI_GCM))
++              if (aes_vid  == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
+                       continue;
+               /*
+@@ -2414,14 +3347,7 @@ static int __init caam_qi_algapi_init(vo
+       }
+       if (registered)
+-              dev_info(priv->qidev, "algorithms registered in /proc/crypto\n");
++              dev_info(ctrldev, "algorithms registered in /proc/crypto\n");
+       return err;
+ }
+-
+-module_init(caam_qi_algapi_init);
+-module_exit(caam_qi_algapi_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("Support for crypto API using CAAM-QI backend");
+-MODULE_AUTHOR("Freescale Semiconductor");
 --- /dev/null
 +++ b/drivers/crypto/caam/caamalg_qi2.c
-@@ -0,0 +1,5691 @@
+@@ -0,0 +1,5843 @@
 +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
 +/*
 + * Copyright 2015-2016 Freescale Semiconductor Inc.
@@ -4179,13 +5057,6 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#define CAAM_MAX_KEY_SIZE     (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE + \
 +                               SHA512_DIGEST_SIZE * 2)
 +
-+#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM
-+bool caam_little_end;
-+EXPORT_SYMBOL(caam_little_end);
-+bool caam_imx;
-+EXPORT_SYMBOL(caam_imx);
-+#endif
-+
 +/*
 + * This is a a cache of buffers, from which the users of CAAM QI driver
 + * can allocate short buffers. It's speedier than doing kmalloc on the hotpath.
@@ -4639,7 +5510,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      edesc->dst_nents = dst_nents;
 +      edesc->iv_dma = iv_dma;
 +
-+      edesc->assoclen = cpu_to_caam32(req->assoclen);
++      if ((alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK) ==
++          OP_ALG_ALGSEL_CHACHA20 && ivsize != CHACHAPOLY_IV_SIZE)
++              /*
++               * The associated data comes already with the IV but we need
++               * to skip it when we authenticate or encrypt...
++               */
++              edesc->assoclen = cpu_to_caam32(req->assoclen - ivsize);
++      else
++              edesc->assoclen = cpu_to_caam32(req->assoclen);
 +      edesc->assoclen_dma = dma_map_single(dev, &edesc->assoclen, 4,
 +                                           DMA_TO_DEVICE);
 +      if (dma_mapping_error(dev, edesc->assoclen_dma)) {
@@ -4709,6 +5588,68 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      return edesc;
 +}
 +
++static int chachapoly_set_sh_desc(struct crypto_aead *aead)
++{
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++      unsigned int ivsize = crypto_aead_ivsize(aead);
++      struct device *dev = ctx->dev;
++      struct caam_flc *flc;
++      u32 *desc;
++
++      if (!ctx->cdata.keylen || !ctx->authsize)
++              return 0;
++
++      flc = &ctx->flc[ENCRYPT];
++      desc = flc->sh_desc;
++      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
++                             ctx->authsize, true, true);
++      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
++      dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT],
++                                 sizeof(flc->flc) + desc_bytes(desc),
++                                 ctx->dir);
++
++      flc = &ctx->flc[DECRYPT];
++      desc = flc->sh_desc;
++      cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
++                             ctx->authsize, false, true);
++      flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */
++      dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT],
++                                 sizeof(flc->flc) + desc_bytes(desc),
++                                 ctx->dir);
++
++      return 0;
++}
++
++static int chachapoly_setauthsize(struct crypto_aead *aead,
++                                unsigned int authsize)
++{
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++
++      if (authsize != POLY1305_DIGEST_SIZE)
++              return -EINVAL;
++
++      ctx->authsize = authsize;
++      return chachapoly_set_sh_desc(aead);
++}
++
++static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
++                           unsigned int keylen)
++{
++      struct caam_ctx *ctx = crypto_aead_ctx(aead);
++      unsigned int ivsize = crypto_aead_ivsize(aead);
++      unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
++
++      if (keylen != CHACHA20_KEY_SIZE + saltlen) {
++              crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
++              return -EINVAL;
++      }
++
++      ctx->cdata.key_virt = key;
++      ctx->cdata.keylen = keylen - saltlen;
++
++      return chachapoly_set_sh_desc(aead);
++}
++
 +static struct tls_edesc *tls_edesc_alloc(struct aead_request *req,
 +                                       bool encrypt)
 +{
@@ -5303,7 +6244,9 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      u32 *desc;
 +      u32 ctx1_iv_off = 0;
 +      const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
-+                             OP_ALG_AAI_CTR_MOD128);
++                             OP_ALG_AAI_CTR_MOD128) &&
++                             ((ctx->cdata.algtype & OP_ALG_ALGSEL_MASK) !=
++                             OP_ALG_ALGSEL_CHACHA20);
 +      const bool is_rfc3686 = alg->caam.rfc3686;
 +
 +#ifdef DEBUG
@@ -6119,7 +7062,23 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                      .ivsize = AES_BLOCK_SIZE,
 +              },
 +              .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
-+      }
++      },
++      {
++              .skcipher = {
++                      .base = {
++                              .cra_name = "chacha20",
++                              .cra_driver_name = "chacha20-caam-qi2",
++                              .cra_blocksize = 1,
++                      },
++                      .setkey = skcipher_setkey,
++                      .encrypt = skcipher_encrypt,
++                      .decrypt = skcipher_decrypt,
++                      .min_keysize = CHACHA20_KEY_SIZE,
++                      .max_keysize = CHACHA20_KEY_SIZE,
++                      .ivsize = CHACHA20_IV_SIZE,
++              },
++              .caam.class1_alg_type = OP_ALG_ALGSEL_CHACHA20,
++      },
 +};
 +
 +static struct caam_aead_alg driver_aeads[] = {
@@ -7236,6 +8195,50 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      {
 +              .aead = {
 +                      .base = {
++                              .cra_name = "rfc7539(chacha20,poly1305)",
++                              .cra_driver_name = "rfc7539-chacha20-poly1305-"
++                                                 "caam-qi2",
++                              .cra_blocksize = 1,
++                      },
++                      .setkey = chachapoly_setkey,
++                      .setauthsize = chachapoly_setauthsize,
++                      .encrypt = aead_encrypt,
++                      .decrypt = aead_decrypt,
++                      .ivsize = CHACHAPOLY_IV_SIZE,
++                      .maxauthsize = POLY1305_DIGEST_SIZE,
++              },
++              .caam = {
++                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
++                                         OP_ALG_AAI_AEAD,
++                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
++                                         OP_ALG_AAI_AEAD,
++              },
++      },
++      {
++              .aead = {
++                      .base = {
++                              .cra_name = "rfc7539esp(chacha20,poly1305)",
++                              .cra_driver_name = "rfc7539esp-chacha20-"
++                                                 "poly1305-caam-qi2",
++                              .cra_blocksize = 1,
++                      },
++                      .setkey = chachapoly_setkey,
++                      .setauthsize = chachapoly_setauthsize,
++                      .encrypt = aead_encrypt,
++                      .decrypt = aead_decrypt,
++                      .ivsize = 8,
++                      .maxauthsize = POLY1305_DIGEST_SIZE,
++              },
++              .caam = {
++                      .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
++                                         OP_ALG_AAI_AEAD,
++                      .class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
++                                         OP_ALG_AAI_AEAD,
++              },
++      },
++      {
++              .aead = {
++                      .base = {
 +                              .cra_name = "authenc(hmac(sha512),"
 +                                          "rfc3686(ctr(aes)))",
 +                              .cra_driver_name = "authenc-hmac-sha512-"
@@ -9040,7 +10043,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              nctx->cb = dpaa2_caam_fqdan_cb;
 +
 +              /* Register notification callbacks */
-+              err = dpaa2_io_service_register(NULL, nctx);
++              ppriv->dpio = dpaa2_io_service_select(cpu);
++              err = dpaa2_io_service_register(ppriv->dpio, nctx, dev);
 +              if (unlikely(err)) {
 +                      dev_dbg(dev, "No affine DPIO for cpu %d\n", cpu);
 +                      nctx->cb = NULL;
@@ -9058,6 +10062,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                                                   dev);
 +              if (unlikely(!ppriv->store)) {
 +                      dev_err(dev, "dpaa2_io_store_create() failed\n");
++                      err = -ENOMEM;
 +                      goto err;
 +              }
 +
@@ -9072,7 +10077,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              ppriv = per_cpu_ptr(priv->ppriv, cpu);
 +              if (!ppriv->nctx.cb)
 +                      break;
-+              dpaa2_io_service_deregister(NULL, &ppriv->nctx);
++              dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev);
 +      }
 +
 +      for_each_online_cpu(cpu) {
@@ -9088,11 +10093,12 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +static void __cold dpaa2_dpseci_dpio_free(struct dpaa2_caam_priv *priv)
 +{
 +      struct dpaa2_caam_priv_per_cpu *ppriv;
++      struct device *dev = priv->dev;
 +      int i = 0, cpu;
 +
 +      for_each_online_cpu(cpu) {
 +              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+              dpaa2_io_service_deregister(NULL, &ppriv->nctx);
++              dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev);
 +              dpaa2_io_store_destroy(ppriv->store);
 +
 +              if (++i == priv->num_pairs)
@@ -9190,7 +10196,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +
 +      /* Retry while portal is busy */
 +      do {
-+              err = dpaa2_io_service_pull_fq(NULL, ppriv->rsp_fqid,
++              err = dpaa2_io_service_pull_fq(ppriv->dpio, ppriv->rsp_fqid,
 +                                             ppriv->store);
 +      } while (err == -EBUSY);
 +
@@ -9258,7 +10264,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +
 +      if (cleaned < budget) {
 +              napi_complete_done(napi, cleaned);
-+              err = dpaa2_io_service_rearm(NULL, &ppriv->nctx);
++              err = dpaa2_io_service_rearm(ppriv->dpio, &ppriv->nctx);
 +              if (unlikely(err))
 +                      dev_err(priv->dev, "Notification rearm failed: %d\n",
 +                              err);
@@ -9399,21 +10405,31 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +
 +      i = 0;
 +      for_each_online_cpu(cpu) {
-+              dev_info(dev, "pair %d: rx queue %d, tx queue %d\n", i,
-+                       priv->rx_queue_attr[i].fqid,
-+                       priv->tx_queue_attr[i].fqid);
++              u8 j;
++
++              j = i % priv->num_pairs;
 +
 +              ppriv = per_cpu_ptr(priv->ppriv, cpu);
-+              ppriv->req_fqid = priv->tx_queue_attr[i].fqid;
-+              ppriv->rsp_fqid = priv->rx_queue_attr[i].fqid;
-+              ppriv->prio = i;
++              ppriv->req_fqid = priv->tx_queue_attr[j].fqid;
 +
-+              ppriv->net_dev.dev = *dev;
-+              INIT_LIST_HEAD(&ppriv->net_dev.napi_list);
-+              netif_napi_add(&ppriv->net_dev, &ppriv->napi, dpaa2_dpseci_poll,
++              /*
++               * Allow all cores to enqueue, while only some of them
++               * will take part in dequeuing.
++               */
++              if (++i > priv->num_pairs)
++                      continue;
++
++              ppriv->rsp_fqid = priv->rx_queue_attr[j].fqid;
++              ppriv->prio = j;
++
++              dev_info(dev, "pair %d: rx queue %d, tx queue %d\n", j,
++                       priv->rx_queue_attr[j].fqid,
++                       priv->tx_queue_attr[j].fqid);
++
++              ppriv->net_dev.dev = *dev;
++              INIT_LIST_HEAD(&ppriv->net_dev.napi_list);
++              netif_napi_add(&ppriv->net_dev, &ppriv->napi, dpaa2_dpseci_poll,
 +                             DPAA2_CAAM_NAPI_WEIGHT);
-+              if (++i == priv->num_pairs)
-+                      break;
 +      }
 +
 +      return 0;
@@ -9538,12 +10554,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      priv->ppriv = alloc_percpu(*priv->ppriv);
 +      if (!priv->ppriv) {
 +              dev_err(dev, "alloc_percpu() failed\n");
++              err = -ENOMEM;
 +              goto err_alloc_ppriv;
 +      }
 +
 +      /* DPSECI initialization */
 +      err = dpaa2_dpseci_setup(dpseci_dev);
-+      if (err < 0) {
++      if (err) {
 +              dev_err(dev, "dpaa2_dpseci_setup() failed\n");
 +              goto err_dpseci_setup;
 +      }
@@ -9551,7 +10568,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      /* DPIO */
 +      err = dpaa2_dpseci_dpio_setup(priv);
 +      if (err) {
-+              dev_err(dev, "dpaa2_dpseci_dpio_setup() failed\n");
++              if (err != -EPROBE_DEFER)
++                      dev_err(dev, "dpaa2_dpseci_dpio_setup() failed\n");
 +              goto err_dpio_setup;
 +      }
 +
@@ -9585,6 +10603,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                  (alg_sel == OP_ALG_ALGSEL_AES))
 +                      continue;
 +
++              /* Skip CHACHA20 algorithms if not supported by device */
++              if (alg_sel == OP_ALG_ALGSEL_CHACHA20 &&
++                  !priv->sec_attr.ccha_acc_num)
++                      continue;
++
 +              t_alg->caam.dev = dev;
 +              caam_skcipher_alg_init(t_alg);
 +
@@ -9617,11 +10640,22 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                  (c1_alg_sel == OP_ALG_ALGSEL_AES))
 +                      continue;
 +
++              /* Skip CHACHA20 algorithms if not supported by device */
++              if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 &&
++                  !priv->sec_attr.ccha_acc_num)
++                      continue;
++
++              /* Skip POLY1305 algorithms if not supported by device */
++              if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 &&
++                  !priv->sec_attr.ptha_acc_num)
++                      continue;
++
 +              /*
 +               * Skip algorithms requiring message digests
 +               * if MD not supported by device.
 +               */
-+              if (!priv->sec_attr.md_acc_num && c2_alg_sel)
++              if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 &&
++                  !priv->sec_attr.md_acc_num)
 +                      continue;
 +
 +              t_alg->caam.dev = dev;
@@ -9761,7 +10795,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +{
 +      struct dpaa2_fd fd;
 +      struct dpaa2_caam_priv *priv = dev_get_drvdata(dev);
-+      int err = 0, i, id;
++      struct dpaa2_caam_priv_per_cpu *ppriv;
++      int err = 0, i;
 +
 +      if (IS_ERR(req))
 +              return PTR_ERR(req);
@@ -9791,23 +10826,18 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1]));
 +      dpaa2_fd_set_flc(&fd, req->flc_dma);
 +
-+      /*
-+       * There is no guarantee that preemption is disabled here,
-+       * thus take action.
-+       */
-+      preempt_disable();
-+      id = smp_processor_id() % priv->dpseci_attr.num_tx_queues;
++      ppriv = this_cpu_ptr(priv->ppriv);
 +      for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) {
-+              err = dpaa2_io_service_enqueue_fq(NULL,
-+                                                priv->tx_queue_attr[id].fqid,
++              err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid,
 +                                                &fd);
 +              if (err != -EBUSY)
 +                      break;
++
++              cpu_relax();
 +      }
-+      preempt_enable();
 +
-+      if (unlikely(err < 0)) {
-+              dev_err(dev, "Error enqueuing frame: %d\n", err);
++      if (unlikely(err)) {
++              dev_err_ratelimited(dev, "Error enqueuing frame: %d\n", err);
 +              goto err_out;
 +      }
 +
@@ -9845,7 +10875,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +module_fsl_mc_driver(dpaa2_caam_driver);
 --- /dev/null
 +++ b/drivers/crypto/caam/caamalg_qi2.h
-@@ -0,0 +1,274 @@
+@@ -0,0 +1,276 @@
 +/*
 + * Copyright 2015-2016 Freescale Semiconductor Inc.
 + * Copyright 2017 NXP
@@ -9953,6 +10983,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 + * @nctx: notification context of response FQ
 + * @store: where dequeued frames are stored
 + * @priv: backpointer to dpaa2_caam_priv
++ * @dpio: portal used for data path operations
 + */
 +struct dpaa2_caam_priv_per_cpu {
 +      struct napi_struct napi;
@@ -9963,6 +10994,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      struct dpaa2_io_notification_ctx nctx;
 +      struct dpaa2_io_store *store;
 +      struct dpaa2_caam_priv *priv;
++      struct dpaa2_io *dpio;
 +};
 +
 +/*
@@ -10122,7 +11154,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#endif        /* _CAAMALG_QI2_H_ */
 --- a/drivers/crypto/caam/caamhash.c
 +++ b/drivers/crypto/caam/caamhash.c
-@@ -62,6 +62,7 @@
+@@ -2,6 +2,7 @@
+  * caam - Freescale FSL CAAM support for ahash functions of crypto API
+  *
+  * Copyright 2011 Freescale Semiconductor, Inc.
++ * Copyright 2018 NXP
+  *
+  * Based on caamalg.c crypto API driver.
+  *
+@@ -62,6 +63,7 @@
  #include "error.h"
  #include "sg_sw_sec4.h"
  #include "key_gen.h"
@@ -10130,7 +11170,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  #define CAAM_CRA_PRIORITY             3000
  
-@@ -71,14 +72,6 @@
+@@ -71,14 +73,6 @@
  #define CAAM_MAX_HASH_BLOCK_SIZE      SHA512_BLOCK_SIZE
  #define CAAM_MAX_HASH_DIGEST_SIZE     SHA512_DIGEST_SIZE
  
@@ -10145,7 +11185,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #define DESC_HASH_MAX_USED_BYTES      (DESC_AHASH_FINAL_LEN + \
                                         CAAM_MAX_HASH_KEY_SIZE)
  #define DESC_HASH_MAX_USED_LEN                (DESC_HASH_MAX_USED_BYTES / CAAM_CMD_SZ)
-@@ -107,6 +100,7 @@ struct caam_hash_ctx {
+@@ -107,6 +101,7 @@ struct caam_hash_ctx {
        dma_addr_t sh_desc_update_first_dma;
        dma_addr_t sh_desc_fin_dma;
        dma_addr_t sh_desc_digest_dma;
@@ -10153,7 +11193,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        struct device *jrdev;
        u8 key[CAAM_MAX_HASH_KEY_SIZE];
        int ctx_len;
-@@ -218,7 +212,7 @@ static inline int buf_map_to_sec4_sg(str
+@@ -218,7 +213,7 @@ static inline int buf_map_to_sec4_sg(str
  }
  
  /* Map state->caam_ctx, and add it to link table */
@@ -10162,7 +11202,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                                     struct caam_hash_state *state, int ctx_len,
                                     struct sec4_sg_entry *sec4_sg, u32 flag)
  {
-@@ -234,68 +228,22 @@ static inline int ctx_map_to_sec4_sg(u32
+@@ -234,68 +229,22 @@ static inline int ctx_map_to_sec4_sg(u32
        return 0;
  }
  
@@ -10237,7 +11277,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #ifdef DEBUG
        print_hex_dump(KERN_ERR,
                       "ahash update shdesc@"__stringify(__LINE__)": ",
-@@ -304,9 +252,10 @@ static int ahash_set_sh_desc(struct cryp
+@@ -304,9 +253,10 @@ static int ahash_set_sh_desc(struct cryp
  
        /* ahash_update_first shared descriptor */
        desc = ctx->sh_desc_update_first;
@@ -10250,7 +11290,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #ifdef DEBUG
        print_hex_dump(KERN_ERR,
                       "ahash update first shdesc@"__stringify(__LINE__)": ",
-@@ -315,9 +264,10 @@ static int ahash_set_sh_desc(struct cryp
+@@ -315,9 +265,10 @@ static int ahash_set_sh_desc(struct cryp
  
        /* ahash_final shared descriptor */
        desc = ctx->sh_desc_fin;
@@ -10263,7 +11303,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #ifdef DEBUG
        print_hex_dump(KERN_ERR, "ahash final shdesc@"__stringify(__LINE__)": ",
                       DUMP_PREFIX_ADDRESS, 16, 4, desc,
-@@ -326,9 +276,10 @@ static int ahash_set_sh_desc(struct cryp
+@@ -326,9 +277,10 @@ static int ahash_set_sh_desc(struct cryp
  
        /* ahash_digest shared descriptor */
        desc = ctx->sh_desc_digest;
@@ -10276,7 +11316,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #ifdef DEBUG
        print_hex_dump(KERN_ERR,
                       "ahash digest shdesc@"__stringify(__LINE__)": ",
-@@ -421,6 +372,7 @@ static int ahash_setkey(struct crypto_ah
+@@ -421,6 +373,7 @@ static int ahash_setkey(struct crypto_ah
        struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
        int blocksize = crypto_tfm_alg_blocksize(&ahash->base);
        int digestsize = crypto_ahash_digestsize(ahash);
@@ -10284,7 +11324,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        int ret;
        u8 *hashed_key = NULL;
  
-@@ -441,16 +393,26 @@ static int ahash_setkey(struct crypto_ah
+@@ -441,16 +394,26 @@ static int ahash_setkey(struct crypto_ah
                key = hashed_key;
        }
  
@@ -10320,7 +11360,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        kfree(hashed_key);
        return ahash_set_sh_desc(ahash);
-@@ -773,7 +735,7 @@ static int ahash_update_ctx(struct ahash
+@@ -773,7 +736,7 @@ static int ahash_update_ctx(struct ahash
                edesc->src_nents = src_nents;
                edesc->sec4_sg_bytes = sec4_sg_bytes;
  
@@ -10329,7 +11369,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                                         edesc->sec4_sg, DMA_BIDIRECTIONAL);
                if (ret)
                        goto unmap_ctx;
-@@ -871,9 +833,8 @@ static int ahash_final_ctx(struct ahash_
+@@ -871,9 +834,8 @@ static int ahash_final_ctx(struct ahash_
        desc = edesc->hw_desc;
  
        edesc->sec4_sg_bytes = sec4_sg_bytes;
@@ -10340,7 +11380,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                                 edesc->sec4_sg, DMA_TO_DEVICE);
        if (ret)
                goto unmap_ctx;
-@@ -967,7 +928,7 @@ static int ahash_finup_ctx(struct ahash_
+@@ -967,7 +929,7 @@ static int ahash_finup_ctx(struct ahash_
  
        edesc->src_nents = src_nents;
  
@@ -10349,7 +11389,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                                 edesc->sec4_sg, DMA_TO_DEVICE);
        if (ret)
                goto unmap_ctx;
-@@ -1126,7 +1087,6 @@ static int ahash_final_no_ctx(struct aha
+@@ -1126,7 +1088,6 @@ static int ahash_final_no_ctx(struct aha
                dev_err(jrdev, "unable to map dst\n");
                goto unmap;
        }
@@ -10357,7 +11397,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  #ifdef DEBUG
        print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
-@@ -1208,7 +1168,6 @@ static int ahash_update_no_ctx(struct ah
+@@ -1208,7 +1169,6 @@ static int ahash_update_no_ctx(struct ah
  
                edesc->src_nents = src_nents;
                edesc->sec4_sg_bytes = sec4_sg_bytes;
@@ -10365,7 +11405,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
                ret = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, state);
                if (ret)
-@@ -1420,7 +1379,6 @@ static int ahash_update_first(struct aha
+@@ -1420,7 +1380,6 @@ static int ahash_update_first(struct aha
                }
  
                edesc->src_nents = src_nents;
@@ -10373,7 +11413,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
                ret = ahash_edesc_add_src(ctx, edesc, req, mapped_nents, 0, 0,
                                          to_hash);
-@@ -1722,6 +1680,7 @@ static int caam_hash_cra_init(struct cry
+@@ -1722,6 +1681,7 @@ static int caam_hash_cra_init(struct cry
                                         HASH_MSG_LEN + 64,
                                         HASH_MSG_LEN + SHA512_DIGEST_SIZE };
        dma_addr_t dma_addr;
@@ -10381,7 +11421,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        /*
         * Get a Job ring from Job Ring driver to ensure in-order
-@@ -1733,10 +1692,13 @@ static int caam_hash_cra_init(struct cry
+@@ -1733,10 +1693,13 @@ static int caam_hash_cra_init(struct cry
                return PTR_ERR(ctx->jrdev);
        }
  
@@ -10396,7 +11436,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (dma_mapping_error(ctx->jrdev, dma_addr)) {
                dev_err(ctx->jrdev, "unable to map shared descriptors\n");
                caam_jr_free(ctx->jrdev);
-@@ -1771,7 +1733,7 @@ static void caam_hash_cra_exit(struct cr
+@@ -1771,11 +1734,11 @@ static void caam_hash_cra_exit(struct cr
        dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_update_dma,
                               offsetof(struct caam_hash_ctx,
                                        sh_desc_update_dma),
@@ -10405,6 +11445,95 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        caam_jr_free(ctx->jrdev);
  }
  
+-static void __exit caam_algapi_hash_exit(void)
++void caam_algapi_hash_exit(void)
+ {
+       struct caam_hash_alg *t_alg, *n;
+@@ -1834,56 +1797,38 @@ caam_hash_alloc(struct caam_hash_templat
+       return t_alg;
+ }
+-static int __init caam_algapi_hash_init(void)
++int caam_algapi_hash_init(struct device *ctrldev)
+ {
+-      struct device_node *dev_node;
+-      struct platform_device *pdev;
+-      struct device *ctrldev;
+       int i = 0, err = 0;
+-      struct caam_drv_private *priv;
++      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
+       unsigned int md_limit = SHA512_DIGEST_SIZE;
+-      u32 cha_inst, cha_vid;
+-
+-      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+-      if (!dev_node) {
+-              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+-              if (!dev_node)
+-                      return -ENODEV;
+-      }
+-
+-      pdev = of_find_device_by_node(dev_node);
+-      if (!pdev) {
+-              of_node_put(dev_node);
+-              return -ENODEV;
+-      }
+-
+-      ctrldev = &pdev->dev;
+-      priv = dev_get_drvdata(ctrldev);
+-      of_node_put(dev_node);
+-
+-      /*
+-       * If priv is NULL, it's probably because the caam driver wasn't
+-       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+-       */
+-      if (!priv)
+-              return -ENODEV;
++      u32 md_inst, md_vid;
+       /*
+        * Register crypto algorithms the device supports.  First, identify
+        * presence and attributes of MD block.
+        */
+-      cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
+-      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
++      if (priv->era < 10) {
++              md_vid = (rd_reg32(&priv->ctrl->perfmon.cha_id_ls) &
++                        CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++              md_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
++                         CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
++      } else {
++              u32 mdha = rd_reg32(&priv->ctrl->vreg.mdha);
++
++              md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
++              md_inst = mdha & CHA_VER_NUM_MASK;
++      }
+       /*
+        * Skip registration of any hashing algorithms if MD block
+        * is not present.
+        */
+-      if (!((cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT))
++      if (!md_inst)
+               return -ENODEV;
+       /* Limit digest size based on LP256 */
+-      if ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256)
++      if (md_vid == CHA_VER_VID_MD_LP256)
+               md_limit = SHA256_DIGEST_SIZE;
+       INIT_LIST_HEAD(&hash_list);
+@@ -1934,10 +1879,3 @@ static int __init caam_algapi_hash_init(
+       return err;
+ }
+-
+-module_init(caam_algapi_hash_init);
+-module_exit(caam_algapi_hash_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("FSL CAAM support for ahash functions of crypto API");
+-MODULE_AUTHOR("Freescale Semiconductor - NMG");
 --- /dev/null
 +++ b/drivers/crypto/caam/caamhash_desc.c
 @@ -0,0 +1,108 @@
@@ -10568,6 +11697,171 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +                     int digestsize, int ctx_len, bool import_ctx, int era);
 +
 +#endif /* _CAAMHASH_DESC_H_ */
+--- a/drivers/crypto/caam/caampkc.c
++++ b/drivers/crypto/caam/caampkc.c
+@@ -2,6 +2,7 @@
+  * caam - Freescale FSL CAAM support for Public Key Cryptography
+  *
+  * Copyright 2016 Freescale Semiconductor, Inc.
++ * Copyright 2018 NXP
+  *
+  * There is no Shared Descriptor for PKC so that the Job Descriptor must carry
+  * all the desired key parameters, input and output pointers.
+@@ -1017,46 +1018,22 @@ static struct akcipher_alg caam_rsa = {
+ };
+ /* Public Key Cryptography module initialization handler */
+-static int __init caam_pkc_init(void)
++int caam_pkc_init(struct device *ctrldev)
+ {
+-      struct device_node *dev_node;
+-      struct platform_device *pdev;
+-      struct device *ctrldev;
+-      struct caam_drv_private *priv;
+-      u32 cha_inst, pk_inst;
++      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
++      u32 pk_inst;
+       int err;
+-      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+-      if (!dev_node) {
+-              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+-              if (!dev_node)
+-                      return -ENODEV;
+-      }
+-
+-      pdev = of_find_device_by_node(dev_node);
+-      if (!pdev) {
+-              of_node_put(dev_node);
+-              return -ENODEV;
+-      }
+-
+-      ctrldev = &pdev->dev;
+-      priv = dev_get_drvdata(ctrldev);
+-      of_node_put(dev_node);
+-
+-      /*
+-       * If priv is NULL, it's probably because the caam driver wasn't
+-       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+-       */
+-      if (!priv)
+-              return -ENODEV;
+-
+       /* Determine public key hardware accelerator presence. */
+-      cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
+-      pk_inst = (cha_inst & CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT;
++      if (priv->era < 10)
++              pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
++                         CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT;
++      else
++              pk_inst = rd_reg32(&priv->ctrl->vreg.pkha) & CHA_VER_NUM_MASK;
+       /* Do not register algorithms if PKHA is not present. */
+       if (!pk_inst)
+-              return -ENODEV;
++              return 0;
+       err = crypto_register_akcipher(&caam_rsa);
+       if (err)
+@@ -1068,14 +1045,7 @@ static int __init caam_pkc_init(void)
+       return err;
+ }
+-static void __exit caam_pkc_exit(void)
++void caam_pkc_exit(void)
+ {
+       crypto_unregister_akcipher(&caam_rsa);
+ }
+-
+-module_init(caam_pkc_init);
+-module_exit(caam_pkc_exit);
+-
+-MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_DESCRIPTION("FSL CAAM support for PKC functions of crypto API");
+-MODULE_AUTHOR("Freescale Semiconductor");
+--- a/drivers/crypto/caam/caamrng.c
++++ b/drivers/crypto/caam/caamrng.c
+@@ -2,6 +2,7 @@
+  * caam - Freescale FSL CAAM support for hw_random
+  *
+  * Copyright 2011 Freescale Semiconductor, Inc.
++ * Copyright 2018 NXP
+  *
+  * Based on caamalg.c crypto API driver.
+  *
+@@ -294,49 +295,29 @@ static struct hwrng caam_rng = {
+       .read           = caam_read,
+ };
+-static void __exit caam_rng_exit(void)
++void caam_rng_exit(void)
+ {
+       caam_jr_free(rng_ctx->jrdev);
+       hwrng_unregister(&caam_rng);
+       kfree(rng_ctx);
+ }
+-static int __init caam_rng_init(void)
++int caam_rng_init(struct device *ctrldev)
+ {
+       struct device *dev;
+-      struct device_node *dev_node;
+-      struct platform_device *pdev;
+-      struct device *ctrldev;
+-      struct caam_drv_private *priv;
++      u32 rng_inst;
++      struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
+       int err;
+-      dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+-      if (!dev_node) {
+-              dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
+-              if (!dev_node)
+-                      return -ENODEV;
+-      }
+-
+-      pdev = of_find_device_by_node(dev_node);
+-      if (!pdev) {
+-              of_node_put(dev_node);
+-              return -ENODEV;
+-      }
+-
+-      ctrldev = &pdev->dev;
+-      priv = dev_get_drvdata(ctrldev);
+-      of_node_put(dev_node);
+-
+-      /*
+-       * If priv is NULL, it's probably because the caam driver wasn't
+-       * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+-       */
+-      if (!priv)
+-              return -ENODEV;
+-
+       /* Check for an instantiated RNG before registration */
+-      if (!(rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & CHA_ID_LS_RNG_MASK))
+-              return -ENODEV;
++      if (priv->era < 10)
++              rng_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) &
++                          CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
++      else
++              rng_inst = rd_reg32(&priv->ctrl->vreg.rng) & CHA_VER_NUM_MASK;
++
++      if (!rng_inst)
++              return 0;
+       dev = caam_jr_alloc();
+       if (IS_ERR(dev)) {
+@@ -361,10 +342,3 @@ free_caam_alloc:
+       caam_jr_free(dev);
+       return err;
+ }
+-
+-module_init(caam_rng_init);
+-module_exit(caam_rng_exit);
+-
+-MODULE_LICENSE("GPL");
+-MODULE_DESCRIPTION("FSL CAAM support for hw_random API");
+-MODULE_AUTHOR("Freescale Semiconductor - NMG");
 --- a/drivers/crypto/caam/compat.h
 +++ b/drivers/crypto/caam/compat.h
 @@ -17,6 +17,7 @@
@@ -10578,7 +11872,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #include <linux/spinlock.h>
  #include <linux/rtnetlink.h>
  #include <linux/in.h>
-@@ -38,6 +39,7 @@
+@@ -34,10 +35,13 @@
+ #include <crypto/des.h>
+ #include <crypto/sha.h>
+ #include <crypto/md5.h>
++#include <crypto/chacha20.h>
++#include <crypto/poly1305.h>
+ #include <crypto/internal/aead.h>
  #include <crypto/authenc.h>
  #include <crypto/akcipher.h>
  #include <crypto/scatterwalk.h>
@@ -10588,7 +11888,26 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #include <crypto/internal/rsa.h>
 --- a/drivers/crypto/caam/ctrl.c
 +++ b/drivers/crypto/caam/ctrl.c
-@@ -27,6 +27,8 @@ EXPORT_SYMBOL(caam_imx);
+@@ -2,6 +2,7 @@
+  * Controller-level driver, kernel property detection, initialization
+  *
+  * Copyright 2008-2012 Freescale Semiconductor, Inc.
++ * Copyright 2018 NXP
+  */
+ #include <linux/device.h>
+@@ -16,17 +17,15 @@
+ #include "desc_constr.h"
+ #include "ctrl.h"
+-bool caam_little_end;
+-EXPORT_SYMBOL(caam_little_end);
+ bool caam_dpaa2;
+ EXPORT_SYMBOL(caam_dpaa2);
+-bool caam_imx;
+-EXPORT_SYMBOL(caam_imx);
+ #ifdef CONFIG_CAAM_QI
  #include "qi.h"
  #endif
  
@@ -10597,7 +11916,61 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  /*
   * i.MX targets tend to have clock control subsystems that can
   * enable/disable clocking to our device.
-@@ -332,6 +334,9 @@ static int caam_remove(struct platform_d
+@@ -105,7 +104,7 @@ static inline int run_descriptor_deco0(s
+       struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl;
+       struct caam_deco __iomem *deco = ctrlpriv->deco;
+       unsigned int timeout = 100000;
+-      u32 deco_dbg_reg, flags;
++      u32 deco_dbg_reg, deco_state, flags;
+       int i;
+@@ -148,13 +147,22 @@ static inline int run_descriptor_deco0(s
+       timeout = 10000000;
+       do {
+               deco_dbg_reg = rd_reg32(&deco->desc_dbg);
++
++              if (ctrlpriv->era < 10)
++                      deco_state = (deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) >>
++                                   DESC_DBG_DECO_STAT_SHIFT;
++              else
++                      deco_state = (rd_reg32(&deco->dbg_exec) &
++                                    DESC_DER_DECO_STAT_MASK) >>
++                                   DESC_DER_DECO_STAT_SHIFT;
++
+               /*
+                * 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)
++              if (deco_state == DECO_STAT_HOST_ERR)
+                       break;
++
+               cpu_relax();
+       } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
+@@ -316,15 +324,15 @@ static int caam_remove(struct platform_d
+       of_platform_depopulate(ctrldev);
+ #ifdef CONFIG_CAAM_QI
+-      if (ctrlpriv->qidev)
+-              caam_qi_shutdown(ctrlpriv->qidev);
++      if (ctrlpriv->qi_init)
++              caam_qi_shutdown(ctrldev);
+ #endif
+       /*
+        * De-initialize RNG state handles initialized by this driver.
+-       * In case of DPAA 2.x, RNG is managed by MC firmware.
++       * In case of SoCs with Management Complex, RNG is managed by MC f/w.
+        */
+-      if (!caam_dpaa2 && ctrlpriv->rng4_sh_init)
++      if (!ctrlpriv->mc_en && ctrlpriv->rng4_sh_init)
+               deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);
+       /* Shut down debug views */
+@@ -332,6 +340,9 @@ static int caam_remove(struct platform_d
        debugfs_remove_recursive(ctrlpriv->dfs_root);
  #endif
  
@@ -10607,7 +11980,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        /* Unmap controller region */
        iounmap(ctrl);
  
-@@ -433,6 +438,10 @@ static int caam_probe(struct platform_de
+@@ -433,6 +444,10 @@ static int caam_probe(struct platform_de
                {.family = "Freescale i.MX"},
                {},
        };
@@ -10618,19 +11991,223 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        struct device *dev;
        struct device_node *nprop, *np;
        struct caam_ctrl __iomem *ctrl;
-@@ -615,6 +624,8 @@ static int caam_probe(struct platform_de
-               goto iounmap_ctrl;
+@@ -442,7 +457,7 @@ static int caam_probe(struct platform_de
+       struct caam_perfmon *perfmon;
+ #endif
+       u32 scfgr, comp_params;
+-      u32 cha_vid_ls;
++      u8 rng_vid;
+       int pg_size;
+       int BLOCK_OFFSET = 0;
+@@ -454,15 +469,54 @@ static int caam_probe(struct platform_de
+       dev_set_drvdata(dev, ctrlpriv);
+       nprop = pdev->dev.of_node;
++      /* Get configuration properties from device tree */
++      /* First, get register page */
++      ctrl = of_iomap(nprop, 0);
++      if (!ctrl) {
++              dev_err(dev, "caam: of_iomap() failed\n");
++              return -ENOMEM;
++      }
++
++      caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) &
++                                (CSTA_PLEND | CSTA_ALT_PLEND));
+       caam_imx = (bool)soc_device_match(imx_soc);
++      comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms);
++      caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2);
++      ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK);
++
++#ifdef CONFIG_CAAM_QI
++      /* If (DPAA 1.x) QI present, check whether dependencies are available */
++      if (ctrlpriv->qi_present && !caam_dpaa2) {
++              ret = qman_is_probed();
++              if (!ret) {
++                      ret = -EPROBE_DEFER;
++                      goto iounmap_ctrl;
++              } else if (ret < 0) {
++                      dev_err(dev, "failing probe due to qman probe error\n");
++                      ret = -ENODEV;
++                      goto iounmap_ctrl;
++              }
++
++              ret = qman_portals_probed();
++              if (!ret) {
++                      ret = -EPROBE_DEFER;
++                      goto iounmap_ctrl;
++              } else if (ret < 0) {
++                      dev_err(dev, "failing probe due to qman portals probe error\n");
++                      ret = -ENODEV;
++                      goto iounmap_ctrl;
++              }
++      }
++#endif
++
+       /* Enable clocking */
+       clk = caam_drv_identify_clk(&pdev->dev, "ipg");
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
+               dev_err(&pdev->dev,
+                       "can't identify CAAM ipg clk: %d\n", ret);
+-              return ret;
++              goto iounmap_ctrl;
+       }
+       ctrlpriv->caam_ipg = clk;
+@@ -471,7 +525,7 @@ static int caam_probe(struct platform_de
+               ret = PTR_ERR(clk);
+               dev_err(&pdev->dev,
+                       "can't identify CAAM mem clk: %d\n", ret);
+-              return ret;
++              goto iounmap_ctrl;
+       }
+       ctrlpriv->caam_mem = clk;
+@@ -480,7 +534,7 @@ static int caam_probe(struct platform_de
+               ret = PTR_ERR(clk);
+               dev_err(&pdev->dev,
+                       "can't identify CAAM aclk clk: %d\n", ret);
+-              return ret;
++              goto iounmap_ctrl;
+       }
+       ctrlpriv->caam_aclk = clk;
+@@ -490,7 +544,7 @@ static int caam_probe(struct platform_de
+                       ret = PTR_ERR(clk);
+                       dev_err(&pdev->dev,
+                               "can't identify CAAM emi_slow clk: %d\n", ret);
+-                      return ret;
++                      goto iounmap_ctrl;
+               }
+               ctrlpriv->caam_emi_slow = clk;
+       }
+@@ -498,7 +552,7 @@ static int caam_probe(struct platform_de
+       ret = clk_prepare_enable(ctrlpriv->caam_ipg);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "can't enable CAAM ipg clock: %d\n", ret);
+-              return ret;
++              goto iounmap_ctrl;
+       }
+       ret = clk_prepare_enable(ctrlpriv->caam_mem);
+@@ -523,25 +577,10 @@ static int caam_probe(struct platform_de
+               }
+       }
+-      /* Get configuration properties from device tree */
+-      /* First, get register page */
+-      ctrl = of_iomap(nprop, 0);
+-      if (ctrl == NULL) {
+-              dev_err(dev, "caam: of_iomap() failed\n");
+-              ret = -ENOMEM;
+-              goto disable_caam_emi_slow;
+-      }
+-
+-      caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) &
+-                                (CSTA_PLEND | CSTA_ALT_PLEND));
+-
+-      /* Finding the page size for using the CTPR_MS register */
+-      comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms);
+-      pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT;
+-
+       /* Allocating the BLOCK_OFFSET based on the supported page size on
+        * the platform
+        */
++      pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT;
+       if (pg_size == 0)
+               BLOCK_OFFSET = PG_SIZE_4K;
+       else
+@@ -563,11 +602,14 @@ static int caam_probe(struct platform_de
+       /*
+        * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
+        * long pointers in master configuration register.
+-       * In case of DPAA 2.x, Management Complex firmware performs
++       * In case of SoCs with Management Complex, MC f/w performs
+        * the configuration.
+        */
+-      caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2);
+-      if (!caam_dpaa2)
++      np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc");
++      ctrlpriv->mc_en = !!np;
++      of_node_put(np);
++
++      if (!ctrlpriv->mc_en)
+               clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
+                             MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
+                             MCFGR_WDENABLE | MCFGR_LARGE_BURST |
+@@ -612,14 +654,11 @@ static int caam_probe(struct platform_de
+       }
+       if (ret) {
+               dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret);
+-              goto iounmap_ctrl;
++              goto disable_caam_emi_slow;
        }
  
+-      ret = of_platform_populate(nprop, caam_match, NULL, dev);
+-      if (ret) {
+-              dev_err(dev, "JR platform devices creation error\n");
+-              goto iounmap_ctrl;
+-      }
 +      ctrlpriv->era = caam_get_era();
++      ctrlpriv->domain = iommu_get_domain_for_dev(dev);
+ #ifdef CONFIG_DEBUG_FS
+       /*
+@@ -633,21 +672,7 @@ static int caam_probe(struct platform_de
+       ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
+ #endif
+-      ring = 0;
+-      for_each_available_child_of_node(nprop, np)
+-              if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
+-                  of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
+-                      ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *)
+-                                           ((__force uint8_t *)ctrl +
+-                                           (ring + JR_BLOCK_NUMBER) *
+-                                            BLOCK_OFFSET
+-                                           );
+-                      ctrlpriv->total_jobrs++;
+-                      ring++;
+-              }
+-
+       /* Check to see if (DPAA 1.x) QI present. If so, enable */
+-      ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK);
+       if (ctrlpriv->qi_present && !caam_dpaa2) {
+               ctrlpriv->qi = (struct caam_queue_if __iomem __force *)
+                              ((__force uint8_t *)ctrl +
+@@ -664,6 +689,25 @@ static int caam_probe(struct platform_de
+ #endif
+       }
++      ret = of_platform_populate(nprop, caam_match, NULL, dev);
++      if (ret) {
++              dev_err(dev, "JR platform devices creation error\n");
++              goto shutdown_qi;
++      }
++
++      ring = 0;
++      for_each_available_child_of_node(nprop, np)
++              if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
++                  of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
++                      ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *)
++                                           ((__force uint8_t *)ctrl +
++                                           (ring + JR_BLOCK_NUMBER) *
++                                            BLOCK_OFFSET
++                                           );
++                      ctrlpriv->total_jobrs++;
++                      ring++;
++              }
 +
-       ret = of_platform_populate(nprop, caam_match, NULL, dev);
-       if (ret) {
-               dev_err(dev, "JR platform devices creation error\n");
-@@ -671,6 +682,16 @@ static int caam_probe(struct platform_de
+       /* If no QI and no rings specified, quit and go home */
+       if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {
+               dev_err(dev, "no queues configured, terminating\n");
+@@ -671,15 +715,29 @@ static int caam_probe(struct platform_de
                goto caam_remove;
        }
  
+-      cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls);
 +      caam_dma_pdev_info.parent = dev;
 +      caam_dma_pdev_info.dma_mask = dma_get_mask(dev);
 +      caam_dma_dev = platform_device_register_full(&caam_dma_pdev_info);
@@ -10641,21 +12218,73 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +              set_dma_ops(&caam_dma_dev->dev, get_dma_ops(dev));
 +      }
 +
-       cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls);
++      if (ctrlpriv->era < 10)
++              rng_vid = (rd_reg32(&ctrl->perfmon.cha_id_ls) &
++                         CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
++      else
++              rng_vid = (rd_reg32(&ctrl->vreg.rng) & CHA_VER_VID_MASK) >>
++                         CHA_VER_VID_SHIFT;
  
        /*
-@@ -746,7 +767,7 @@ static int caam_probe(struct platform_de
+        * If SEC has RNG version >= 4 and RNG state handle has not been
+        * already instantiated, do RNG instantiation
+-       * In case of DPAA 2.x, RNG is managed by MC firmware.
++       * In case of SoCs with Management Complex, RNG is managed by MC f/w.
+        */
+-      if (!caam_dpaa2 &&
+-          (cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) {
++      if (!ctrlpriv->mc_en && rng_vid >= 4) {
+               ctrlpriv->rng4_sh_init =
+                       rd_reg32(&ctrl->r4tst[0].rdsta);
+               /*
+@@ -746,10 +804,9 @@ static int caam_probe(struct platform_de
  
        /* Report "alive" for developer to see */
        dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
 -               caam_get_era());
+-      dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n",
+-               ctrlpriv->total_jobrs, ctrlpriv->qi_present,
+-               caam_dpaa2 ? "yes" : "no");
 +               ctrlpriv->era);
-       dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n",
-                ctrlpriv->total_jobrs, ctrlpriv->qi_present,
-                caam_dpaa2 ? "yes" : "no");
++      dev_info(dev, "job rings = %d, qi = %d\n",
++               ctrlpriv->total_jobrs, ctrlpriv->qi_present);
+ #ifdef CONFIG_DEBUG_FS
+       debugfs_create_file("rq_dequeued", S_IRUSR | S_IRGRP | S_IROTH,
+@@ -816,8 +873,11 @@ caam_remove:
+       caam_remove(pdev);
+       return ret;
+-iounmap_ctrl:
+-      iounmap(ctrl);
++shutdown_qi:
++#ifdef CONFIG_CAAM_QI
++      if (ctrlpriv->qi_init)
++              caam_qi_shutdown(dev);
++#endif
+ disable_caam_emi_slow:
+       if (ctrlpriv->caam_emi_slow)
+               clk_disable_unprepare(ctrlpriv->caam_emi_slow);
+@@ -827,6 +887,8 @@ disable_caam_mem:
+       clk_disable_unprepare(ctrlpriv->caam_mem);
+ disable_caam_ipg:
+       clk_disable_unprepare(ctrlpriv->caam_ipg);
++iounmap_ctrl:
++      iounmap(ctrl);
+       return ret;
+ }
 --- a/drivers/crypto/caam/desc.h
 +++ b/drivers/crypto/caam/desc.h
-@@ -42,6 +42,7 @@
+@@ -4,6 +4,7 @@
+  * Definitions to support CAAM descriptor instruction generation
+  *
+  * Copyright 2008-2011 Freescale Semiconductor, Inc.
++ * Copyright 2018 NXP
+  */
+ #ifndef DESC_H
+@@ -42,6 +43,7 @@
  #define CMD_SEQ_LOAD          (0x03 << CMD_SHIFT)
  #define CMD_FIFO_LOAD         (0x04 << CMD_SHIFT)
  #define CMD_SEQ_FIFO_LOAD     (0x05 << CMD_SHIFT)
@@ -10663,7 +12292,28 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #define CMD_STORE             (0x0a << CMD_SHIFT)
  #define CMD_SEQ_STORE         (0x0b << CMD_SHIFT)
  #define CMD_FIFO_STORE                (0x0c << CMD_SHIFT)
-@@ -355,6 +356,7 @@
+@@ -242,6 +244,7 @@
+ #define LDST_SRCDST_WORD_DESCBUF_SHARED       (0x42 << LDST_SRCDST_SHIFT)
+ #define LDST_SRCDST_WORD_DESCBUF_JOB_WE       (0x45 << LDST_SRCDST_SHIFT)
+ #define LDST_SRCDST_WORD_DESCBUF_SHARED_WE (0x46 << LDST_SRCDST_SHIFT)
++#define LDST_SRCDST_WORD_INFO_FIFO_SM (0x71 << LDST_SRCDST_SHIFT)
+ #define LDST_SRCDST_WORD_INFO_FIFO    (0x7a << LDST_SRCDST_SHIFT)
+ /* Offset in source/destination */
+@@ -284,6 +287,12 @@
+ #define LDLEN_SET_OFIFO_OFFSET_SHIFT  0
+ #define LDLEN_SET_OFIFO_OFFSET_MASK   (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
++/* Special Length definitions when dst=sm, nfifo-{sm,m} */
++#define LDLEN_MATH0                   0
++#define LDLEN_MATH1                   1
++#define LDLEN_MATH2                   2
++#define LDLEN_MATH3                   3
++
+ /*
+  * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
+  * Command Constructs
+@@ -355,6 +364,7 @@
  #define FIFOLD_TYPE_PK_N      (0x08 << FIFOLD_TYPE_SHIFT)
  #define FIFOLD_TYPE_PK_A      (0x0c << FIFOLD_TYPE_SHIFT)
  #define FIFOLD_TYPE_PK_B      (0x0d << FIFOLD_TYPE_SHIFT)
@@ -10671,7 +12321,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  /* Other types. Need to OR in last/flush bits as desired */
  #define FIFOLD_TYPE_MSG_MASK  (0x38 << FIFOLD_TYPE_SHIFT)
-@@ -408,6 +410,7 @@
+@@ -408,6 +418,7 @@
  #define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT)
  #define FIFOST_TYPE_RNGSTORE   (0x34 << FIFOST_TYPE_SHIFT)
  #define FIFOST_TYPE_RNGFIFO    (0x35 << FIFOST_TYPE_SHIFT)
@@ -10679,7 +12329,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #define FIFOST_TYPE_SKIP       (0x3f << FIFOST_TYPE_SHIFT)
  
  /*
-@@ -444,6 +447,18 @@
+@@ -444,6 +455,18 @@
  #define OP_PCLID_DSAVERIFY    (0x16 << OP_PCLID_SHIFT)
  #define OP_PCLID_RSAENC_PUBKEY  (0x18 << OP_PCLID_SHIFT)
  #define OP_PCLID_RSADEC_PRVKEY  (0x19 << OP_PCLID_SHIFT)
@@ -10698,7 +12348,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  /* Assuming OP_TYPE = OP_TYPE_DECAP_PROTOCOL/ENCAP_PROTOCOL */
  #define OP_PCLID_IPSEC                (0x01 << OP_PCLID_SHIFT)
-@@ -1093,6 +1108,22 @@
+@@ -1093,6 +1116,22 @@
  /* MacSec protinfos */
  #define OP_PCL_MACSEC                          0x0001
  
@@ -10721,7 +12371,60 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  /* PKI unidirectional protocol protinfo bits */
  #define OP_PCL_PKPROT_TEST                     0x0008
  #define OP_PCL_PKPROT_DECRYPT                  0x0004
-@@ -1440,10 +1471,11 @@
+@@ -1105,6 +1144,12 @@
+ #define OP_ALG_TYPE_CLASS1    (2 << OP_ALG_TYPE_SHIFT)
+ #define OP_ALG_TYPE_CLASS2    (4 << OP_ALG_TYPE_SHIFT)
++/* version register fields */
++#define OP_VER_CCHA_NUM  0x000000ff /* Number CCHAs instantiated */
++#define OP_VER_CCHA_MISC 0x0000ff00 /* CCHA Miscellaneous Information */
++#define OP_VER_CCHA_REV  0x00ff0000 /* CCHA Revision Number */
++#define OP_VER_CCHA_VID  0xff000000 /* CCHA Version ID */
++
+ #define OP_ALG_ALGSEL_SHIFT   16
+ #define OP_ALG_ALGSEL_MASK    (0xff << OP_ALG_ALGSEL_SHIFT)
+ #define OP_ALG_ALGSEL_SUBMASK (0x0f << OP_ALG_ALGSEL_SHIFT)
+@@ -1124,6 +1169,8 @@
+ #define OP_ALG_ALGSEL_KASUMI  (0x70 << OP_ALG_ALGSEL_SHIFT)
+ #define OP_ALG_ALGSEL_CRC     (0x90 << OP_ALG_ALGSEL_SHIFT)
+ #define OP_ALG_ALGSEL_SNOW_F9 (0xA0 << OP_ALG_ALGSEL_SHIFT)
++#define OP_ALG_ALGSEL_CHACHA20        (0xD0 << OP_ALG_ALGSEL_SHIFT)
++#define OP_ALG_ALGSEL_POLY1305        (0xE0 << OP_ALG_ALGSEL_SHIFT)
+ #define OP_ALG_AAI_SHIFT      4
+ #define OP_ALG_AAI_MASK               (0x1ff << OP_ALG_AAI_SHIFT)
+@@ -1171,6 +1218,11 @@
+ #define OP_ALG_AAI_RNG4_AI    (0x80 << OP_ALG_AAI_SHIFT)
+ #define OP_ALG_AAI_RNG4_SK    (0x100 << OP_ALG_AAI_SHIFT)
++/* Chacha20 AAI set */
++#define OP_ALG_AAI_AEAD       (0x002 << OP_ALG_AAI_SHIFT)
++#define OP_ALG_AAI_KEYSTREAM  (0x001 << OP_ALG_AAI_SHIFT)
++#define OP_ALG_AAI_BC8                (0x008 << OP_ALG_AAI_SHIFT)
++
+ /* hmac/smac AAI set */
+ #define OP_ALG_AAI_HASH               (0x00 << OP_ALG_AAI_SHIFT)
+ #define OP_ALG_AAI_HMAC               (0x01 << OP_ALG_AAI_SHIFT)
+@@ -1359,6 +1411,7 @@
+ #define MOVE_SRC_MATH3                (0x07 << MOVE_SRC_SHIFT)
+ #define MOVE_SRC_INFIFO               (0x08 << MOVE_SRC_SHIFT)
+ #define MOVE_SRC_INFIFO_CL    (0x09 << MOVE_SRC_SHIFT)
++#define MOVE_SRC_AUX_ABLK     (0x0a << MOVE_SRC_SHIFT)
+ #define MOVE_DEST_SHIFT               16
+ #define MOVE_DEST_MASK                (0x0f << MOVE_DEST_SHIFT)
+@@ -1385,6 +1438,10 @@
+ #define MOVELEN_MRSEL_SHIFT   0
+ #define MOVELEN_MRSEL_MASK    (0x3 << MOVE_LEN_SHIFT)
++#define MOVELEN_MRSEL_MATH0   (0 << MOVELEN_MRSEL_SHIFT)
++#define MOVELEN_MRSEL_MATH1   (1 << MOVELEN_MRSEL_SHIFT)
++#define MOVELEN_MRSEL_MATH2   (2 << MOVELEN_MRSEL_SHIFT)
++#define MOVELEN_MRSEL_MATH3   (3 << MOVELEN_MRSEL_SHIFT)
+ /*
+  * MATH Command Constructs
+@@ -1440,10 +1497,11 @@
  #define MATH_SRC1_REG2                (0x02 << MATH_SRC1_SHIFT)
  #define MATH_SRC1_REG3                (0x03 << MATH_SRC1_SHIFT)
  #define MATH_SRC1_IMM         (0x04 << MATH_SRC1_SHIFT)
@@ -10734,7 +12437,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  /* Destination selectors */
  #define MATH_DEST_SHIFT               8
-@@ -1452,6 +1484,7 @@
+@@ -1452,6 +1510,7 @@
  #define MATH_DEST_REG1                (0x01 << MATH_DEST_SHIFT)
  #define MATH_DEST_REG2                (0x02 << MATH_DEST_SHIFT)
  #define MATH_DEST_REG3                (0x03 << MATH_DEST_SHIFT)
@@ -10742,7 +12445,15 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #define MATH_DEST_SEQINLEN    (0x08 << MATH_DEST_SHIFT)
  #define MATH_DEST_SEQOUTLEN   (0x09 << MATH_DEST_SHIFT)
  #define MATH_DEST_VARSEQINLEN (0x0a << MATH_DEST_SHIFT)
-@@ -1624,4 +1657,31 @@
+@@ -1560,6 +1619,7 @@
+ #define NFIFOENTRY_DTYPE_IV   (0x2 << NFIFOENTRY_DTYPE_SHIFT)
+ #define NFIFOENTRY_DTYPE_SAD  (0x3 << NFIFOENTRY_DTYPE_SHIFT)
+ #define NFIFOENTRY_DTYPE_ICV  (0xA << NFIFOENTRY_DTYPE_SHIFT)
++#define NFIFOENTRY_DTYPE_POLY (0xB << NFIFOENTRY_DTYPE_SHIFT)
+ #define NFIFOENTRY_DTYPE_SKIP (0xE << NFIFOENTRY_DTYPE_SHIFT)
+ #define NFIFOENTRY_DTYPE_MSG  (0xF << NFIFOENTRY_DTYPE_SHIFT)
+@@ -1624,4 +1684,31 @@
  /* Frame Descriptor Command for Replacement Job Descriptor */
  #define FD_CMD_REPLACE_JOB_DESC                               0x20000000
  
@@ -10794,15 +12505,16 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                                   u32 command)
  {
        append_cmd(desc, command | IMMEDIATE | len);
-@@ -189,6 +189,7 @@ static inline u32 *append_##cmd(u32 * co
+@@ -189,6 +189,8 @@ static inline u32 *append_##cmd(u32 * co
  }
  APPEND_CMD_RET(jump, JUMP)
  APPEND_CMD_RET(move, MOVE)
 +APPEND_CMD_RET(moveb, MOVEB)
++APPEND_CMD_RET(move_len, MOVE_LEN)
  
  static inline void set_jump_tgt_here(u32 * const desc, u32 *jump_cmd)
  {
-@@ -271,7 +272,7 @@ APPEND_SEQ_PTR_INTLEN(in, IN)
+@@ -271,7 +273,7 @@ APPEND_SEQ_PTR_INTLEN(in, IN)
  APPEND_SEQ_PTR_INTLEN(out, OUT)
  
  #define APPEND_CMD_PTR_TO_IMM(cmd, op) \
@@ -10811,7 +12523,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                                         unsigned int len, u32 options) \
  { \
        PRINT_POS; \
-@@ -312,7 +313,7 @@ APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_
+@@ -312,7 +314,7 @@ APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_
   * from length of immediate data provided, e.g., split keys
   */
  #define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
@@ -10820,7 +12532,20 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                                         unsigned int data_len, \
                                         unsigned int len, u32 options) \
  { \
-@@ -452,7 +453,7 @@ struct alginfo {
+@@ -327,7 +329,11 @@ static inline void append_##cmd##_imm_##
+                                            u32 options) \
+ { \
+       PRINT_POS; \
+-      append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \
++      if (options & LDST_LEN_MASK) \
++              append_cmd(desc, CMD_##op | IMMEDIATE | options); \
++      else \
++              append_cmd(desc, CMD_##op | IMMEDIATE | options | \
++                         sizeof(type)); \
+       append_cmd(desc, immediate); \
+ }
+ APPEND_CMD_RAW_IMM(load, LOAD, u32);
+@@ -452,7 +458,7 @@ struct alginfo {
        unsigned int keylen_pad;
        union {
                dma_addr_t key_dma;
@@ -10829,7 +12554,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        };
        bool key_inline;
  };
-@@ -496,4 +497,45 @@ static inline int desc_inline_query(unsi
+@@ -496,4 +502,45 @@ static inline int desc_inline_query(unsi
        return (rem_bytes >= 0) ? 0 : -1;
  }
  
@@ -12471,7 +14196,20 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +#endif /* _DPSECI_CMD_H_ */
 --- a/drivers/crypto/caam/error.c
 +++ b/drivers/crypto/caam/error.c
-@@ -108,6 +108,54 @@ static const struct {
+@@ -50,6 +50,12 @@ void caam_dump_sg(const char *level, con
+ #endif /* DEBUG */
+ EXPORT_SYMBOL(caam_dump_sg);
++bool caam_little_end;
++EXPORT_SYMBOL(caam_little_end);
++
++bool caam_imx;
++EXPORT_SYMBOL(caam_imx);
++
+ static const struct {
+       u8 value;
+       const char *error_text;
+@@ -108,6 +114,54 @@ static const struct {
        { 0xF1, "3GPP HFN matches or exceeds the Threshold" },
  };
  
@@ -12526,7 +14264,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  static const char * const cha_id_list[] = {
        "",
        "AES",
-@@ -236,6 +284,27 @@ static void report_deco_status(struct de
+@@ -236,6 +290,27 @@ static void report_deco_status(struct de
                status, error, idx_str, idx, err_str, err_err_code);
  }
  
@@ -12554,7 +14292,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  static void report_jr_status(struct device *jrdev, const u32 status,
                             const char *error)
  {
-@@ -250,7 +319,7 @@ static void report_cond_code_status(stru
+@@ -250,7 +325,7 @@ static void report_cond_code_status(stru
                status, error, __func__);
  }
  
@@ -12563,7 +14301,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  {
        static const struct stat_src {
                void (*report_ssed)(struct device *jrdev, const u32 status,
-@@ -262,7 +331,7 @@ void caam_jr_strstatus(struct device *jr
+@@ -262,7 +337,7 @@ void caam_jr_strstatus(struct device *jr
                { report_ccb_status, "CCB" },
                { report_jump_status, "Jump" },
                { report_deco_status, "DECO" },
@@ -12572,7 +14310,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                { report_jr_status, "Job Ring" },
                { report_cond_code_status, "Condition Code" },
                { NULL, NULL },
-@@ -288,4 +357,4 @@ void caam_jr_strstatus(struct device *jr
+@@ -288,4 +363,4 @@ void caam_jr_strstatus(struct device *jr
        else
                dev_err(jrdev, "%d: unknown error source\n", ssrc);
  }
@@ -12595,17 +14333,140 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                  int rowsize, int groupsize, struct scatterlist *sg,
 --- a/drivers/crypto/caam/intern.h
 +++ b/drivers/crypto/caam/intern.h
-@@ -84,6 +84,7 @@ struct caam_drv_private {
+@@ -65,10 +65,6 @@ struct caam_drv_private_jr {
+  * Driver-private storage for a single CAAM block instance
+  */
+ struct caam_drv_private {
+-#ifdef CONFIG_CAAM_QI
+-      struct device *qidev;
+-#endif
+-
+       /* Physical-presence section */
+       struct caam_ctrl __iomem *ctrl; /* controller region */
+       struct caam_deco __iomem *deco; /* DECO/CCB views */
+@@ -76,14 +72,21 @@ struct caam_drv_private {
+       struct caam_queue_if __iomem *qi; /* QI control region */
+       struct caam_job_ring __iomem *jr[4];    /* JobR's register space */
++      struct iommu_domain *domain;
++
+       /*
+        * Detected geometry block. Filled in from device tree if powerpc,
+        * or from register-based version detection code
+        */
+       u8 total_jobrs;         /* Total Job Rings in device */
        u8 qi_present;          /* Nonzero if QI present in device */
++#ifdef CONFIG_CAAM_QI
++      u8 qi_init;             /* Nonzero if QI has been initialized */
++#endif
++      u8 mc_en;               /* Nonzero if MC f/w is active */
        int secvio_irq;         /* Security violation interrupt number */
        int virt_en;            /* Virtualization enabled in CAAM */
 +      int era;                /* CAAM Era (internal HW revision) */
  
  #define       RNG4_MAX_HANDLES 2
        /* RNG4 block */
+@@ -108,8 +111,95 @@ struct caam_drv_private {
+ #endif
+ };
+-void caam_jr_algapi_init(struct device *dev);
+-void caam_jr_algapi_remove(struct device *dev);
++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API
++
++int caam_algapi_init(struct device *dev);
++void caam_algapi_exit(void);
++
++#else
++
++static inline int caam_algapi_init(struct device *dev)
++{
++      return 0;
++}
++
++static inline void caam_algapi_exit(void)
++{
++}
++
++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API */
++
++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API
++
++int caam_algapi_hash_init(struct device *dev);
++void caam_algapi_hash_exit(void);
++
++#else
++
++static inline int caam_algapi_hash_init(struct device *dev)
++{
++      return 0;
++}
++
++static inline void caam_algapi_hash_exit(void)
++{
++}
++
++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API */
++
++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API
++
++int caam_pkc_init(struct device *dev);
++void caam_pkc_exit(void);
++
++#else
++
++static inline int caam_pkc_init(struct device *dev)
++{
++      return 0;
++}
++
++static inline void caam_pkc_exit(void)
++{
++}
++
++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API */
++
++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API
++
++int caam_rng_init(struct device *dev);
++void caam_rng_exit(void);
++
++#else
++
++static inline int caam_rng_init(struct device *dev)
++{
++      return 0;
++}
++
++static inline void caam_rng_exit(void)
++{
++}
++
++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API */
++
++#ifdef CONFIG_CAAM_QI
++
++int caam_qi_algapi_init(struct device *dev);
++void caam_qi_algapi_exit(void);
++
++#else
++
++static inline int caam_qi_algapi_init(struct device *dev)
++{
++      return 0;
++}
++
++static inline void caam_qi_algapi_exit(void)
++{
++}
++
++#endif /* CONFIG_CAAM_QI */
+ #ifdef CONFIG_DEBUG_FS
+ static int caam_debugfs_u64_get(void *data, u64 *val)
 --- a/drivers/crypto/caam/jr.c
 +++ b/drivers/crypto/caam/jr.c
-@@ -23,6 +23,14 @@ struct jr_driver_data {
+@@ -23,6 +23,52 @@ struct jr_driver_data {
  
  static struct jr_driver_data driver_data;
  
@@ -12616,11 +14477,59 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      return jr_driver_probed;
 +}
 +EXPORT_SYMBOL(caam_jr_driver_probed);
++
++static DEFINE_MUTEX(algs_lock);
++static unsigned int active_devs;
++
++static void register_algs(struct device *dev)
++{
++      mutex_lock(&algs_lock);
++
++      if (++active_devs != 1)
++              goto algs_unlock;
++
++      caam_algapi_init(dev);
++      caam_algapi_hash_init(dev);
++      caam_pkc_init(dev);
++      caam_rng_init(dev);
++      caam_qi_algapi_init(dev);
++
++algs_unlock:
++      mutex_unlock(&algs_lock);
++}
++
++static void unregister_algs(void)
++{
++      mutex_lock(&algs_lock);
++
++      if (--active_devs != 0)
++              goto algs_unlock;
++
++      caam_qi_algapi_exit();
++
++      caam_rng_exit();
++      caam_pkc_exit();
++      caam_algapi_hash_exit();
++      caam_algapi_exit();
++
++algs_unlock:
++      mutex_unlock(&algs_lock);
++}
 +
  static int caam_reset_hw_jr(struct device *dev)
  {
        struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
-@@ -119,6 +127,8 @@ static int caam_jr_remove(struct platfor
+@@ -108,6 +154,9 @@ static int caam_jr_remove(struct platfor
+               return -EBUSY;
+       }
++      /* Unregister JR-based RNG & crypto algorithms */
++      unregister_algs();
++
+       /* Remove the node from Physical JobR list maintained by driver */
+       spin_lock(&driver_data.jr_alloc_lock);
+       list_del(&jrpriv->list_node);
+@@ -119,6 +168,8 @@ static int caam_jr_remove(struct platfor
                dev_err(jrdev, "Failed to shut down job ring\n");
        irq_dispose_mapping(jrpriv->irq);
  
@@ -12629,7 +14538,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        return ret;
  }
  
-@@ -282,6 +292,36 @@ struct device *caam_jr_alloc(void)
+@@ -282,6 +333,36 @@ struct device *caam_jr_alloc(void)
  EXPORT_SYMBOL(caam_jr_alloc);
  
  /**
@@ -12666,10 +14575,11 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
   * caam_jr_free() - Free the Job Ring
   * @rdev     - points to the dev that identifies the Job ring to
   *             be released.
-@@ -539,6 +579,8 @@ static int caam_jr_probe(struct platform
+@@ -539,6 +620,9 @@ static int caam_jr_probe(struct platform
  
        atomic_set(&jrpriv->tfm_count, 0);
  
++      register_algs(jrdev->parent);
 +      jr_driver_probed++;
 +
        return 0;
@@ -12776,7 +14686,32 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
  #include "regs.h"
  #include "qi.h"
-@@ -105,23 +105,21 @@ static struct kmem_cache *qi_cache;
+@@ -58,11 +58,9 @@ static DEFINE_PER_CPU(int, last_cpu);
+ /*
+  * caam_qi_priv - CAAM QI backend private params
+  * @cgr: QMan congestion group
+- * @qi_pdev: platform device for QI backend
+  */
+ struct caam_qi_priv {
+       struct qman_cgr cgr;
+-      struct platform_device *qi_pdev;
+ };
+ static struct caam_qi_priv qipriv ____cacheline_aligned;
+@@ -102,26 +100,34 @@ static int mod_init_cpu;
+  */
+ static struct kmem_cache *qi_cache;
++static void *caam_iova_to_virt(struct iommu_domain *domain,
++                             dma_addr_t iova_addr)
++{
++      phys_addr_t phys_addr;
++
++      phys_addr = domain ? iommu_iova_to_phys(domain, iova_addr) : iova_addr;
++
++      return phys_to_virt(phys_addr);
++}
++
  int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req)
  {
        struct qm_fd fd;
@@ -12806,7 +14741,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                if (likely(!ret))
                        return 0;
  
-@@ -137,7 +135,7 @@ int caam_qi_enqueue(struct device *qidev
+@@ -137,20 +143,21 @@ int caam_qi_enqueue(struct device *qidev
  EXPORT_SYMBOL(caam_qi_enqueue);
  
  static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq,
@@ -12815,7 +14750,8 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  {
        const struct qm_fd *fd;
        struct caam_drv_req *drv_req;
-@@ -145,7 +143,7 @@ static void caam_fq_ern_cb(struct qman_p
+       struct device *qidev = &(raw_cpu_ptr(&pcpu_qipriv)->net_dev.dev);
++      struct caam_drv_private *priv = dev_get_drvdata(qidev);
  
        fd = &msg->ern.fd;
  
@@ -12824,7 +14760,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                dev_err(qidev, "Non-compound FD from CAAM\n");
                return;
        }
-@@ -180,20 +178,22 @@ static struct qman_fq *create_caam_req_f
+-      drv_req = (struct caam_drv_req *)phys_to_virt(qm_fd_addr_get64(fd));
++      drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
+       if (!drv_req) {
+               dev_err(qidev,
+                       "Can't find original request for CAAM response\n");
+@@ -180,20 +187,22 @@ static struct qman_fq *create_caam_req_f
        req_fq->cb.fqs = NULL;
  
        ret = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID |
@@ -12856,7 +14798,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        opts.fqd.cgid = qipriv.cgr.cgrid;
  
        ret = qman_init_fq(req_fq, fq_sched_flag, &opts);
-@@ -207,7 +207,7 @@ static struct qman_fq *create_caam_req_f
+@@ -207,7 +216,7 @@ static struct qman_fq *create_caam_req_f
        return req_fq;
  
  init_req_fq_fail:
@@ -12865,7 +14807,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  create_req_fq_fail:
        kfree(req_fq);
        return ERR_PTR(ret);
-@@ -275,7 +275,7 @@ empty_fq:
+@@ -275,7 +284,7 @@ empty_fq:
        if (ret)
                dev_err(qidev, "OOS of FQID: %u failed\n", fq->fqid);
  
@@ -12874,7 +14816,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        kfree(fq);
  
        return ret;
-@@ -292,7 +292,7 @@ static int empty_caam_fq(struct qman_fq
+@@ -292,7 +301,7 @@ static int empty_caam_fq(struct qman_fq
                if (ret)
                        return ret;
  
@@ -12883,11 +14825,29 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
                        break;
  
                msleep(20);
-@@ -572,22 +572,27 @@ static enum qman_cb_dqrr_result caam_rsp
+@@ -495,7 +504,7 @@ EXPORT_SYMBOL(caam_drv_ctx_rel);
+ int caam_qi_shutdown(struct device *qidev)
+ {
+       int i, ret;
+-      struct caam_qi_priv *priv = dev_get_drvdata(qidev);
++      struct caam_qi_priv *priv = &qipriv;
+       const cpumask_t *cpus = qman_affine_cpus();
+       struct cpumask old_cpumask = current->cpus_allowed;
+@@ -528,7 +537,6 @@ int caam_qi_shutdown(struct device *qide
+       /* Now that we're done with the CGRs, restore the cpus allowed mask */
+       set_cpus_allowed_ptr(current, &old_cpumask);
+-      platform_device_unregister(priv->qi_pdev);
+       return ret;
+ }
+@@ -572,22 +580,28 @@ static enum qman_cb_dqrr_result caam_rsp
        struct caam_drv_req *drv_req;
        const struct qm_fd *fd;
        struct device *qidev = &(raw_cpu_ptr(&pcpu_qipriv)->net_dev.dev);
 -      u32 status;
++      struct caam_drv_private *priv = dev_get_drvdata(qidev);
  
        if (caam_qi_napi_schedule(p, caam_napi))
                return qman_cb_dqrr_stop;
@@ -12899,25 +14859,25 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
 +      if (unlikely(fd->status)) {
 +              u32 ssrc = fd->status & JRSTA_SSRC_MASK;
 +              u8 err_id = fd->status & JRSTA_CCBERR_ERRID_MASK;
-+
+-      if (unlikely(qm_fd_get_format(fd) != qm_fd_compound)) {
 +              if (ssrc != JRSTA_SSRC_CCB_ERROR ||
 +                  err_id != JRSTA_CCBERR_ERRID_ICVCHK)
 +                      dev_err(qidev, "Error: %#x in CAAM response FD\n",
 +                              fd->status);
 +      }
--      if (unlikely(qm_fd_get_format(fd) != qm_fd_compound)) {
++
 +      if (unlikely(fd->format != qm_fd_compound)) {
                dev_err(qidev, "Non-compound FD from CAAM\n");
                return qman_cb_dqrr_consume;
        }
  
 -      drv_req = (struct caam_drv_req *)phys_to_virt(qm_fd_addr_get64(fd));
-+      drv_req = (struct caam_drv_req *)phys_to_virt(fd->addr);
++      drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd));
        if (unlikely(!drv_req)) {
                dev_err(qidev,
                        "Can't find original request for caam response\n");
-@@ -597,7 +602,7 @@ static enum qman_cb_dqrr_result caam_rsp
+@@ -597,7 +611,7 @@ static enum qman_cb_dqrr_result caam_rsp
        dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd),
                         sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL);
  
@@ -12926,7 +14886,7 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        return qman_cb_dqrr_consume;
  }
  
-@@ -621,17 +626,18 @@ static int alloc_rsp_fq_cpu(struct devic
+@@ -621,17 +635,18 @@ static int alloc_rsp_fq_cpu(struct devic
                return -ENODEV;
        }
  
@@ -12953,7 +14913,19 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  
        ret = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &opts);
        if (ret) {
-@@ -662,8 +668,7 @@ static int init_cgr(struct device *qidev
+@@ -650,9 +665,8 @@ static int init_cgr(struct device *qidev
+ {
+       int ret;
+       struct qm_mcc_initcgr opts;
+-      const u64 cpus = *(u64 *)qman_affine_cpus();
+-      const int num_cpus = hweight64(cpus);
+-      const u64 val = num_cpus * MAX_RSP_FQ_BACKLOG_PER_CPU;
++      const u64 val = (u64)cpumask_weight(qman_affine_cpus()) *
++                      MAX_RSP_FQ_BACKLOG_PER_CPU;
+       ret = qman_alloc_cgrid(&qipriv.cgr.cgrid);
+       if (ret) {
+@@ -662,8 +676,7 @@ static int init_cgr(struct device *qidev
  
        qipriv.cgr.cb = cgr_cb;
        memset(&opts, 0, sizeof(opts));
@@ -12963,6 +14935,81 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        opts.cgr.cscn_en = QM_CGR_EN;
        opts.cgr.mode = QMAN_CGR_MODE_FRAME;
        qm_cgr_cs_thres_set64(&opts.cgr.cs_thres, val, 1);
+@@ -708,15 +721,10 @@ static void free_rsp_fqs(void)
+ int caam_qi_init(struct platform_device *caam_pdev)
+ {
+       int err, i;
+-      struct platform_device *qi_pdev;
+       struct device *ctrldev = &caam_pdev->dev, *qidev;
+       struct caam_drv_private *ctrlpriv;
+       const cpumask_t *cpus = qman_affine_cpus();
+       struct cpumask old_cpumask = current->cpus_allowed;
+-      static struct platform_device_info qi_pdev_info = {
+-              .name = "caam_qi",
+-              .id = PLATFORM_DEVID_NONE
+-      };
+       /*
+        * QMAN requires CGRs to be removed from same CPU+portal from where it
+@@ -728,24 +736,13 @@ int caam_qi_init(struct platform_device
+       mod_init_cpu = cpumask_first(cpus);
+       set_cpus_allowed_ptr(current, get_cpu_mask(mod_init_cpu));
+-      qi_pdev_info.parent = ctrldev;
+-      qi_pdev_info.dma_mask = dma_get_mask(ctrldev);
+-      qi_pdev = platform_device_register_full(&qi_pdev_info);
+-      if (IS_ERR(qi_pdev))
+-              return PTR_ERR(qi_pdev);
+-      set_dma_ops(&qi_pdev->dev, get_dma_ops(ctrldev));
+-
+       ctrlpriv = dev_get_drvdata(ctrldev);
+-      qidev = &qi_pdev->dev;
+-
+-      qipriv.qi_pdev = qi_pdev;
+-      dev_set_drvdata(qidev, &qipriv);
++      qidev = ctrldev;
+       /* Initialize the congestion detection */
+       err = init_cgr(qidev);
+       if (err) {
+               dev_err(qidev, "CGR initialization failed: %d\n", err);
+-              platform_device_unregister(qi_pdev);
+               return err;
+       }
+@@ -754,7 +751,6 @@ int caam_qi_init(struct platform_device
+       if (err) {
+               dev_err(qidev, "Can't allocate CAAM response FQs: %d\n", err);
+               free_rsp_fqs();
+-              platform_device_unregister(qi_pdev);
+               return err;
+       }
+@@ -777,15 +773,11 @@ int caam_qi_init(struct platform_device
+               napi_enable(irqtask);
+       }
+-      /* Hook up QI device to parent controlling caam device */
+-      ctrlpriv->qidev = qidev;
+-
+       qi_cache = kmem_cache_create("caamqicache", CAAM_QI_MEMCACHE_SIZE, 0,
+                                    SLAB_CACHE_DMA, NULL);
+       if (!qi_cache) {
+               dev_err(qidev, "Can't allocate CAAM cache\n");
+               free_rsp_fqs();
+-              platform_device_unregister(qi_pdev);
+               return -ENOMEM;
+       }
+@@ -795,6 +787,8 @@ int caam_qi_init(struct platform_device
+       debugfs_create_file("qi_congested", 0444, ctrlpriv->ctl,
+                           &times_congested, &caam_fops_u64_ro);
+ #endif
++
++      ctrlpriv->qi_init = 1;
+       dev_info(qidev, "Linux CAAM Queue I/F driver initialised\n");
+       return 0;
+ }
 --- a/drivers/crypto/caam/qi.h
 +++ b/drivers/crypto/caam/qi.h
 @@ -9,7 +9,7 @@
@@ -12976,7 +15023,128 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #include "desc_constr.h"
 --- a/drivers/crypto/caam/regs.h
 +++ b/drivers/crypto/caam/regs.h
-@@ -627,6 +627,8 @@ struct caam_job_ring {
+@@ -3,6 +3,7 @@
+  * CAAM hardware register-level view
+  *
+  * Copyright 2008-2011 Freescale Semiconductor, Inc.
++ * Copyright 2018 NXP
+  */
+ #ifndef REGS_H
+@@ -211,6 +212,47 @@ struct jr_outentry {
+       u32 jrstatus;   /* Status for completed descriptor */
+ } __packed;
++/* Version registers (Era 10+)        e80-eff */
++struct version_regs {
++      u32 crca;       /* CRCA_VERSION */
++      u32 afha;       /* AFHA_VERSION */
++      u32 kfha;       /* KFHA_VERSION */
++      u32 pkha;       /* PKHA_VERSION */
++      u32 aesa;       /* AESA_VERSION */
++      u32 mdha;       /* MDHA_VERSION */
++      u32 desa;       /* DESA_VERSION */
++      u32 snw8a;      /* SNW8A_VERSION */
++      u32 snw9a;      /* SNW9A_VERSION */
++      u32 zuce;       /* ZUCE_VERSION */
++      u32 zuca;       /* ZUCA_VERSION */
++      u32 ccha;       /* CCHA_VERSION */
++      u32 ptha;       /* PTHA_VERSION */
++      u32 rng;        /* RNG_VERSION */
++      u32 trng;       /* TRNG_VERSION */
++      u32 aaha;       /* AAHA_VERSION */
++      u32 rsvd[10];
++      u32 sr;         /* SR_VERSION */
++      u32 dma;        /* DMA_VERSION */
++      u32 ai;         /* AI_VERSION */
++      u32 qi;         /* QI_VERSION */
++      u32 jr;         /* JR_VERSION */
++      u32 deco;       /* DECO_VERSION */
++};
++
++/* Version registers bitfields */
++
++/* Number of CHAs instantiated */
++#define CHA_VER_NUM_MASK      0xffull
++/* CHA Miscellaneous Information */
++#define CHA_VER_MISC_SHIFT    8
++#define CHA_VER_MISC_MASK     (0xffull << CHA_VER_MISC_SHIFT)
++/* CHA Revision Number */
++#define CHA_VER_REV_SHIFT     16
++#define CHA_VER_REV_MASK      (0xffull << CHA_VER_REV_SHIFT)
++/* CHA Version ID */
++#define CHA_VER_VID_SHIFT     24
++#define CHA_VER_VID_MASK      (0xffull << CHA_VER_VID_SHIFT)
++
+ /*
+  * caam_perfmon - Performance Monitor/Secure Memory Status/
+  *                CAAM Global Status/Component Version IDs
+@@ -223,15 +265,13 @@ struct jr_outentry {
+ #define CHA_NUM_MS_DECONUM_MASK       (0xfull << CHA_NUM_MS_DECONUM_SHIFT)
+ /*
+- * CHA version IDs / instantiation bitfields
++ * CHA version IDs / instantiation bitfields (< Era 10)
+  * Defined for use with the cha_id fields in perfmon, but the same shift/mask
+  * selectors can be used to pull out the number of instantiated blocks within
+  * cha_num fields in perfmon because the locations are the same.
+  */
+ #define CHA_ID_LS_AES_SHIFT   0
+ #define CHA_ID_LS_AES_MASK    (0xfull << CHA_ID_LS_AES_SHIFT)
+-#define CHA_ID_LS_AES_LP      (0x3ull << CHA_ID_LS_AES_SHIFT)
+-#define CHA_ID_LS_AES_HP      (0x4ull << CHA_ID_LS_AES_SHIFT)
+ #define CHA_ID_LS_DES_SHIFT   4
+ #define CHA_ID_LS_DES_MASK    (0xfull << CHA_ID_LS_DES_SHIFT)
+@@ -241,9 +281,6 @@ struct jr_outentry {
+ #define CHA_ID_LS_MD_SHIFT    12
+ #define CHA_ID_LS_MD_MASK     (0xfull << CHA_ID_LS_MD_SHIFT)
+-#define CHA_ID_LS_MD_LP256    (0x0ull << CHA_ID_LS_MD_SHIFT)
+-#define CHA_ID_LS_MD_LP512    (0x1ull << CHA_ID_LS_MD_SHIFT)
+-#define CHA_ID_LS_MD_HP               (0x2ull << CHA_ID_LS_MD_SHIFT)
+ #define CHA_ID_LS_RNG_SHIFT   16
+ #define CHA_ID_LS_RNG_MASK    (0xfull << CHA_ID_LS_RNG_SHIFT)
+@@ -269,6 +306,13 @@ struct jr_outentry {
+ #define CHA_ID_MS_JR_SHIFT    28
+ #define CHA_ID_MS_JR_MASK     (0xfull << CHA_ID_MS_JR_SHIFT)
++/* Specific CHA version IDs */
++#define CHA_VER_VID_AES_LP    0x3ull
++#define CHA_VER_VID_AES_HP    0x4ull
++#define CHA_VER_VID_MD_LP256  0x0ull
++#define CHA_VER_VID_MD_LP512  0x1ull
++#define CHA_VER_VID_MD_HP     0x2ull
++
+ struct sec_vid {
+       u16 ip_id;
+       u8 maj_rev;
+@@ -473,8 +517,10 @@ struct caam_ctrl {
+               struct rng4tst r4tst[2];
+       };
+-      u32 rsvd9[448];
++      u32 rsvd9[416];
++      /* Version registers - introduced with era 10           e80-eff */
++      struct version_regs vreg;
+       /* Performance Monitor                                  f00-fff */
+       struct caam_perfmon perfmon;
+ };
+@@ -564,8 +610,10 @@ struct caam_job_ring {
+       u32 rsvd11;
+       u32 jrcommand;  /* JRCRx - JobR command */
+-      u32 rsvd12[932];
++      u32 rsvd12[900];
++      /* Version registers - introduced with era 10           e80-eff */
++      struct version_regs vreg;
+       /* Performance Monitor                                  f00-fff */
+       struct caam_perfmon perfmon;
+ };
+@@ -627,6 +675,8 @@ struct caam_job_ring {
  #define JRSTA_DECOERR_INVSIGN       0x86
  #define JRSTA_DECOERR_DSASIGN       0x87
  
@@ -12985,6 +15153,28 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
  #define JRSTA_CCBERR_JUMP           0x08000000
  #define JRSTA_CCBERR_INDEX_MASK     0xff00
  #define JRSTA_CCBERR_INDEX_SHIFT    8
+@@ -870,13 +920,19 @@ struct caam_deco {
+       u32 rsvd29[48];
+       u32 descbuf[64];        /* DxDESB - Descriptor buffer */
+       u32 rscvd30[193];
+-#define DESC_DBG_DECO_STAT_HOST_ERR   0x00D00000
+ #define DESC_DBG_DECO_STAT_VALID      0x80000000
+ #define DESC_DBG_DECO_STAT_MASK               0x00F00000
++#define DESC_DBG_DECO_STAT_SHIFT      20
+       u32 desc_dbg;           /* DxDDR - DECO Debug Register */
+-      u32 rsvd31[126];
++      u32 rsvd31[13];
++#define DESC_DER_DECO_STAT_MASK               0x000F0000
++#define DESC_DER_DECO_STAT_SHIFT      16
++      u32 dbg_exec;           /* DxDER - DECO Debug Exec Register */
++      u32 rsvd32[112];
+ };
++#define DECO_STAT_HOST_ERR    0xD
++
+ #define DECO_JQCR_WHL         0x20000000
+ #define DECO_JQCR_FOUR                0x10000000
 --- a/drivers/crypto/caam/sg_sw_qm.h
 +++ b/drivers/crypto/caam/sg_sw_qm.h
 @@ -34,46 +34,61 @@
@@ -13091,3 +15281,13 @@ Signed-off-by: Biwen Li <biwen.li@nxp.com>
        if (ret > 1) {
                tbl_off += ret;
                sync_needed = true;
+--- a/include/crypto/chacha20.h
++++ b/include/crypto/chacha20.h
+@@ -13,6 +13,7 @@
+ #define CHACHA20_IV_SIZE      16
+ #define CHACHA20_KEY_SIZE     32
+ #define CHACHA20_BLOCK_SIZE   64
++#define CHACHAPOLY_IV_SIZE    12
+ struct chacha20_ctx {
+       u32 key[8];