Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / drivers / bus / stm32_firewall.c
blob2fc9761dadecf3a4099e4b1d9ce7c76699450382
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4 */
6 #include <linux/bitfield.h>
7 #include <linux/bits.h>
8 #include <linux/bus/stm32_firewall_device.h>
9 #include <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/init.h>
12 #include <linux/io.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_platform.h>
17 #include <linux/platform_device.h>
18 #include <linux/types.h>
19 #include <linux/slab.h>
21 #include "stm32_firewall.h"
23 /* Corresponds to STM32_FIREWALL_MAX_EXTRA_ARGS + firewall ID */
24 #define STM32_FIREWALL_MAX_ARGS (STM32_FIREWALL_MAX_EXTRA_ARGS + 1)
26 static LIST_HEAD(firewall_controller_list);
27 static DEFINE_MUTEX(firewall_controller_list_lock);
29 /* Firewall device API */
31 int stm32_firewall_get_firewall(struct device_node *np, struct stm32_firewall *firewall,
32 unsigned int nb_firewall)
34 struct stm32_firewall_controller *ctrl;
35 struct of_phandle_iterator it;
36 unsigned int i, j = 0;
37 int err;
39 if (!firewall || !nb_firewall)
40 return -EINVAL;
42 /* Parse property with phandle parsed out */
43 of_for_each_phandle(&it, err, np, "access-controllers", "#access-controller-cells", 0) {
44 struct of_phandle_args provider_args;
45 struct device_node *provider = it.node;
46 const char *fw_entry;
47 bool match = false;
49 if (err) {
50 pr_err("Unable to get access-controllers property for node %s\n, err: %d",
51 np->full_name, err);
52 of_node_put(provider);
53 return err;
56 if (j >= nb_firewall) {
57 pr_err("Too many firewall controllers");
58 of_node_put(provider);
59 return -EINVAL;
62 provider_args.args_count = of_phandle_iterator_args(&it, provider_args.args,
63 STM32_FIREWALL_MAX_ARGS);
65 /* Check if the parsed phandle corresponds to a registered firewall controller */
66 mutex_lock(&firewall_controller_list_lock);
67 list_for_each_entry(ctrl, &firewall_controller_list, entry) {
68 if (ctrl->dev->of_node->phandle == it.phandle) {
69 match = true;
70 firewall[j].firewall_ctrl = ctrl;
71 break;
74 mutex_unlock(&firewall_controller_list_lock);
76 if (!match) {
77 firewall[j].firewall_ctrl = NULL;
78 pr_err("No firewall controller registered for %s\n", np->full_name);
79 of_node_put(provider);
80 return -ENODEV;
83 err = of_property_read_string_index(np, "access-controller-names", j, &fw_entry);
84 if (err == 0)
85 firewall[j].entry = fw_entry;
87 /* Handle the case when there are no arguments given along with the phandle */
88 if (provider_args.args_count < 0 ||
89 provider_args.args_count > STM32_FIREWALL_MAX_ARGS) {
90 of_node_put(provider);
91 return -EINVAL;
92 } else if (provider_args.args_count == 0) {
93 firewall[j].extra_args_size = 0;
94 firewall[j].firewall_id = U32_MAX;
95 j++;
96 continue;
99 /* The firewall ID is always the first argument */
100 firewall[j].firewall_id = provider_args.args[0];
102 /* Extra args start at the second argument */
103 for (i = 0; i < provider_args.args_count - 1; i++)
104 firewall[j].extra_args[i] = provider_args.args[i + 1];
106 /* Remove the firewall ID arg that is not an extra argument */
107 firewall[j].extra_args_size = provider_args.args_count - 1;
109 j++;
112 return 0;
114 EXPORT_SYMBOL_GPL(stm32_firewall_get_firewall);
116 int stm32_firewall_grant_access(struct stm32_firewall *firewall)
118 struct stm32_firewall_controller *firewall_controller;
120 if (!firewall || firewall->firewall_id == U32_MAX)
121 return -EINVAL;
123 firewall_controller = firewall->firewall_ctrl;
125 if (!firewall_controller)
126 return -ENODEV;
128 return firewall_controller->grant_access(firewall_controller, firewall->firewall_id);
130 EXPORT_SYMBOL_GPL(stm32_firewall_grant_access);
132 int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
134 struct stm32_firewall_controller *firewall_controller;
136 if (!firewall || subsystem_id == U32_MAX || firewall->firewall_id == U32_MAX)
137 return -EINVAL;
139 firewall_controller = firewall->firewall_ctrl;
141 if (!firewall_controller)
142 return -ENODEV;
144 return firewall_controller->grant_access(firewall_controller, subsystem_id);
146 EXPORT_SYMBOL_GPL(stm32_firewall_grant_access_by_id);
148 void stm32_firewall_release_access(struct stm32_firewall *firewall)
150 struct stm32_firewall_controller *firewall_controller;
152 if (!firewall || firewall->firewall_id == U32_MAX) {
153 pr_debug("Incorrect arguments when releasing a firewall access\n");
154 return;
157 firewall_controller = firewall->firewall_ctrl;
159 if (!firewall_controller) {
160 pr_debug("No firewall controller to release\n");
161 return;
164 firewall_controller->release_access(firewall_controller, firewall->firewall_id);
166 EXPORT_SYMBOL_GPL(stm32_firewall_release_access);
168 void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
170 struct stm32_firewall_controller *firewall_controller;
172 if (!firewall || subsystem_id == U32_MAX || firewall->firewall_id == U32_MAX) {
173 pr_debug("Incorrect arguments when releasing a firewall access");
174 return;
177 firewall_controller = firewall->firewall_ctrl;
179 if (!firewall_controller) {
180 pr_debug("No firewall controller to release");
181 return;
184 firewall_controller->release_access(firewall_controller, subsystem_id);
186 EXPORT_SYMBOL_GPL(stm32_firewall_release_access_by_id);
188 /* Firewall controller API */
190 int stm32_firewall_controller_register(struct stm32_firewall_controller *firewall_controller)
192 struct stm32_firewall_controller *ctrl;
194 if (!firewall_controller)
195 return -ENODEV;
197 pr_info("Registering %s firewall controller\n", firewall_controller->name);
199 mutex_lock(&firewall_controller_list_lock);
200 list_for_each_entry(ctrl, &firewall_controller_list, entry) {
201 if (ctrl == firewall_controller) {
202 pr_debug("%s firewall controller already registered\n",
203 firewall_controller->name);
204 mutex_unlock(&firewall_controller_list_lock);
205 return 0;
208 list_add_tail(&firewall_controller->entry, &firewall_controller_list);
209 mutex_unlock(&firewall_controller_list_lock);
211 return 0;
213 EXPORT_SYMBOL_GPL(stm32_firewall_controller_register);
215 void stm32_firewall_controller_unregister(struct stm32_firewall_controller *firewall_controller)
217 struct stm32_firewall_controller *ctrl;
218 bool controller_removed = false;
220 if (!firewall_controller) {
221 pr_debug("Null reference while unregistering firewall controller\n");
222 return;
225 mutex_lock(&firewall_controller_list_lock);
226 list_for_each_entry(ctrl, &firewall_controller_list, entry) {
227 if (ctrl == firewall_controller) {
228 controller_removed = true;
229 list_del_init(&ctrl->entry);
230 break;
233 mutex_unlock(&firewall_controller_list_lock);
235 if (!controller_removed)
236 pr_debug("There was no firewall controller named %s to unregister\n",
237 firewall_controller->name);
239 EXPORT_SYMBOL_GPL(stm32_firewall_controller_unregister);
241 int stm32_firewall_populate_bus(struct stm32_firewall_controller *firewall_controller)
243 struct stm32_firewall *firewalls;
244 struct device_node *child;
245 struct device *parent;
246 unsigned int i;
247 int len;
248 int err;
250 parent = firewall_controller->dev;
252 dev_dbg(parent, "Populating %s system bus\n", dev_name(firewall_controller->dev));
254 for_each_available_child_of_node(dev_of_node(parent), child) {
255 /* The access-controllers property is mandatory for firewall bus devices */
256 len = of_count_phandle_with_args(child, "access-controllers",
257 "#access-controller-cells");
258 if (len <= 0) {
259 of_node_put(child);
260 return -EINVAL;
263 firewalls = kcalloc(len, sizeof(*firewalls), GFP_KERNEL);
264 if (!firewalls) {
265 of_node_put(child);
266 return -ENOMEM;
269 err = stm32_firewall_get_firewall(child, firewalls, (unsigned int)len);
270 if (err) {
271 kfree(firewalls);
272 of_node_put(child);
273 return err;
276 for (i = 0; i < len; i++) {
277 if (firewall_controller->grant_access(firewall_controller,
278 firewalls[i].firewall_id)) {
280 * Peripheral access not allowed or not defined.
281 * Mark the node as populated so platform bus won't probe it
283 of_detach_node(child);
284 dev_err(parent, "%s: Device driver will not be probed\n",
285 child->full_name);
289 kfree(firewalls);
292 return 0;
294 EXPORT_SYMBOL_GPL(stm32_firewall_populate_bus);