LCOV - code coverage report
Current view: top level - include/linux - irqdomain.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 10 24 41.7 %
Date: 2021-04-22 12:43:58 Functions: 0 0 -

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : /*
       3             :  * irq_domain - IRQ translation domains
       4             :  *
       5             :  * Translation infrastructure between hw and linux irq numbers.  This is
       6             :  * helpful for interrupt controllers to implement mapping between hardware
       7             :  * irq numbers and the Linux irq number space.
       8             :  *
       9             :  * irq_domains also have hooks for translating device tree or other
      10             :  * firmware interrupt representations into a hardware irq number that
      11             :  * can be mapped back to a Linux irq number without any extra platform
      12             :  * support code.
      13             :  *
      14             :  * Interrupt controller "domain" data structure. This could be defined as a
      15             :  * irq domain controller. That is, it handles the mapping between hardware
      16             :  * and virtual interrupt numbers for a given interrupt domain. The domain
      17             :  * structure is generally created by the PIC code for a given PIC instance
      18             :  * (though a domain can cover more than one PIC if they have a flat number
      19             :  * model). It's the domain callbacks that are responsible for setting the
      20             :  * irq_chip on a given irq_desc after it's been mapped.
      21             :  *
      22             :  * The host code and data structures use a fwnode_handle pointer to
      23             :  * identify the domain. In some cases, and in order to preserve source
      24             :  * code compatibility, this fwnode pointer is "upgraded" to a DT
      25             :  * device_node. For those firmware infrastructures that do not provide
      26             :  * a unique identifier for an interrupt controller, the irq_domain
      27             :  * code offers a fwnode allocator.
      28             :  */
      29             : 
      30             : #ifndef _LINUX_IRQDOMAIN_H
      31             : #define _LINUX_IRQDOMAIN_H
      32             : 
      33             : #include <linux/types.h>
      34             : #include <linux/irqhandler.h>
      35             : #include <linux/of.h>
      36             : #include <linux/mutex.h>
      37             : #include <linux/radix-tree.h>
      38             : 
      39             : struct device_node;
      40             : struct fwnode_handle;
      41             : struct irq_domain;
      42             : struct irq_chip;
      43             : struct irq_data;
      44             : struct cpumask;
      45             : struct seq_file;
      46             : struct irq_affinity_desc;
      47             : 
      48             : /* Number of irqs reserved for a legacy isa controller */
      49             : #define NUM_ISA_INTERRUPTS      16
      50             : 
      51             : #define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16
      52             : 
      53             : /**
      54             :  * struct irq_fwspec - generic IRQ specifier structure
      55             :  *
      56             :  * @fwnode:             Pointer to a firmware-specific descriptor
      57             :  * @param_count:        Number of device-specific parameters
      58             :  * @param:              Device-specific parameters
      59             :  *
      60             :  * This structure, directly modeled after of_phandle_args, is used to
      61             :  * pass a device-specific description of an interrupt.
      62             :  */
      63             : struct irq_fwspec {
      64             :         struct fwnode_handle *fwnode;
      65             :         int param_count;
      66             :         u32 param[IRQ_DOMAIN_IRQ_SPEC_PARAMS];
      67             : };
      68             : 
      69             : /*
      70             :  * Should several domains have the same device node, but serve
      71             :  * different purposes (for example one domain is for PCI/MSI, and the
      72             :  * other for wired IRQs), they can be distinguished using a
      73             :  * bus-specific token. Most domains are expected to only carry
      74             :  * DOMAIN_BUS_ANY.
      75             :  */
      76             : enum irq_domain_bus_token {
      77             :         DOMAIN_BUS_ANY          = 0,
      78             :         DOMAIN_BUS_WIRED,
      79             :         DOMAIN_BUS_GENERIC_MSI,
      80             :         DOMAIN_BUS_PCI_MSI,
      81             :         DOMAIN_BUS_PLATFORM_MSI,
      82             :         DOMAIN_BUS_NEXUS,
      83             :         DOMAIN_BUS_IPI,
      84             :         DOMAIN_BUS_FSL_MC_MSI,
      85             :         DOMAIN_BUS_TI_SCI_INTA_MSI,
      86             :         DOMAIN_BUS_WAKEUP,
      87             :         DOMAIN_BUS_VMD_MSI,
      88             : };
      89             : 
      90             : /**
      91             :  * struct irq_domain_ops - Methods for irq_domain objects
      92             :  * @match: Match an interrupt controller device node to a host, returns
      93             :  *         1 on a match
      94             :  * @map: Create or update a mapping between a virtual irq number and a hw
      95             :  *       irq number. This is called only once for a given mapping.
      96             :  * @unmap: Dispose of such a mapping
      97             :  * @xlate: Given a device tree node and interrupt specifier, decode
      98             :  *         the hardware irq number and linux irq type value.
      99             :  *
     100             :  * Functions below are provided by the driver and called whenever a new mapping
     101             :  * is created or an old mapping is disposed. The driver can then proceed to
     102             :  * whatever internal data structures management is required. It also needs
     103             :  * to setup the irq_desc when returning from map().
     104             :  */
     105             : struct irq_domain_ops {
     106             :         int (*match)(struct irq_domain *d, struct device_node *node,
     107             :                      enum irq_domain_bus_token bus_token);
     108             :         int (*select)(struct irq_domain *d, struct irq_fwspec *fwspec,
     109             :                       enum irq_domain_bus_token bus_token);
     110             :         int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
     111             :         void (*unmap)(struct irq_domain *d, unsigned int virq);
     112             :         int (*xlate)(struct irq_domain *d, struct device_node *node,
     113             :                      const u32 *intspec, unsigned int intsize,
     114             :                      unsigned long *out_hwirq, unsigned int *out_type);
     115             : #ifdef  CONFIG_IRQ_DOMAIN_HIERARCHY
     116             :         /* extended V2 interfaces to support hierarchy irq_domains */
     117             :         int (*alloc)(struct irq_domain *d, unsigned int virq,
     118             :                      unsigned int nr_irqs, void *arg);
     119             :         void (*free)(struct irq_domain *d, unsigned int virq,
     120             :                      unsigned int nr_irqs);
     121             :         int (*activate)(struct irq_domain *d, struct irq_data *irqd, bool reserve);
     122             :         void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data);
     123             :         int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec,
     124             :                          unsigned long *out_hwirq, unsigned int *out_type);
     125             : #endif
     126             : #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
     127             :         void (*debug_show)(struct seq_file *m, struct irq_domain *d,
     128             :                            struct irq_data *irqd, int ind);
     129             : #endif
     130             : };
     131             : 
     132             : extern struct irq_domain_ops irq_generic_chip_ops;
     133             : 
     134             : struct irq_domain_chip_generic;
     135             : 
     136             : /**
     137             :  * struct irq_domain - Hardware interrupt number translation object
     138             :  * @link: Element in global irq_domain list.
     139             :  * @name: Name of interrupt domain
     140             :  * @ops: pointer to irq_domain methods
     141             :  * @host_data: private data pointer for use by owner.  Not touched by irq_domain
     142             :  *             core code.
     143             :  * @flags: host per irq_domain flags
     144             :  * @mapcount: The number of mapped interrupts
     145             :  *
     146             :  * Optional elements
     147             :  * @fwnode: Pointer to firmware node associated with the irq_domain. Pretty easy
     148             :  *          to swap it for the of_node via the irq_domain_get_of_node accessor
     149             :  * @gc: Pointer to a list of generic chips. There is a helper function for
     150             :  *      setting up one or more generic chips for interrupt controllers
     151             :  *      drivers using the generic chip library which uses this pointer.
     152             :  * @parent: Pointer to parent irq_domain to support hierarchy irq_domains
     153             :  *
     154             :  * Revmap data, used internally by irq_domain
     155             :  * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
     156             :  *                         support direct mapping
     157             :  * @revmap_size: Size of the linear map table @linear_revmap[]
     158             :  * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
     159             :  * @linear_revmap: Linear table of hwirq->virq reverse mappings
     160             :  */
     161             : struct irq_domain {
     162             :         struct list_head link;
     163             :         const char *name;
     164             :         const struct irq_domain_ops *ops;
     165             :         void *host_data;
     166             :         unsigned int flags;
     167             :         unsigned int mapcount;
     168             : 
     169             :         /* Optional data */
     170             :         struct fwnode_handle *fwnode;
     171             :         enum irq_domain_bus_token bus_token;
     172             :         struct irq_domain_chip_generic *gc;
     173             : #ifdef  CONFIG_IRQ_DOMAIN_HIERARCHY
     174             :         struct irq_domain *parent;
     175             : #endif
     176             : 
     177             :         /* reverse map data. The linear map gets appended to the irq_domain */
     178             :         irq_hw_number_t hwirq_max;
     179             :         unsigned int revmap_direct_max_irq;
     180             :         unsigned int revmap_size;
     181             :         struct radix_tree_root revmap_tree;
     182             :         struct mutex revmap_tree_mutex;
     183             :         unsigned int linear_revmap[];
     184             : };
     185             : 
     186             : /* Irq domain flags */
     187             : enum {
     188             :         /* Irq domain is hierarchical */
     189             :         IRQ_DOMAIN_FLAG_HIERARCHY       = (1 << 0),
     190             : 
     191             :         /* Irq domain name was allocated in __irq_domain_add() */
     192             :         IRQ_DOMAIN_NAME_ALLOCATED       = (1 << 1),
     193             : 
     194             :         /* Irq domain is an IPI domain with virq per cpu */
     195             :         IRQ_DOMAIN_FLAG_IPI_PER_CPU     = (1 << 2),
     196             : 
     197             :         /* Irq domain is an IPI domain with single virq */
     198             :         IRQ_DOMAIN_FLAG_IPI_SINGLE      = (1 << 3),
     199             : 
     200             :         /* Irq domain implements MSIs */
     201             :         IRQ_DOMAIN_FLAG_MSI             = (1 << 4),
     202             : 
     203             :         /* Irq domain implements MSI remapping */
     204             :         IRQ_DOMAIN_FLAG_MSI_REMAP       = (1 << 5),
     205             : 
     206             :         /*
     207             :          * Quirk to handle MSI implementations which do not provide
     208             :          * masking. Currently known to affect x86, but partially
     209             :          * handled in core code.
     210             :          */
     211             :         IRQ_DOMAIN_MSI_NOMASK_QUIRK     = (1 << 6),
     212             : 
     213             :         /*
     214             :          * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
     215             :          * for implementation specific purposes and ignored by the
     216             :          * core code.
     217             :          */
     218             :         IRQ_DOMAIN_FLAG_NONCORE         = (1 << 16),
     219             : };
     220             : 
     221           0 : static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
     222             : {
     223           0 :         return to_of_node(d->fwnode);
     224             : }
     225             : 
     226             : #ifdef CONFIG_IRQ_DOMAIN
     227             : struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id,
     228             :                                                 const char *name, phys_addr_t *pa);
     229             : 
     230             : enum {
     231             :         IRQCHIP_FWNODE_REAL,
     232             :         IRQCHIP_FWNODE_NAMED,
     233             :         IRQCHIP_FWNODE_NAMED_ID,
     234             : };
     235             : 
     236             : static inline
     237           1 : struct fwnode_handle *irq_domain_alloc_named_fwnode(const char *name)
     238             : {
     239           1 :         return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED, 0, name, NULL);
     240             : }
     241             : 
     242             : static inline
     243           1 : struct fwnode_handle *irq_domain_alloc_named_id_fwnode(const char *name, int id)
     244             : {
     245           1 :         return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED_ID, id, name,
     246             :                                          NULL);
     247             : }
     248             : 
     249             : static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
     250             : {
     251             :         return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_REAL, 0, NULL, pa);
     252             : }
     253             : 
     254             : void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
     255             : struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
     256             :                                     irq_hw_number_t hwirq_max, int direct_max,
     257             :                                     const struct irq_domain_ops *ops,
     258             :                                     void *host_data);
     259             : struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
     260             :                                          unsigned int size,
     261             :                                          unsigned int first_irq,
     262             :                                          const struct irq_domain_ops *ops,
     263             :                                          void *host_data);
     264             : struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
     265             :                                          unsigned int size,
     266             :                                          unsigned int first_irq,
     267             :                                          irq_hw_number_t first_hwirq,
     268             :                                          const struct irq_domain_ops *ops,
     269             :                                          void *host_data);
     270             : struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
     271             :                                             unsigned int size,
     272             :                                             unsigned int first_irq,
     273             :                                             irq_hw_number_t first_hwirq,
     274             :                                             const struct irq_domain_ops *ops,
     275             :                                             void *host_data);
     276             : extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
     277             :                                                    enum irq_domain_bus_token bus_token);
     278             : extern bool irq_domain_check_msi_remap(void);
     279             : extern void irq_set_default_host(struct irq_domain *host);
     280             : extern struct irq_domain *irq_get_default_host(void);
     281             : extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
     282             :                                   irq_hw_number_t hwirq, int node,
     283             :                                   const struct irq_affinity_desc *affinity);
     284             : 
     285           0 : static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
     286             : {
     287           0 :         return node ? &node->fwnode : NULL;
     288             : }
     289             : 
     290             : extern const struct fwnode_operations irqchip_fwnode_ops;
     291             : 
     292           3 : static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
     293             : {
     294           3 :         return fwnode && fwnode->ops == &irqchip_fwnode_ops;
     295             : }
     296             : 
     297             : extern void irq_domain_update_bus_token(struct irq_domain *domain,
     298             :                                         enum irq_domain_bus_token bus_token);
     299             : 
     300             : static inline
     301             : struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
     302             :                                             enum irq_domain_bus_token bus_token)
     303             : {
     304             :         struct irq_fwspec fwspec = {
     305             :                 .fwnode = fwnode,
     306             :         };
     307             : 
     308             :         return irq_find_matching_fwspec(&fwspec, bus_token);
     309             : }
     310             : 
     311             : static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
     312             :                                                         enum irq_domain_bus_token bus_token)
     313             : {
     314             :         return irq_find_matching_fwnode(of_node_to_fwnode(node), bus_token);
     315             : }
     316             : 
     317             : static inline struct irq_domain *irq_find_host(struct device_node *node)
     318             : {
     319             :         struct irq_domain *d;
     320             : 
     321             :         d = irq_find_matching_host(node, DOMAIN_BUS_WIRED);
     322             :         if (!d)
     323             :                 d = irq_find_matching_host(node, DOMAIN_BUS_ANY);
     324             : 
     325             :         return d;
     326             : }
     327             : 
     328             : /**
     329             :  * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain.
     330             :  * @of_node: pointer to interrupt controller's device tree node.
     331             :  * @size: Number of interrupts in the domain.
     332             :  * @ops: map/unmap domain callbacks
     333             :  * @host_data: Controller private data pointer
     334             :  */
     335             : static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
     336             :                                          unsigned int size,
     337             :                                          const struct irq_domain_ops *ops,
     338             :                                          void *host_data)
     339             : {
     340             :         return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
     341             : }
     342             : static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
     343             :                                          unsigned int max_irq,
     344             :                                          const struct irq_domain_ops *ops,
     345             :                                          void *host_data)
     346             : {
     347             :         return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
     348             : }
     349             : static inline struct irq_domain *irq_domain_add_legacy_isa(
     350             :                                 struct device_node *of_node,
     351             :                                 const struct irq_domain_ops *ops,
     352             :                                 void *host_data)
     353             : {
     354             :         return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
     355             :                                      host_data);
     356             : }
     357             : static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
     358             :                                          const struct irq_domain_ops *ops,
     359             :                                          void *host_data)
     360             : {
     361             :         return __irq_domain_add(of_node_to_fwnode(of_node), 0, ~0, 0, ops, host_data);
     362             : }
     363             : 
     364           1 : static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
     365             :                                          unsigned int size,
     366             :                                          const struct irq_domain_ops *ops,
     367             :                                          void *host_data)
     368             : {
     369           1 :         return __irq_domain_add(fwnode, size, size, 0, ops, host_data);
     370             : }
     371             : 
     372           1 : static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
     373             :                                          const struct irq_domain_ops *ops,
     374             :                                          void *host_data)
     375             : {
     376           1 :         return __irq_domain_add(fwnode, 0, ~0, 0, ops, host_data);
     377             : }
     378             : 
     379             : extern void irq_domain_remove(struct irq_domain *host);
     380             : 
     381             : extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
     382             :                                         irq_hw_number_t hwirq);
     383             : extern void irq_domain_associate_many(struct irq_domain *domain,
     384             :                                       unsigned int irq_base,
     385             :                                       irq_hw_number_t hwirq_base, int count);
     386             : 
     387             : extern unsigned int irq_create_mapping_affinity(struct irq_domain *host,
     388             :                                       irq_hw_number_t hwirq,
     389             :                                       const struct irq_affinity_desc *affinity);
     390             : extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
     391             : extern void irq_dispose_mapping(unsigned int virq);
     392             : 
     393           0 : static inline unsigned int irq_create_mapping(struct irq_domain *host,
     394             :                                               irq_hw_number_t hwirq)
     395             : {
     396           0 :         return irq_create_mapping_affinity(host, hwirq, NULL);
     397             : }
     398             : 
     399             : 
     400             : /**
     401             :  * irq_linear_revmap() - Find a linux irq from a hw irq number.
     402             :  * @domain: domain owning this hardware interrupt
     403             :  * @hwirq: hardware irq number in that domain space
     404             :  *
     405             :  * This is a fast path alternative to irq_find_mapping() that can be
     406             :  * called directly by irq controller code to save a handful of
     407             :  * instructions. It is always safe to call, but won't find irqs mapped
     408             :  * using the radix tree.
     409             :  */
     410             : static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
     411             :                                              irq_hw_number_t hwirq)
     412             : {
     413             :         return hwirq < domain->revmap_size ? domain->linear_revmap[hwirq] : 0;
     414             : }
     415             : extern unsigned int irq_find_mapping(struct irq_domain *host,
     416             :                                      irq_hw_number_t hwirq);
     417             : extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
     418             : extern int irq_create_strict_mappings(struct irq_domain *domain,
     419             :                                       unsigned int irq_base,
     420             :                                       irq_hw_number_t hwirq_base, int count);
     421             : 
     422             : static inline int irq_create_identity_mapping(struct irq_domain *host,
     423             :                                               irq_hw_number_t hwirq)
     424             : {
     425             :         return irq_create_strict_mappings(host, hwirq, hwirq, 1);
     426             : }
     427             : 
     428             : extern const struct irq_domain_ops irq_domain_simple_ops;
     429             : 
     430             : /* stock xlate functions */
     431             : int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
     432             :                         const u32 *intspec, unsigned int intsize,
     433             :                         irq_hw_number_t *out_hwirq, unsigned int *out_type);
     434             : int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
     435             :                         const u32 *intspec, unsigned int intsize,
     436             :                         irq_hw_number_t *out_hwirq, unsigned int *out_type);
     437             : int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
     438             :                         const u32 *intspec, unsigned int intsize,
     439             :                         irq_hw_number_t *out_hwirq, unsigned int *out_type);
     440             : 
     441             : int irq_domain_translate_twocell(struct irq_domain *d,
     442             :                                  struct irq_fwspec *fwspec,
     443             :                                  unsigned long *out_hwirq,
     444             :                                  unsigned int *out_type);
     445             : 
     446             : int irq_domain_translate_onecell(struct irq_domain *d,
     447             :                                  struct irq_fwspec *fwspec,
     448             :                                  unsigned long *out_hwirq,
     449             :                                  unsigned int *out_type);
     450             : 
     451             : /* IPI functions */
     452             : int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
     453             : int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
     454             : 
     455             : /* V2 interfaces to support hierarchy IRQ domains. */
     456             : extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
     457             :                                                 unsigned int virq);
     458             : extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
     459             :                                 irq_hw_number_t hwirq, struct irq_chip *chip,
     460             :                                 void *chip_data, irq_flow_handler_t handler,
     461             :                                 void *handler_data, const char *handler_name);
     462             : extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
     463             : #ifdef  CONFIG_IRQ_DOMAIN_HIERARCHY
     464             : extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
     465             :                         unsigned int flags, unsigned int size,
     466             :                         struct fwnode_handle *fwnode,
     467             :                         const struct irq_domain_ops *ops, void *host_data);
     468             : 
     469             : static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
     470             :                                             unsigned int flags,
     471             :                                             unsigned int size,
     472             :                                             struct device_node *node,
     473             :                                             const struct irq_domain_ops *ops,
     474             :                                             void *host_data)
     475             : {
     476             :         return irq_domain_create_hierarchy(parent, flags, size,
     477             :                                            of_node_to_fwnode(node),
     478             :                                            ops, host_data);
     479             : }
     480             : 
     481             : extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
     482             :                                    unsigned int nr_irqs, int node, void *arg,
     483             :                                    bool realloc,
     484             :                                    const struct irq_affinity_desc *affinity);
     485             : extern void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs);
     486             : extern int irq_domain_activate_irq(struct irq_data *irq_data, bool early);
     487             : extern void irq_domain_deactivate_irq(struct irq_data *irq_data);
     488             : 
     489           0 : static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
     490             :                         unsigned int nr_irqs, int node, void *arg)
     491             : {
     492           0 :         return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false,
     493             :                                        NULL);
     494             : }
     495             : 
     496             : extern int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
     497             :                                            unsigned int irq_base,
     498             :                                            unsigned int nr_irqs, void *arg);
     499             : extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
     500             :                                          unsigned int virq,
     501             :                                          irq_hw_number_t hwirq,
     502             :                                          struct irq_chip *chip,
     503             :                                          void *chip_data);
     504             : extern void irq_domain_free_irqs_common(struct irq_domain *domain,
     505             :                                         unsigned int virq,
     506             :                                         unsigned int nr_irqs);
     507             : extern void irq_domain_free_irqs_top(struct irq_domain *domain,
     508             :                                      unsigned int virq, unsigned int nr_irqs);
     509             : 
     510             : extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
     511             : extern int irq_domain_pop_irq(struct irq_domain *domain, int virq);
     512             : 
     513             : extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
     514             :                                         unsigned int irq_base,
     515             :                                         unsigned int nr_irqs, void *arg);
     516             : 
     517             : extern void irq_domain_free_irqs_parent(struct irq_domain *domain,
     518             :                                         unsigned int irq_base,
     519             :                                         unsigned int nr_irqs);
     520             : 
     521             : extern int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
     522             :                                            unsigned int virq);
     523             : 
     524           0 : static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
     525             : {
     526           0 :         return domain->flags & IRQ_DOMAIN_FLAG_HIERARCHY;
     527             : }
     528             : 
     529             : static inline bool irq_domain_is_ipi(struct irq_domain *domain)
     530             : {
     531             :         return domain->flags &
     532             :                 (IRQ_DOMAIN_FLAG_IPI_PER_CPU | IRQ_DOMAIN_FLAG_IPI_SINGLE);
     533             : }
     534             : 
     535             : static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
     536             : {
     537             :         return domain->flags & IRQ_DOMAIN_FLAG_IPI_PER_CPU;
     538             : }
     539             : 
     540             : static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
     541             : {
     542             :         return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
     543             : }
     544             : 
     545           0 : static inline bool irq_domain_is_msi(struct irq_domain *domain)
     546             : {
     547           0 :         return domain->flags & IRQ_DOMAIN_FLAG_MSI;
     548             : }
     549             : 
     550           0 : static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
     551             : {
     552           0 :         return domain->flags & IRQ_DOMAIN_FLAG_MSI_REMAP;
     553             : }
     554             : 
     555             : extern bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain);
     556             : 
     557             : #else   /* CONFIG_IRQ_DOMAIN_HIERARCHY */
     558             : static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
     559             :                         unsigned int nr_irqs, int node, void *arg)
     560             : {
     561             :         return -1;
     562             : }
     563             : 
     564             : static inline void irq_domain_free_irqs(unsigned int virq,
     565             :                                         unsigned int nr_irqs) { }
     566             : 
     567             : static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
     568             : {
     569             :         return false;
     570             : }
     571             : 
     572             : static inline bool irq_domain_is_ipi(struct irq_domain *domain)
     573             : {
     574             :         return false;
     575             : }
     576             : 
     577             : static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
     578             : {
     579             :         return false;
     580             : }
     581             : 
     582             : static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
     583             : {
     584             :         return false;
     585             : }
     586             : 
     587             : static inline bool irq_domain_is_msi(struct irq_domain *domain)
     588             : {
     589             :         return false;
     590             : }
     591             : 
     592             : static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
     593             : {
     594             :         return false;
     595             : }
     596             : 
     597             : static inline bool
     598             : irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
     599             : {
     600             :         return false;
     601             : }
     602             : #endif  /* CONFIG_IRQ_DOMAIN_HIERARCHY */
     603             : 
     604             : #else /* CONFIG_IRQ_DOMAIN */
     605             : static inline void irq_dispose_mapping(unsigned int virq) { }
     606             : static inline struct irq_domain *irq_find_matching_fwnode(
     607             :         struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
     608             : {
     609             :         return NULL;
     610             : }
     611             : static inline bool irq_domain_check_msi_remap(void)
     612             : {
     613             :         return false;
     614             : }
     615             : #endif /* !CONFIG_IRQ_DOMAIN */
     616             : 
     617             : #endif /* _LINUX_IRQDOMAIN_H */

Generated by: LCOV version 1.14