]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bus: stm32_firewall: add stm32_firewall_get_grant_all_access() API
authorGatien Chevallier <gatien.chevallier@foss.st.com>
Thu, 26 Feb 2026 10:30:20 +0000 (11:30 +0100)
committerAlexandre Torgue <alexandre.torgue@foss.st.com>
Wed, 25 Mar 2026 16:40:22 +0000 (17:40 +0100)
Add the stm32_firewall_get_grant_all_access() API to be able to fetch
all firewall references in an access-controllers property and try to grant
access to all of them.

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://lore.kernel.org/r/20260226-debug_bus-v6-5-5d794697798d@foss.st.com
Signed-off-by: Alexandre Torgue <alexandre.torgue@foss.st.com>
drivers/bus/stm32_firewall.c
include/linux/bus/stm32_firewall_device.h

index e69bc8c1a4e797428e6cc3f3fb46a2d5194ae13a..e3619dba8b069667afd29a31b247318edb0664f7 100644 (file)
@@ -184,6 +184,48 @@ void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 su
 }
 EXPORT_SYMBOL_GPL(stm32_firewall_release_access_by_id);
 
+int stm32_firewall_get_grant_all_access(struct device *dev, struct stm32_firewall **firewall,
+                                       int *nb_firewall)
+{
+       struct stm32_firewall *loc_firewall;
+       int err;
+       int i;
+
+       *nb_firewall = of_count_phandle_with_args(dev->of_node, "access-controllers",
+                                                 "#access-controller-cells");
+       if (*nb_firewall < 0)
+               return *nb_firewall;
+
+       if (!*nb_firewall) {
+               *firewall = NULL;
+               return 0;
+       }
+
+       loc_firewall = devm_kcalloc(dev, *nb_firewall, sizeof(*loc_firewall), GFP_KERNEL);
+       if (!loc_firewall)
+               return -ENOMEM;
+
+       /* Get stm32 firewall information */
+       err = stm32_firewall_get_firewall(dev->of_node, loc_firewall, *nb_firewall);
+       if (err)
+               return err;
+
+       for (i = 0; i < *nb_firewall; i++) {
+               err = stm32_firewall_grant_access(&loc_firewall[i]);
+               if (err) {
+                       while (i--)
+                               stm32_firewall_release_access(&loc_firewall[i]);
+
+                       return err;
+               }
+       }
+
+       *firewall = loc_firewall;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_get_grant_all_access);
+
 /* Firewall controller API */
 
 int stm32_firewall_controller_register(struct stm32_firewall_controller *firewall_controller)
index eaa7a3f5445072af70b44b0cfc904ebbf9e7451e..6c878f3ca86f257ec40264d57e9fd30ee32f57af 100644 (file)
@@ -112,6 +112,25 @@ int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsy
  */
 void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id);
 
+/**
+ * stm32_firewall_get_grant_all_access - Allocate and get all the firewall(s) associated to given
+ *                                      device. Then, try to grant access rights for each element.
+ *                                      This function is basically a helper function that wraps
+ *                                      both stm32_firewall_get_firewall() and
+ *                                      stm32_firewall_grant_access() on all firewall references of
+ *                                      a device along with the allocation of the array.
+ *                                      Realease access using stm32_firewall_release_access* APIs
+ *                                      when done.
+ *
+ * @dev:                       Device performing the checks
+ * @firewall:                  Pointer to the array of firewall references to be allocated
+ * @nb_firewall:               Number of allocated elements in @firewall
+ *
+ * Returns 0 on success, or appropriate errno code if error occurred.
+ */
+int stm32_firewall_get_grant_all_access(struct device *dev, struct stm32_firewall **firewall,
+                                       int *nb_firewall);
+
 #else /* CONFIG_STM32_FIREWALL */
 
 static inline int stm32_firewall_get_firewall(struct device_node *np,
@@ -141,5 +160,12 @@ static inline void stm32_firewall_release_access_by_id(struct stm32_firewall *fi
 {
 }
 
+static inline int stm32_firewall_get_grant_all_access(struct device *dev,
+                                                     struct stm32_firewall **firewall,
+                                                     int *nb_firewall)
+{
+       return -ENODEV;
+}
+
 #endif /* CONFIG_STM32_FIREWALL */
 #endif /* STM32_FIREWALL_DEVICE_H */