Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irq_domain: Move irq_virq_count into NOMAP revmap

This patch replaces the old global setting of irq_virq_count that is only
used by the NOMAP mapping and instead uses a revmap_data property so that
the maximum NOMAP allocation can be set per NOMAP irq_domain.

There is exactly one user of irq_virq_count in-tree right now: PS3.
Also, irq_virq_count is only useful for the NOMAP mapping. So,
instead of having a single global irq_virq_count values, this change
drops it entirely and added a max_irq argument to irq_domain_add_nomap().
That makes it a property of an individual nomap irq domain instead of
a global system settting.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Tested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Milton Miller <miltonm@bga.com>

+17 -31
+1 -1
arch/powerpc/platforms/cell/axon_msi.c
··· 392 392 } 393 393 memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); 394 394 395 - msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic); 395 + msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); 396 396 if (!msic->irq_domain) { 397 397 printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", 398 398 dn->full_name);
+1 -1
arch/powerpc/platforms/cell/beat_interrupt.c
··· 239 239 ppc_md.get_irq = beatic_get_irq; 240 240 241 241 /* Allocate an irq host */ 242 - beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL); 242 + beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL); 243 243 BUG_ON(beatic_host == NULL); 244 244 irq_set_default_host(beatic_host); 245 245 }
+1 -1
arch/powerpc/platforms/powermac/smp.c
··· 192 192 { 193 193 int rc = -ENOMEM; 194 194 195 - psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL); 195 + psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL); 196 196 197 197 if (psurge_host) 198 198 psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
+1 -2
arch/powerpc/platforms/ps3/interrupt.c
··· 753 753 unsigned cpu; 754 754 struct irq_domain *host; 755 755 756 - host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL); 756 + host = irq_domain_add_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL); 757 757 irq_set_default_host(host); 758 - irq_set_virq_count(PS3_PLUG_MAX + 1); 759 758 760 759 for_each_possible_cpu(cpu) { 761 760 struct ps3_private *pd = &per_cpu(ps3_private, cpu);
+4 -2
include/linux/irqdomain.h
··· 98 98 unsigned int size; 99 99 unsigned int *revmap; 100 100 } linear; 101 + struct { 102 + unsigned int max_irq; 103 + } nomap; 101 104 struct radix_tree_root tree; 102 105 } revmap_data; 103 106 const struct irq_domain_ops *ops; ··· 123 120 const struct irq_domain_ops *ops, 124 121 void *host_data); 125 122 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, 123 + unsigned int max_irq, 126 124 const struct irq_domain_ops *ops, 127 125 void *host_data); 128 126 struct irq_domain *irq_domain_add_tree(struct device_node *of_node, ··· 132 128 133 129 extern struct irq_domain *irq_find_host(struct device_node *node); 134 130 extern void irq_set_default_host(struct irq_domain *host); 135 - extern void irq_set_virq_count(unsigned int count); 136 131 137 132 static inline struct irq_domain *irq_domain_add_legacy_isa( 138 133 struct device_node *of_node, ··· 143 140 } 144 141 extern struct irq_domain *irq_find_host(struct device_node *node); 145 142 extern void irq_set_default_host(struct irq_domain *host); 146 - extern void irq_set_virq_count(unsigned int count); 147 143 148 144 149 145 extern unsigned int irq_create_mapping(struct irq_domain *host,
+9 -24
kernel/irq/irqdomain.c
··· 23 23 static DEFINE_MUTEX(irq_domain_mutex); 24 24 25 25 static DEFINE_MUTEX(revmap_trees_mutex); 26 - static unsigned int irq_virq_count = NR_IRQS; 27 26 static struct irq_domain *irq_default_domain; 28 27 29 28 /** ··· 183 184 } 184 185 185 186 struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, 187 + unsigned int max_irq, 186 188 const struct irq_domain_ops *ops, 187 189 void *host_data) 188 190 { 189 191 struct irq_domain *domain = irq_domain_alloc(of_node, 190 192 IRQ_DOMAIN_MAP_NOMAP, ops, host_data); 191 - if (domain) 193 + if (domain) { 194 + domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0; 192 195 irq_domain_add(domain); 196 + } 193 197 return domain; 194 198 } 195 199 ··· 264 262 irq_default_domain = domain; 265 263 } 266 264 267 - /** 268 - * irq_set_virq_count() - Set the maximum number of linux irqs 269 - * @count: number of linux irqs, capped with NR_IRQS 270 - * 271 - * This is mainly for use by platforms like iSeries who want to program 272 - * the virtual irq number in the controller to avoid the reverse mapping 273 - */ 274 - void irq_set_virq_count(unsigned int count) 275 - { 276 - pr_debug("irq: Trying to set virq count to %d\n", count); 277 - 278 - BUG_ON(count < NUM_ISA_INTERRUPTS); 279 - if (count < NR_IRQS) 280 - irq_virq_count = count; 281 - } 282 - 283 265 static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, 284 266 irq_hw_number_t hwirq) 285 267 { ··· 306 320 pr_debug("irq: create_direct virq allocation failed\n"); 307 321 return 0; 308 322 } 309 - if (virq >= irq_virq_count) { 323 + if (virq >= domain->revmap_data.nomap.max_irq) { 310 324 pr_err("ERROR: no free irqs available below %i maximum\n", 311 - irq_virq_count); 325 + domain->revmap_data.nomap.max_irq); 312 326 irq_free_desc(virq); 313 327 return 0; 314 328 } 315 - 316 329 pr_debug("irq: create_direct obtained virq %d\n", virq); 317 330 318 331 if (irq_setup_virq(domain, virq, virq)) { ··· 363 378 return irq_domain_legacy_revmap(domain, hwirq); 364 379 365 380 /* Allocate a virtual interrupt number */ 366 - hint = hwirq % irq_virq_count; 381 + hint = hwirq % nr_irqs; 367 382 if (hint == 0) 368 383 hint++; 369 384 virq = irq_alloc_desc_from(hint, 0); ··· 501 516 irq_hw_number_t hwirq) 502 517 { 503 518 unsigned int i; 504 - unsigned int hint = hwirq % irq_virq_count; 519 + unsigned int hint = hwirq % nr_irqs; 505 520 506 521 /* Look for default domain if nececssary */ 507 522 if (domain == NULL) ··· 522 537 if (data && (data->domain == domain) && (data->hwirq == hwirq)) 523 538 return i; 524 539 i++; 525 - if (i >= irq_virq_count) 540 + if (i >= nr_irqs) 526 541 i = 1; 527 542 } while(i != hint); 528 543 return 0;