// SPDX-License-Identifier: GPL-2.0+ /* * Derived from arch/i386/kernel/irq.c * Copyright (C) 1992 Linus Torvalds * Adapted from arch/i386 by Gary Thomas * Copyright (C) 1995-1996 Gary Thomas ([email protected]) * Updated and modified by Cort Dougan <[email protected]> * Copyright (C) 1996-2001 Cort Dougan * Adapted for Power Macintosh by Paul Mackerras * Copyright (C) 1996 Paul Mackerras ([email protected]) * * This file contains the code used to make IRQ descriptions in the * device tree to actual irq numbers on an interrupt controller * driver. */ #define pr_fmt(fmt) … #include <linux/device.h> #include <linux/errno.h> #include <linux/list.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/string.h> #include <linux/slab.h> #include "of_private.h" /** * irq_of_parse_and_map - Parse and map an interrupt into linux virq space * @dev: Device node of the device whose interrupt is to be mapped * @index: Index of the interrupt to map * * This function is a wrapper that chains of_irq_parse_one() and * irq_create_of_mapping() to make things easier to callers */ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) { … } EXPORT_SYMBOL_GPL(…); /** * of_irq_find_parent - Given a device node, find its interrupt parent node * @child: pointer to device node * * Return: A pointer to the interrupt parent node, or NULL if the interrupt * parent could not be determined. */ struct device_node *of_irq_find_parent(struct device_node *child) { … } EXPORT_SYMBOL_GPL(…); /* * These interrupt controllers abuse interrupt-map for unspeakable * reasons and rely on the core code to *ignore* it (the drivers do * their own parsing of the property). The PAsemi entry covers a * non-sensical interrupt-map that is better left ignored. * * If you think of adding to the list for something *new*, think * again. There is a high chance that you will be sent back to the * drawing board. */ static const char * const of_irq_imap_abusers[] = …; const __be32 *of_irq_parse_imap_parent(const __be32 *imap, int len, struct of_phandle_args *out_irq) { … } /** * of_irq_parse_raw - Low level interrupt tree parsing * @addr: address specifier (start of "reg" property of the device) in be32 format * @out_irq: structure of_phandle_args updated by this function * * This function is a low-level interrupt tree walking function. It * can be used to do a partial walk with synthetized reg and interrupts * properties, for example when resolving PCI interrupts when no device * node exist for the parent. It takes an interrupt specifier structure as * input, walks the tree looking for any interrupt-map properties, translates * the specifier for each map, and then returns the translated map. * * Return: 0 on success and a negative number on error */ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) { … } EXPORT_SYMBOL_GPL(…); /** * of_irq_parse_one - Resolve an interrupt for a device * @device: the device whose interrupt is to be resolved * @index: index of the interrupt to resolve * @out_irq: structure of_phandle_args filled by this function * * This function resolves an interrupt for a node by walking the interrupt tree, * finding which interrupt controller node it is attached to, and returning the * interrupt specifier that can be used to retrieve a Linux IRQ number. */ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) { … } EXPORT_SYMBOL_GPL(…); /** * of_irq_to_resource - Decode a node's IRQ and return it as a resource * @dev: pointer to device tree node * @index: zero-based index of the irq * @r: pointer to resource structure to return result into. */ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) { … } EXPORT_SYMBOL_GPL(…); /** * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number * @dev: pointer to device tree node * @index: zero-based index of the IRQ * * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case * of any other failure. */ int of_irq_get(struct device_node *dev, int index) { … } EXPORT_SYMBOL_GPL(…); /** * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number * @dev: pointer to device tree node * @name: IRQ name * * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case * of any other failure. */ int of_irq_get_byname(struct device_node *dev, const char *name) { … } EXPORT_SYMBOL_GPL(…); /** * of_irq_count - Count the number of IRQs a node uses * @dev: pointer to device tree node */ int of_irq_count(struct device_node *dev) { … } /** * of_irq_to_resource_table - Fill in resource table with node's IRQ info * @dev: pointer to device tree node * @res: array of resources to fill in * @nr_irqs: the number of IRQs (and upper bound for num of @res elements) * * Return: The size of the filled in table (up to @nr_irqs). */ int of_irq_to_resource_table(struct device_node *dev, struct resource *res, int nr_irqs) { … } EXPORT_SYMBOL_GPL(…); struct of_intc_desc { … }; /** * of_irq_init - Scan and init matching interrupt controllers in DT * @matches: 0 terminated array of nodes to match and init function to call * * This function scans the device tree for matching interrupt controller nodes, * and calls their initialization functions in order with parents first. */ void __init of_irq_init(const struct of_device_id *matches) { … } static u32 __of_msi_map_id(struct device *dev, struct device_node **np, u32 id_in) { … } /** * of_msi_map_id - Map a MSI ID for a device. * @dev: device for which the mapping is to be done. * @msi_np: device node of the expected msi controller. * @id_in: unmapped MSI ID for the device. * * Walk up the device hierarchy looking for devices with a "msi-map" * property. If found, apply the mapping to @id_in. * * Return: The mapped MSI ID. */ u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in) { … } /** * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain * @dev: device for which the mapping is to be done. * @id: Device ID. * @bus_token: Bus token * * Walk up the device hierarchy looking for devices with a "msi-map" * property. * * Returns: the MSI domain for this device (or NULL on failure) */ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id, u32 bus_token) { … } /** * of_msi_get_domain - Use msi-parent to find the relevant MSI domain * @dev: device for which the domain is requested * @np: device node for @dev * @token: bus type for this domain * * Parse the msi-parent property (both the simple and the complex * versions), and returns the corresponding MSI domain. * * Returns: the MSI domain for this device (or NULL on failure). */ struct irq_domain *of_msi_get_domain(struct device *dev, struct device_node *np, enum irq_domain_bus_token token) { … } EXPORT_SYMBOL_GPL(…); /** * of_msi_configure - Set the msi_domain field of a device * @dev: device structure to associate with an MSI irq domain * @np: device node for that device */ void of_msi_configure(struct device *dev, struct device_node *np) { … } EXPORT_SYMBOL_GPL(…);