diff options
author | Kevin Hilman <khilman@linaro.org> | 2013-10-14 18:29:10 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@linaro.org> | 2013-10-14 18:29:24 -0400 |
commit | 7587b5965f57c1c4d6fd1377432a8473f5cd449a (patch) | |
tree | 85b7ced77656ac142369c6436df02b51d6d13527 /arch/powerpc/kernel/irq.c | |
parent | 6a9d10d529db69244baab335fb02caba3d6ebbc9 (diff) | |
parent | 8d71528343c69ce387bd5fdb4fd8dc2b9f69d97c (diff) |
Merge tag 'omap-for-v3.13/quirk-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/dt
From Tony Lindgren:
Changes needed to prepare for making omap3 device tree only:
- Always build in board-generic, and add pdata quirks and auxdata
support for it so we have all the pdata related quirks
in the same place.
- Merge of the drivers/pinctrl changes that are needed for PM
to continue working on omap3 and also needed for other omaps
eventually. The three pinctrl related patches have been acked
by Linus Walleij and are pulled into both the pinctrl tree
and this branch.
- Few defconfig related changes for drivers needed.
* tag 'omap-for-v3.13/quirk-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (523 commits)
ARM: configs: omap2plus_defconfig: enable dwc3 and dependencies
ARM: OMAP2+: Add WLAN modules and of_serial to omap2plus_defconfig
ARM: OMAP2+: Run make savedefconfig on omap2plus_defconfig to shrink it
ARM: OMAP2+: Add minimal 8250 support for GPMC
ARM: OMAP2+: Use pdata quirks for wl12xx for omap3 evm and zoom3
ARM: OMAP: Move DT wake-up event handling over to use pinctrl-single-omap
ARM: OMAP2+: Add support for auxdata
pinctrl: single: Add support for auxdata
pinctrl: single: Add support for wake-up interrupts
pinctrl: single: Prepare for supporting SoC specific features
ARM: OMAP2+: igep0020: use display init from dss-common
ARM: OMAP2+: pdata-quirks: add legacy display init for IGEPv2 board
+Linux 3.12-rc4
Signed-off-by: Kevin Hilman <khilman@linaro.org>
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r-- | arch/powerpc/kernel/irq.c | 100 |
1 files changed, 44 insertions, 56 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index c69440cef7af..57d286a78f86 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -441,50 +441,6 @@ void migrate_irqs(void) | |||
441 | } | 441 | } |
442 | #endif | 442 | #endif |
443 | 443 | ||
444 | static inline void handle_one_irq(unsigned int irq) | ||
445 | { | ||
446 | struct thread_info *curtp, *irqtp; | ||
447 | unsigned long saved_sp_limit; | ||
448 | struct irq_desc *desc; | ||
449 | |||
450 | desc = irq_to_desc(irq); | ||
451 | if (!desc) | ||
452 | return; | ||
453 | |||
454 | /* Switch to the irq stack to handle this */ | ||
455 | curtp = current_thread_info(); | ||
456 | irqtp = hardirq_ctx[smp_processor_id()]; | ||
457 | |||
458 | if (curtp == irqtp) { | ||
459 | /* We're already on the irq stack, just handle it */ | ||
460 | desc->handle_irq(irq, desc); | ||
461 | return; | ||
462 | } | ||
463 | |||
464 | saved_sp_limit = current->thread.ksp_limit; | ||
465 | |||
466 | irqtp->task = curtp->task; | ||
467 | irqtp->flags = 0; | ||
468 | |||
469 | /* Copy the softirq bits in preempt_count so that the | ||
470 | * softirq checks work in the hardirq context. */ | ||
471 | irqtp->preempt_count = (irqtp->preempt_count & ~SOFTIRQ_MASK) | | ||
472 | (curtp->preempt_count & SOFTIRQ_MASK); | ||
473 | |||
474 | current->thread.ksp_limit = (unsigned long)irqtp + | ||
475 | _ALIGN_UP(sizeof(struct thread_info), 16); | ||
476 | |||
477 | call_handle_irq(irq, desc, irqtp, desc->handle_irq); | ||
478 | current->thread.ksp_limit = saved_sp_limit; | ||
479 | irqtp->task = NULL; | ||
480 | |||
481 | /* Set any flag that may have been set on the | ||
482 | * alternate stack | ||
483 | */ | ||
484 | if (irqtp->flags) | ||
485 | set_bits(irqtp->flags, &curtp->flags); | ||
486 | } | ||
487 | |||
488 | static inline void check_stack_overflow(void) | 444 | static inline void check_stack_overflow(void) |
489 | { | 445 | { |
490 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | 446 | #ifdef CONFIG_DEBUG_STACKOVERFLOW |
@@ -501,9 +457,9 @@ static inline void check_stack_overflow(void) | |||
501 | #endif | 457 | #endif |
502 | } | 458 | } |
503 | 459 | ||
504 | void do_IRQ(struct pt_regs *regs) | 460 | void __do_irq(struct pt_regs *regs) |
505 | { | 461 | { |
506 | struct pt_regs *old_regs = set_irq_regs(regs); | 462 | struct irq_desc *desc; |
507 | unsigned int irq; | 463 | unsigned int irq; |
508 | 464 | ||
509 | irq_enter(); | 465 | irq_enter(); |
@@ -519,18 +475,56 @@ void do_IRQ(struct pt_regs *regs) | |||
519 | */ | 475 | */ |
520 | irq = ppc_md.get_irq(); | 476 | irq = ppc_md.get_irq(); |
521 | 477 | ||
522 | /* We can hard enable interrupts now */ | 478 | /* We can hard enable interrupts now to allow perf interrupts */ |
523 | may_hard_irq_enable(); | 479 | may_hard_irq_enable(); |
524 | 480 | ||
525 | /* And finally process it */ | 481 | /* And finally process it */ |
526 | if (irq != NO_IRQ) | 482 | if (unlikely(irq == NO_IRQ)) |
527 | handle_one_irq(irq); | ||
528 | else | ||
529 | __get_cpu_var(irq_stat).spurious_irqs++; | 483 | __get_cpu_var(irq_stat).spurious_irqs++; |
484 | else { | ||
485 | desc = irq_to_desc(irq); | ||
486 | if (likely(desc)) | ||
487 | desc->handle_irq(irq, desc); | ||
488 | } | ||
530 | 489 | ||
531 | trace_irq_exit(regs); | 490 | trace_irq_exit(regs); |
532 | 491 | ||
533 | irq_exit(); | 492 | irq_exit(); |
493 | } | ||
494 | |||
495 | void do_IRQ(struct pt_regs *regs) | ||
496 | { | ||
497 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
498 | struct thread_info *curtp, *irqtp; | ||
499 | |||
500 | /* Switch to the irq stack to handle this */ | ||
501 | curtp = current_thread_info(); | ||
502 | irqtp = hardirq_ctx[raw_smp_processor_id()]; | ||
503 | |||
504 | /* Already there ? */ | ||
505 | if (unlikely(curtp == irqtp)) { | ||
506 | __do_irq(regs); | ||
507 | set_irq_regs(old_regs); | ||
508 | return; | ||
509 | } | ||
510 | |||
511 | /* Prepare the thread_info in the irq stack */ | ||
512 | irqtp->task = curtp->task; | ||
513 | irqtp->flags = 0; | ||
514 | |||
515 | /* Copy the preempt_count so that the [soft]irq checks work. */ | ||
516 | irqtp->preempt_count = curtp->preempt_count; | ||
517 | |||
518 | /* Switch stack and call */ | ||
519 | call_do_irq(regs, irqtp); | ||
520 | |||
521 | /* Restore stack limit */ | ||
522 | irqtp->task = NULL; | ||
523 | |||
524 | /* Copy back updates to the thread_info */ | ||
525 | if (irqtp->flags) | ||
526 | set_bits(irqtp->flags, &curtp->flags); | ||
527 | |||
534 | set_irq_regs(old_regs); | 528 | set_irq_regs(old_regs); |
535 | } | 529 | } |
536 | 530 | ||
@@ -592,28 +586,22 @@ void irq_ctx_init(void) | |||
592 | memset((void *)softirq_ctx[i], 0, THREAD_SIZE); | 586 | memset((void *)softirq_ctx[i], 0, THREAD_SIZE); |
593 | tp = softirq_ctx[i]; | 587 | tp = softirq_ctx[i]; |
594 | tp->cpu = i; | 588 | tp->cpu = i; |
595 | tp->preempt_count = 0; | ||
596 | 589 | ||
597 | memset((void *)hardirq_ctx[i], 0, THREAD_SIZE); | 590 | memset((void *)hardirq_ctx[i], 0, THREAD_SIZE); |
598 | tp = hardirq_ctx[i]; | 591 | tp = hardirq_ctx[i]; |
599 | tp->cpu = i; | 592 | tp->cpu = i; |
600 | tp->preempt_count = HARDIRQ_OFFSET; | ||
601 | } | 593 | } |
602 | } | 594 | } |
603 | 595 | ||
604 | static inline void do_softirq_onstack(void) | 596 | static inline void do_softirq_onstack(void) |
605 | { | 597 | { |
606 | struct thread_info *curtp, *irqtp; | 598 | struct thread_info *curtp, *irqtp; |
607 | unsigned long saved_sp_limit = current->thread.ksp_limit; | ||
608 | 599 | ||
609 | curtp = current_thread_info(); | 600 | curtp = current_thread_info(); |
610 | irqtp = softirq_ctx[smp_processor_id()]; | 601 | irqtp = softirq_ctx[smp_processor_id()]; |
611 | irqtp->task = curtp->task; | 602 | irqtp->task = curtp->task; |
612 | irqtp->flags = 0; | 603 | irqtp->flags = 0; |
613 | current->thread.ksp_limit = (unsigned long)irqtp + | ||
614 | _ALIGN_UP(sizeof(struct thread_info), 16); | ||
615 | call_do_softirq(irqtp); | 604 | call_do_softirq(irqtp); |
616 | current->thread.ksp_limit = saved_sp_limit; | ||
617 | irqtp->task = NULL; | 605 | irqtp->task = NULL; |
618 | 606 | ||
619 | /* Set any flag that may have been set on the | 607 | /* Set any flag that may have been set on the |