--- /dev/null
+From f126384ed55279c3b676f89d5ab547b8de8df782 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:48 +0200
+Subject: crypto: talitos - add chaining of arbitrary number of descriptor for the SEC1
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit f126384ed55279c3b676f89d5ab547b8de8df782 upstream.
+
+The SEC1 hardware can process a chain of descriptors without host
+intervention. Only the hash implementation currently use this feature,
+but with a chain of at most 2 descriptors added in commit 37b5e8897eb5
+("crypto: talitos - chain in buffered data for ahash on SEC1").
+
+Add supports for chaining an arbitrary number of descriptors in a chain.
+
+Adapt the ahash implementation to make it compatible.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c | 180 +++++++++++++++++++++++++++++++----------------
+ drivers/crypto/talitos.h | 2
+ 2 files changed, 124 insertions(+), 58 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -272,7 +272,10 @@ static int talitos_submit(struct device
+ void *context, int error),
+ void *context)
+ {
++ struct talitos_edesc *edesc = container_of(desc, struct talitos_edesc, desc);
+ struct talitos_private *priv = dev_get_drvdata(dev);
++ dma_addr_t dma_desc, prev_dma_desc;
++ struct talitos_edesc *prev_edesc = NULL;
+ struct talitos_request *request;
+ unsigned long flags;
+ int head;
+@@ -291,10 +294,31 @@ static int talitos_submit(struct device
+
+ /* map descriptor and save caller data */
+ if (is_sec1) {
+- desc->hdr1 = desc->hdr;
+- request->dma_desc = dma_map_single(dev, &desc->hdr1,
++ while (edesc) {
++ edesc->desc.hdr1 = edesc->desc.hdr;
++
++ dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
++ TALITOS_DESC_SIZE,
++ DMA_BIDIRECTIONAL);
++
++ if (!prev_edesc) {
++ request->dma_desc = dma_desc;
++ goto next;
++ }
++
++ /* Chain in any previous descriptors. */
++
++ prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
++
++ dma_sync_single_for_device(dev, prev_dma_desc,
+ TALITOS_DESC_SIZE,
+- DMA_BIDIRECTIONAL);
++ DMA_TO_DEVICE);
++
++next:
++ prev_edesc = edesc;
++ prev_dma_desc = dma_desc;
++ edesc = edesc->next_desc;
++ }
+ } else {
+ request->dma_desc = dma_map_single(dev, desc,
+ TALITOS_DESC_SIZE,
+@@ -325,6 +349,7 @@ static __be32 get_request_hdr(struct dev
+ struct talitos_request *request, bool is_sec1)
+ {
+ struct talitos_edesc *edesc;
++ dma_addr_t dma_desc;
+
+ if (!is_sec1) {
+ dma_sync_single_for_cpu(dev, request->dma_desc,
+@@ -333,19 +358,17 @@ static __be32 get_request_hdr(struct dev
+ return request->desc->hdr;
+ }
+
+- if (!request->desc->next_desc) {
+- dma_sync_single_for_cpu(dev, request->dma_desc,
+- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+- return request->desc->hdr1;
+- } else {
+- dma_sync_single_for_cpu(dev,
+- be32_to_cpu(request->desc->next_desc),
+- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+- edesc = container_of(request->desc, struct talitos_edesc, desc);
+-
+- return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))
+- ->hdr1;
++ edesc = container_of(request->desc, struct talitos_edesc, desc);
++ dma_desc = request->dma_desc;
++ while (edesc->next_desc) {
++ dma_desc = be32_to_cpu(edesc->desc.next_desc);
++ edesc = edesc->next_desc;
+ }
++
++ dma_sync_single_for_cpu(dev, dma_desc, TALITOS_DESC_SIZE,
++ DMA_BIDIRECTIONAL);
++
++ return edesc->desc.hdr1;
+ }
+
+ /*
+@@ -355,6 +378,7 @@ static void flush_channel(struct device
+ {
+ struct talitos_private *priv = dev_get_drvdata(dev);
+ struct talitos_request *request, saved_req;
++ struct talitos_edesc *edesc;
+ unsigned long flags;
+ int tail, status;
+ bool is_sec1 = has_ftr_sec1(priv);
+@@ -379,9 +403,22 @@ static void flush_channel(struct device
+ else
+ status = error;
+
+- dma_unmap_single(dev, request->dma_desc,
+- TALITOS_DESC_SIZE,
+- DMA_BIDIRECTIONAL);
++ if (is_sec1) {
++ dma_unmap_single(dev, request->dma_desc,
++ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++ edesc = container_of(request->desc,
++ struct talitos_edesc, desc);
++ while (edesc->next_desc) {
++ dma_unmap_single(
++ dev, be32_to_cpu(edesc->desc.next_desc),
++ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++ edesc = edesc->next_desc;
++ }
++ } else {
++ dma_unmap_single(dev, request->dma_desc,
++ TALITOS_DESC_SIZE,
++ DMA_BIDIRECTIONAL);
++ }
+
+ /* copy entries so we can call callback outside lock */
+ saved_req.desc = request->desc;
+@@ -476,8 +513,12 @@ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH
+ static __be32 current_desc_hdr(struct device *dev, int ch)
+ {
+ struct talitos_private *priv = dev_get_drvdata(dev);
++ bool is_sec1 = has_ftr_sec1(priv);
++ struct talitos_request *request;
++ struct talitos_edesc *edesc;
+ int tail, iter;
+ dma_addr_t cur_desc;
++ __be32 hdr = 0;
+
+ cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32;
+ cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO);
+@@ -488,27 +529,35 @@ static __be32 current_desc_hdr(struct de
+ }
+
+ tail = priv->chan[ch].tail;
+-
+ iter = tail;
+- while (priv->chan[ch].fifo[iter].dma_desc != cur_desc &&
+- priv->chan[ch].fifo[iter].desc->next_desc != cpu_to_be32(cur_desc)) {
+- iter = (iter + 1) & (priv->fifo_len - 1);
+- if (iter == tail) {
+- dev_err(dev, "couldn't locate current descriptor\n");
+- return 0;
++ do {
++ request = &priv->chan[ch].fifo[iter];
++
++ if (request->dma_desc == cur_desc) {
++ hdr = request->desc->hdr;
++ } else if (is_sec1) {
++ edesc = container_of(request->desc,
++ struct talitos_edesc, desc);
++ while (edesc->next_desc) {
++ if (edesc->desc.next_desc ==
++ cpu_to_be32(cur_desc)) {
++ hdr = edesc->next_desc->desc.hdr1;
++ break;
++ }
++ edesc = edesc->next_desc;
++ }
+ }
+- }
+
+- if (priv->chan[ch].fifo[iter].desc->next_desc == cpu_to_be32(cur_desc)) {
+- struct talitos_edesc *edesc;
++ if (hdr)
++ break;
+
+- edesc = container_of(priv->chan[ch].fifo[iter].desc,
+- struct talitos_edesc, desc);
+- return ((struct talitos_desc *)
+- (edesc->buf + edesc->dma_len))->hdr;
+- }
++ iter = (iter + 1) & (priv->fifo_len - 1);
++ } while (iter != tail);
++
++ if (!hdr)
++ dev_err(dev, "couldn't locate current descriptor\n");
+
+- return priv->chan[ch].fifo[iter].desc->hdr;
++ return hdr;
+ }
+
+ /*
+@@ -1399,10 +1448,6 @@ static struct talitos_edesc *talitos_ede
+ dma_len = 0;
+ }
+ alloc_len += icv_stashing ? authsize : 0;
+-
+- /* if its a ahash, add space for a second desc next to the first one */
+- if (is_sec1 && !dst)
+- alloc_len += sizeof(struct talitos_desc);
+ alloc_len += ivsize;
+
+ edesc = kmalloc(alloc_len, GFP_DMA | flags);
+@@ -1418,6 +1463,7 @@ static struct talitos_edesc *talitos_ede
+ edesc->dst_nents = dst_nents;
+ edesc->iv_dma = iv_dma;
+ edesc->dma_len = dma_len;
++ edesc->next_desc = NULL;
+ if (dma_len)
+ edesc->dma_link_tbl = dma_map_single(dev, &edesc->link_tbl[0],
+ edesc->dma_len,
+@@ -1718,8 +1764,10 @@ static void common_nonsnoop_hash_unmap(s
+ struct talitos_private *priv = dev_get_drvdata(dev);
+ bool is_sec1 = has_ftr_sec1(priv);
+ struct talitos_desc *desc = &edesc->desc;
+- struct talitos_desc *desc2 = (struct talitos_desc *)
+- (edesc->buf + edesc->dma_len);
++ struct talitos_desc *desc2;
++
++ if (desc->next_desc)
++ desc2 = &edesc->next_desc->desc;
+
+ unmap_single_talitos_ptr(dev, &desc->ptr[5], DMA_FROM_DEVICE);
+ if (desc->next_desc &&
+@@ -1747,10 +1795,17 @@ static void common_nonsnoop_hash_unmap(s
+ if (edesc->dma_len)
+ dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
+ DMA_BIDIRECTIONAL);
++}
+
+- if (desc->next_desc)
+- dma_unmap_single(dev, be32_to_cpu(desc->next_desc),
+- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++static void free_edesc_list_from(struct talitos_edesc *edesc)
++{
++ struct talitos_edesc *next;
++
++ while (edesc) {
++ next = edesc->next_desc;
++ kfree(edesc);
++ edesc = next;
++ }
+ }
+
+ static void ahash_done(struct device *dev,
+@@ -1769,7 +1824,7 @@ static void ahash_done(struct device *de
+ }
+ common_nonsnoop_hash_unmap(dev, edesc, areq);
+
+- kfree(edesc);
++ free_edesc_list_from(edesc);
+
+ areq->base.complete(&areq->base, err);
+ }
+@@ -1872,14 +1927,23 @@ static int common_nonsnoop_hash(struct t
+ talitos_handle_buggy_hash(ctx, edesc, &desc->ptr[3]);
+
+ if (is_sec1 && req_ctx->nbuf && length) {
+- struct talitos_desc *desc2 = (struct talitos_desc *)
+- (edesc->buf + edesc->dma_len);
+- dma_addr_t next_desc;
++ struct talitos_edesc *edesc2;
++ struct talitos_desc *desc2;
++
++ edesc2 = kzalloc(sizeof(*edesc2),
++ areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
++ GFP_KERNEL :
++ GFP_ATOMIC);
++ if (!edesc2) {
++ ret = -ENOMEM;
++ goto err;
++ }
++ edesc->next_desc = edesc2;
++
++ desc2 = &edesc2->desc;
+
+- memset(desc2, 0, sizeof(*desc2));
+ desc2->hdr = desc->hdr;
+ desc2->hdr &= ~DESC_HDR_MODE0_MDEU_INIT;
+- desc2->hdr1 = desc2->hdr;
+ desc->hdr &= ~DESC_HDR_MODE0_MDEU_PAD;
+ desc->hdr |= DESC_HDR_MODE0_MDEU_CONT;
+ desc->hdr &= ~DESC_HDR_DONE_NOTIFY;
+@@ -1903,21 +1967,21 @@ static int common_nonsnoop_hash(struct t
+ req_ctx->hw_context_size,
+ req_ctx->hw_context,
+ DMA_FROM_DEVICE);
+-
+- next_desc = dma_map_single(dev, &desc2->hdr1, TALITOS_DESC_SIZE,
+- DMA_BIDIRECTIONAL);
+- desc->next_desc = cpu_to_be32(next_desc);
+ }
+
+ if (sync_needed)
+ dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+ edesc->dma_len, DMA_BIDIRECTIONAL);
+
+- ret = talitos_submit(dev, ctx->ch, desc, callback, areq);
+- if (ret != -EINPROGRESS) {
+- common_nonsnoop_hash_unmap(dev, edesc, areq);
+- kfree(edesc);
+- }
++ ret = talitos_submit(dev, ctx->ch, desc, callback,
++ areq);
++ if (ret != -EINPROGRESS)
++ goto err;
++
++ return -EINPROGRESS;
++err:
++ common_nonsnoop_hash_unmap(dev, edesc, areq);
++ kfree(edesc);
+ return ret;
+ }
+
+--- a/drivers/crypto/talitos.h
++++ b/drivers/crypto/talitos.h
+@@ -49,6 +49,7 @@ struct talitos_desc {
+ * @iv_dma: dma address of iv for checking continuity and link table
+ * @dma_len: length of dma mapped link_tbl space
+ * @dma_link_tbl: bus physical address of link_tbl/buf
++ * @next_desc: next descriptor
+ * @desc: h/w descriptor
+ * @link_tbl: input and output h/w link tables (if {src,dst}_nents > 1) (SEC2)
+ * @buf: input and output buffeur (if {src,dst}_nents > 1) (SEC1)
+@@ -63,6 +64,7 @@ struct talitos_edesc {
+ dma_addr_t iv_dma;
+ int dma_len;
+ dma_addr_t dma_link_tbl;
++ struct talitos_edesc *next_desc;
+ struct talitos_desc desc;
+ union {
+ struct talitos_ptr link_tbl[0];
--- /dev/null
+From f8713d9e6091755dd30f7f1cfa25f8440cddf81b Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:51 +0200
+Subject: crypto: talitos - move code in current_desc_hdr() into a standalone function
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit f8713d9e6091755dd30f7f1cfa25f8440cddf81b upstream.
+
+Previously added code in current_desc_hdr() in order to add support for
+searching an offending descriptor inside a descriptor chain.
+
+Move that code into a standalone function to improve readability.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -519,6 +519,24 @@ DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0
+ DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
+ DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
+
++static __be32 search_desc_hdr_in_request(struct talitos_request *request,
++ dma_addr_t cur_desc, bool is_sec1)
++{
++ struct talitos_edesc *edesc;
++
++ if (request->dma_desc == cur_desc) {
++ return request->desc->hdr;
++ } else if (is_sec1) {
++ edesc = container_of(request->desc, struct talitos_edesc, desc);
++ while (edesc->next_desc) {
++ if (edesc->desc.next_desc == cpu_to_be32(cur_desc))
++ return edesc->next_desc->desc.hdr1;
++ edesc = edesc->next_desc;
++ }
++ }
++ return 0;
++}
++
+ /*
+ * locate current (offending) descriptor
+ */
+@@ -527,7 +545,6 @@ static __be32 current_desc_hdr(struct de
+ struct talitos_private *priv = dev_get_drvdata(dev);
+ bool is_sec1 = has_ftr_sec1(priv);
+ struct talitos_request *request;
+- struct talitos_edesc *edesc;
+ int tail, iter;
+ dma_addr_t cur_desc;
+ __be32 hdr = 0;
+@@ -545,21 +562,7 @@ static __be32 current_desc_hdr(struct de
+ do {
+ request = &priv->chan[ch].fifo[iter];
+
+- if (request->dma_desc == cur_desc) {
+- hdr = request->desc->hdr;
+- } else if (is_sec1) {
+- edesc = container_of(request->desc,
+- struct talitos_edesc, desc);
+- while (edesc->next_desc) {
+- if (edesc->desc.next_desc ==
+- cpu_to_be32(cur_desc)) {
+- hdr = edesc->next_desc->desc.hdr1;
+- break;
+- }
+- edesc = edesc->next_desc;
+- }
+- }
+-
++ hdr = search_desc_hdr_in_request(request, cur_desc, is_sec1);
+ if (hdr)
+ break;
+
--- /dev/null
+From 5c0aa8cad7745505297103f05dda3fa06e8ac670 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:50 +0200
+Subject: crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 5c0aa8cad7745505297103f05dda3fa06e8ac670 upstream.
+
+Previously added code to talitos_submit() in order to map an entire
+descriptor chain.
+
+Move that code into a standalone function to improve readability.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c | 75 +++++++++++++++++++++++++----------------------
+ 1 file changed, 41 insertions(+), 34 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -254,6 +254,46 @@ static int init_device(struct device *de
+ return 0;
+ }
+
++static void dma_map_request(struct device *dev, struct talitos_request *request,
++ struct talitos_desc *desc, bool is_sec1)
++{
++ struct talitos_edesc *edesc =
++ container_of(desc, struct talitos_edesc, desc);
++ dma_addr_t dma_desc, prev_dma_desc;
++ struct talitos_edesc *prev_edesc = NULL;
++
++ if (is_sec1) {
++ while (edesc) {
++ edesc->desc.hdr1 = edesc->desc.hdr;
++
++ dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
++ TALITOS_DESC_SIZE,
++ DMA_BIDIRECTIONAL);
++
++ if (!prev_edesc) {
++ request->dma_desc = dma_desc;
++ goto next;
++ }
++
++ /* Chain in any previous descriptors. */
++
++ prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
++
++ dma_sync_single_for_device(dev, prev_dma_desc,
++ TALITOS_DESC_SIZE,
++ DMA_TO_DEVICE);
++
++next:
++ prev_edesc = edesc;
++ prev_dma_desc = dma_desc;
++ edesc = edesc->next_desc;
++ }
++ } else {
++ request->dma_desc = dma_map_single(dev, desc, TALITOS_DESC_SIZE,
++ DMA_BIDIRECTIONAL);
++ }
++}
++
+ /**
+ * talitos_submit - submits a descriptor to the device for processing
+ * @dev: the SEC device to be used
+@@ -272,10 +312,7 @@ static int talitos_submit(struct device
+ void *context, int error),
+ void *context)
+ {
+- struct talitos_edesc *edesc = container_of(desc, struct talitos_edesc, desc);
+ struct talitos_private *priv = dev_get_drvdata(dev);
+- dma_addr_t dma_desc, prev_dma_desc;
+- struct talitos_edesc *prev_edesc = NULL;
+ struct talitos_request *request;
+ unsigned long flags;
+ int head;
+@@ -293,37 +330,7 @@ static int talitos_submit(struct device
+ request = &priv->chan[ch].fifo[head];
+
+ /* map descriptor and save caller data */
+- if (is_sec1) {
+- while (edesc) {
+- edesc->desc.hdr1 = edesc->desc.hdr;
+-
+- dma_desc = dma_map_single(dev, &edesc->desc.hdr1,
+- TALITOS_DESC_SIZE,
+- DMA_BIDIRECTIONAL);
+-
+- if (!prev_edesc) {
+- request->dma_desc = dma_desc;
+- goto next;
+- }
+-
+- /* Chain in any previous descriptors. */
+-
+- prev_edesc->desc.next_desc = cpu_to_be32(dma_desc);
+-
+- dma_sync_single_for_device(dev, prev_dma_desc,
+- TALITOS_DESC_SIZE,
+- DMA_TO_DEVICE);
+-
+-next:
+- prev_edesc = edesc;
+- prev_dma_desc = dma_desc;
+- edesc = edesc->next_desc;
+- }
+- } else {
+- request->dma_desc = dma_map_single(dev, desc,
+- TALITOS_DESC_SIZE,
+- DMA_BIDIRECTIONAL);
+- }
++ dma_map_request(dev, request, desc, is_sec1);
+ request->callback = callback;
+ request->context = context;
+
--- /dev/null
+From 4d9b0b7415b9e79a3d54d18b5ff230974ea78740 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:49 +0200
+Subject: crypto: talitos - move dma unmapping code in flush_channel() into a standalone dma_unmap_request() function
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit 4d9b0b7415b9e79a3d54d18b5ff230974ea78740 upstream.
+
+Previously added code to flush_channel() in order to unmap an entire
+descriptor.
+
+Move that code into a standalone function to improve readability.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c | 39 ++++++++++++++++++++++-----------------
+ 1 file changed, 22 insertions(+), 17 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -371,6 +371,27 @@ static __be32 get_request_hdr(struct dev
+ return edesc->desc.hdr1;
+ }
+
++static void dma_unmap_request(struct device *dev,
++ struct talitos_request *request, bool is_sec1)
++{
++ struct talitos_edesc *edesc;
++
++ if (is_sec1) {
++ dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
++ DMA_BIDIRECTIONAL);
++ edesc = container_of(request->desc, struct talitos_edesc, desc);
++ while (edesc->next_desc) {
++ dma_unmap_single(dev,
++ be32_to_cpu(edesc->desc.next_desc),
++ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++ edesc = edesc->next_desc;
++ }
++ } else {
++ dma_unmap_single(dev, request->dma_desc, TALITOS_DESC_SIZE,
++ DMA_BIDIRECTIONAL);
++ }
++}
++
+ /*
+ * process what was done, notify callback of error if not
+ */
+@@ -378,7 +399,6 @@ static void flush_channel(struct device
+ {
+ struct talitos_private *priv = dev_get_drvdata(dev);
+ struct talitos_request *request, saved_req;
+- struct talitos_edesc *edesc;
+ unsigned long flags;
+ int tail, status;
+ bool is_sec1 = has_ftr_sec1(priv);
+@@ -403,22 +423,7 @@ static void flush_channel(struct device
+ else
+ status = error;
+
+- if (is_sec1) {
+- dma_unmap_single(dev, request->dma_desc,
+- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+- edesc = container_of(request->desc,
+- struct talitos_edesc, desc);
+- while (edesc->next_desc) {
+- dma_unmap_single(
+- dev, be32_to_cpu(edesc->desc.next_desc),
+- TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+- edesc = edesc->next_desc;
+- }
+- } else {
+- dma_unmap_single(dev, request->dma_desc,
+- TALITOS_DESC_SIZE,
+- DMA_BIDIRECTIONAL);
+- }
++ dma_unmap_request(dev, request, is_sec1);
+
+ /* copy entries so we can call callback outside lock */
+ saved_req.desc = request->desc;
--- /dev/null
+From e17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6 Mon Sep 17 00:00:00 2001
+From: Paul Louvel <paul.louvel@bootlin.com>
+Date: Thu, 7 May 2026 16:41:47 +0200
+Subject: crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header
+
+From: Paul Louvel <paul.louvel@bootlin.com>
+
+commit e17ff3d6ff907dc8406261e8fd3e1fc8a908f0f6 upstream.
+
+In order to know if a descriptor has been processed by the device,
+the driver polls the FIFO to see if DESC_HDR_DONE is set on a descriptor
+header to confirm completion.
+The current code does not make sure that the CPU gets up to date data
+before reading the descriptor.
+
+Fix this by calling dma_sync_single_for_cpu() before reading memory
+written by the device.
+
+Cc: stable@vger.kernel.org
+Fixes: 58cdbc6d2263 ("crypto: talitos - fix hash on SEC1.")
+Signed-off-by: Paul Louvel <paul.louvel@bootlin.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/talitos.c | 28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -321,19 +321,31 @@ static int talitos_submit(struct device
+ return -EINPROGRESS;
+ }
+
+-static __be32 get_request_hdr(struct talitos_request *request, bool is_sec1)
++static __be32 get_request_hdr(struct device *dev,
++ struct talitos_request *request, bool is_sec1)
+ {
+ struct talitos_edesc *edesc;
+
+- if (!is_sec1)
++ if (!is_sec1) {
++ dma_sync_single_for_cpu(dev, request->dma_desc,
++ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++
+ return request->desc->hdr;
++ }
+
+- if (!request->desc->next_desc)
++ if (!request->desc->next_desc) {
++ dma_sync_single_for_cpu(dev, request->dma_desc,
++ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
+ return request->desc->hdr1;
+-
+- edesc = container_of(request->desc, struct talitos_edesc, desc);
+-
+- return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))->hdr1;
++ } else {
++ dma_sync_single_for_cpu(dev,
++ be32_to_cpu(request->desc->next_desc),
++ TALITOS_DESC_SIZE, DMA_BIDIRECTIONAL);
++ edesc = container_of(request->desc, struct talitos_edesc, desc);
++
++ return ((struct talitos_desc *)(edesc->buf + edesc->dma_len))
++ ->hdr1;
++ }
+ }
+
+ /*
+@@ -357,7 +369,7 @@ static void flush_channel(struct device
+
+ /* descriptors with their done bits set don't get the error */
+ rmb();
+- hdr = get_request_hdr(request, is_sec1);
++ hdr = get_request_hdr(dev, request, is_sec1);
+
+ if ((hdr & DESC_HDR_DONE) == DESC_HDR_DONE)
+ status = 0;
--- /dev/null
+From e360a6d65bb46c527a5909430a31d640cdd5036e Mon Sep 17 00:00:00 2001
+From: Vasily Khoruzhick <vasilykh@arista.com>
+Date: Tue, 14 Apr 2026 11:17:16 -0700
+Subject: EDAC/i10nm: Don't fail probing if ADXL is missing
+
+From: Vasily Khoruzhick <vasilykh@arista.com>
+
+commit e360a6d65bb46c527a5909430a31d640cdd5036e upstream.
+
+ADXL is not present in Coreboot- or Slimbootloader-based BIOSes and as
+result, the driver fails to probe there.
+
+Since commit 2738c69a8813 ("EDAC/i10nm: Add driver decoder for Ice Lake
+and Tremont CPUs"), i10nm_edac supports driver decoder. Switch to driver
+decoding when ADXL is not present.
+
+Signed-off-by: Vasily Khoruzhick <vasilykh@arista.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
+Cc: stable@vger.kernel.org # v6.1+
+Link: https://patch.msgid.link/20260414181735.87023-1-anarsoul@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/edac/i10nm_base.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -76,6 +76,7 @@ static struct res_config *res_cfg;
+ static int retry_rd_err_log;
+ static int decoding_via_mca;
+ static bool mem_cfg_2lm;
++static bool no_adxl;
+
+ static u32 offsets_scrub_icx[] = {0x22c60, 0x22c54, 0x22c5c, 0x22c58, 0x22c28, 0x20ed8};
+ static u32 offsets_scrub_spr[] = {0x22c60, 0x22c54, 0x22f08, 0x22c58, 0x22c28, 0x20ed8};
+@@ -826,8 +827,14 @@ static int __init i10nm_init(void)
+ }
+
+ rc = skx_adxl_get();
+- if (rc)
+- goto fail;
++ if (rc) {
++ /* Decoding errors via MCA banks for 2LM isn't supported yet */
++ if (rc != -ENODEV || mem_cfg_2lm)
++ goto fail;
++ i10nm_printk(KERN_INFO, "ADXL not found, falling back to MCA-based decoding.\n");
++ no_adxl = true;
++ decoding_via_mca = true;
++ }
+
+ opstate_init();
+ mce_register_decode_chain(&i10nm_mce_dec);
+@@ -861,7 +868,8 @@ static void __exit i10nm_exit(void)
+
+ teardown_i10nm_debug();
+ mce_unregister_decode_chain(&i10nm_mce_dec);
+- skx_adxl_put();
++ if (!no_adxl)
++ skx_adxl_put();
+ skx_remove();
+ }
+
crypto-drbg-fix-returning-success-on-failure-in-ctr_drbg.patch
crypto-drbg-fix-drbg_max_addtl-on-64-bit-kernels.patch
crypto-drbg-fix-the-fips_enabled-priority-boost.patch
+crypto-talitos-use-dma_sync_single_for_cpu-before-reading-descriptor-header.patch
+crypto-talitos-add-chaining-of-arbitrary-number-of-descriptor-for-the-sec1.patch
+crypto-talitos-move-dma-unmapping-code-in-flush_channel-into-a-standalone-dma_unmap_request-function.patch
+crypto-talitos-move-dma-mapping-code-in-talitos_submit-into-a-standalone-dma_map_request-function.patch
+crypto-talitos-move-code-in-current_desc_hdr-into-a-standalone-function.patch
+spi-fsl-lpspi-replace-dmaengine_terminate_all-with-dmaengine_terminate_sync.patch
+spi-fsl-lpspi-terminate-the-rx-channel-on-tx-prepare-failure-path.patch
+edac-i10nm-don-t-fail-probing-if-adxl-is-missing.patch
+watchdog-apple-add-apple-t8103-wdt-compatible.patch
--- /dev/null
+From e703ce47691b967fe9b4057fb1d062273211afa9 Mon Sep 17 00:00:00 2001
+From: Carlos Song <carlos.song@nxp.com>
+Date: Mon, 25 May 2026 14:23:56 +0800
+Subject: spi: fsl-lpspi: replace dmaengine_terminate_all() with dmaengine_terminate_sync()
+
+From: Carlos Song <carlos.song@nxp.com>
+
+commit e703ce47691b967fe9b4057fb1d062273211afa9 upstream.
+
+dmaengine_terminate_all() has been deprecated, so replace it with
+dmaengine_terminate_sync().
+
+Fixes: 09c04466ce7e ("spi: lpspi: add dma mode support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Carlos Song <carlos.song@nxp.com>
+Link: https://patch.msgid.link/20260525062357.3191349-2-carlos.song@oss.nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-fsl-lpspi.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -577,7 +577,7 @@ static int fsl_lpspi_dma_transfer(struct
+ tx->sgl, tx->nents, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_tx) {
+- dmaengine_terminate_all(controller->dma_tx);
++ dmaengine_terminate_sync(controller->dma_tx);
+ return -EINVAL;
+ }
+
+@@ -598,8 +598,8 @@ static int fsl_lpspi_dma_transfer(struct
+ transfer_timeout);
+ if (!timeout) {
+ dev_err(fsl_lpspi->dev, "I/O Error in DMA TX\n");
+- dmaengine_terminate_all(controller->dma_tx);
+- dmaengine_terminate_all(controller->dma_rx);
++ dmaengine_terminate_sync(controller->dma_tx);
++ dmaengine_terminate_sync(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -ETIMEDOUT;
+ }
+@@ -608,8 +608,8 @@ static int fsl_lpspi_dma_transfer(struct
+ transfer_timeout);
+ if (!timeout) {
+ dev_err(fsl_lpspi->dev, "I/O Error in DMA RX\n");
+- dmaengine_terminate_all(controller->dma_tx);
+- dmaengine_terminate_all(controller->dma_rx);
++ dmaengine_terminate_sync(controller->dma_tx);
++ dmaengine_terminate_sync(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -ETIMEDOUT;
+ }
+@@ -618,8 +618,8 @@ static int fsl_lpspi_dma_transfer(struct
+ fsl_lpspi->slave_aborted) {
+ dev_dbg(fsl_lpspi->dev,
+ "I/O Error in DMA TX interrupted\n");
+- dmaengine_terminate_all(controller->dma_tx);
+- dmaengine_terminate_all(controller->dma_rx);
++ dmaengine_terminate_sync(controller->dma_tx);
++ dmaengine_terminate_sync(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -EINTR;
+ }
+@@ -628,8 +628,8 @@ static int fsl_lpspi_dma_transfer(struct
+ fsl_lpspi->slave_aborted) {
+ dev_dbg(fsl_lpspi->dev,
+ "I/O Error in DMA RX interrupted\n");
+- dmaengine_terminate_all(controller->dma_tx);
+- dmaengine_terminate_all(controller->dma_rx);
++ dmaengine_terminate_sync(controller->dma_tx);
++ dmaengine_terminate_sync(controller->dma_rx);
+ fsl_lpspi_reset(fsl_lpspi);
+ return -EINTR;
+ }
--- /dev/null
+From 01980b5da56e573d62798d0ff6c86bcaa2b22cbe Mon Sep 17 00:00:00 2001
+From: Carlos Song <carlos.song@nxp.com>
+Date: Mon, 25 May 2026 14:23:57 +0800
+Subject: spi: fsl-lpspi: terminate the RX channel on TX prepare failure path
+
+From: Carlos Song <carlos.song@nxp.com>
+
+commit 01980b5da56e573d62798d0ff6c86bcaa2b22cbe upstream.
+
+When dmaengine_prep_slave_sg() fails for the TX channel, the error path
+terminates the TX DMA channel but leaves the RX channel running. Since
+the RX channel was already submitted and issued prior to preparing
+the TX descriptor, returning -EINVAL causes the SPI core to unmap the
+DMA buffers while the RX DMA engine continues writing to them, leading
+to potential memory corruption or use-after-free.
+
+Terminate the RX channel before returning on the TX prepare failure path.
+
+Fixes: 09c04466ce7e ("spi: lpspi: add dma mode support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Carlos Song <carlos.song@nxp.com>
+Link: https://patch.msgid.link/20260525062357.3191349-3-carlos.song@oss.nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-fsl-lpspi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-fsl-lpspi.c
++++ b/drivers/spi/spi-fsl-lpspi.c
+@@ -577,7 +577,7 @@ static int fsl_lpspi_dma_transfer(struct
+ tx->sgl, tx->nents, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ if (!desc_tx) {
+- dmaengine_terminate_sync(controller->dma_tx);
++ dmaengine_terminate_sync(controller->dma_rx);
+ return -EINVAL;
+ }
+
--- /dev/null
+From 14ca4868886f2188401fe06cd7bf01a330b3fb99 Mon Sep 17 00:00:00 2001
+From: Janne Grunau <j@jannau.net>
+Date: Wed, 31 Dec 2025 13:07:21 +0100
+Subject: watchdog: apple: Add "apple,t8103-wdt" compatible
+
+From: Janne Grunau <j@jannau.net>
+
+commit 14ca4868886f2188401fe06cd7bf01a330b3fb99 upstream.
+
+After discussion with the devicetree maintainers we agreed to not extend
+lists with the generic compatible "apple,wdt" anymore [1]. Use
+"apple,t8103-wdt" as base compatible as it is the SoC the driver and
+bindings were written for.
+
+[1]: https://lore.kernel.org/asahi/12ab93b7-1fc2-4ce0-926e-c8141cfe81bf@kernel.org/
+
+Fixes: 4ed224aeaf66 ("watchdog: Add Apple SoC watchdog driver")
+Cc: stable@vger.kernel.org
+Reviewed-by: Neal Gompa <neal@gompa.dev>
+Signed-off-by: Janne Grunau <j@jannau.net>
+Link: https://lore.kernel.org/r/20251231-watchdog-apple-t8103-base-compat-v1-1-1702a02e0c45@jannau.net
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/watchdog/apple_wdt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/watchdog/apple_wdt.c
++++ b/drivers/watchdog/apple_wdt.c
+@@ -207,6 +207,7 @@ static int apple_wdt_probe(struct platfo
+ }
+
+ static const struct of_device_id apple_wdt_of_match[] = {
++ { .compatible = "apple,t8103-wdt" },
+ { .compatible = "apple,wdt" },
+ {},
+ };