Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
[linux-block.git] / drivers / bus / stm32_firewall.c
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
26 static LIST_HEAD(firewall_controller_list);
27 static DEFINE_MUTEX(firewall_controller_list_lock);
28
29 /* Firewall device API */
30
31 int 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 }
114 EXPORT_SYMBOL_GPL(stm32_firewall_get_firewall);
115
116 int 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 }
130 EXPORT_SYMBOL_GPL(stm32_firewall_grant_access);
131
132 int 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 }
146 EXPORT_SYMBOL_GPL(stm32_firewall_grant_access_by_id);
147
148 void 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 }
166 EXPORT_SYMBOL_GPL(stm32_firewall_release_access);
167
168 void 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 }
186 EXPORT_SYMBOL_GPL(stm32_firewall_release_access_by_id);
187
188 /* Firewall controller API */
189
190 int 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 }
213 EXPORT_SYMBOL_GPL(stm32_firewall_controller_register);
214
215 void 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 }
239 EXPORT_SYMBOL_GPL(stm32_firewall_controller_unregister);
240
241 int 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 }
294 EXPORT_SYMBOL_GPL(stm32_firewall_populate_bus);