diff options
Diffstat (limited to 'include/linux/irq.h')
-rw-r--r-- | include/linux/irq.h | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 6f8b34066442..11bf09288ddb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -110,8 +110,8 @@ enum { | |||
110 | /* | 110 | /* |
111 | * Return value for chip->irq_set_affinity() | 111 | * Return value for chip->irq_set_affinity() |
112 | * | 112 | * |
113 | * IRQ_SET_MASK_OK - OK, core updates irq_data.affinity | 113 | * IRQ_SET_MASK_OK - OK, core updates irq_common_data.affinity |
114 | * IRQ_SET_MASK_NOCPY - OK, chip did update irq_data.affinity | 114 | * IRQ_SET_MASK_NOCPY - OK, chip did update irq_common_data.affinity |
115 | * IRQ_SET_MASK_OK_DONE - Same as IRQ_SET_MASK_OK for core. Special code to | 115 | * IRQ_SET_MASK_OK_DONE - Same as IRQ_SET_MASK_OK for core. Special code to |
116 | * support stacked irqchips, which indicates skipping | 116 | * support stacked irqchips, which indicates skipping |
117 | * all descendent irqchips. | 117 | * all descendent irqchips. |
@@ -129,9 +129,19 @@ struct irq_domain; | |||
129 | * struct irq_common_data - per irq data shared by all irqchips | 129 | * struct irq_common_data - per irq data shared by all irqchips |
130 | * @state_use_accessors: status information for irq chip functions. | 130 | * @state_use_accessors: status information for irq chip functions. |
131 | * Use accessor functions to deal with it | 131 | * Use accessor functions to deal with it |
132 | * @node: node index useful for balancing | ||
133 | * @handler_data: per-IRQ data for the irq_chip methods | ||
134 | * @affinity: IRQ affinity on SMP | ||
135 | * @msi_desc: MSI descriptor | ||
132 | */ | 136 | */ |
133 | struct irq_common_data { | 137 | struct irq_common_data { |
134 | unsigned int state_use_accessors; | 138 | unsigned int state_use_accessors; |
139 | #ifdef CONFIG_NUMA | ||
140 | unsigned int node; | ||
141 | #endif | ||
142 | void *handler_data; | ||
143 | struct msi_desc *msi_desc; | ||
144 | cpumask_var_t affinity; | ||
135 | }; | 145 | }; |
136 | 146 | ||
137 | /** | 147 | /** |
@@ -139,38 +149,26 @@ struct irq_common_data { | |||
139 | * @mask: precomputed bitmask for accessing the chip registers | 149 | * @mask: precomputed bitmask for accessing the chip registers |
140 | * @irq: interrupt number | 150 | * @irq: interrupt number |
141 | * @hwirq: hardware interrupt number, local to the interrupt domain | 151 | * @hwirq: hardware interrupt number, local to the interrupt domain |
142 | * @node: node index useful for balancing | ||
143 | * @common: point to data shared by all irqchips | 152 | * @common: point to data shared by all irqchips |
144 | * @chip: low level interrupt hardware access | 153 | * @chip: low level interrupt hardware access |
145 | * @domain: Interrupt translation domain; responsible for mapping | 154 | * @domain: Interrupt translation domain; responsible for mapping |
146 | * between hwirq number and linux irq number. | 155 | * between hwirq number and linux irq number. |
147 | * @parent_data: pointer to parent struct irq_data to support hierarchy | 156 | * @parent_data: pointer to parent struct irq_data to support hierarchy |
148 | * irq_domain | 157 | * irq_domain |
149 | * @handler_data: per-IRQ data for the irq_chip methods | ||
150 | * @chip_data: platform-specific per-chip private data for the chip | 158 | * @chip_data: platform-specific per-chip private data for the chip |
151 | * methods, to allow shared chip implementations | 159 | * methods, to allow shared chip implementations |
152 | * @msi_desc: MSI descriptor | ||
153 | * @affinity: IRQ affinity on SMP | ||
154 | * | ||
155 | * The fields here need to overlay the ones in irq_desc until we | ||
156 | * cleaned up the direct references and switched everything over to | ||
157 | * irq_data. | ||
158 | */ | 160 | */ |
159 | struct irq_data { | 161 | struct irq_data { |
160 | u32 mask; | 162 | u32 mask; |
161 | unsigned int irq; | 163 | unsigned int irq; |
162 | unsigned long hwirq; | 164 | unsigned long hwirq; |
163 | unsigned int node; | ||
164 | struct irq_common_data *common; | 165 | struct irq_common_data *common; |
165 | struct irq_chip *chip; | 166 | struct irq_chip *chip; |
166 | struct irq_domain *domain; | 167 | struct irq_domain *domain; |
167 | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY | 168 | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY |
168 | struct irq_data *parent_data; | 169 | struct irq_data *parent_data; |
169 | #endif | 170 | #endif |
170 | void *handler_data; | ||
171 | void *chip_data; | 171 | void *chip_data; |
172 | struct msi_desc *msi_desc; | ||
173 | cpumask_var_t affinity; | ||
174 | }; | 172 | }; |
175 | 173 | ||
176 | /* | 174 | /* |
@@ -190,6 +188,7 @@ struct irq_data { | |||
190 | * IRQD_IRQ_MASKED - Masked state of the interrupt | 188 | * IRQD_IRQ_MASKED - Masked state of the interrupt |
191 | * IRQD_IRQ_INPROGRESS - In progress state of the interrupt | 189 | * IRQD_IRQ_INPROGRESS - In progress state of the interrupt |
192 | * IRQD_WAKEUP_ARMED - Wakeup mode armed | 190 | * IRQD_WAKEUP_ARMED - Wakeup mode armed |
191 | * IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU | ||
193 | */ | 192 | */ |
194 | enum { | 193 | enum { |
195 | IRQD_TRIGGER_MASK = 0xf, | 194 | IRQD_TRIGGER_MASK = 0xf, |
@@ -204,6 +203,7 @@ enum { | |||
204 | IRQD_IRQ_MASKED = (1 << 17), | 203 | IRQD_IRQ_MASKED = (1 << 17), |
205 | IRQD_IRQ_INPROGRESS = (1 << 18), | 204 | IRQD_IRQ_INPROGRESS = (1 << 18), |
206 | IRQD_WAKEUP_ARMED = (1 << 19), | 205 | IRQD_WAKEUP_ARMED = (1 << 19), |
206 | IRQD_FORWARDED_TO_VCPU = (1 << 20), | ||
207 | }; | 207 | }; |
208 | 208 | ||
209 | #define __irqd_to_state(d) ((d)->common->state_use_accessors) | 209 | #define __irqd_to_state(d) ((d)->common->state_use_accessors) |
@@ -282,6 +282,20 @@ static inline bool irqd_is_wakeup_armed(struct irq_data *d) | |||
282 | return __irqd_to_state(d) & IRQD_WAKEUP_ARMED; | 282 | return __irqd_to_state(d) & IRQD_WAKEUP_ARMED; |
283 | } | 283 | } |
284 | 284 | ||
285 | static inline bool irqd_is_forwarded_to_vcpu(struct irq_data *d) | ||
286 | { | ||
287 | return __irqd_to_state(d) & IRQD_FORWARDED_TO_VCPU; | ||
288 | } | ||
289 | |||
290 | static inline void irqd_set_forwarded_to_vcpu(struct irq_data *d) | ||
291 | { | ||
292 | __irqd_to_state(d) |= IRQD_FORWARDED_TO_VCPU; | ||
293 | } | ||
294 | |||
295 | static inline void irqd_clr_forwarded_to_vcpu(struct irq_data *d) | ||
296 | { | ||
297 | __irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU; | ||
298 | } | ||
285 | 299 | ||
286 | /* | 300 | /* |
287 | * Functions for chained handlers which can be enabled/disabled by the | 301 | * Functions for chained handlers which can be enabled/disabled by the |
@@ -461,14 +475,14 @@ static inline int irq_set_parent(int irq, int parent_irq) | |||
461 | * Built-in IRQ handlers for various IRQ types, | 475 | * Built-in IRQ handlers for various IRQ types, |
462 | * callable via desc->handle_irq() | 476 | * callable via desc->handle_irq() |
463 | */ | 477 | */ |
464 | extern void handle_level_irq(unsigned int irq, struct irq_desc *desc); | 478 | extern void handle_level_irq(struct irq_desc *desc); |
465 | extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc); | 479 | extern void handle_fasteoi_irq(struct irq_desc *desc); |
466 | extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc); | 480 | extern void handle_edge_irq(struct irq_desc *desc); |
467 | extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc); | 481 | extern void handle_edge_eoi_irq(struct irq_desc *desc); |
468 | extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc); | 482 | extern void handle_simple_irq(struct irq_desc *desc); |
469 | extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc); | 483 | extern void handle_percpu_irq(struct irq_desc *desc); |
470 | extern void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc); | 484 | extern void handle_percpu_devid_irq(struct irq_desc *desc); |
471 | extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc); | 485 | extern void handle_bad_irq(struct irq_desc *desc); |
472 | extern void handle_nested_irq(unsigned int irq); | 486 | extern void handle_nested_irq(unsigned int irq); |
473 | 487 | ||
474 | extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); | 488 | extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg); |
@@ -627,23 +641,23 @@ static inline void *irq_data_get_irq_chip_data(struct irq_data *d) | |||
627 | static inline void *irq_get_handler_data(unsigned int irq) | 641 | static inline void *irq_get_handler_data(unsigned int irq) |
628 | { | 642 | { |
629 | struct irq_data *d = irq_get_irq_data(irq); | 643 | struct irq_data *d = irq_get_irq_data(irq); |
630 | return d ? d->handler_data : NULL; | 644 | return d ? d->common->handler_data : NULL; |
631 | } | 645 | } |
632 | 646 | ||
633 | static inline void *irq_data_get_irq_handler_data(struct irq_data *d) | 647 | static inline void *irq_data_get_irq_handler_data(struct irq_data *d) |
634 | { | 648 | { |
635 | return d->handler_data; | 649 | return d->common->handler_data; |
636 | } | 650 | } |
637 | 651 | ||
638 | static inline struct msi_desc *irq_get_msi_desc(unsigned int irq) | 652 | static inline struct msi_desc *irq_get_msi_desc(unsigned int irq) |
639 | { | 653 | { |
640 | struct irq_data *d = irq_get_irq_data(irq); | 654 | struct irq_data *d = irq_get_irq_data(irq); |
641 | return d ? d->msi_desc : NULL; | 655 | return d ? d->common->msi_desc : NULL; |
642 | } | 656 | } |
643 | 657 | ||
644 | static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d) | 658 | static inline struct msi_desc *irq_data_get_msi_desc(struct irq_data *d) |
645 | { | 659 | { |
646 | return d->msi_desc; | 660 | return d->common->msi_desc; |
647 | } | 661 | } |
648 | 662 | ||
649 | static inline u32 irq_get_trigger_type(unsigned int irq) | 663 | static inline u32 irq_get_trigger_type(unsigned int irq) |
@@ -652,21 +666,30 @@ static inline u32 irq_get_trigger_type(unsigned int irq) | |||
652 | return d ? irqd_get_trigger_type(d) : 0; | 666 | return d ? irqd_get_trigger_type(d) : 0; |
653 | } | 667 | } |
654 | 668 | ||
655 | static inline int irq_data_get_node(struct irq_data *d) | 669 | static inline int irq_common_data_get_node(struct irq_common_data *d) |
656 | { | 670 | { |
671 | #ifdef CONFIG_NUMA | ||
657 | return d->node; | 672 | return d->node; |
673 | #else | ||
674 | return 0; | ||
675 | #endif | ||
676 | } | ||
677 | |||
678 | static inline int irq_data_get_node(struct irq_data *d) | ||
679 | { | ||
680 | return irq_common_data_get_node(d->common); | ||
658 | } | 681 | } |
659 | 682 | ||
660 | static inline struct cpumask *irq_get_affinity_mask(int irq) | 683 | static inline struct cpumask *irq_get_affinity_mask(int irq) |
661 | { | 684 | { |
662 | struct irq_data *d = irq_get_irq_data(irq); | 685 | struct irq_data *d = irq_get_irq_data(irq); |
663 | 686 | ||
664 | return d ? d->affinity : NULL; | 687 | return d ? d->common->affinity : NULL; |
665 | } | 688 | } |
666 | 689 | ||
667 | static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d) | 690 | static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d) |
668 | { | 691 | { |
669 | return d->affinity; | 692 | return d->common->affinity; |
670 | } | 693 | } |
671 | 694 | ||
672 | unsigned int arch_dynirq_lower_bound(unsigned int from); | 695 | unsigned int arch_dynirq_lower_bound(unsigned int from); |