From: Gatien Chevallier <gatien.chevall...@foss.st.com>

Replace RIFSC check access APIs by grant/release access ones that handle
the RIF semaphores.

Signed-off-by: Gatien Chevallier <gatien.chevall...@foss.st.com>

Signed-off-by: Patrice Chotard <patrice.chot...@foss.st.com>
---

 arch/arm/mach-stm32mp/include/mach/rif.h |  48 +++++++--
 arch/arm/mach-stm32mp/stm32mp2/rifsc.c   | 127 +++++++++++++----------
 drivers/clk/stm32/clk-stm32mp25.c        |   2 +-
 3 files changed, 116 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-stm32mp/include/mach/rif.h 
b/arch/arm/mach-stm32mp/include/mach/rif.h
index 10b22108120..4f51313980d 100644
--- a/arch/arm/mach-stm32mp/include/mach/rif.h
+++ b/arch/arm/mach-stm32mp/include/mach/rif.h
@@ -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*/
diff --git a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c 
b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
index 136ed68bba1..f8f67af4449 100644
--- a/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
+++ b/arch/arm/mach-stm32mp/stm32mp2/rifsc.c
@@ -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;
 }
diff --git a/drivers/clk/stm32/clk-stm32mp25.c 
b/drivers/clk/stm32/clk-stm32mp25.c
index 18c0b1cb867..b487f33b6c7 100644
--- a/drivers/clk/stm32/clk-stm32mp25.c
+++ b/drivers/clk/stm32/clk-stm32mp25.c
@@ -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);
-- 
2.25.1

Reply via email to