diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-12 15:49:56 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-12 15:49:56 -0400 |
| commit | 7e066489726b52bea419085e5b8929e1e89f57a8 (patch) | |
| tree | b144712e5200002b55b45f362ffa1fd53d0389c6 /kernel | |
| parent | 4abb663b641ee21024906dae45af7de50ebad2d8 (diff) | |
| parent | 6fa6c8e25e95bdc73e92e4c96b8e3299169b616e (diff) | |
Merge tag 'irqdomain-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull irqdomain bug fixes from Grant Likely:
"This branch fixes a bug in irq_create_mapping() where an error return
from irq_alloc_desc_from() gets ignored.
It also removes irq_virq_count to fix a bug on powerpc where the
irqdomain code does not find irqs allocated above the CONFIG_NR_IRQS
boundary.
The remaining patches get rid of an completely pointless export and
fix some minor bugs in the irqdomain debug output."
* tag 'irqdomain-for-linus' of git://git.secretlab.ca/git/linux-2.6:
irq_domain: Move irq_virq_count into NOMAP revmap
irqdomain: Fix debugfs formatting
irq_domain: correct the debugfs file name
irq: Kill pointless irqd_to_hw export
irq/irq_domain: Quit ignoring error returns from irq_alloc_desc_from().
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/irq/Kconfig | 2 | ||||
| -rw-r--r-- | kernel/irq/irqdomain.c | 46 |
2 files changed, 17 insertions, 31 deletions
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index cf1a4a68ce44..d1a758bc972a 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig | |||
| @@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG | |||
| 62 | help | 62 | help |
| 63 | This option will show the mapping relationship between hardware irq | 63 | This option will show the mapping relationship between hardware irq |
| 64 | numbers and Linux irq numbers. The mapping is exposed via debugfs | 64 | numbers and Linux irq numbers. The mapping is exposed via debugfs |
| 65 | in the file "virq_mapping". | 65 | in the file "irq_domain_mapping". |
| 66 | 66 | ||
| 67 | If you don't know what this means you don't need it. | 67 | If you don't know what this means you don't need it. |
| 68 | 68 | ||
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 3601f3fbf67c..d34413e78628 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c | |||
| @@ -23,7 +23,6 @@ static LIST_HEAD(irq_domain_list); | |||
| 23 | static DEFINE_MUTEX(irq_domain_mutex); | 23 | static DEFINE_MUTEX(irq_domain_mutex); |
| 24 | 24 | ||
| 25 | static DEFINE_MUTEX(revmap_trees_mutex); | 25 | static DEFINE_MUTEX(revmap_trees_mutex); |
| 26 | static unsigned int irq_virq_count = NR_IRQS; | ||
| 27 | static struct irq_domain *irq_default_domain; | 26 | static struct irq_domain *irq_default_domain; |
| 28 | 27 | ||
| 29 | /** | 28 | /** |
| @@ -184,13 +183,16 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, | |||
| 184 | } | 183 | } |
| 185 | 184 | ||
| 186 | struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, | 185 | struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, |
| 186 | unsigned int max_irq, | ||
| 187 | const struct irq_domain_ops *ops, | 187 | const struct irq_domain_ops *ops, |
| 188 | void *host_data) | 188 | void *host_data) |
| 189 | { | 189 | { |
| 190 | struct irq_domain *domain = irq_domain_alloc(of_node, | 190 | struct irq_domain *domain = irq_domain_alloc(of_node, |
| 191 | IRQ_DOMAIN_MAP_NOMAP, ops, host_data); | 191 | IRQ_DOMAIN_MAP_NOMAP, ops, host_data); |
| 192 | if (domain) | 192 | if (domain) { |
| 193 | domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0; | ||
| 193 | irq_domain_add(domain); | 194 | irq_domain_add(domain); |
| 195 | } | ||
| 194 | return domain; | 196 | return domain; |
| 195 | } | 197 | } |
| 196 | 198 | ||
| @@ -262,22 +264,6 @@ void irq_set_default_host(struct irq_domain *domain) | |||
| 262 | irq_default_domain = domain; | 264 | irq_default_domain = domain; |
| 263 | } | 265 | } |
| 264 | 266 | ||
| 265 | /** | ||
| 266 | * irq_set_virq_count() - Set the maximum number of linux irqs | ||
| 267 | * @count: number of linux irqs, capped with NR_IRQS | ||
| 268 | * | ||
| 269 | * This is mainly for use by platforms like iSeries who want to program | ||
| 270 | * the virtual irq number in the controller to avoid the reverse mapping | ||
| 271 | */ | ||
| 272 | void irq_set_virq_count(unsigned int count) | ||
| 273 | { | ||
| 274 | pr_debug("irq: Trying to set virq count to %d\n", count); | ||
| 275 | |||
| 276 | BUG_ON(count < NUM_ISA_INTERRUPTS); | ||
| 277 | if (count < NR_IRQS) | ||
| 278 | irq_virq_count = count; | ||
| 279 | } | ||
| 280 | |||
| 281 | static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, | 267 | static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, |
| 282 | irq_hw_number_t hwirq) | 268 | irq_hw_number_t hwirq) |
| 283 | { | 269 | { |
| @@ -320,13 +306,12 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) | |||
| 320 | pr_debug("irq: create_direct virq allocation failed\n"); | 306 | pr_debug("irq: create_direct virq allocation failed\n"); |
| 321 | return 0; | 307 | return 0; |
| 322 | } | 308 | } |
| 323 | if (virq >= irq_virq_count) { | 309 | if (virq >= domain->revmap_data.nomap.max_irq) { |
| 324 | pr_err("ERROR: no free irqs available below %i maximum\n", | 310 | pr_err("ERROR: no free irqs available below %i maximum\n", |
| 325 | irq_virq_count); | 311 | domain->revmap_data.nomap.max_irq); |
| 326 | irq_free_desc(virq); | 312 | irq_free_desc(virq); |
| 327 | return 0; | 313 | return 0; |
| 328 | } | 314 | } |
| 329 | |||
| 330 | pr_debug("irq: create_direct obtained virq %d\n", virq); | 315 | pr_debug("irq: create_direct obtained virq %d\n", virq); |
| 331 | 316 | ||
| 332 | if (irq_setup_virq(domain, virq, virq)) { | 317 | if (irq_setup_virq(domain, virq, virq)) { |
| @@ -350,7 +335,8 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) | |||
| 350 | unsigned int irq_create_mapping(struct irq_domain *domain, | 335 | unsigned int irq_create_mapping(struct irq_domain *domain, |
| 351 | irq_hw_number_t hwirq) | 336 | irq_hw_number_t hwirq) |
| 352 | { | 337 | { |
| 353 | unsigned int virq, hint; | 338 | unsigned int hint; |
| 339 | int virq; | ||
| 354 | 340 | ||
| 355 | pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); | 341 | pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); |
| 356 | 342 | ||
| @@ -377,13 +363,13 @@ unsigned int irq_create_mapping(struct irq_domain *domain, | |||
| 377 | return irq_domain_legacy_revmap(domain, hwirq); | 363 | return irq_domain_legacy_revmap(domain, hwirq); |
| 378 | 364 | ||
| 379 | /* Allocate a virtual interrupt number */ | 365 | /* Allocate a virtual interrupt number */ |
| 380 | hint = hwirq % irq_virq_count; | 366 | hint = hwirq % nr_irqs; |
| 381 | if (hint == 0) | 367 | if (hint == 0) |
| 382 | hint++; | 368 | hint++; |
| 383 | virq = irq_alloc_desc_from(hint, 0); | 369 | virq = irq_alloc_desc_from(hint, 0); |
| 384 | if (!virq) | 370 | if (virq <= 0) |
| 385 | virq = irq_alloc_desc_from(1, 0); | 371 | virq = irq_alloc_desc_from(1, 0); |
| 386 | if (!virq) { | 372 | if (virq <= 0) { |
| 387 | pr_debug("irq: -> virq allocation failed\n"); | 373 | pr_debug("irq: -> virq allocation failed\n"); |
| 388 | return 0; | 374 | return 0; |
| 389 | } | 375 | } |
| @@ -515,7 +501,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, | |||
| 515 | irq_hw_number_t hwirq) | 501 | irq_hw_number_t hwirq) |
| 516 | { | 502 | { |
| 517 | unsigned int i; | 503 | unsigned int i; |
| 518 | unsigned int hint = hwirq % irq_virq_count; | 504 | unsigned int hint = hwirq % nr_irqs; |
| 519 | 505 | ||
| 520 | /* Look for default domain if nececssary */ | 506 | /* Look for default domain if nececssary */ |
| 521 | if (domain == NULL) | 507 | if (domain == NULL) |
| @@ -536,7 +522,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, | |||
| 536 | if (data && (data->domain == domain) && (data->hwirq == hwirq)) | 522 | if (data && (data->domain == domain) && (data->hwirq == hwirq)) |
| 537 | return i; | 523 | return i; |
| 538 | i++; | 524 | i++; |
| 539 | if (i >= irq_virq_count) | 525 | if (i >= nr_irqs) |
| 540 | i = 1; | 526 | i = 1; |
| 541 | } while(i != hint); | 527 | } while(i != hint); |
| 542 | return 0; | 528 | return 0; |
| @@ -642,8 +628,8 @@ static int virq_debug_show(struct seq_file *m, void *private) | |||
| 642 | void *data; | 628 | void *data; |
| 643 | int i; | 629 | int i; |
| 644 | 630 | ||
| 645 | seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", | 631 | seq_printf(m, "%-5s %-7s %-15s %-*s %s\n", "irq", "hwirq", |
| 646 | "chip name", "chip data", "domain name"); | 632 | "chip name", 2 * sizeof(void *) + 2, "chip data", "domain name"); |
| 647 | 633 | ||
| 648 | for (i = 1; i < nr_irqs; i++) { | 634 | for (i = 1; i < nr_irqs; i++) { |
| 649 | desc = irq_to_desc(i); | 635 | desc = irq_to_desc(i); |
| @@ -666,7 +652,7 @@ static int virq_debug_show(struct seq_file *m, void *private) | |||
| 666 | seq_printf(m, "%-15s ", p); | 652 | seq_printf(m, "%-15s ", p); |
| 667 | 653 | ||
| 668 | data = irq_desc_get_chip_data(desc); | 654 | data = irq_desc_get_chip_data(desc); |
| 669 | seq_printf(m, "0x%16p ", data); | 655 | seq_printf(m, data ? "0x%p " : " %p ", data); |
| 670 | 656 | ||
| 671 | if (desc->irq_data.domain && desc->irq_data.domain->of_node) | 657 | if (desc->irq_data.domain && desc->irq_data.domain->of_node) |
| 672 | p = desc->irq_data.domain->of_node->full_name; | 658 | p = desc->irq_data.domain->of_node->full_name; |
