108a543ad33fc188650801bd36eed4ffe272643e1Grant Likely/* 208a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * irq_domain - IRQ translation domains 308a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * 408a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * Translation infrastructure between hw and linux irq numbers. This is 508a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * helpful for interrupt controllers to implement mapping between hardware 608a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * irq numbers and the Linux irq number space. 708a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * 808a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * irq_domains also have a hook for translating device tree interrupt 908a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * representation into a hardware irq number that can be mapped back to a 1008a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * Linux irq number without any extra platform support code. 1108a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * 127bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * Interrupt controller "domain" data structure. This could be defined as a 137bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * irq domain controller. That is, it handles the mapping between hardware 147bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * and virtual interrupt numbers for a given interrupt domain. The domain 157bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * structure is generally created by the PIC code for a given PIC instance 167bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * (though a domain can cover more than one PIC if they have a flat number 177bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * model). It's the domain callbacks that are responsible for setting the 187bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * irq_chip on a given irq_desc after it's been mapped. 19cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * 20cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * The host code and data structures are agnostic to whether or not 21cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * we use an open firmware device-tree. We do have references to struct 22cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * device_node in two places: in irq_find_host() to find the host matching 23cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * a given interrupt controller node, and of course as an argument to its 24cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * counterpart domain->ops->match() callback. However, those are treated as 25cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * generic pointers by the core and the fact that it's actually a device-node 26cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * pointer is purely a convention between callers and implementation. This 27cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * code could thus be used on other architectures by replacing those two 28cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * by some sort of arch-specific void * "token" used to identify interrupt 29cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely * controllers. 3008a543ad33fc188650801bd36eed4ffe272643e1Grant Likely */ 317bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely 3208a543ad33fc188650801bd36eed4ffe272643e1Grant Likely#ifndef _LINUX_IRQDOMAIN_H 3308a543ad33fc188650801bd36eed4ffe272643e1Grant Likely#define _LINUX_IRQDOMAIN_H 3408a543ad33fc188650801bd36eed4ffe272643e1Grant Likely 357bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely#include <linux/types.h> 367bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely#include <linux/radix-tree.h> 3708a543ad33fc188650801bd36eed4ffe272643e1Grant Likely 3808a543ad33fc188650801bd36eed4ffe272643e1Grant Likelystruct device_node; 3908a543ad33fc188650801bd36eed4ffe272643e1Grant Likelystruct irq_domain; 407bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likelystruct of_device_id; 417bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely 421bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely/* Number of irqs reserved for a legacy isa controller */ 431bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely#define NUM_ISA_INTERRUPTS 16 441bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely 4508a543ad33fc188650801bd36eed4ffe272643e1Grant Likely/** 4608a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * struct irq_domain_ops - Methods for irq_domain objects 477bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @match: Match an interrupt controller device node to a host, returns 487bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * 1 on a match 497bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @map: Create or update a mapping between a virtual irq number and a hw 507bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * irq number. This is called only once for a given mapping. 517bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @unmap: Dispose of such a mapping 527bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @xlate: Given a device tree node and interrupt specifier, decode 537bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * the hardware irq number and linux irq type value. 547bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * 557bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * Functions below are provided by the driver and called whenever a new mapping 567bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * is created or an old mapping is disposed. The driver can then proceed to 577bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * whatever internal data structures management is required. It also needs 587bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * to setup the irq_desc when returning from map(). 5908a543ad33fc188650801bd36eed4ffe272643e1Grant Likely */ 6008a543ad33fc188650801bd36eed4ffe272643e1Grant Likelystruct irq_domain_ops { 617bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely int (*match)(struct irq_domain *d, struct device_node *node); 627bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw); 637bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely void (*unmap)(struct irq_domain *d, unsigned int virq); 647bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely int (*xlate)(struct irq_domain *d, struct device_node *node, 657bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely const u32 *intspec, unsigned int intsize, 667bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely unsigned long *out_hwirq, unsigned int *out_type); 6708a543ad33fc188650801bd36eed4ffe272643e1Grant Likely}; 6808a543ad33fc188650801bd36eed4ffe272643e1Grant Likely 6908a543ad33fc188650801bd36eed4ffe272643e1Grant Likely/** 7008a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * struct irq_domain - Hardware interrupt number translation object 717bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @link: Element in global irq_domain list. 727bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This 737bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * will be one of the IRQ_DOMAIN_MAP_* values. 747bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @revmap_data: Revmap method specific data. 757bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @ops: pointer to irq_domain methods 767bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * @host_data: private data pointer for use by owner. Not touched by irq_domain 777bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely * core code. 7808a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * @irq_base: Start of irq_desc range assigned to the irq_domain. The creator 7908a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * of the irq_domain is responsible for allocating the array of 8008a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * irq_desc structures. 8108a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * @nr_irq: Number of irqs managed by the irq domain 826d274309d0e64bdbdb6c50945ca2964596e8fa5aRob Herring * @hwirq_base: Starting number for hwirqs managed by the irq domain 8308a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * @of_node: (optional) Pointer to device tree nodes associated with the 8408a543ad33fc188650801bd36eed4ffe272643e1Grant Likely * irq_domain. Used when decoding device tree interrupt specifiers. 8508a543ad33fc188650801bd36eed4ffe272643e1Grant Likely */ 8608a543ad33fc188650801bd36eed4ffe272643e1Grant Likelystruct irq_domain { 877bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely struct list_head link; 887bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely 897bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely /* type of reverse mapping_technique */ 907bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely unsigned int revmap_type; 917bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely union { 927bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely struct { 937bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely unsigned int size; 941bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely unsigned int first_irq; 951bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely irq_hw_number_t first_hwirq; 961bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely } legacy; 971bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely struct { 981bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely unsigned int size; 997bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely unsigned int *revmap; 1007bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely } linear; 1016fa6c8e25e95bdc73e92e4c96b8e3299169b616eGrant Likely struct { 1026fa6c8e25e95bdc73e92e4c96b8e3299169b616eGrant Likely unsigned int max_irq; 1036fa6c8e25e95bdc73e92e4c96b8e3299169b616eGrant Likely } nomap; 1047bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely struct radix_tree_root tree; 1057bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely } revmap_data; 106a18dc81bf58258ac0920bec26b91656cb0140d2aGrant Likely const struct irq_domain_ops *ops; 1077bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely void *host_data; 1087bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely irq_hw_number_t inval_irq; 1097bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely 1107bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely /* Optional device node pointer */ 11108a543ad33fc188650801bd36eed4ffe272643e1Grant Likely struct device_node *of_node; 11208a543ad33fc188650801bd36eed4ffe272643e1Grant Likely}; 11308a543ad33fc188650801bd36eed4ffe272643e1Grant Likely 1147bb69bade0d41715bdf1b24f5ef0b8f798769fe9Grant Likely#ifdef CONFIG_IRQ_DOMAIN 115a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likelystruct irq_domain *irq_domain_add_legacy(struct device_node *of_node, 1161bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely unsigned int size, 1171bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely unsigned int first_irq, 1181bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely irq_hw_number_t first_hwirq, 119a18dc81bf58258ac0920bec26b91656cb0140d2aGrant Likely const struct irq_domain_ops *ops, 120a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likely void *host_data); 121a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likelystruct irq_domain *irq_domain_add_linear(struct device_node *of_node, 122a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likely unsigned int size, 123a18dc81bf58258ac0920bec26b91656cb0140d2aGrant Likely const struct irq_domain_ops *ops, 124a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likely void *host_data); 125a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likelystruct irq_domain *irq_domain_add_nomap(struct device_node *of_node, 1266fa6c8e25e95bdc73e92e4c96b8e3299169b616eGrant Likely unsigned int max_irq, 127a18dc81bf58258ac0920bec26b91656cb0140d2aGrant Likely const struct irq_domain_ops *ops, 128a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likely void *host_data); 129a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likelystruct irq_domain *irq_domain_add_tree(struct device_node *of_node, 130a18dc81bf58258ac0920bec26b91656cb0140d2aGrant Likely const struct irq_domain_ops *ops, 131a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likely void *host_data); 132a8db8cf0d894df5f1dcfd4bce9894e0dbcc01c96Grant Likely 133cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern struct irq_domain *irq_find_host(struct device_node *node); 134cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern void irq_set_default_host(struct irq_domain *host); 135cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely 1361bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likelystatic inline struct irq_domain *irq_domain_add_legacy_isa( 1371bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely struct device_node *of_node, 138a18dc81bf58258ac0920bec26b91656cb0140d2aGrant Likely const struct irq_domain_ops *ops, 1391bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely void *host_data) 1401bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely{ 1411bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, 1421bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely host_data); 1431bc04f2cf8c2a1feadbd994f50c40bb145bf2989Grant Likely} 14475294957be1dee7d22dd7d90bd31334ba410e836Grant Likelyextern struct irq_domain *irq_find_host(struct device_node *node); 14575294957be1dee7d22dd7d90bd31334ba410e836Grant Likelyextern void irq_set_default_host(struct irq_domain *host); 14675294957be1dee7d22dd7d90bd31334ba410e836Grant Likely 147cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely 148cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern unsigned int irq_create_mapping(struct irq_domain *host, 149cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely irq_hw_number_t hwirq); 150cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern void irq_dispose_mapping(unsigned int virq); 151cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern unsigned int irq_find_mapping(struct irq_domain *host, 152cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely irq_hw_number_t hwirq); 153cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern unsigned int irq_create_direct_mapping(struct irq_domain *host); 154cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq, 155cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely irq_hw_number_t hwirq); 156cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern unsigned int irq_radix_revmap_lookup(struct irq_domain *host, 157cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely irq_hw_number_t hwirq); 158cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likelyextern unsigned int irq_linear_revmap(struct irq_domain *host, 159cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely irq_hw_number_t hwirq); 160cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely 161a18dc81bf58258ac0920bec26b91656cb0140d2aGrant Likelyextern const struct irq_domain_ops irq_domain_simple_ops; 16216b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely 16316b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely/* stock xlate functions */ 16416b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likelyint irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr, 16516b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely const u32 *intspec, unsigned int intsize, 16616b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely irq_hw_number_t *out_hwirq, unsigned int *out_type); 16716b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likelyint irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr, 16816b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely const u32 *intspec, unsigned int intsize, 16916b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely irq_hw_number_t *out_hwirq, unsigned int *out_type); 17016b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likelyint irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr, 17116b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely const u32 *intspec, unsigned int intsize, 17216b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely irq_hw_number_t *out_hwirq, unsigned int *out_type); 17316b2e6e2f31dda41f114aa0acade04f7e10f67c9Grant Likely 174cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely#if defined(CONFIG_OF_IRQ) 1757e71330169d8056536b299290544980bccc6b300Grant Likelyextern void irq_domain_generate_simple(const struct of_device_id *match, 1767e71330169d8056536b299290544980bccc6b300Grant Likely u64 phys_base, unsigned int irq_start); 177cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely#else /* CONFIG_OF_IRQ */ 1787e71330169d8056536b299290544980bccc6b300Grant Likelystatic inline void irq_domain_generate_simple(const struct of_device_id *match, 1797e71330169d8056536b299290544980bccc6b300Grant Likely u64 phys_base, unsigned int irq_start) { } 180cc79ca691c292e9fd44f589c7940b9654e22f2f6Grant Likely#endif /* !CONFIG_OF_IRQ */ 181d593f25ff263b1a7752b7380f8b7d57809206c40Grant Likely 182d593f25ff263b1a7752b7380f8b7d57809206c40Grant Likely#else /* CONFIG_IRQ_DOMAIN */ 183d593f25ff263b1a7752b7380f8b7d57809206c40Grant Likelystatic inline void irq_dispose_mapping(unsigned int virq) { } 184d593f25ff263b1a7752b7380f8b7d57809206c40Grant Likely#endif /* !CONFIG_IRQ_DOMAIN */ 1857e71330169d8056536b299290544980bccc6b300Grant Likely 18608a543ad33fc188650801bd36eed4ffe272643e1Grant Likely#endif /* _LINUX_IRQDOMAIN_H */ 187