]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
ARM: stm32mp: replace RIFSC check access APIs
authorGatien Chevallier <gatien.chevallier@foss.st.com>
Fri, 8 Aug 2025 14:03:57 +0000 (16:03 +0200)
committerPatrice Chotard <patrice.chotard@foss.st.com>
Thu, 18 Sep 2025 15:20:34 +0000 (17:20 +0200)
Replace RIFSC check access APIs by grant/release access ones that handle
the RIF semaphores.

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
arch/arm/mach-stm32mp/include/mach/rif.h
arch/arm/mach-stm32mp/stm32mp2/rifsc.c
drivers/clk/stm32/clk-stm32mp25.c

index 10b221081202571a81c0d651b2975daa0a40d767..4f51313980d970845fce6bb5660bfab8a234a484 100644 (file)
@@ -8,19 +8,53 @@
 
 #include <linux/types.h>
 
+#if IS_ENABLED(CONFIG_STM32MP21X) || IS_ENABLED(CONFIG_STM32MP23X) || IS_ENABLED(CONFIG_STM32MP25X)
 /**
- * stm32_rifsc_check_access - Check RIF accesses for given device node
+ * stm32_rifsc_grant_access_by_id - Grant RIFSC access for a given peripheral using its ID
  *
- * @device_node                Node of the device for which the accesses are checked
+ * @device_node Node of the peripheral
+ * @id ID of the peripheral of which access should be granted
  */
-int stm32_rifsc_check_access(ofnode device_node);
+int stm32_rifsc_grant_access_by_id(ofnode device_node, u32 id);
 
 /**
- * stm32_rifsc_check_access - Check RIF accesses for given id
+ * stm32_rifsc_grant_access_by_id - Grant RIFSC access for a given peripheral using its node
  *
- * @device_node                Node of the device to get a reference on RIFSC
- * @id                 ID of the resource to check
+ * @id node of the peripheral of which access should be granted
  */
-int stm32_rifsc_check_access_by_id(ofnode device_node, u32 id);
+int stm32_rifsc_grant_access(ofnode device_node);
 
+/**
+ * stm32_rifsc_release_access_by_id - Release RIFSC access for a given peripheral using its ID
+ *
+ * @device_node Node of the peripheral
+ * @id ID of the peripheral of which access should be released
+ */
+void stm32_rifsc_release_access_by_id(ofnode device_node, u32 id);
+
+/**
+ * stm32_rifsc_release_access_by_id - Release RIFSC access for a given peripheral using its node
+ *
+ * @id node of the peripheral of which access should be released
+ */
+void stm32_rifsc_release_access(ofnode device_node);
+#else
+static inline int stm32_rifsc_grant_access_by_id(ofnode device_node, u32 id)
+{
+       return -EACCES;
+}
+
+static inline int stm32_rifsc_grant_access(ofnode device_node)
+{
+       return -EACCES;
+}
+
+static inline void stm32_rifsc_release_access_by_id(ofnode device_node, u32 id)
+{
+}
+
+static inline void stm32_rifsc_release_access(ofnode device_node)
+{
+}
+#endif
 #endif /* MACH_RIF_H*/
index 136ed68bba1c7deffbfd267a31c465c13a531094..f8f67af44494f14109b538c7d22c29a16eb51dec 100644 (file)
@@ -61,43 +61,41 @@ struct stm32_rifsc_child_plat {
        u32 domain_id;
 };
 
-static bool stm32_rif_is_semaphore_available(void *base, u32 id)
+static bool stm32_rif_is_semaphore_available(void *addr)
 {
-       void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
-
        return !(readl(addr) & SEMCR_MUTEX);
 }
 
