From: Chen-Yu Tsai Date: Tue, 24 Mar 2026 16:43:52 +0000 (+0800) Subject: soc: sunxi: sram: Allow SRAM to be claimed multiple times X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=67890da74dd1b85a47769561bfc6e0c542762d45;p=thirdparty%2Flinux.git soc: sunxi: sram: Allow SRAM to be claimed multiple times On the H616, the SRAM C region is an alias mapping to part of the VE SRAM (accessible in whole at a different address) and part of the DE SRAM (otherwise unaccessible). As such both the VE and DE need to claim this SRAM region to prevent access from the CPU. The SRAM claim API is designed so that a "claim" routes the SRAM to the peripheral device, disabling access from the CPU. So long as the written register value is the same for all the claimants involved, allowing multiple or repeated claims is trivial. This is indeed the case for all supported SRAM regions. The only known SRAM region to have multiple different settings is the SRAM C2 region; this can be claimed by the AE, CE, or ACE (assumed to be AE + CE). This region is not supported, and likely will never be needed nor supported, as there is no documentation for the peripherals involved. Change the SRAM region "claimed" field from a boolean to a reference count. A claim will increment the count, while a release decreases it. The first claim will trigger the register value write. The driver otherwise behaves as before. Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20260324164357.1607247-5-wens@kernel.org Signed-off-by: Chen-Yu Tsai --- diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index 5e8c80ae35094..aba155379ccc9 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -38,7 +39,7 @@ struct sunxi_sram_data { struct sunxi_sram_desc { struct sunxi_sram_data data; - bool claimed; + u8 claim_cnt; }; #define SUNXI_SRAM_MAP(_reg_val, _val, _func) \ @@ -244,9 +245,11 @@ int sunxi_sram_claim(struct device *dev) spin_lock(&sram_lock); - if (sram_desc->claimed) { + if (sram_desc->claim_cnt) { + if (!WARN_ON(sram_desc->claim_cnt == U8_MAX)) + sram_desc->claim_cnt++; spin_unlock(&sram_lock); - return -EBUSY; + return 0; } mask = GENMASK(sram_data->offset + sram_data->width - 1, @@ -256,7 +259,7 @@ int sunxi_sram_claim(struct device *dev) writel(val | ((device << sram_data->offset) & mask), base + sram_data->reg); - sram_desc->claimed = true; + sram_desc->claim_cnt++; spin_unlock(&sram_lock); return 0; @@ -278,7 +281,8 @@ void sunxi_sram_release(struct device *dev) sram_desc = to_sram_desc(sram_data); spin_lock(&sram_lock); - sram_desc->claimed = false; + if (!WARN_ON(sram_desc->claim_cnt == 0)) + sram_desc->claim_cnt--; spin_unlock(&sram_lock); } EXPORT_SYMBOL(sunxi_sram_release);