From b0ea5175358f0872ffdc9c6073585637dc01815a Mon Sep 17 00:00:00 2001 From: Judith Mendez Date: Mon, 9 Feb 2026 11:23:29 -0600 Subject: [PATCH 01/20] dt-bindings: hwinfo: ti,k3-socinfo: Add nvmem-cells support Add optional nvmem-cells and nvmem-cell-names properties to support reading silicon revision information from alternate location using NVMEM providers. This is used on AM62P to read GP_SW1 register for accurate silicon revision detection. Signed-off-by: Judith Mendez Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260209172330.53623-2-jm@ti.com Signed-off-by: Nishanth Menon --- .../devicetree/bindings/hwinfo/ti,k3-socinfo.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml index dada28b47ea0..2900224aac74 100644 --- a/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml +++ b/Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml @@ -15,6 +15,9 @@ description: | represented by CTRLMMR_xxx_JTAGID register which contains information about SoC id and revision. + On some SoCs like AM62P, the silicon revision is determined by reading + alternative registers via NVMEM cells. + properties: $nodename: pattern: "^chipid@[0-9a-f]+$" @@ -26,6 +29,14 @@ properties: reg: maxItems: 1 + nvmem-cells: + items: + - description: Alternate silicon revision register + + nvmem-cell-names: + items: + - const: gpsw1 + required: - compatible - reg From 97cfbd30525ef0df3de0681a4ca04a80a06d4f16 Mon Sep 17 00:00:00 2001 From: Judith Mendez Date: Mon, 9 Feb 2026 11:23:30 -0600 Subject: [PATCH 02/20] soc: ti: k3-socinfo: Add support for AM62P variants via NVMEM Add support for detecting AM62P silicon revisions. On AM62P, silicon revision is discovered with GP_SW1 register instead of JTAGID register. Use the NVMEM framework to read GP_SW1 from the gpsw-efuse nvmem provider to determine SoC revision. Signed-off-by: Judith Mendez Reviewed-by: Andrew Davis Link: https://patch.msgid.link/20260209172330.53623-3-jm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/k3-socinfo.c | 41 ++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/drivers/soc/ti/k3-socinfo.c b/drivers/soc/ti/k3-socinfo.c index 676041879eca..48dbef3acceb 100644 --- a/drivers/soc/ti/k3-socinfo.c +++ b/drivers/soc/ti/k3-socinfo.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -25,6 +26,8 @@ #define CTRLMMR_WKUP_JTAGID_VARIANT_SHIFT (28) #define CTRLMMR_WKUP_JTAGID_VARIANT_MASK GENMASK(31, 28) +#define GP_SW1_ADR_MASK GENMASK(3, 0) + #define CTRLMMR_WKUP_JTAGID_PARTNO_SHIFT (12) #define CTRLMMR_WKUP_JTAGID_PARTNO_MASK GENMASK(27, 12) @@ -70,6 +73,23 @@ static const char * const am62lx_rev_string_map[] = { "1.0", "1.1", }; +static const char * const am62p_gpsw_rev_string_map[] = { + "1.0", "1.1", "1.2", +}; + +static int +k3_chipinfo_get_gpsw_variant(struct device *dev) +{ + u32 gpsw_val = 0; + int ret; + + ret = nvmem_cell_read_u32(dev, "gpsw1", &gpsw_val); + if (ret) + return ret; + + return gpsw_val & GP_SW1_ADR_MASK; +} + static int k3_chipinfo_partno_to_names(unsigned int partno, struct soc_device_attribute *soc_dev_attr) @@ -86,9 +106,11 @@ k3_chipinfo_partno_to_names(unsigned int partno, } static int -k3_chipinfo_variant_to_sr(unsigned int partno, unsigned int variant, - struct soc_device_attribute *soc_dev_attr) +k3_chipinfo_variant_to_sr(struct device *dev, unsigned int partno, + unsigned int variant, struct soc_device_attribute *soc_dev_attr) { + int gpsw_variant = 0; + switch (partno) { case JTAG_ID_PARTNO_J721E: if (variant >= ARRAY_SIZE(j721e_rev_string_map)) @@ -102,6 +124,19 @@ k3_chipinfo_variant_to_sr(unsigned int partno, unsigned int variant, soc_dev_attr->revision = kasprintf(GFP_KERNEL, "SR%s", am62lx_rev_string_map[variant]); break; + case JTAG_ID_PARTNO_AM62PX: + /* Check GP_SW1 for silicon revision */ + gpsw_variant = k3_chipinfo_get_gpsw_variant(dev); + if (gpsw_variant == -EPROBE_DEFER) + return gpsw_variant; + if (gpsw_variant < 0 || gpsw_variant >= ARRAY_SIZE(am62p_gpsw_rev_string_map)) { + dev_warn(dev, "Failed to get silicon variant (%d), set SR1.0\n", + gpsw_variant); + gpsw_variant = 0; + } + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "SR%s", + am62p_gpsw_rev_string_map[gpsw_variant]); + break; default: variant++; soc_dev_attr->revision = kasprintf(GFP_KERNEL, "SR%x.0", @@ -173,7 +208,7 @@ static int k3_chipinfo_probe(struct platform_device *pdev) goto err; } - ret = k3_chipinfo_variant_to_sr(partno_id, variant, soc_dev_attr); + ret = k3_chipinfo_variant_to_sr(dev, partno_id, variant, soc_dev_attr); if (ret) { dev_err(dev, "Unknown SoC SR[0x%08X]: %d\n", jtag_id, ret); goto err; From af76cdcf02b7be9277af999f0e316943d94d7fd4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 28 Feb 2026 17:12:28 -0800 Subject: [PATCH 03/20] soc: ti: knav_dma: fix all kernel-doc warnings in knav_dma.h Use correct struct member names and formats to avoid kernel-doc warnings: Warning: include/linux/soc/ti/knav_dma.h:83 struct member 'priority' not described in 'knav_dma_tx_cfg' Warning: include/linux/soc/ti/knav_dma.h:113 struct member 'err_mode' not described in 'knav_dma_rx_cfg' Warning: include/linux/soc/ti/knav_dma.h:113 struct member 'desc_type' not described in 'knav_dma_rx_cfg' Warning: include/linux/soc/ti/knav_dma.h:113 struct member 'fdq' not described in 'knav_dma_rx_cfg' Warning: include/linux/soc/ti/knav_dma.h:127 struct member 'direction' not described in 'knav_dma_cfg' Warning: include/linux/soc/ti/knav_dma.h:127 struct member 'u' not described in 'knav_dma_cfg' Signed-off-by: Randy Dunlap Link: https://patch.msgid.link/20260301011228.3064940-1-rdunlap@infradead.org Signed-off-by: Nishanth Menon --- include/linux/soc/ti/knav_dma.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/linux/soc/ti/knav_dma.h b/include/linux/soc/ti/knav_dma.h index 18d806a8e52c..eb1e6b014eaf 100644 --- a/include/linux/soc/ti/knav_dma.h +++ b/include/linux/soc/ti/knav_dma.h @@ -75,7 +75,7 @@ enum knav_dma_desc_type { * struct knav_dma_tx_cfg: Tx channel configuration * @filt_einfo: Filter extended packet info * @filt_pswords: Filter PS words present - * @knav_dma_tx_priority: Tx channel scheduling priority + * @priority: Tx channel scheduling priority */ struct knav_dma_tx_cfg { bool filt_einfo; @@ -87,13 +87,13 @@ struct knav_dma_tx_cfg { * struct knav_dma_rx_cfg: Rx flow configuration * @einfo_present: Extended packet info present * @psinfo_present: PS words present - * @knav_dma_rx_err_mode: Error during buffer starvation - * @knav_dma_desc_type: Host or Monolithic desc + * @err_mode: Error during buffer starvation + * @desc_type: Host or Monolithic desc * @psinfo_at_sop: PS word located at start of packet * @sop_offset: Start of packet offset * @dst_q: Destination queue for a given flow * @thresh: Rx flow size threshold - * @fdq[]: Free desc Queue array + * @fdq: Free desc Queue array * @sz_thresh0: RX packet size threshold 0 * @sz_thresh1: RX packet size threshold 1 * @sz_thresh2: RX packet size threshold 2 @@ -115,7 +115,8 @@ struct knav_dma_rx_cfg { /** * struct knav_dma_cfg: Pktdma channel configuration - * @sl_cfg: Slave configuration + * @direction: DMA transfer mode and direction + * @u: union containing @tx or @rx * @tx: Tx channel configuration * @rx: Rx flow configuration */ From b920352cfd2b0fcd1249ff006618c939b64fc8f7 Mon Sep 17 00:00:00 2001 From: Siddharth Vadapalli Date: Fri, 1 May 2026 18:10:54 +0530 Subject: [PATCH 04/20] soc: ti: k3-ringacc: Fix access mode for k3_ringacc_ring_pop_tail_io/proxy k3_ringacc_ring_pop_tail_io() and k3_ringacc_ring_pop_tail_proxy() incorrectly use K3_RINGACC_ACCESS_MODE_POP_HEAD instead of K3_RINGACC_ACCESS_MODE_POP_TAIL. This will result in ring elements being popped in the reverse order of that which the caller expects. Fix this. Fixes: 3277e8aa2504 ("soc: ti: k3: add navss ringacc driver") Cc: stable@vger.kernel.org Signed-off-by: Siddharth Vadapalli Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260501124129.362192-1-s-vadapalli@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/k3-ringacc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c index 7602b8a909b0..e2ca380812d2 100644 --- a/drivers/soc/ti/k3-ringacc.c +++ b/drivers/soc/ti/k3-ringacc.c @@ -1012,7 +1012,7 @@ static int k3_ringacc_ring_pop_head_proxy(struct k3_ring *ring, void *elem) static int k3_ringacc_ring_pop_tail_proxy(struct k3_ring *ring, void *elem) { return k3_ringacc_ring_access_proxy(ring, elem, - K3_RINGACC_ACCESS_MODE_POP_HEAD); + K3_RINGACC_ACCESS_MODE_POP_TAIL); } static int k3_ringacc_ring_access_io(struct k3_ring *ring, void *elem, @@ -1083,7 +1083,7 @@ static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem) static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void *elem) { return k3_ringacc_ring_access_io(ring, elem, - K3_RINGACC_ACCESS_MODE_POP_HEAD); + K3_RINGACC_ACCESS_MODE_POP_TAIL); } /* From 10a1969353b20caa50c320717e054601631c0d3e Mon Sep 17 00:00:00 2001 From: Md Shofiqul Islam Date: Wed, 6 May 2026 18:41:14 +0300 Subject: [PATCH 05/20] soc: ti: knav_qmss_queue: Implement resource cleanup in remove() Implement the TODO in knav_queue_remove() by stopping PDSPs and freeing queue regions and queue ranges before disabling runtime PM, mirroring the cleanup performed in the probe error path. Set device_ready to false before cleanup to prevent any further use of the device during teardown. This ensures resources are released on driver unbind and avoids leaking queue/region state. Suggested-by: Nishanth Menon Signed-off-by: Md Shofiqul Islam Link: https://lore.kernel.org/linux-arm-kernel/20260506154114.2288-1-shofiqtest@gmail.com/ Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss_queue.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 86d7a9c9ae01..a0644578789f 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -1873,7 +1873,12 @@ static int knav_queue_probe(struct platform_device *pdev) static void knav_queue_remove(struct platform_device *pdev) { - /* TODO: Free resources */ + struct knav_device *kdev = platform_get_drvdata(pdev); + + device_ready = false; + knav_queue_stop_pdsps(kdev); + knav_queue_free_regions(kdev); + knav_free_queue_ranges(kdev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); } From a76c24eb1f10366f128c621f876c20a13ae53489 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:13 -0500 Subject: [PATCH 06/20] soc: ti: knav_qmss: Remove remaining redundant ENOMEM printks Commit 168d2fb78055 ("soc: ti: knav_qmss: Remove ENOMEM printks") removed redundant dev_err() calls after allocation failures in knav_queue_setup_regions, knav_queue_init_qmgrs and knav_queue_init_pdsps, but missed three further instances in knav_pool_create, knav_queue_setup_region and knav_setup_queue_range. Remove the missed instances. Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-2-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss_queue.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index a0644578789f..c5669a371312 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -769,10 +769,8 @@ void *knav_pool_create(const char *name, return ERR_PTR(-ENODEV); pool = devm_kzalloc(kdev->dev, sizeof(*pool), GFP_KERNEL); - if (!pool) { - dev_err(kdev->dev, "out of memory allocating pool\n"); + if (!pool) return ERR_PTR(-ENOMEM); - } for_each_region(kdev, reg_itr) { if (reg_itr->id != region_id) @@ -1025,10 +1023,8 @@ static void knav_queue_setup_region(struct knav_device *kdev, region->dma_end = region->dma_start + size; pool = devm_kzalloc(kdev->dev, sizeof(*pool), GFP_KERNEL); - if (!pool) { - dev_err(kdev->dev, "out of memory allocating dummy pool\n"); + if (!pool) goto fail; - } pool->num_desc = 0; pool->region_offset = region->num_desc; list_add(&pool->region_inst, ®ion->pools); @@ -1211,10 +1207,8 @@ static int knav_setup_queue_range(struct knav_device *kdev, int ret, i; range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL); - if (!range) { - dev_err(dev, "out of memory allocating range\n"); + if (!range) return -ENOMEM; - } range->kdev = kdev; range->name = knav_queue_find_name(node); From 7db27a04fb8a33a7f9904961ee6f3c75f65d1118 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:14 -0500 Subject: [PATCH 07/20] soc: ti: knav_qmss: Rename global kdev to knav_qdev to fix -Wshadow Building with W=2 (clang, LLVM=1) produces 22 -Wshadow warnings in knav_qmss_queue.c because the file-scoped singleton 'kdev' is shadowed by a parameter of the same name in 21 internal functions and one local variable, e.g.: knav_qmss_queue.c:194:49: warning: declaration shadows a variable in the global scope [-Wshadow] 194 | knav_queue_match_id_to_inst(struct knav_device *kdev, unsigned id) Rename the global singleton from kdev to knav_qdev rather than renaming all ~21 function parameters, as this requires fewer changes and leaves function signatures, struct field accesses, and header macros in knav_qmss.h untouched. Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-3-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss_queue.c | 94 ++++++++++++++++---------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index c5669a371312..52a30abb2caf 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -25,7 +25,7 @@ #include "knav_qmss.h" -static struct knav_device *kdev; +static struct knav_device *knav_qdev; static DEFINE_MUTEX(knav_dev_lock); #define knav_dev_lock_held() \ lockdep_is_held(&knav_dev_lock) @@ -205,10 +205,10 @@ knav_queue_match_id_to_inst(struct knav_device *kdev, unsigned id) static inline struct knav_queue_inst *knav_queue_find_by_id(int id) { - if (kdev->base_id <= id && - kdev->base_id + kdev->num_queues > id) { - id -= kdev->base_id; - return knav_queue_match_id_to_inst(kdev, id); + if (knav_qdev->base_id <= id && + knav_qdev->base_id + knav_qdev->num_queues > id) { + id -= knav_qdev->base_id; + return knav_queue_match_id_to_inst(knav_qdev, id); } return NULL; } @@ -296,7 +296,7 @@ static struct knav_queue *knav_queue_open_by_type(const char *name, mutex_lock(&knav_dev_lock); - for_each_instance(idx, inst, kdev) { + for_each_instance(idx, inst, knav_qdev) { if (knav_queue_is_reserved(inst)) continue; if (!knav_queue_match_type(inst, type)) @@ -469,9 +469,9 @@ static int knav_queue_debug_show(struct seq_file *s, void *v) mutex_lock(&knav_dev_lock); seq_printf(s, "%s: %u-%u\n", - dev_name(kdev->dev), kdev->base_id, - kdev->base_id + kdev->num_queues - 1); - for_each_instance(idx, inst, kdev) + dev_name(knav_qdev->dev), knav_qdev->base_id, + knav_qdev->base_id + knav_qdev->num_queues - 1); + for_each_instance(idx, inst, knav_qdev) knav_queue_debug_show_instance(s, inst); mutex_unlock(&knav_dev_lock); @@ -762,17 +762,17 @@ void *knav_pool_create(const char *name, unsigned last_offset; int ret; - if (!kdev) + if (!knav_qdev) return ERR_PTR(-EPROBE_DEFER); - if (!kdev->dev) + if (!knav_qdev->dev) return ERR_PTR(-ENODEV); - pool = devm_kzalloc(kdev->dev, sizeof(*pool), GFP_KERNEL); + pool = devm_kzalloc(knav_qdev->dev, sizeof(*pool), GFP_KERNEL); if (!pool) return ERR_PTR(-ENOMEM); - for_each_region(kdev, reg_itr) { + for_each_region(knav_qdev, reg_itr) { if (reg_itr->id != region_id) continue; region = reg_itr; @@ -780,14 +780,14 @@ void *knav_pool_create(const char *name, } if (!region) { - dev_err(kdev->dev, "region-id(%d) not found\n", region_id); + dev_err(knav_qdev->dev, "region-id(%d) not found\n", region_id); ret = -EINVAL; goto err; } pool->queue = knav_queue_open(name, KNAV_QUEUE_GP, 0); if (IS_ERR(pool->queue)) { - dev_err(kdev->dev, + dev_err(knav_qdev->dev, "failed to open queue for pool(%s), error %ld\n", name, PTR_ERR(pool->queue)); ret = PTR_ERR(pool->queue); @@ -795,13 +795,13 @@ void *knav_pool_create(const char *name, } pool->name = kstrndup(name, KNAV_NAME_SIZE - 1, GFP_KERNEL); - pool->kdev = kdev; - pool->dev = kdev->dev; + pool->kdev = knav_qdev; + pool->dev = knav_qdev->dev; mutex_lock(&knav_dev_lock); if (num_desc > (region->num_desc - region->used_desc)) { - dev_err(kdev->dev, "out of descs in region(%d) for pool(%s)\n", + dev_err(knav_qdev->dev, "out of descs in region(%d) for pool(%s)\n", region_id, name); ret = -ENOMEM; goto err_unlock; @@ -827,10 +827,10 @@ void *knav_pool_create(const char *name, pool->num_desc = num_desc; pool->region_offset = last_offset; region->used_desc += num_desc; - list_add_tail(&pool->list, &kdev->pools); + list_add_tail(&pool->list, &knav_qdev->pools); list_add_tail(&pool->region_inst, node); } else { - dev_err(kdev->dev, "pool(%s) create failed: fragmented desc pool in region(%d)\n", + dev_err(knav_qdev->dev, "pool(%s) create failed: fragmented desc pool in region(%d)\n", name, region_id); ret = -ENOMEM; goto err_unlock; @@ -844,7 +844,7 @@ void *knav_pool_create(const char *name, mutex_unlock(&knav_dev_lock); err: kfree(pool->name); - devm_kfree(kdev->dev, pool); + devm_kfree(knav_qdev->dev, pool); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(knav_pool_create); @@ -872,7 +872,7 @@ void knav_pool_destroy(void *ph) mutex_unlock(&knav_dev_lock); kfree(pool->name); - devm_kfree(kdev->dev, pool); + devm_kfree(knav_qdev->dev, pool); } EXPORT_SYMBOL_GPL(knav_pool_destroy); @@ -1683,7 +1683,7 @@ static inline struct knav_qmgr_info *knav_find_qmgr(unsigned id) { struct knav_qmgr_info *qmgr; - for_each_qmgr(kdev, qmgr) { + for_each_qmgr(knav_qdev, qmgr) { if ((id >= qmgr->start_queue) && (id < qmgr->start_queue + qmgr->num_queues)) return qmgr; @@ -1775,22 +1775,22 @@ static int knav_queue_probe(struct platform_device *pdev) return -ENODEV; } - kdev = devm_kzalloc(dev, sizeof(struct knav_device), GFP_KERNEL); - if (!kdev) { + knav_qdev = devm_kzalloc(dev, sizeof(struct knav_device), GFP_KERNEL); + if (!knav_qdev) { dev_err(dev, "memory allocation failed\n"); return -ENOMEM; } if (device_get_match_data(dev)) - kdev->version = QMSS_66AK2G; + knav_qdev->version = QMSS_66AK2G; - platform_set_drvdata(pdev, kdev); - kdev->dev = dev; - INIT_LIST_HEAD(&kdev->queue_ranges); - INIT_LIST_HEAD(&kdev->qmgrs); - INIT_LIST_HEAD(&kdev->pools); - INIT_LIST_HEAD(&kdev->regions); - INIT_LIST_HEAD(&kdev->pdsps); + platform_set_drvdata(pdev, knav_qdev); + knav_qdev->dev = dev; + INIT_LIST_HEAD(&knav_qdev->queue_ranges); + INIT_LIST_HEAD(&knav_qdev->qmgrs); + INIT_LIST_HEAD(&knav_qdev->pools); + INIT_LIST_HEAD(&knav_qdev->regions); + INIT_LIST_HEAD(&knav_qdev->pdsps); pm_runtime_enable(&pdev->dev); ret = pm_runtime_resume_and_get(&pdev->dev); @@ -1805,31 +1805,31 @@ static int knav_queue_probe(struct platform_device *pdev) ret = -ENODEV; goto err; } - kdev->base_id = temp[0]; - kdev->num_queues = temp[1]; + knav_qdev->base_id = temp[0]; + knav_qdev->num_queues = temp[1]; /* Initialize queue managers using device tree configuration */ - ret = knav_queue_init_qmgrs(kdev, node); + ret = knav_queue_init_qmgrs(knav_qdev, node); if (ret) goto err; /* get pdsp configuration values from device tree */ - ret = knav_queue_setup_pdsps(kdev, node); + ret = knav_queue_setup_pdsps(knav_qdev, node); if (ret) goto err; /* get usable queue range values from device tree */ - ret = knav_setup_queue_pools(kdev, node); + ret = knav_setup_queue_pools(knav_qdev, node); if (ret) goto err; - ret = knav_get_link_ram(kdev, "linkram0", &kdev->link_rams[0]); + ret = knav_get_link_ram(knav_qdev, "linkram0", &knav_qdev->link_rams[0]); if (ret) { - dev_err(kdev->dev, "could not setup linking ram\n"); + dev_err(knav_qdev->dev, "could not setup linking ram\n"); goto err; } - ret = knav_get_link_ram(kdev, "linkram1", &kdev->link_rams[1]); + ret = knav_get_link_ram(knav_qdev, "linkram1", &knav_qdev->link_rams[1]); if (ret) { /* * nothing really, we have one linking ram already, so we just @@ -1837,15 +1837,15 @@ static int knav_queue_probe(struct platform_device *pdev) */ } - ret = knav_queue_setup_link_ram(kdev); + ret = knav_queue_setup_link_ram(knav_qdev); if (ret) goto err; - ret = knav_queue_setup_regions(kdev, node); + ret = knav_queue_setup_regions(knav_qdev, node); if (ret) goto err; - ret = knav_queue_init_queues(kdev); + ret = knav_queue_init_queues(knav_qdev); if (ret < 0) { dev_err(dev, "hwqueue initialization failed\n"); goto err; @@ -1857,9 +1857,9 @@ static int knav_queue_probe(struct platform_device *pdev) return 0; err: - knav_queue_stop_pdsps(kdev); - knav_queue_free_regions(kdev); - knav_free_queue_ranges(kdev); + knav_queue_stop_pdsps(knav_qdev); + knav_queue_free_regions(knav_qdev); + knav_free_queue_ranges(knav_qdev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; From b6542cf0f4d062133f6e05de03382080ad941c67 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:15 -0500 Subject: [PATCH 08/20] soc: ti: knav_qmss: Inline lockdep condition in for_each_handle_rcu knav_dev_lock_held() is a single-use wrapper around lockdep_is_held(&knav_dev_lock), used only as the lockdep condition in for_each_handle_rcu. When CONFIG_PROVE_RCU_LIST is disabled, list_for_each_entry_rcu() elides the condition argument entirely, causing clang to report the macro as unused with W=2: knav_qmss_queue.c:30:9: warning: macro is not used [-Wunused-macros] 30 | #define knav_dev_lock_held() \ Remove the intermediate macro and open-code lockdep_is_held() directly in the for_each_handle_rcu definition. Reviewed-by: Andrew Davis Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-4-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss_queue.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 52a30abb2caf..68c55134ad6c 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -27,9 +27,6 @@ static struct knav_device *knav_qdev; static DEFINE_MUTEX(knav_dev_lock); -#define knav_dev_lock_held() \ - lockdep_is_held(&knav_dev_lock) - /* Queue manager register indices in DTS */ #define KNAV_QUEUE_PEEK_REG_INDEX 0 #define KNAV_QUEUE_STATUS_REG_INDEX 1 @@ -58,7 +55,7 @@ static DEFINE_MUTEX(knav_dev_lock); #define for_each_handle_rcu(qh, inst) \ list_for_each_entry_rcu(qh, &inst->handles, list, \ - knav_dev_lock_held()) + lockdep_is_held(&knav_dev_lock)) #define for_each_instance(idx, inst, kdev) \ for (idx = 0, inst = kdev->instances; \ From 7650590dbf12a3d4a3d302cd33ac31270e39c43c Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:16 -0500 Subject: [PATCH 09/20] soc: ti: knav_qmss: Fix kernel-doc Return: tags Fix functions that use inline 'Returns ...' instead of 'Return:' kernel-doc comments, producing warnings with W=2: knav_qmss_queue.c:524: No description found for return value of 'knav_queue_open' Tested-by: Randy Dunlap Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Acked-by: Randy Dunlap Link: https://patch.msgid.link/20260512170623.3174416-5-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss_queue.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 68c55134ad6c..7e3c05554254 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -517,7 +517,7 @@ static int knav_queue_flush(struct knav_queue *qh) * Subsequent attempts to open a shared queue should * also have this flag. * - * Returns a handle to the open hardware queue if successful. Use IS_ERR() + * Return: handle to the open hardware queue on success. Use IS_ERR() * to check the returned value for error codes. */ void *knav_queue_open(const char *name, unsigned id, @@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(knav_queue_close); * @cmd: - control commands * @arg: - command argument * - * Returns 0 on success, errno otherwise. + * Return: 0 on success, errno otherwise. */ int knav_queue_device_control(void *qhandle, enum knav_queue_ctrl_cmd cmd, unsigned long arg) @@ -625,7 +625,7 @@ EXPORT_SYMBOL_GPL(knav_queue_device_control); * @size: - size of data to push * @flags: - can be used to pass additional information * - * Returns 0 on success, errno otherwise. + * Return: 0 on success, errno otherwise. */ int knav_queue_push(void *qhandle, dma_addr_t dma, unsigned size, unsigned flags) @@ -646,7 +646,7 @@ EXPORT_SYMBOL_GPL(knav_queue_push); * @qhandle: - hardware queue handle * @size: - (optional) size of the data pop'ed. * - * Returns a DMA address on success, 0 on failure. + * Return: DMA address on success, 0 on failure. */ dma_addr_t knav_queue_pop(void *qhandle, unsigned *size) { @@ -747,8 +747,8 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_dma_to_virt); * @region_id: - QMSS region id from which the descriptors are to be * allocated. * - * Returns a pool handle on success. - * Use IS_ERR_OR_NULL() to identify error values on return. + * Return: pool handle on success. Use IS_ERR_OR_NULL() to identify + * error values on return. */ void *knav_pool_create(const char *name, int num_desc, int region_id) @@ -878,7 +878,7 @@ EXPORT_SYMBOL_GPL(knav_pool_destroy); * knav_pool_desc_get() - Get a descriptor from the pool * @ph: - pool handle * - * Returns descriptor from the pool. + * Return: descriptor from the pool on success, error pointer otherwise. */ void *knav_pool_desc_get(void *ph) { @@ -917,7 +917,7 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_put); * @dma: - DMA address return pointer * @dma_sz: - adjusted return pointer * - * Returns 0 on success, errno otherwise. + * Return: 0 on success, errno otherwise. */ int knav_pool_desc_map(void *ph, void *desc, unsigned size, dma_addr_t *dma, unsigned *dma_sz) @@ -942,7 +942,7 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_map); * @dma: - DMA address of descriptor to unmap * @dma_sz: - size of descriptor to unmap * - * Returns descriptor address on success, Use IS_ERR_OR_NULL() to identify + * Return: descriptor address on success. Use IS_ERR_OR_NULL() to identify * error values on return. */ void *knav_pool_desc_unmap(void *ph, dma_addr_t dma, unsigned dma_sz) @@ -962,7 +962,8 @@ EXPORT_SYMBOL_GPL(knav_pool_desc_unmap); /** * knav_pool_count() - Get the number of descriptors in pool. * @ph: - pool handle - * Returns number of elements in the pool. + * + * Return: number of elements in the pool. */ int knav_pool_count(void *ph) { From a5f624c4fee6d7b51f7bc4bd6e213c220b610ec3 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:17 -0500 Subject: [PATCH 10/20] soc: ti: knav_qmss: Use %pe to print PTR_ERR() Coccinelle (scripts/coccinelle/misc/ptr_err_to_pe.cocci) flags the dev_err() call in knav_pool_create(): knav_qmss_queue.c:789:9-16: WARNING: Consider using %pe to print PTR_ERR() Replace the %ld / PTR_ERR() pair with %pe and pass the error pointer directly to also print the symbolic error name. Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-6-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss_queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 7e3c05554254..8af88a143159 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -785,8 +785,8 @@ void *knav_pool_create(const char *name, pool->queue = knav_queue_open(name, KNAV_QUEUE_GP, 0); if (IS_ERR(pool->queue)) { dev_err(knav_qdev->dev, - "failed to open queue for pool(%s), error %ld\n", - name, PTR_ERR(pool->queue)); + "failed to open queue for pool(%s), error %pe\n", + name, pool->queue); ret = PTR_ERR(pool->queue); goto err; } From cb1a271a4f20faae9a10891bfae2b543778d2b4a Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:18 -0500 Subject: [PATCH 11/20] soc: ti: knav_qmss: Fix __iomem annotations and __be32 type Fix several address-space and type annotation issues reported by sparse: - Change pdsp->command from 'void __iomem *' to 'u32 __iomem *' to match the other union members (acc_command, qos_command); adjust the offset in knav_queue_load_pdsp() from +0x18 to +0x6 to preserve the 24-byte offset. - Fix knav_queue_pdsp_wait() declaration: correct the parameter annotation from 'u32 * __iomem' (pointer-in-iomem-space) to 'u32 __iomem *' (pointer-to-iomem); use 'unsigned int' for the timeout parameter instead of bare 'unsigned'; fix the continuation- line alignment. - Use IOMEM_ERR_PTR() in knav_queue_map_reg() instead of ERR_PTR() when returning an error as void __iomem *. - Annotate the firmware data array as 'const __be32 *' instead of 'u32 *', as be32_to_cpu() requires __be32 input. Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-7-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss.h | 2 +- drivers/soc/ti/knav_qmss_queue.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h index 9325e8ce2e25..037dc1b36645 100644 --- a/drivers/soc/ti/knav_qmss.h +++ b/drivers/soc/ti/knav_qmss.h @@ -123,7 +123,7 @@ struct knav_pdsp_info { const char *name; struct knav_reg_pdsp_regs __iomem *regs; union { - void __iomem *command; + u32 __iomem *command; struct knav_reg_acc_command __iomem *acc_command; u32 __iomem *qos_command; }; diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 8af88a143159..7410b63af0e6 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -477,8 +477,8 @@ static int knav_queue_debug_show(struct seq_file *s, void *v) DEFINE_SHOW_ATTRIBUTE(knav_queue_debug); -static inline int knav_queue_pdsp_wait(u32 * __iomem addr, unsigned timeout, - u32 flags) +static inline int knav_queue_pdsp_wait(u32 __iomem *addr, unsigned int timeout, + u32 flags) { unsigned long end; u32 val = 0; @@ -1368,7 +1368,7 @@ static void __iomem *knav_queue_map_reg(struct knav_device *kdev, if (ret) { dev_err(kdev->dev, "Can't translate of node(%pOFn) address for index(%d)\n", node, index); - return ERR_PTR(ret); + return IOMEM_ERR_PTR(ret); } regs = devm_ioremap_resource(kdev->dev, &res); @@ -1556,7 +1556,7 @@ static int knav_queue_load_pdsp(struct knav_device *kdev, int i, ret, fwlen; const struct firmware *fw; bool found = false; - u32 *fwdata; + const __be32 *fwdata; for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) { if (knav_acc_firmwares[i]) { @@ -1578,9 +1578,9 @@ static int knav_queue_load_pdsp(struct knav_device *kdev, dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n", knav_acc_firmwares[i]); - writel_relaxed(pdsp->id + 1, pdsp->command + 0x18); + writel_relaxed(pdsp->id + 1, pdsp->command + 0x6); /* download the firmware */ - fwdata = (u32 *)fw->data; + fwdata = (const __be32 *)fw->data; fwlen = (fw->size + sizeof(u32) - 1) / sizeof(u32); for (i = 0; i < fwlen; i++) writel_relaxed(be32_to_cpu(fwdata[i]), pdsp->iram + i); From ebc1a345bf1166b22035f0cfbf877b9d0e80ba4e Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:19 -0500 Subject: [PATCH 12/20] soc: ti: knav_qmss_acc: Fix kernel-doc Return: tag Fix knav_init_acc_range() use of 'Return ...' instead of 'Return:' kernel-doc comment, which produces a warning with W=2: knav_qmss_acc.c:473: No description found for return value of 'knav_init_acc_range' Tested-by: Randy Dunlap Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Acked-by: Randy Dunlap Link: https://patch.msgid.link/20260512170623.3174416-8-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_qmss_acc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c index 269b4e75ae40..1f8b5acdd462 100644 --- a/drivers/soc/ti/knav_qmss_acc.c +++ b/drivers/soc/ti/knav_qmss_acc.c @@ -466,7 +466,7 @@ static const struct knav_range_ops knav_acc_range_ops = { * @node: device node * @range: qmms range information * - * Return 0 on success or error + * Return: 0 on success, errno otherwise. */ int knav_init_acc_range(struct knav_device *kdev, struct device_node *node, From 2b47cc255a952d3bd7ec3c0f38fdd81ccde3cb58 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:20 -0500 Subject: [PATCH 13/20] soc: ti: knav_dma: Remove unused DMA_PRIO_MASK macro DMA_PRIO_MASK (GENMASK(3, 0)) is defined alongside the other priority macros but is never referenced in the code. tx_priority and rx_priority are only ever assigned DMA_PRIO_DEFAULT (0) and are never sourced from device tree or user-controlled input, so no out-of-range value is possible. W=2 builds report: knav_dma.c:32:9: warning: macro is not used [-Wunused-macros] 32 | #define DMA_PRIO_MASK GENMASK(3, 0) Remove the dead macro. Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-9-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index e5f5e3142fc4..462d181ca564 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -29,7 +29,6 @@ #define DMA_TX_FILT_EINFO BIT(30) #define DMA_TX_PRIO_SHIFT 0 #define DMA_RX_PRIO_SHIFT 16 -#define DMA_PRIO_MASK GENMASK(3, 0) #define DMA_PRIO_DEFAULT 0 #define DMA_RX_TIMEOUT_DEFAULT 17500 /* cycles */ #define DMA_RX_TIMEOUT_MASK GENMASK(16, 0) From fe5272e13e34025a9bb10cc452805e5085492a92 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:21 -0500 Subject: [PATCH 14/20] soc: ti: knav_dma: Remove dead check on unsigned args.args[0] smatch warns: knav_dma.c:390 of_channel_match_helper() warn: unsigned 'args.args[0]' is never less than zero. of_phandle_args.args[] is uint32_t, so the 'args.args[0] < 0' check is always false. of_parse_phandle_with_fixed_args() already handles errors by returning a non-zero code, which is checked immediately above. Remove the dead check. Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-10-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_dma.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index 462d181ca564..7ba6fd58e9ce 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -387,11 +387,6 @@ static int of_channel_match_helper(struct device_node *np, const char *name, return -ENODEV; } - if (args.args[0] < 0) { - dev_err(kdev->dev, "Missing args for %s\n", name); - return -ENODEV; - } - return args.args[0]; } From 81f2c17bc0596f619616a2e85fab142c8316de85 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:22 -0500 Subject: [PATCH 15/20] soc: ti: knav_dma: Use IOMEM_ERR_PTR() in pktdma_get_regs() pktdma_get_regs() returns a void __iomem * but uses ERR_PTR() on the error path, causing sparse to warn about an address space mismatch. Replace ERR_PTR() with IOMEM_ERR_PTR() to resolve the warning cleanly. Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-11-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/knav_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c index 7ba6fd58e9ce..96df3982e47b 100644 --- a/drivers/soc/ti/knav_dma.c +++ b/drivers/soc/ti/knav_dma.c @@ -520,7 +520,7 @@ static void __iomem *pktdma_get_regs(struct knav_dma_device *dma, if (ret) { dev_err(dev, "Can't translate of node(%pOFn) address for index(%d)\n", node, index); - return ERR_PTR(ret); + return IOMEM_ERR_PTR(ret); } regs = devm_ioremap_resource(kdev->dev, &res); From 33050d81b828c7d699ad0ad0c7489a198c527019 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Tue, 12 May 2026 12:06:23 -0500 Subject: [PATCH 16/20] soc: ti: k3-ringacc: Use str_enabled_disabled() helper Coccinelle (scripts/coccinelle/api/string_choices.cocci) flags an opportunity to replace the open-coded ternary expression in the probe dev_info() call: k3-ringacc.c:1439:3-32: opportunity for str_enabled_disabled(ringacc->dma_ring_reset_quirk) Replace the ternary with str_enabled_disabled() and add the required include for . Reviewed-by: Sai Sree Kartheek Adivi Reviewed-by: Hari Prasath Gujulan Elango Link: https://patch.msgid.link/20260512170623.3174416-12-nm@ti.com Signed-off-by: Nishanth Menon --- drivers/soc/ti/k3-ringacc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c index e2ca380812d2..5966db4327b1 100644 --- a/drivers/soc/ti/k3-ringacc.c +++ b/drivers/soc/ti/k3-ringacc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1436,7 +1437,7 @@ static int k3_ringacc_init(struct platform_device *pdev, ringacc->rm_gp_range->desc[0].num, ringacc->tisci_dev_id); dev_info(dev, "dma-ring-reset-quirk: %s\n", - ringacc->dma_ring_reset_quirk ? "enabled" : "disabled"); + str_enabled_disabled(ringacc->dma_ring_reset_quirk)); dev_info(dev, "RA Proxy rev. %08x, num_proxies:%u\n", readl(&ringacc->proxy_gcfg->revision), ringacc->num_proxies); From e9f06763b9b88cb1338ef8a3f113b0fb94d714dd Mon Sep 17 00:00:00 2001 From: "Thomas Richard (TI)" Date: Tue, 19 May 2026 17:06:56 +0200 Subject: [PATCH 17/20] firmware: ti_sci: Add BOARDCFG_MANAGED mode support In BOARDCFG_MANAGED mode, the low power mode configuration is done statically for the DM via the boardcfg. Constraints are not supported, and prepare_sleep() is not needed. Reviewed-by: Dhruva Gole Reviewed-by: Kendall Willis Signed-off-by: Thomas Richard (TI) Link: https://patch.msgid.link/20260519-ti-sci-jacinto-s2r-restore-irq-v9-1-c550a8ae0f31@bootlin.com Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 10 +++++++--- drivers/firmware/ti_sci.h | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index e027a2bd8f26..a8dcdbe874b6 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -3770,8 +3770,11 @@ static int ti_sci_prepare_system_suspend(struct ti_sci_info *info) return ti_sci_cmd_prepare_sleep(&info->handle, TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED, 0, 0, 0); + } else if (info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED) { + /* Nothing to do in the BOARDCFG_MANAGED mode */ + return 0; } else { - /* DM Managed is not supported by the firmware. */ + /* DM Managed and BoardCfg Managed are not supported by the firmware. */ dev_err(info->dev, "Suspend to memory is not supported by the firmware\n"); return -EOPNOTSUPP; } @@ -4009,12 +4012,13 @@ static int ti_sci_probe(struct platform_device *pdev) } ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps); - dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n", + dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s\n", info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "", - info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "" + info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "", + info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED ? " BoardConfig-Managed" : "" ); ti_sci_setup_ops(info); diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 4616127e33ff..d5e06769b01c 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -150,6 +150,8 @@ struct ti_sci_msg_req_reboot { * MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM * MSG_FLAG_CAPS_LPM_ABORT: Abort entry to LPM * MSG_FLAG_CAPS_IO_ISOLATION: IO Isolation support + * MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED: LPM config done statically + * for the DM via boardcfg * * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS * providing currently available SOC/firmware capabilities. SoC that don't @@ -162,6 +164,7 @@ struct ti_sci_msg_resp_query_fw_caps { #define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5) #define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9) #define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7) +#define MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED TI_SCI_MSG_FLAG(12) #define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1) u64 fw_caps; } __packed; From 703b341fdd875c2d9c30a835021689e5a430a39a Mon Sep 17 00:00:00 2001 From: "Thomas Richard (TI)" Date: Tue, 19 May 2026 17:06:57 +0200 Subject: [PATCH 18/20] firmware: ti_sci: Add support for restoring IRQs during resume Some DM-Firmware are not able to restore the IRQ context after a suspend-resume. The IRQ_CONTEXT_LOST firmware capability has been introduced to identify this characteristic. In this case the responsibility is delegated to the ti_sci driver, which maintains an internal list of all requested IRQs. This list is updated on each set()/free() operation, and all IRQs are restored during the resume_noirq() phase. Reviewed-by: Dhruva Gole Reviewed-by: Kendall Willis Signed-off-by: Thomas Richard (TI) Link: https://patch.msgid.link/20260519-ti-sci-jacinto-s2r-restore-irq-v9-2-c550a8ae0f31@bootlin.com Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 190 +++++++++++++++++++++++++++++++++++--- drivers/firmware/ti_sci.h | 3 + 2 files changed, 181 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index a8dcdbe874b6..f6bffeae30f5 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -12,11 +12,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -87,6 +89,16 @@ struct ti_sci_desc { int max_msg_size; }; +/** + * struct ti_sci_irq - Description of allocated irqs + * @node: Link to hash table + * @desc: Description of the irq + */ +struct ti_sci_irq { + struct hlist_node node; + struct ti_sci_msg_req_manage_irq desc; +}; + /** * struct ti_sci_info - Structure representing a TI SCI instance * @dev: Device pointer @@ -101,6 +113,8 @@ struct ti_sci_desc { * @chan_rx: Receive mailbox channel * @minfo: Message info * @node: list head + * @irqs: List of allocated irqs + * @irq_lock: Protection for irq hash list * @host_id: Host ID * @fw_caps: FW/SoC low power capabilities * @users: Number of users of this instance @@ -118,6 +132,8 @@ struct ti_sci_info { struct mbox_chan *chan_rx; struct ti_sci_xfers_info minfo; struct list_head node; + DECLARE_HASHTABLE(irqs, 8); + struct mutex irq_lock; u8 host_id; u64 fw_caps; /* protected by ti_sci_list_mutex */ @@ -2299,6 +2315,32 @@ static int ti_sci_manage_irq(const struct ti_sci_handle *handle, return ret; } +/** + * ti_sci_irq_hash() - Helper API to compute irq hash for the hash table. + * @irq: irq to hash + * + * Return: the computed hash value. + */ +static int ti_sci_irq_hash(struct ti_sci_msg_req_manage_irq *irq) +{ + return irq->src_id ^ irq->src_index; +} + +/** + * ti_sci_irq_equal() - Helper API to compare two irqs (generic headers are not + * compared) + * @irq_a: irq_a to compare + * @irq_b: irq_b to compare + * + * Return: true if the two irqs are equal, else false. + */ +static bool ti_sci_irq_equal(struct ti_sci_msg_req_manage_irq *irq_a, + struct ti_sci_msg_req_manage_irq *irq_b) +{ + return !memcmp(&irq_a->valid_params, &irq_b->valid_params, + sizeof(*irq_a) - sizeof(irq_a->hdr)); +} + /** * ti_sci_set_irq() - Helper api to configure the irq route between the * requested source and destination @@ -2322,15 +2364,53 @@ static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params, u16 dst_host_irq, u16 ia_id, u16 vint, u16 global_event, u8 vint_status_bit, u8 s_host) { + struct ti_sci_info *info = handle_to_ti_sci_info(handle); + struct ti_sci_msg_req_manage_irq *desc; + struct ti_sci_irq *irq; + int ret; + + /* Lock for set_irq() and free_irq() to keep the IRQ hash list consistent */ + guard(mutex)(&info->irq_lock); + pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n", __func__, valid_params, src_id, src_index, dst_id, dst_host_irq, ia_id, vint, global_event, vint_status_bit); - return ti_sci_manage_irq(handle, valid_params, src_id, src_index, - dst_id, dst_host_irq, ia_id, vint, - global_event, vint_status_bit, s_host, - TI_SCI_MSG_SET_IRQ); + ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, s_host, + TI_SCI_MSG_SET_IRQ); + + if (ret || !(info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST)) + goto end; + + irq = kzalloc_obj(*irq, GFP_KERNEL); + if (!irq) { + ti_sci_manage_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, s_host, + TI_SCI_MSG_FREE_IRQ); + ret = -ENOMEM; + goto end; + } + + desc = &irq->desc; + desc->valid_params = valid_params; + desc->src_id = src_id; + desc->src_index = src_index; + desc->dst_id = dst_id; + desc->dst_host_irq = dst_host_irq; + desc->ia_id = ia_id; + desc->vint = vint; + desc->global_event = global_event; + desc->vint_status_bit = vint_status_bit; + desc->secondary_host = s_host; + + hash_add(info->irqs, &irq->node, ti_sci_irq_hash(desc)); + +end: + return ret; } /** @@ -2356,15 +2436,53 @@ static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params, u16 dst_host_irq, u16 ia_id, u16 vint, u16 global_event, u8 vint_status_bit, u8 s_host) { + struct ti_sci_info *info = handle_to_ti_sci_info(handle); + struct ti_sci_msg_req_manage_irq irq_desc; + struct device *dev = info->dev; + struct ti_sci_irq *this_irq; + struct hlist_node *tmp_node; + int ret; + + guard(mutex)(&info->irq_lock); + pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n", __func__, valid_params, src_id, src_index, dst_id, dst_host_irq, ia_id, vint, global_event, vint_status_bit); - return ti_sci_manage_irq(handle, valid_params, src_id, src_index, - dst_id, dst_host_irq, ia_id, vint, - global_event, vint_status_bit, s_host, - TI_SCI_MSG_FREE_IRQ); + ret = ti_sci_manage_irq(handle, valid_params, src_id, src_index, + dst_id, dst_host_irq, ia_id, vint, + global_event, vint_status_bit, s_host, + TI_SCI_MSG_FREE_IRQ); + + if (ret || !(info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST)) + goto end; + + irq_desc.valid_params = valid_params; + irq_desc.src_id = src_id; + irq_desc.src_index = src_index; + irq_desc.dst_id = dst_id; + irq_desc.dst_host_irq = dst_host_irq; + irq_desc.ia_id = ia_id; + irq_desc.vint = vint; + irq_desc.global_event = global_event; + irq_desc.vint_status_bit = vint_status_bit; + irq_desc.secondary_host = s_host; + + hash_for_each_possible_safe(info->irqs, this_irq, tmp_node, node, + ti_sci_irq_hash(&irq_desc)) { + if (ti_sci_irq_equal(&irq_desc, &this_irq->desc)) { + hlist_del(&this_irq->node); + kfree(this_irq); + goto end; + } + } + + dev_warn(dev, "%s: should not be here, IRQ was not found in hash list\n", + __func__); + +end: + return ret; } /** @@ -3845,7 +3963,10 @@ static int ti_sci_suspend_noirq(struct device *dev) static int ti_sci_resume_noirq(struct device *dev) { struct ti_sci_info *info = dev_get_drvdata(dev); - int ret = 0; + struct ti_sci_msg_req_manage_irq *irq_desc; + struct ti_sci_irq *irq; + struct hlist_node *tmp_node; + int ret = 0, err = 0, i; u32 source; u64 time; u8 pin; @@ -3857,13 +3978,50 @@ static int ti_sci_resume_noirq(struct device *dev) return ret; } + switch (pm_suspend_target_state) { + case PM_SUSPEND_MEM: + if (info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST) { + hash_for_each_safe(info->irqs, i, tmp_node, irq, node) { + irq_desc = &irq->desc; + ret = ti_sci_manage_irq(&info->handle, + irq_desc->valid_params, + irq_desc->src_id, + irq_desc->src_index, + irq_desc->dst_id, + irq_desc->dst_host_irq, + irq_desc->ia_id, + irq_desc->vint, + irq_desc->global_event, + irq_desc->vint_status_bit, + irq_desc->secondary_host, + TI_SCI_MSG_SET_IRQ); + if (ret) { + dev_err(dev, "failed to restore IRQ with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d, via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n", + irq_desc->valid_params, + irq_desc->src_id, + irq_desc->src_index, + irq_desc->dst_id, + irq_desc->dst_host_irq, + irq_desc->ia_id, + irq_desc->vint, + irq_desc->global_event, + irq_desc->vint_status_bit); + err = ret; + } + } + } + break; + default: + break; + } + ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode); /* Do not fail to resume on error as the wake reason is not critical */ if (!ret) dev_info(dev, "ti_sci: wakeup source:0x%x, pin:0x%x, mode:0x%x\n", source, pin, mode); - return 0; + return err; } static void ti_sci_pm_complete(struct device *dev) @@ -4012,13 +4170,14 @@ static int ti_sci_probe(struct platform_device *pdev) } ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps); - dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s\n", + dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s%s\n", info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "", info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "", - info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED ? " BoardConfig-Managed" : "" + info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED ? " BoardConfig-Managed" : "", + info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST ? " IRQ-Context-Lost" : "" ); ti_sci_setup_ops(info); @@ -4051,6 +4210,13 @@ static int ti_sci_probe(struct platform_device *pdev) list_add_tail(&info->node, &ti_sci_list); mutex_unlock(&ti_sci_list_mutex); + ret = devm_mutex_init(dev, &info->irq_lock); + if (ret) + goto out; + + if (info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST) + hash_init(info->irqs); + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); if (ret) { dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret)); diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index d5e06769b01c..ad69c765d614 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -152,6 +152,8 @@ struct ti_sci_msg_req_reboot { * MSG_FLAG_CAPS_IO_ISOLATION: IO Isolation support * MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED: LPM config done statically * for the DM via boardcfg + * MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST: DM is not able to restore IRQ + * context * * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS * providing currently available SOC/firmware capabilities. SoC that don't @@ -165,6 +167,7 @@ struct ti_sci_msg_resp_query_fw_caps { #define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9) #define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7) #define MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED TI_SCI_MSG_FLAG(12) +#define MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST TI_SCI_MSG_FLAG(14) #define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1) u64 fw_caps; } __packed; From 3c5912373340cb79db6585f0fcd8107198d4933d Mon Sep 17 00:00:00 2001 From: "Thomas Richard (TI)" Date: Tue, 19 May 2026 17:06:58 +0200 Subject: [PATCH 19/20] clk: keystone: sci-clk: Add restore_context() operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the restore_context() operation to restore the clock rate and the clock parent state. The clock rate is saved in sci_clk struct during set_rate() and recalc_rate() operations. The parent index is saved in sci_clk struct during set_parent() operation. During clock registration, the core retrieves each clock’s parent using get_parent() operation to ensure the internal clock tree reflects the actual hardware state, including any configurations made by the bootloader. So we also save the parent index in get_parent(). Reviewed-by: Dhruva Gole Reviewed-by: Kendall Willis Acked-by: Stephen Boyd Reviewed-by: Brian Masney Signed-off-by: Thomas Richard (TI) Link: https://patch.msgid.link/20260519-ti-sci-jacinto-s2r-restore-irq-v9-3-c550a8ae0f31@bootlin.com Signed-off-by: Nishanth Menon --- drivers/clk/keystone/sci-clk.c | 45 ++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c index 9d5071223f4c..7c0f7b3e89e0 100644 --- a/drivers/clk/keystone/sci-clk.c +++ b/drivers/clk/keystone/sci-clk.c @@ -47,6 +47,8 @@ struct sci_clk_provider { * @node: Link for handling clocks probed via DT * @cached_req: Cached requested freq for determine rate calls * @cached_res: Cached result freq for determine rate calls + * @parent_id: Parent index for this clock + * @rate: Clock rate */ struct sci_clk { struct clk_hw hw; @@ -58,6 +60,8 @@ struct sci_clk { struct list_head node; unsigned long cached_req; unsigned long cached_res; + int parent_id; + unsigned long rate; }; #define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw) @@ -150,6 +154,8 @@ static unsigned long sci_clk_recalc_rate(struct clk_hw *hw, return 0; } + clk->rate = freq; + return freq; } @@ -210,10 +216,15 @@ static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct sci_clk *clk = to_sci_clk(hw); + int ret; - return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id, - clk->clk_id, rate / 10 * 9, rate, - rate / 10 * 11); + ret = clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id, + clk->clk_id, rate / 10 * 9, rate, + rate / 10 * 11); + if (!ret) + clk->rate = rate; + + return ret; } /** @@ -234,12 +245,13 @@ static u8 sci_clk_get_parent(struct clk_hw *hw) dev_err(clk->provider->dev, "get-parent failed for dev=%d, clk=%d, ret=%d\n", clk->dev_id, clk->clk_id, ret); + clk->parent_id = ret; return 0; } - parent_id = parent_id - clk->clk_id - 1; + clk->parent_id = parent_id - clk->clk_id - 1; - return (u8)parent_id; + return (u8)clk->parent_id; } /** @@ -252,12 +264,28 @@ static u8 sci_clk_get_parent(struct clk_hw *hw) static int sci_clk_set_parent(struct clk_hw *hw, u8 index) { struct sci_clk *clk = to_sci_clk(hw); + int ret; clk->cached_req = 0; - return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id, - clk->clk_id, - index + 1 + clk->clk_id); + ret = clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id, + clk->clk_id, + index + 1 + clk->clk_id); + if (!ret) + clk->parent_id = index; + + return ret; +} + +static void sci_clk_restore_context(struct clk_hw *hw) +{ + struct sci_clk *clk = to_sci_clk(hw); + + if (clk->num_parents > 1 && clk->parent_id >= 0) + sci_clk_set_parent(hw, (u8)clk->parent_id); + + if (clk->rate) + sci_clk_set_rate(hw, clk->rate, 0); } static const struct clk_ops sci_clk_ops = { @@ -269,6 +297,7 @@ static const struct clk_ops sci_clk_ops = { .set_rate = sci_clk_set_rate, .get_parent = sci_clk_get_parent, .set_parent = sci_clk_set_parent, + .restore_context = sci_clk_restore_context, }; /** From dc51f820bd32415445655aa6e3af9011b9e3e0f3 Mon Sep 17 00:00:00 2001 From: "Thomas Richard (TI)" Date: Tue, 19 May 2026 17:06:59 +0200 Subject: [PATCH 20/20] firmware: ti_sci: Add support for restoring clock context during resume Some DM-Firmware are not able to restore the clock rates and the clock parents after a suspend-resume. The CLK_CONTEXT_LOST firmware capability has been introduced to identify this characteristic. In this case the responsibility is therefore delegated to the ti_sci driver, which uses clk_restore_context() to trigger the context_restore() operation for all registered clocks, including those managed by the sci-clk. The sci-clk driver implements the context_restore() operation to ensure rates and clock parents are correctly restored. Reviewed-by: Dhruva Gole Reviewed-by: Kendall Willis Signed-off-by: Thomas Richard (TI) Link: https://patch.msgid.link/20260519-ti-sci-jacinto-s2r-restore-irq-v9-4-c550a8ae0f31@bootlin.com Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 9 +++++++-- drivers/firmware/ti_sci.h | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index f6bffeae30f5..590a464403c5 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -9,6 +9,7 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ #include +#include #include #include #include @@ -4010,6 +4011,9 @@ static int ti_sci_resume_noirq(struct device *dev) } } } + + if (info->fw_caps & MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST) + clk_restore_context(); break; default: break; @@ -4170,14 +4174,15 @@ static int ti_sci_probe(struct platform_device *pdev) } ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps); - dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s%s\n", + dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s%s%s%s\n", info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "", info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED ? " BoardConfig-Managed" : "", - info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST ? " IRQ-Context-Lost" : "" + info->fw_caps & MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST ? " IRQ-Context-Lost" : "", + info->fw_caps & MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST ? " Clk-Context-Lost" : "" ); ti_sci_setup_ops(info); diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index ad69c765d614..8fccbcd1c9a2 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -154,6 +154,8 @@ struct ti_sci_msg_req_reboot { * for the DM via boardcfg * MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST: DM is not able to restore IRQ * context + * MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST: DM is not able to restore + * Clock context * * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS * providing currently available SOC/firmware capabilities. SoC that don't @@ -168,6 +170,7 @@ struct ti_sci_msg_resp_query_fw_caps { #define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7) #define MSG_FLAG_CAPS_LPM_BOARDCFG_MANAGED TI_SCI_MSG_FLAG(12) #define MSG_FLAG_CAPS_LPM_IRQ_CONTEXT_LOST TI_SCI_MSG_FLAG(14) +#define MSG_FLAG_CAPS_LPM_CLK_CONTEXT_LOST TI_SCI_MSG_FLAG(15) #define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1) u64 fw_caps; } __packed;