drivers/bus/stm32_firewall.c

Source file repositories/reference/linux-study-clean/drivers/bus/stm32_firewall.c

File Facts

System
Linux kernel
Corpus path
drivers/bus/stm32_firewall.c
Extension
.c
Size
9076 bytes
Lines
330
Domain
Driver Families
Bucket
drivers/bus
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err) {
			pr_err("Unable to get access-controllers property for node %s\n, err: %d",
			       np->full_name, err);
			of_node_put(provider);
			return err;
		}

		if (j >= nb_firewall) {
			pr_err("Too many firewall controllers");
			of_node_put(provider);
			return -EINVAL;
		}

		provider_args.args_count = of_phandle_iterator_args(&it, provider_args.args,
								    STM32_FIREWALL_MAX_ARGS);

		/* Check if the parsed phandle corresponds to a registered firewall controller */
		mutex_lock(&firewall_controller_list_lock);
		list_for_each_entry(ctrl, &firewall_controller_list, entry) {
			if (ctrl->dev->of_node->phandle == it.phandle) {
				match = true;
				firewall[j].firewall_ctrl = ctrl;
				break;
			}
		}
		mutex_unlock(&firewall_controller_list_lock);

		if (!match) {
			firewall[j].firewall_ctrl = NULL;
			pr_err("No firewall controller registered for %s\n", np->full_name);
			of_node_put(provider);
			return -ENODEV;
		}

		err = of_property_read_string_index(np, "access-controller-names", j, &fw_entry);
		if (err == 0)
			firewall[j].entry = fw_entry;

		/* Handle the case when there are no arguments given along with the phandle */
		if (provider_args.args_count < 0 ||
		    provider_args.args_count > STM32_FIREWALL_MAX_ARGS) {
			of_node_put(provider);
			return -EINVAL;
		} else if (provider_args.args_count == 0) {
			firewall[j].extra_args_size = 0;
			firewall[j].firewall_id = U32_MAX;
			j++;
			continue;
		}

		/* The firewall ID is always the first argument */
		firewall[j].firewall_id = provider_args.args[0];

		/* Extra args start at the second argument */
		for (i = 0; i < provider_args.args_count - 1; i++)
			firewall[j].extra_args[i] = provider_args.args[i + 1];

		/* Remove the firewall ID arg that is not an extra argument */
		firewall[j].extra_args_size = provider_args.args_count - 1;

		j++;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(stm32_firewall_get_firewall);

int stm32_firewall_grant_access(struct stm32_firewall *firewall)
{
	struct stm32_firewall_controller *firewall_controller;

	if (!firewall || firewall->firewall_id == U32_MAX)
		return -EINVAL;

	firewall_controller = firewall->firewall_ctrl;

	if (!firewall_controller)
		return -ENODEV;

	return firewall_controller->grant_access(firewall_controller, firewall->firewall_id);
}
EXPORT_SYMBOL_GPL(stm32_firewall_grant_access);

int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
{
	struct stm32_firewall_controller *firewall_controller;

	if (!firewall || subsystem_id == U32_MAX || firewall->firewall_id == U32_MAX)
		return -EINVAL;

Annotation

Implementation Notes