1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4 */
5
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>
20
21#include "stm32_firewall.h"
22
23/* Corresponds to STM32_FIREWALL_MAX_EXTRA_ARGS + firewall ID */
24#define STM32_FIREWALL_MAX_ARGS		(STM32_FIREWALL_MAX_EXTRA_ARGS + 1)
25
26static LIST_HEAD(firewall_controller_list);
27static DEFINE_MUTEX(firewall_controller_list_lock);
28
29/* Firewall device API */
30
31int stm32_firewall_get_firewall(struct device_node *np, struct stm32_firewall *firewall,
32				unsigned int nb_firewall)
33{
34	struct stm32_firewall_controller *ctrl;
35	struct of_phandle_iterator it;
36	unsigned int i, j = 0;
37	int err;
38
39	if (!firewall || !nb_firewall)
40		return -EINVAL;
41
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;
48
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;
54		}
55
56		if (j >= nb_firewall) {
57			pr_err("Too many firewall controllers");
58			of_node_put(provider);
59			return -EINVAL;
60		}
61
62		provider_args.args_count = of_phandle_iterator_args(&it, provider_args.args,
63								    STM32_FIREWALL_MAX_ARGS);
64
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;
72			}
73		}
74		mutex_unlock(&firewall_controller_list_lock);
75
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;
81		}
82
83		err = of_property_read_string_index(np, "access-controller-names", j, &fw_entry);
84		if (err == 0)
85			firewall[j].entry = fw_entry;
86
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;
97		}
98
99		/* The firewall ID is always the first argument */
100		firewall[j].firewall_id = provider_args.args[0];
101
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];
105
106		/* Remove the firewall ID arg that is not an extra argument */
107		firewall[j].extra_args_size = provider_args.args_count - 1;
108
109		j++;
110	}
111
112	return 0;
113}
114EXPORT_SYMBOL_GPL(stm32_firewall_get_firewall);
115
116int stm32_firewall_grant_access(struct stm32_firewall *firewall)
117{
118	struct stm32_firewall_controller *firewall_controller;
119
120	if (!firewall || firewall->firewall_id == U32_MAX)
121		return -EINVAL;
122
123	firewall_controller = firewall->firewall_ctrl;
124
125	if (!firewall_controller)
126		return -ENODEV;
127
128	return firewall_controller->grant_access(firewall_controller, firewall->firewall_id);
129}
130EXPORT_SYMBOL_GPL(stm32_firewall_grant_access);
131
132int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
133{
134	struct stm32_firewall_controller *firewall_controller;
135
136	if (!firewall || subsystem_id == U32_MAX || firewall->firewall_id == U32_MAX)
137		return -EINVAL;
138
139	firewall_controller = firewall->firewall_ctrl;
140
141	if (!firewall_controller)
142		return -ENODEV;
143
144	return firewall_controller->grant_access(firewall_controller, subsystem_id);
145}
146EXPORT_SYMBOL_GPL(stm32_firewall_grant_access_by_id);
147
148void stm32_firewall_release_access(struct stm32_firewall *firewall)
149{
150	struct stm32_firewall_controller *firewall_controller;
151
152	if (!firewall || firewall->firewall_id == U32_MAX) {
153		pr_debug("Incorrect arguments when releasing a firewall access\n");
154		return;
155	}
156
157	firewall_controller = firewall->firewall_ctrl;
158
159	if (!firewall_controller) {
160		pr_debug("No firewall controller to release\n");
161		return;
162	}
163
164	firewall_controller->release_access(firewall_controller, firewall->firewall_id);
165}
166EXPORT_SYMBOL_GPL(stm32_firewall_release_access);
167
168void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
169{
170	struct stm32_firewall_controller *firewall_controller;
171
172	if (!firewall || subsystem_id == U32_MAX || firewall->firewall_id == U32_MAX) {
173		pr_debug("Incorrect arguments when releasing a firewall access");
174		return;
175	}
176
177	firewall_controller = firewall->firewall_ctrl;
178
179	if (!firewall_controller) {
180		pr_debug("No firewall controller to release");
181		return;
182	}
183
184	firewall_controller->release_access(firewall_controller, subsystem_id);
185}
186EXPORT_SYMBOL_GPL(stm32_firewall_release_access_by_id);
187
188/* Firewall controller API */
189
190int stm32_firewall_controller_register(struct stm32_firewall_controller *firewall_controller)
191{
192	struct stm32_firewall_controller *ctrl;
193
194	if (!firewall_controller)
195		return -ENODEV;
196
197	pr_info("Registering %s firewall controller\n", firewall_controller->name);
198
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;
206		}
207	}
208	list_add_tail(&firewall_controller->entry, &firewall_controller_list);
209	mutex_unlock(&firewall_controller_list_lock);
210
211	return 0;
212}
213EXPORT_SYMBOL_GPL(stm32_firewall_controller_register);
214
215void stm32_firewall_controller_unregister(struct stm32_firewall_controller *firewall_controller)
216{
217	struct stm32_firewall_controller *ctrl;
218	bool controller_removed = false;
219
220	if (!firewall_controller) {
221		pr_debug("Null reference while unregistering firewall controller\n");
222		return;
223	}
224
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;
231		}
232	}
233	mutex_unlock(&firewall_controller_list_lock);
234
235	if (!controller_removed)
236		pr_debug("There was no firewall controller named %s to unregister\n",
237			 firewall_controller->name);
238}
239EXPORT_SYMBOL_GPL(stm32_firewall_controller_unregister);
240
241int stm32_firewall_populate_bus(struct stm32_firewall_controller *firewall_controller)
242{
243	struct stm32_firewall *firewalls;
244	struct device_node *child;
245	struct device *parent;
246	unsigned int i;
247	int len;
248	int err;
249
250	parent = firewall_controller->dev;
251
252	dev_dbg(parent, "Populating %s system bus\n", dev_name(firewall_controller->dev));
253
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;
261		}
262
263		firewalls = kcalloc(len, sizeof(*firewalls), GFP_KERNEL);
264		if (!firewalls) {
265			of_node_put(child);
266			return -ENOMEM;
267		}
268
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;
274		}
275
276		for (i = 0; i < len; i++) {
277			if (firewall_controller->grant_access(firewall_controller,
278							      firewalls[i].firewall_id)) {
279				/*
280				 * Peripheral access not allowed or not defined.
281				 * Mark the node as populated so platform bus won't probe it
282				 */
283				of_detach_node(child);
284				dev_err(parent, "%s: Device driver will not be probed\n",
285					child->full_name);
286			}
287		}
288
289		kfree(firewalls);
290	}
291
292	return 0;
293}
294EXPORT_SYMBOL_GPL(stm32_firewall_populate_bus);
295