-static int stm32_rif_acquire_semaphore(void *base, u32 id)
+static int stm32_rifsc_acquire_semaphore(void *base, u32 id)
 {
        void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
 
        /* Check that the semaphore is available */
-       if (!stm32_rif_is_semaphore_available(base, id) &&
+       if (!stm32_rif_is_semaphore_available(addr) &&
            FIELD_GET(RIFSC_RISC_SCID_MASK, (readl(addr)) != RIF_CID1))
                return -EACCES;
 
        setbits_le32(addr, SEMCR_MUTEX);
 
        /* Check that CID1 has the semaphore */
-       if (stm32_rif_is_semaphore_available(base, id) ||
+       if (stm32_rif_is_semaphore_available(addr) ||
            FIELD_GET(RIFSC_RISC_SCID_MASK, (readl(addr)) != RIF_CID1))
                return -EACCES;
 
        return 0;
 }
 
-static int stm32_rif_release_semaphore(void *base, u32 id)
+static int stm32_rifsc_release_semaphore(void *base, u32 id)
 {
        void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
 
-       if (stm32_rif_is_semaphore_available(base, id))
+       if (stm32_rif_is_semaphore_available(addr))
                return 0;
 
        clrbits_le32(addr, SEMCR_MUTEX);
 
        /* Ok if another compartment takes the semaphore before the check */
-       if (!stm32_rif_is_semaphore_available(base, id) &&
+       if (!stm32_rif_is_semaphore_available(addr) &&
            FIELD_GET(RIFSC_RISC_SCID_MASK, (readl(addr)) == RIF_CID1))
                return -EACCES;
 
@@ -106,11 +104,10 @@ static int stm32_rif_release_semaphore(void *base, u32 id)
 
 static int rifsc_parse_access_controller(ofnode node, struct ofnode_phandle_args *args)
 {
-       int ret;
+       int ret = ofnode_parse_phandle_with_args(node, "access-controllers",
+                                                "#access-controller-cells", 0,
+                                                0, args);
 
-       ret = ofnode_parse_phandle_with_args(node, "access-controllers",
-                                            "#access-controller-cells", 0,
-                                            0, args);
        if (ret) {
                log_debug("failed to parse access-controller (%d)\n", ret);
                return ret;
@@ -171,7 +168,7 @@ static int rifsc_check_access(void *base, u32 id)
                        log_debug("Not in semaphore whitelist for peripheral %d\n", id);
                        return -EACCES;
                }
-               if (!stm32_rif_is_semaphore_available(base, id) &&
+               if (!stm32_rif_is_semaphore_available(base + RIFSC_RISC_PER0_SEMCR(id)) &&
                    !(FIELD_GET(RIFSC_RISC_SCID_MASK, sem_reg_value) & RIF_CID1)) {
                        log_debug("Semaphore unavailable for peripheral %d\n", id);
                        return -EACCES;
@@ -188,22 +185,44 @@ skip_cid_check:
        return 0;
 }
 
-int stm32_rifsc_check_access_by_id(ofnode device_node, u32 id)
+int stm32_rifsc_grant_access_by_id(ofnode device_node, u32 id)
 {
        struct ofnode_phandle_args args;
+       u32 cid_reg_value;
+       void *rifsc_base;
        int err;
 
-       if (id >= STM32MP25_RIFSC_ENTRIES)
-               return -EINVAL;
-
        err = rifsc_parse_access_controller(device_node, &args);
+       if (err)
+               panic("Failed to parse access-controllers property\n");
+
+       rifsc_base = (void *)ofnode_get_addr(args.node);
+
+       err = rifsc_check_access(rifsc_base, id);
        if (err)
                return err;
 
-       return rifsc_check_access((void *)ofnode_get_addr(args.node), id);
+       cid_reg_value = readl(rifsc_base + RIFSC_RISC_PER0_CIDCFGR(id));
+
+       /*
+        * If the peripheral is in semaphore mode, take the semaphore so that
+        * the CID1 has the ownership.
+        */
+       if (cid_reg_value & CIDCFGR_SEMEN &&
+           (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
+               err = stm32_rifsc_acquire_semaphore(rifsc_base, id);
+               if (err) {
+                       pr_err("Couldn't acquire RIF semaphore for peripheral %d (%d)\n",
+                              id, err);
+                       return err;
+               }
+               pr_debug("Acquiring RIF semaphore for peripheral %d\n", id);
+       }
+
+       return 0;
 }
 
-int stm32_rifsc_check_access(ofnode device_node)
+int stm32_rifsc_grant_access(ofnode device_node)
 {
        struct ofnode_phandle_args args;
        int err;
@@ -212,58 +231,60 @@ int stm32_rifsc_check_access(ofnode device_node)
        if (err)
                return err;
 
-       return rifsc_check_access((void *)ofnode_get_addr(args.node), args.args[0]);
+       return stm32_rifsc_grant_access_by_id(device_node, args.args[0]);
+
 }
 
-static int stm32_rifsc_child_pre_probe(struct udevice *dev)
+void stm32_rifsc_release_access_by_id(ofnode device_node, u32 id)
 {
-       struct stm32_rifsc_plat *plat = dev_get_plat(dev->parent);
-       struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
+       struct ofnode_phandle_args args;
        u32 cid_reg_value;
+       void *rifsc_base;
        int err;
-       u32 id = child_plat->domain_id;
 
-       cid_reg_value = readl(plat->base + RIFSC_RISC_PER0_CIDCFGR(id));
+       err = rifsc_parse_access_controller(device_node, &args);
+       if (err)
+               panic("Failed to parse access-controllers property\n");
 
-       /*
-        * If the peripheral is in semaphore mode, take the semaphore so that
-        * the CID1 has the ownership.
-        */
+       rifsc_base = (void *)ofnode_get_addr(args.node);
+
+       cid_reg_value = readl(rifsc_base + RIFSC_RISC_PER0_CIDCFGR(id));
+
+       /* If the peripheral is in semaphore mode, release it if we have the ownership */
        if (cid_reg_value & CIDCFGR_SEMEN &&
            (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
-               err = stm32_rif_acquire_semaphore(plat->base, id);
+               err = stm32_rifsc_release_semaphore(rifsc_base, id);
                if (err) {
-                       dev_err(dev, "Couldn't acquire RIF semaphore for peripheral %d (%d)\n",
-                               id, err);
-                       return err;
+                       panic("Couldn't release RIF semaphore for peripheral %d (%d)\n", id, err);
                }
-               dev_dbg(dev, "Acquiring semaphore for peripheral %d\n", id);
+               pr_debug("Releasing RIF semaphore for peripheral %d\n", id);
        }
+}
 
-       return 0;
+void stm32_rifsc_release_access(ofnode device_node)
+{
+       struct ofnode_phandle_args args;
+       int err;
+
+       err = rifsc_parse_access_controller(device_node, &args);
+       if (err)
+               panic("Failed to parse access-controllers property\n");
+
+       stm32_rifsc_release_access_by_id(device_node, args.args[0]);
 }
 
-static int stm32_rifsc_child_post_remove(struct udevice *dev)
+static int stm32_rifsc_child_pre_probe(struct udevice *dev)
 {
-       struct stm32_rifsc_plat *plat = dev_get_plat(dev->parent);
        struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
-       u32 cid_reg_value;
-       int err;
-       u32 id = child_plat->domain_id;
 
-       cid_reg_value = readl(plat->base + RIFSC_RISC_PER0_CIDCFGR(id));
+       return stm32_rifsc_grant_access_by_id(dev_ofnode(dev), child_plat->domain_id);
+}
 
-       /*
-        * If the peripheral is in semaphore mode, release the semaphore so that
-        * there's no ownership.
-        */
-       if (cid_reg_value & CIDCFGR_SEMEN &&
-           (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
-               err = stm32_rif_release_semaphore(plat->base, id);
-               if (err)
-                       dev_err(dev, "Couldn't release rif semaphore for peripheral %d (%d)\n",
-                               id, err);
-       }
+static int stm32_rifsc_child_post_remove(struct udevice *dev)
+{
+       struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
+
+       stm32_rifsc_release_access_by_id(dev_ofnode(dev), child_plat->domain_id);
 
        return 0;
 }
index 18c0b1cb867f86c70fb673f3f50f57a28bda5b10..b487f33b6c720ed782b707615142fe5b157648de 100644 (file)
@@ -430,7 +430,7 @@ static int stm32mp25_check_security(struct udevice *dev, void __iomem *base,
                u32 index = (u32)cfg->sec_id;
 
                if (index & SEC_RIFSC_FLAG)
-                       ret = stm32_rifsc_check_access_by_id(dev_ofnode(dev),
+                       ret = stm32_rifsc_grant_access_by_id(dev_ofnode(dev),
                                                             index & ~SEC_RIFSC_FLAG);
                else
                        ret = stm32_rcc_get_access(dev, index);