at v3.3 4.0 kB view raw
1/* 2 * irq_domain - IRQ translation domains 3 * 4 * Translation infrastructure between hw and linux irq numbers. This is 5 * helpful for interrupt controllers to implement mapping between hardware 6 * irq numbers and the Linux irq number space. 7 * 8 * irq_domains also have a hook for translating device tree interrupt 9 * representation into a hardware irq number that can be mapped back to a 10 * Linux irq number without any extra platform support code. 11 * 12 * irq_domain is expected to be embedded in an interrupt controller's private 13 * data structure. 14 */ 15#ifndef _LINUX_IRQDOMAIN_H 16#define _LINUX_IRQDOMAIN_H 17 18#include <linux/irq.h> 19#include <linux/mod_devicetable.h> 20 21#ifdef CONFIG_IRQ_DOMAIN 22struct device_node; 23struct irq_domain; 24 25/** 26 * struct irq_domain_ops - Methods for irq_domain objects 27 * @to_irq: (optional) given a local hardware irq number, return the linux 28 * irq number. If to_irq is not implemented, then the irq_domain 29 * will use this translation: irq = (domain->irq_base + hwirq) 30 * @dt_translate: Given a device tree node and interrupt specifier, decode 31 * the hardware irq number and linux irq type value. 32 */ 33struct irq_domain_ops { 34 unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq); 35 36#ifdef CONFIG_OF 37 int (*dt_translate)(struct irq_domain *d, struct device_node *node, 38 const u32 *intspec, unsigned int intsize, 39 unsigned long *out_hwirq, unsigned int *out_type); 40#endif /* CONFIG_OF */ 41}; 42 43/** 44 * struct irq_domain - Hardware interrupt number translation object 45 * @list: Element in global irq_domain list. 46 * @irq_base: Start of irq_desc range assigned to the irq_domain. The creator 47 * of the irq_domain is responsible for allocating the array of 48 * irq_desc structures. 49 * @nr_irq: Number of irqs managed by the irq domain 50 * @hwirq_base: Starting number for hwirqs managed by the irq domain 51 * @ops: pointer to irq_domain methods 52 * @priv: private data pointer for use by owner. Not touched by irq_domain 53 * core code. 54 * @of_node: (optional) Pointer to device tree nodes associated with the 55 * irq_domain. Used when decoding device tree interrupt specifiers. 56 */ 57struct irq_domain { 58 struct list_head list; 59 unsigned int irq_base; 60 unsigned int nr_irq; 61 unsigned int hwirq_base; 62 const struct irq_domain_ops *ops; 63 void *priv; 64 struct device_node *of_node; 65}; 66 67/** 68 * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number 69 * 70 * Returns the linux irq number associated with a hardware irq. By default, 71 * the mapping is irq == domain->irq_base + hwirq, but this mapping can 72 * be overridden if the irq_domain implements a .to_irq() hook. 73 */ 74static inline unsigned int irq_domain_to_irq(struct irq_domain *d, 75 unsigned long hwirq) 76{ 77 if (d->ops->to_irq) 78 return d->ops->to_irq(d, hwirq); 79 if (WARN_ON(hwirq < d->hwirq_base)) 80 return 0; 81 return d->irq_base + hwirq - d->hwirq_base; 82} 83 84#define irq_domain_for_each_hwirq(d, hw) \ 85 for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++) 86 87#define irq_domain_for_each_irq(d, hw, irq) \ 88 for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \ 89 hw < d->hwirq_base + d->nr_irq; \ 90 hw++, irq = irq_domain_to_irq(d, hw)) 91 92extern void irq_domain_add(struct irq_domain *domain); 93extern void irq_domain_del(struct irq_domain *domain); 94 95extern struct irq_domain_ops irq_domain_simple_ops; 96#endif /* CONFIG_IRQ_DOMAIN */ 97 98#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ) 99extern void irq_domain_add_simple(struct device_node *controller, int irq_base); 100extern void irq_domain_generate_simple(const struct of_device_id *match, 101 u64 phys_base, unsigned int irq_start); 102#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */ 103static inline void irq_domain_generate_simple(const struct of_device_id *match, 104 u64 phys_base, unsigned int irq_start) { } 105#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */ 106 107#endif /* _LINUX_IRQDOMAIN_H */