LCOV - code coverage report
Current view: top level - include/linux - irqdomain.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 14 0.0 %
Date: 2023-03-27 20:00:47 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/irqdomain_defs.h>
      35             : #include <linux/irqhandler.h>
      36             : #include <linux/of.h>
      37             : #include <linux/mutex.h>
      38             : #include <linux/radix-tree.h>
      39             : 
      40             : struct device_node;
      41             : struct fwnode_handle;
      42             : struct irq_domain;
      43             : struct irq_chip;
      44             : struct irq_data;
      45             : struct irq_desc;
      46             : struct cpumask;
      47             : struct seq_file;
      48             : struct irq_affinity_desc;
      49             : struct msi_parent_ops;
      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             : /* Conversion function from of_phandle_args fields to fwspec  */
      70             : void of_phandle_args_to_fwspec(struct device_node *np, const u32 *args,
      71             :                                unsigned int count, struct irq_fwspec *fwspec);
      72             : 
      73             : /**
      74             :  * struct irq_domain_ops - Methods for irq_domain objects
      75             :  * @match: Match an interrupt controller device node to a host, returns
      76             :  *         1 on a match
      77             :  * @map: Create or update a mapping between a virtual irq number and a hw
      78             :  *       irq number. This is called only once for a given mapping.
      79             :  * @unmap: Dispose of such a mapping
      80             :  * @xlate: Given a device tree node and interrupt specifier, decode
      81             :  *         the hardware irq number and linux irq type value.
      82             :  *
      83             :  * Functions below are provided by the driver and called whenever a new mapping
      84             :  * is created or an old mapping is disposed. The driver can then proceed to
      85             :  * whatever internal data structures management is required. It also needs
      86             :  * to setup the irq_desc when returning from map().
      87             :  */
      88             : struct irq_domain_ops {
      89             :         int (*match)(struct irq_domain *d, struct device_node *node,
      90             :                      enum irq_domain_bus_token bus_token);
      91             :         int (*select)(struct irq_domain *d, struct irq_fwspec *fwspec,
      92             :                       enum irq_domain_bus_token bus_token);
      93             :         int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
      94             :         void (*unmap)(struct irq_domain *d, unsigned int virq);
      95             :         int (*xlate)(struct irq_domain *d, struct device_node *node,
      96             :                      const u32 *intspec, unsigned int intsize,
      97             :                      unsigned long *out_hwirq, unsigned int *out_type);
      98             : #ifdef  CONFIG_IRQ_DOMAIN_HIERARCHY
      99             :         /* extended V2 interfaces to support hierarchy irq_domains */
     100             :         int (*alloc)(struct irq_domain *d, unsigned int virq,
     101             :                      unsigned int nr_irqs, void *arg);
     102             :         void (*free)(struct irq_domain *d, unsigned int virq,
     103             :                      unsigned int nr_irqs);
     104             :         int (*activate)(struct irq_domain *d, struct irq_data *irqd, bool reserve);
     105             :         void (*deactivate)(struct irq_domain *d, struct irq_data *irq_data);
     106             :         int (*translate)(struct irq_domain *d, struct irq_fwspec *fwspec,
     107             :                          unsigned long *out_hwirq, unsigned int *out_type);
     108             : #endif
     109             : #ifdef CONFIG_GENERIC_IRQ_DEBUGFS
     110             :         void (*debug_show)(struct seq_file *m, struct irq_domain *d,
     111             :                            struct irq_data *irqd, int ind);
     112             : #endif
     113             : };
     114             : 
     115             : extern const struct irq_domain_ops irq_generic_chip_ops;
     116             : 
     117             : struct irq_domain_chip_generic;
     118             : 
     119             : /**
     120             :  * struct irq_domain - Hardware interrupt number translation object
     121             :  * @link:       Element in global irq_domain list.
     122             :  * @name:       Name of interrupt domain
     123             :  * @ops:        Pointer to irq_domain methods
     124             :  * @host_data:  Private data pointer for use by owner.  Not touched by irq_domain
     125             :  *              core code.
     126             :  * @flags:      Per irq_domain flags
     127             :  * @mapcount:   The number of mapped interrupts
     128             :  * @mutex:      Domain lock, hierarchical domains use root domain's lock
     129             :  * @root:       Pointer to root domain, or containing structure if non-hierarchical
     130             :  *
     131             :  * Optional elements:
     132             :  * @fwnode:     Pointer to firmware node associated with the irq_domain. Pretty easy
     133             :  *              to swap it for the of_node via the irq_domain_get_of_node accessor
     134             :  * @gc:         Pointer to a list of generic chips. There is a helper function for
     135             :  *              setting up one or more generic chips for interrupt controllers
     136             :  *              drivers using the generic chip library which uses this pointer.
     137             :  * @dev:        Pointer to the device which instantiated the irqdomain
     138             :  *              With per device irq domains this is not necessarily the same
     139             :  *              as @pm_dev.
     140             :  * @pm_dev:     Pointer to a device that can be utilized for power management
     141             :  *              purposes related to the irq domain.
     142             :  * @parent:     Pointer to parent irq_domain to support hierarchy irq_domains
     143             :  * @msi_parent_ops: Pointer to MSI parent domain methods for per device domain init
     144             :  *
     145             :  * Revmap data, used internally by the irq domain code:
     146             :  * @revmap_size:        Size of the linear map table @revmap[]
     147             :  * @revmap_tree:        Radix map tree for hwirqs that don't fit in the linear map
     148             :  * @revmap:             Linear table of irq_data pointers
     149             :  */
     150             : struct irq_domain {
     151             :         struct list_head                link;
     152             :         const char                      *name;
     153             :         const struct irq_domain_ops     *ops;
     154             :         void                            *host_data;
     155             :         unsigned int                    flags;
     156             :         unsigned int                    mapcount;
     157             :         struct mutex                    mutex;
     158             :         struct irq_domain               *root;
     159             : 
     160             :         /* Optional data */
     161             :         struct fwnode_handle            *fwnode;
     162             :         enum irq_domain_bus_token       bus_token;
     163             :         struct irq_domain_chip_generic  *gc;
     164             :         struct device                   *dev;
     165             :         struct device                   *pm_dev;
     166             : #ifdef  CONFIG_IRQ_DOMAIN_HIERARCHY
     167             :         struct irq_domain               *parent;
     168             : #endif
     169             : #ifdef CONFIG_GENERIC_MSI_IRQ
     170             :         const struct msi_parent_ops     *msi_parent_ops;
     171             : #endif
     172             : 
     173             :         /* reverse map data. The linear map gets appended to the irq_domain */
     174             :         irq_hw_number_t                 hwirq_max;
     175             :         unsigned int                    revmap_size;
     176             :         struct radix_tree_root          revmap_tree;
     177             :         struct irq_data __rcu           *revmap[];
     178             : };
     179             : 
     180             : /* Irq domain flags */
     181             : enum {
     182             :         /* Irq domain is hierarchical */
     183             :         IRQ_DOMAIN_FLAG_HIERARCHY       = (1 << 0),
     184             : 
     185             :         /* Irq domain name was allocated in __irq_domain_add() */
     186             :         IRQ_DOMAIN_NAME_ALLOCATED       = (1 << 1),
     187             : 
     188             :         /* Irq domain is an IPI domain with virq per cpu */
     189             :         IRQ_DOMAIN_FLAG_IPI_PER_CPU     = (1 << 2),
     190             : 
     191             :         /* Irq domain is an IPI domain with single virq */
     192             :         IRQ_DOMAIN_FLAG_IPI_SINGLE      = (1 << 3),
     193             : 
     194             :         /* Irq domain implements MSIs */
     195             :         IRQ_DOMAIN_FLAG_MSI             = (1 << 4),
     196             : 
     197             :         /*
     198             :          * Irq domain implements isolated MSI, see msi_device_has_isolated_msi()
     199             :          */
     200             :         IRQ_DOMAIN_FLAG_ISOLATED_MSI    = (1 << 5),
     201             : 
     202             :         /* Irq domain doesn't translate anything */
     203             :         IRQ_DOMAIN_FLAG_NO_MAP          = (1 << 6),
     204             : 
     205             :         /* Irq domain is a MSI parent domain */
     206             :         IRQ_DOMAIN_FLAG_MSI_PARENT      = (1 << 8),
     207             : 
     208             :         /* Irq domain is a MSI device domain */
     209             :         IRQ_DOMAIN_FLAG_MSI_DEVICE      = (1 << 9),
     210             : 
     211             :         /*
     212             :          * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
     213             :          * for implementation specific purposes and ignored by the
     214             :          * core code.
     215             :          */
     216             :         IRQ_DOMAIN_FLAG_NONCORE         = (1 << 16),
     217             : };
     218             : 
     219             : static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
     220             : {
     221           0 :         return to_of_node(d->fwnode);
     222             : }
     223             : 
     224             : static inline void irq_domain_set_pm_device(struct irq_domain *d,
     225             :                                             struct device *dev)
     226             : {
     227             :         if (d)
     228             :                 d->pm_dev = dev;
     229             : }
     230             : 
     231             : #ifdef CONFIG_IRQ_DOMAIN
     232             : struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id,
     233             :                                                 const char *name, phys_addr_t *pa);
     234             : 
     235             : enum {
     236             :         IRQCHIP_FWNODE_REAL,
     237             :         IRQCHIP_FWNODE_NAMED,
     238             :         IRQCHIP_FWNODE_NAMED_ID,
     239             : };
     240             : 
     241             : static inline
     242             : struct fwnode_handle *irq_domain_alloc_named_fwnode(const char *name)
     243             : {
     244           0 :         return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED, 0, name, NULL);
     245             : }
     246             : 
     247             : static inline
     248             : struct fwnode_handle *irq_domain_alloc_named_id_fwnode(const char *name, int id)
     249             : {
     250             :         return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_NAMED_ID, id, name,
     251             :                                          NULL);
     252             : }
     253             : 
     254             : static inline struct fwnode_handle *irq_domain_alloc_fwnode(phys_addr_t *pa)
     255             : {
     256             :         return __irq_domain_alloc_fwnode(IRQCHIP_FWNODE_REAL, 0, NULL, pa);
     257             : }
     258             : 
     259             : void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
     260             : struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
     261             :                                     irq_hw_number_t hwirq_max, int direct_max,
     262             :                                     const struct irq_domain_ops *ops,
     263             :                                     void *host_data);
     264             : struct irq_domain *irq_domain_create_simple(struct fwnode_handle *fwnode,
     265             :                                             unsigned int size,
     266             :                                             unsigned int first_irq,
     267             :                                             const struct irq_domain_ops *ops,
     268             :                                             void *host_data);
     269             : struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
     270             :                                          unsigned int size,
     271             :                                          unsigned int first_irq,
     272             :                                          irq_hw_number_t first_hwirq,
     273             :                                          const struct irq_domain_ops *ops,
     274             :                                          void *host_data);
     275             : struct irq_domain *irq_domain_create_legacy(struct fwnode_handle *fwnode,
     276             :                                             unsigned int size,
     277             :                                             unsigned int first_irq,
     278             :                                             irq_hw_number_t first_hwirq,
     279             :                                             const struct irq_domain_ops *ops,
     280             :                                             void *host_data);
     281             : extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
     282             :                                                    enum irq_domain_bus_token bus_token);
     283             : extern void irq_set_default_host(struct irq_domain *host);
     284             : extern struct irq_domain *irq_get_default_host(void);
     285             : extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
     286             :                                   irq_hw_number_t hwirq, int node,
     287             :                                   const struct irq_affinity_desc *affinity);
     288             : 
     289             : static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
     290             : {
     291           0 :         return node ? &node->fwnode : NULL;
     292             : }
     293             : 
     294             : extern const struct fwnode_operations irqchip_fwnode_ops;
     295             : 
     296             : static inline bool is_fwnode_irqchip(struct fwnode_handle *fwnode)
     297             : {
     298           0 :         return fwnode && fwnode->ops == &irqchip_fwnode_ops;
     299             : }
     300             : 
     301             : extern void irq_domain_update_bus_token(struct irq_domain *domain,
     302             :                                         enum irq_domain_bus_token bus_token);
     303             : 
     304             : static inline
     305             : struct irq_domain *irq_find_matching_fwnode(struct fwnode_handle *fwnode,
     306             :                                             enum irq_domain_bus_token bus_token)
     307             : {
     308           0 :         struct irq_fwspec fwspec = {
     309             :                 .fwnode = fwnode,
     310             :         };
     311             : 
     312           0 :         return irq_find_matching_fwspec(&fwspec, bus_token);
     313             : }
     314             : 
     315             : static inline struct irq_domain *irq_find_matching_host(struct device_node *node,
     316             :                                                         enum irq_domain_bus_token bus_token)
     317             : {
     318             :         return irq_find_matching_fwnode(of_node_to_fwnode(node), bus_token);
     319             : }
     320             : 
     321             : static inline struct irq_domain *irq_find_host(struct device_node *node)
     322             : {
     323             :         struct irq_domain *d;
     324             : 
     325             :         d = irq_find_matching_host(node, DOMAIN_BUS_WIRED);
     326             :         if (!d)
     327             :                 d = irq_find_matching_host(node, DOMAIN_BUS_ANY);
     328             : 
     329             :         return d;
     330             : }
     331             : 
     332             : static inline struct irq_domain *irq_domain_add_simple(struct device_node *of_node,
     333             :                                                        unsigned int size,
     334             :                                                        unsigned int first_irq,
     335             :                                                        const struct irq_domain_ops *ops,
     336             :                                                        void *host_data)
     337             : {
     338             :         return irq_domain_create_simple(of_node_to_fwnode(of_node), size, first_irq, ops, host_data);
     339             : }
     340             : 
     341             : /**
     342             :  * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain.
     343             :  * @of_node: pointer to interrupt controller's device tree node.
     344             :  * @size: Number of interrupts in the domain.
     345             :  * @ops: map/unmap domain callbacks
     346             :  * @host_data: Controller private data pointer
     347             :  */
     348             : static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
     349             :                                          unsigned int size,
     350             :                                          const struct irq_domain_ops *ops,
     351             :                                          void *host_data)
     352             : {
     353             :         return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
     354             : }
     355             : 
     356             : #ifdef CONFIG_IRQ_DOMAIN_NOMAP
     357             : static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
     358             :                                          unsigned int max_irq,
     359             :                                          const struct irq_domain_ops *ops,
     360             :                                          void *host_data)
     361             : {
     362             :         return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
     363             : }
     364             : 
     365             : extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
     366             : #endif
     367             : 
     368             : static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
     369             :                                          const struct irq_domain_ops *ops,
     370             :                                          void *host_data)
     371             : {
     372             :         return __irq_domain_add(of_node_to_fwnode(of_node), 0, ~0, 0, ops, host_data);
     373             : }
     374             : 
     375             : static inline struct irq_domain *irq_domain_create_linear(struct fwnode_handle *fwnode,
     376             :                                          unsigned int size,
     377             :                                          const struct irq_domain_ops *ops,
     378             :                                          void *host_data)
     379             : {
     380           0 :         return __irq_domain_add(fwnode, size, size, 0, ops, host_data);
     381             : }
     382             : 
     383             : static inline struct irq_domain *irq_domain_create_tree(struct fwnode_handle *fwnode,
     384             :                                          const struct irq_domain_ops *ops,
     385             :                                          void *host_data)
     386             : {
     387             :         return __irq_domain_add(fwnode, 0, ~0, 0, ops, host_data);
     388             : }
     389             : 
     390             : extern void irq_domain_remove(struct irq_domain *host);
     391             : 
     392             : extern int irq_domain_associate(struct irq_domain *domain, unsigned int irq,
     393             :                                         irq_hw_number_t hwirq);
     394             : extern void irq_domain_associate_many(struct irq_domain *domain,
     395             :                                       unsigned int irq_base,
     396             :                                       irq_hw_number_t hwirq_base, int count);
     397             : 
     398             : extern unsigned int irq_create_mapping_affinity(struct irq_domain *host,
     399             :                                       irq_hw_number_t hwirq,
     400             :                                       const struct irq_affinity_desc *affinity);
     401             : extern unsigned int irq_create_fwspec_mapping(struct irq_fwspec *fwspec);
     402             : extern void irq_dispose_mapping(unsigned int virq);
     403             : 
     404             : static inline unsigned int irq_create_mapping(struct irq_domain *host,
     405             :                                               irq_hw_number_t hwirq)
     406             : {
     407           0 :         return irq_create_mapping_affinity(host, hwirq, NULL);
     408             : }
     409             : 
     410             : extern struct irq_desc *__irq_resolve_mapping(struct irq_domain *domain,
     411             :                                               irq_hw_number_t hwirq,
     412             :                                               unsigned int *irq);
     413             : 
     414             : static inline struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
     415             :                                                    irq_hw_number_t hwirq)
     416             : {
     417           0 :         return __irq_resolve_mapping(domain, hwirq, NULL);
     418             : }
     419             : 
     420             : /**
     421             :  * irq_find_mapping() - Find a linux irq from a hw irq number.
     422             :  * @domain: domain owning this hardware interrupt
     423             :  * @hwirq: hardware irq number in that domain space
     424             :  */
     425             : static inline unsigned int irq_find_mapping(struct irq_domain *domain,
     426             :                                             irq_hw_number_t hwirq)
     427             : {
     428             :         unsigned int irq;
     429             : 
     430           0 :         if (__irq_resolve_mapping(domain, hwirq, &irq))
     431           0 :                 return irq;
     432             : 
     433             :         return 0;
     434             : }
     435             : 
     436             : static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
     437             :                                              irq_hw_number_t hwirq)
     438             : {
     439             :         return irq_find_mapping(domain, hwirq);
     440             : }
     441             : 
     442             : extern const struct irq_domain_ops irq_domain_simple_ops;
     443             : 
     444             : /* stock xlate functions */
     445             : int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
     446             :                         const u32 *intspec, unsigned int intsize,
     447             :                         irq_hw_number_t *out_hwirq, unsigned int *out_type);
     448             : int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
     449             :                         const u32 *intspec, unsigned int intsize,
     450             :                         irq_hw_number_t *out_hwirq, unsigned int *out_type);
     451             : int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
     452             :                         const u32 *intspec, unsigned int intsize,
     453             :                         irq_hw_number_t *out_hwirq, unsigned int *out_type);
     454             : 
     455             : int irq_domain_translate_twocell(struct irq_domain *d,
     456             :                                  struct irq_fwspec *fwspec,
     457             :                                  unsigned long *out_hwirq,
     458             :                                  unsigned int *out_type);
     459             : 
     460             : int irq_domain_translate_onecell(struct irq_domain *d,
     461             :                                  struct irq_fwspec *fwspec,
     462             :                                  unsigned long *out_hwirq,
     463             :                                  unsigned int *out_type);
     464             : 
     465             : /* IPI functions */
     466             : int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
     467             : int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
     468             : 
     469             : /* V2 interfaces to support hierarchy IRQ domains. */
     470             : extern struct irq_data *irq_domain_get_irq_data(struct irq_domain *domain,
     471             :                                                 unsigned int virq);
     472             : extern void irq_domain_set_info(struct irq_domain *domain, unsigned int virq,
     473             :                                 irq_hw_number_t hwirq,
     474             :                                 const struct irq_chip *chip,
     475             :                                 void *chip_data, irq_flow_handler_t handler,
     476             :                                 void *handler_data, const char *handler_name);
     477             : extern void irq_domain_reset_irq_data(struct irq_data *irq_data);
     478             : #ifdef  CONFIG_IRQ_DOMAIN_HIERARCHY
     479             : extern struct irq_domain *irq_domain_create_hierarchy(struct irq_domain *parent,
     480             :                         unsigned int flags, unsigned int size,
     481             :                         struct fwnode_handle *fwnode,
     482             :                         const struct irq_domain_ops *ops, void *host_data);
     483             : 
     484             : static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *parent,
     485             :                                             unsigned int flags,
     486             :                                             unsigned int size,
     487             :                                             struct device_node *node,
     488             :                                             const struct irq_domain_ops *ops,
     489             :                                             void *host_data)
     490             : {
     491             :         return irq_domain_create_hierarchy(parent, flags, size,
     492             :                                            of_node_to_fwnode(node),
     493             :                                            ops, host_data);
     494             : }
     495             : 
     496             : extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
     497             :                                    unsigned int nr_irqs, int node, void *arg,
     498             :                                    bool realloc,
     499             :                                    const struct irq_affinity_desc *affinity);
     500             : extern void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs);
     501             : extern int irq_domain_activate_irq(struct irq_data *irq_data, bool early);
     502             : extern void irq_domain_deactivate_irq(struct irq_data *irq_data);
     503             : 
     504             : static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
     505             :                         unsigned int nr_irqs, int node, void *arg)
     506             : {
     507             :         return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false,
     508             :                                        NULL);
     509             : }
     510             : 
     511             : extern int irq_domain_alloc_irqs_hierarchy(struct irq_domain *domain,
     512             :                                            unsigned int irq_base,
     513             :                                            unsigned int nr_irqs, void *arg);
     514             : extern int irq_domain_set_hwirq_and_chip(struct irq_domain *domain,
     515             :                                          unsigned int virq,
     516             :                                          irq_hw_number_t hwirq,
     517             :                                          const struct irq_chip *chip,
     518             :                                          void *chip_data);
     519             : extern void irq_domain_free_irqs_common(struct irq_domain *domain,
     520             :                                         unsigned int virq,
     521             :                                         unsigned int nr_irqs);
     522             : extern void irq_domain_free_irqs_top(struct irq_domain *domain,
     523             :                                      unsigned int virq, unsigned int nr_irqs);
     524             : 
     525             : extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
     526             : extern int irq_domain_pop_irq(struct irq_domain *domain, int virq);
     527             : 
     528             : extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
     529             :                                         unsigned int irq_base,
     530             :                                         unsigned int nr_irqs, void *arg);
     531             : 
     532             : extern void irq_domain_free_irqs_parent(struct irq_domain *domain,
     533             :                                         unsigned int irq_base,
     534             :                                         unsigned int nr_irqs);
     535             : 
     536             : extern int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
     537             :                                            unsigned int virq);
     538             : 
     539             : static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
     540             : {
     541           0 :         return domain->flags & IRQ_DOMAIN_FLAG_HIERARCHY;
     542             : }
     543             : 
     544             : static inline bool irq_domain_is_ipi(struct irq_domain *domain)
     545             : {
     546             :         return domain->flags &
     547             :                 (IRQ_DOMAIN_FLAG_IPI_PER_CPU | IRQ_DOMAIN_FLAG_IPI_SINGLE);
     548             : }
     549             : 
     550             : static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
     551             : {
     552             :         return domain->flags & IRQ_DOMAIN_FLAG_IPI_PER_CPU;
     553             : }
     554             : 
     555             : static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
     556             : {
     557             :         return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
     558             : }
     559             : 
     560             : static inline bool irq_domain_is_msi(struct irq_domain *domain)
     561             : {
     562             :         return domain->flags & IRQ_DOMAIN_FLAG_MSI;
     563             : }
     564             : 
     565             : static inline bool irq_domain_is_msi_parent(struct irq_domain *domain)
     566             : {
     567           0 :         return domain->flags & IRQ_DOMAIN_FLAG_MSI_PARENT;
     568             : }
     569             : 
     570             : static inline bool irq_domain_is_msi_device(struct irq_domain *domain)
     571             : {
     572           0 :         return domain->flags & IRQ_DOMAIN_FLAG_MSI_DEVICE;
     573             : }
     574             : 
     575             : #else   /* CONFIG_IRQ_DOMAIN_HIERARCHY */
     576             : static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
     577             :                         unsigned int nr_irqs, int node, void *arg)
     578             : {
     579             :         return -1;
     580             : }
     581             : 
     582             : static inline void irq_domain_free_irqs(unsigned int virq,
     583             :                                         unsigned int nr_irqs) { }
     584             : 
     585             : static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
     586             : {
     587             :         return false;
     588             : }
     589             : 
     590             : static inline bool irq_domain_is_ipi(struct irq_domain *domain)
     591             : {
     592             :         return false;
     593             : }
     594             : 
     595             : static inline bool irq_domain_is_ipi_per_cpu(struct irq_domain *domain)
     596             : {
     597             :         return false;
     598             : }
     599             : 
     600             : static inline bool irq_domain_is_ipi_single(struct irq_domain *domain)
     601             : {
     602             :         return false;
     603             : }
     604             : 
     605             : static inline bool irq_domain_is_msi(struct irq_domain *domain)
     606             : {
     607             :         return false;
     608             : }
     609             : 
     610             : static inline bool irq_domain_is_msi_parent(struct irq_domain *domain)
     611             : {
     612             :         return false;
     613             : }
     614             : 
     615             : static inline bool irq_domain_is_msi_device(struct irq_domain *domain)
     616             : {
     617             :         return false;
     618             : }
     619             : 
     620             : #endif  /* CONFIG_IRQ_DOMAIN_HIERARCHY */
     621             : 
     622             : #else /* CONFIG_IRQ_DOMAIN */
     623             : static inline void irq_dispose_mapping(unsigned int virq) { }
     624             : static inline struct irq_domain *irq_find_matching_fwnode(
     625             :         struct fwnode_handle *fwnode, enum irq_domain_bus_token bus_token)
     626             : {
     627             :         return NULL;
     628             : }
     629             : #endif /* !CONFIG_IRQ_DOMAIN */
     630             : 
     631             : #endif /* _LINUX_IRQDOMAIN_H */

Generated by: LCOV version 1.14