diff options
| -rw-r--r-- | arch/powerpc/platforms/cell/beat_interrupt.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powermac/smp.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/devicetree.c | 4 | ||||
| -rw-r--r-- | include/linux/irqdomain.h | 142 | ||||
| -rw-r--r-- | kernel/irq/generic-chip.c | 6 | ||||
| -rw-r--r-- | kernel/irq/irqdomain.c | 579 | ||||
| -rw-r--r-- | kernel/irq/proc.c | 2 |
7 files changed, 264 insertions, 473 deletions
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index 8c6dc42ecf65..9e5dfbcc00af 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c | |||
| @@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void) | |||
| 239 | ppc_md.get_irq = beatic_get_irq; | 239 | ppc_md.get_irq = beatic_get_irq; |
| 240 | 240 | ||
| 241 | /* Allocate an irq host */ | 241 | /* Allocate an irq host */ |
| 242 | beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL); | 242 | beatic_host = irq_domain_add_nomap(NULL, ~0, &beatic_pic_host_ops, NULL); |
| 243 | BUG_ON(beatic_host == NULL); | 243 | BUG_ON(beatic_host == NULL); |
| 244 | irq_set_default_host(beatic_host); | 244 | irq_set_default_host(beatic_host); |
| 245 | } | 245 | } |
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 49c9f9501c21..5cbd4d67d5c4 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
| @@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void) | |||
| 192 | { | 192 | { |
| 193 | int rc = -ENOMEM; | 193 | int rc = -ENOMEM; |
| 194 | 194 | ||
| 195 | psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL); | 195 | psurge_host = irq_domain_add_nomap(NULL, ~0, &psurge_host_ops, NULL); |
| 196 | 196 | ||
| 197 | if (psurge_host) | 197 | if (psurge_host) |
| 198 | psurge_secondary_virq = irq_create_direct_mapping(psurge_host); | 198 | psurge_secondary_virq = irq_create_direct_mapping(psurge_host); |
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index b1581527a236..4934890e4db2 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c | |||
| @@ -364,9 +364,7 @@ static void dt_add_ioapic_domain(unsigned int ioapic_num, | |||
| 364 | * and assigned so we can keep the 1:1 mapping which the ioapic | 364 | * and assigned so we can keep the 1:1 mapping which the ioapic |
| 365 | * is having. | 365 | * is having. |
| 366 | */ | 366 | */ |
| 367 | ret = irq_domain_associate_many(id, 0, 0, NR_IRQS_LEGACY); | 367 | irq_domain_associate_many(id, 0, 0, NR_IRQS_LEGACY); |
| 368 | if (ret) | ||
| 369 | pr_err("Error mapping legacy IRQs: %d\n", ret); | ||
| 370 | 368 | ||
| 371 | if (num > NR_IRQS_LEGACY) { | 369 | if (num > NR_IRQS_LEGACY) { |
| 372 | ret = irq_create_strict_mappings(id, NR_IRQS_LEGACY, | 370 | ret = irq_create_strict_mappings(id, NR_IRQS_LEGACY, |
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index ba2c708adcff..c983ed18c332 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h | |||
| @@ -73,57 +73,48 @@ struct irq_domain_chip_generic; | |||
| 73 | /** | 73 | /** |
| 74 | * struct irq_domain - Hardware interrupt number translation object | 74 | * struct irq_domain - Hardware interrupt number translation object |
| 75 | * @link: Element in global irq_domain list. | 75 | * @link: Element in global irq_domain list. |
| 76 | * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This | 76 | * @name: Name of interrupt domain |
| 77 | * will be one of the IRQ_DOMAIN_MAP_* values. | ||
| 78 | * @revmap_data: Revmap method specific data. | ||
| 79 | * @ops: pointer to irq_domain methods | 77 | * @ops: pointer to irq_domain methods |
| 80 | * @host_data: private data pointer for use by owner. Not touched by irq_domain | 78 | * @host_data: private data pointer for use by owner. Not touched by irq_domain |
| 81 | * core code. | 79 | * core code. |
| 82 | * @irq_base: Start of irq_desc range assigned to the irq_domain. The creator | 80 | * |
| 83 | * of the irq_domain is responsible for allocating the array of | 81 | * Optional elements |
| 84 | * irq_desc structures. | 82 | * @of_node: Pointer to device tree nodes associated with the irq_domain. Used |
| 85 | * @nr_irq: Number of irqs managed by the irq domain | 83 | * when decoding device tree interrupt specifiers. |
| 86 | * @hwirq_base: Starting number for hwirqs managed by the irq domain | 84 | * @gc: Pointer to a list of generic chips. There is a helper function for |
| 87 | * @of_node: (optional) Pointer to device tree nodes associated with the | 85 | * setting up one or more generic chips for interrupt controllers |
| 88 | * irq_domain. Used when decoding device tree interrupt specifiers. | 86 | * drivers using the generic chip library which uses this pointer. |
| 87 | * | ||
| 88 | * Revmap data, used internally by irq_domain | ||
| 89 | * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that | ||
| 90 | * support direct mapping | ||
| 91 | * @revmap_size: Size of the linear map table @linear_revmap[] | ||
| 92 | * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map | ||
| 93 | * @linear_revmap: Linear table of hwirq->virq reverse mappings | ||
| 89 | */ | 94 | */ |
| 90 | struct irq_domain { | 95 | struct irq_domain { |
| 91 | struct list_head link; | 96 | struct list_head link; |
| 92 | 97 | const char *name; | |
| 93 | /* type of reverse mapping_technique */ | ||
| 94 | unsigned int revmap_type; | ||
| 95 | union { | ||
| 96 | struct { | ||
| 97 | unsigned int size; | ||
| 98 | unsigned int first_irq; | ||
| 99 | irq_hw_number_t first_hwirq; | ||
| 100 | } legacy; | ||
| 101 | struct { | ||
| 102 | unsigned int size; | ||
| 103 | unsigned int *revmap; | ||
| 104 | } linear; | ||
| 105 | struct { | ||
| 106 | unsigned int max_irq; | ||
| 107 | } nomap; | ||
| 108 | struct radix_tree_root tree; | ||
| 109 | } revmap_data; | ||
| 110 | const struct irq_domain_ops *ops; | 98 | const struct irq_domain_ops *ops; |
| 111 | void *host_data; | 99 | void *host_data; |
| 112 | irq_hw_number_t inval_irq; | ||
| 113 | 100 | ||
| 114 | /* Optional device node pointer */ | 101 | /* Optional data */ |
| 115 | struct device_node *of_node; | 102 | struct device_node *of_node; |
| 116 | /* Optional pointer to generic interrupt chips */ | ||
| 117 | struct irq_domain_chip_generic *gc; | 103 | struct irq_domain_chip_generic *gc; |
| 118 | }; | ||
| 119 | 104 | ||
| 120 | #define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs. | 105 | /* reverse map data. The linear map gets appended to the irq_domain */ |
| 121 | * ie. legacy 8259, gets irqs 1..15 */ | 106 | irq_hw_number_t hwirq_max; |
| 122 | #define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */ | 107 | unsigned int revmap_direct_max_irq; |
| 123 | #define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */ | 108 | unsigned int revmap_size; |
| 124 | #define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */ | 109 | struct radix_tree_root revmap_tree; |
| 110 | unsigned int linear_revmap[]; | ||
| 111 | }; | ||
| 125 | 112 | ||
| 126 | #ifdef CONFIG_IRQ_DOMAIN | 113 | #ifdef CONFIG_IRQ_DOMAIN |
| 114 | struct irq_domain *__irq_domain_add(struct device_node *of_node, int size, | ||
| 115 | irq_hw_number_t hwirq_max, int direct_max, | ||
| 116 | const struct irq_domain_ops *ops, | ||
| 117 | void *host_data); | ||
| 127 | struct irq_domain *irq_domain_add_simple(struct device_node *of_node, | 118 | struct irq_domain *irq_domain_add_simple(struct device_node *of_node, |
| 128 | unsigned int size, | 119 | unsigned int size, |
| 129 | unsigned int first_irq, | 120 | unsigned int first_irq, |
| @@ -135,21 +126,30 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, | |||
| 135 | irq_hw_number_t first_hwirq, | 126 | irq_hw_number_t first_hwirq, |
| 136 | const struct irq_domain_ops *ops, | 127 | const struct irq_domain_ops *ops, |
| 137 | void *host_data); | 128 | void *host_data); |
| 138 | struct irq_domain *irq_domain_add_linear(struct device_node *of_node, | 129 | extern struct irq_domain *irq_find_host(struct device_node *node); |
| 130 | extern void irq_set_default_host(struct irq_domain *host); | ||
| 131 | |||
| 132 | /** | ||
| 133 | * irq_domain_add_linear() - Allocate and register a linear revmap irq_domain. | ||
| 134 | * @of_node: pointer to interrupt controller's device tree node. | ||
| 135 | * @size: Number of interrupts in the domain. | ||
| 136 | * @ops: map/unmap domain callbacks | ||
| 137 | * @host_data: Controller private data pointer | ||
| 138 | */ | ||
| 139 | static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_node, | ||
| 139 | unsigned int size, | 140 | unsigned int size, |
| 140 | const struct irq_domain_ops *ops, | 141 | const struct irq_domain_ops *ops, |
| 141 | void *host_data); | 142 | void *host_data) |
| 142 | struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, | 143 | { |
| 144 | return __irq_domain_add(of_node, size, size, 0, ops, host_data); | ||
| 145 | } | ||
| 146 | static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, | ||
| 143 | unsigned int max_irq, | 147 | unsigned int max_irq, |
| 144 | const struct irq_domain_ops *ops, | 148 | const struct irq_domain_ops *ops, |
| 145 | void *host_data); | 149 | void *host_data) |
| 146 | struct irq_domain *irq_domain_add_tree(struct device_node *of_node, | 150 | { |
| 147 | const struct irq_domain_ops *ops, | 151 | return __irq_domain_add(of_node, 0, max_irq, max_irq, ops, host_data); |
| 148 | void *host_data); | 152 | } |
| 149 | |||
| 150 | extern struct irq_domain *irq_find_host(struct device_node *node); | ||
| 151 | extern void irq_set_default_host(struct irq_domain *host); | ||
| 152 | |||
| 153 | static inline struct irq_domain *irq_domain_add_legacy_isa( | 153 | static inline struct irq_domain *irq_domain_add_legacy_isa( |
| 154 | struct device_node *of_node, | 154 | struct device_node *of_node, |
| 155 | const struct irq_domain_ops *ops, | 155 | const struct irq_domain_ops *ops, |
| @@ -158,21 +158,40 @@ static inline struct irq_domain *irq_domain_add_legacy_isa( | |||
| 158 | return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, | 158 | return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops, |
| 159 | |||
