diff options
| author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-05-08 20:57:57 -0400 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2012-05-08 20:57:57 -0400 |
| commit | ea4e89afedc7fc64078076eacbcffaaa742baf0d (patch) | |
| tree | 1e4a14dd1ada2eff8d1cb4d76bf9e337e079845e | |
| parent | 43671cc96e58458b2711f1e97ff24a4c0e7cd1ac (diff) | |
| parent | a3512b2dd57cb653bb33645ca9c934436e547e3c (diff) | |
Merge branch 'merge' into next
| -rw-r--r-- | arch/powerpc/include/asm/exception-64s.h | 7 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/irq.h | 4 | ||||
| -rw-r--r-- | arch/powerpc/kernel/entry_64.S | 18 | ||||
| -rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/irq.c | 14 | ||||
| -rw-r--r-- | arch/powerpc/kernel/machine_kexec.c | 7 | ||||
| -rw-r--r-- | arch/powerpc/kernel/traps.c | 10 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/axon_msi.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/beat_interrupt.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powermac/pic.c | 6 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/Kconfig | 4 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/cpm2_pic.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/mpc8xx_pic.c | 61 | ||||
| -rw-r--r-- | arch/powerpc/sysdev/xics/xics-common.c | 7 | ||||
| -rw-r--r-- | drivers/tty/serial/pmac_zilog.c | 6 |
15 files changed, 55 insertions, 104 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 548da3aa0a30..d58fc4e4149c 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h | |||
| @@ -288,13 +288,6 @@ label##_hv: \ | |||
| 288 | /* Exception addition: Hard disable interrupts */ | 288 | /* Exception addition: Hard disable interrupts */ |
| 289 | #define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11) | 289 | #define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11) |
| 290 | 290 | ||
| 291 | /* Exception addition: Keep interrupt state */ | ||
| 292 | #define ENABLE_INTS \ | ||
| 293 | ld r11,PACAKMSR(r13); \ | ||
| 294 | ld r12,_MSR(r1); \ | ||
| 295 | rlwimi r11,r12,0,MSR_EE; \ | ||
| 296 | mtmsrd r11,1 | ||
| 297 | |||
| 298 | #define ADD_NVGPRS \ | 291 | #define ADD_NVGPRS \ |
| 299 | bl .save_nvgprs | 292 | bl .save_nvgprs |
| 300 | 293 | ||
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index e648af92ced1..0e40843a1c6e 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h | |||
| @@ -18,10 +18,6 @@ | |||
| 18 | #include <linux/atomic.h> | 18 | #include <linux/atomic.h> |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | /* Define a way to iterate across irqs. */ | ||
| 22 | #define for_each_irq(i) \ | ||
| 23 | for ((i) = 0; (i) < NR_IRQS; ++(i)) | ||
| 24 | |||
| 25 | extern atomic_t ppc_n_lost_interrupts; | 21 | extern atomic_t ppc_n_lost_interrupts; |
| 26 | 22 | ||
| 27 | /* This number is used when no interrupt has been assigned */ | 23 | /* This number is used when no interrupt has been assigned */ |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index fd4604674468..29f13570214d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
| @@ -763,16 +763,6 @@ do_work: | |||
| 763 | SOFT_DISABLE_INTS(r3,r4) | 763 | SOFT_DISABLE_INTS(r3,r4) |
| 764 | 1: bl .preempt_schedule_irq | 764 | 1: bl .preempt_schedule_irq |
| 765 | 765 | ||
| 766 | /* Hard-disable interrupts again (and update PACA) */ | ||
| 767 | #ifdef CONFIG_PPC_BOOK3E | ||
| 768 | wrteei 0 | ||
| 769 | #else | ||
| 770 | ld r10,PACAKMSR(r13) /* Get kernel MSR without EE */ | ||
| 771 | mtmsrd r10,1 | ||
| 772 | #endif /* CONFIG_PPC_BOOK3E */ | ||
| 773 | li r0,PACA_IRQ_HARD_DIS | ||
| 774 | stb r0,PACAIRQHAPPENED(r13) | ||
| 775 | |||
| 776 | /* Re-test flags and eventually loop */ | 766 | /* Re-test flags and eventually loop */ |
| 777 | clrrdi r9,r1,THREAD_SHIFT | 767 | clrrdi r9,r1,THREAD_SHIFT |
| 778 | ld r4,TI_FLAGS(r9) | 768 | ld r4,TI_FLAGS(r9) |
| @@ -783,14 +773,6 @@ do_work: | |||
| 783 | user_work: | 773 | user_work: |
| 784 | #endif /* CONFIG_PREEMPT */ | 774 | #endif /* CONFIG_PREEMPT */ |
| 785 | 775 | ||
| 786 | /* Enable interrupts */ | ||
| 787 | #ifdef CONFIG_PPC_BOOK3E | ||
| 788 | wrteei 1 | ||
| 789 | #else | ||
| 790 | ori r10,r10,MSR_EE | ||
| 791 | mtmsrd r10,1 | ||
| 792 | #endif /* CONFIG_PPC_BOOK3E */ | ||
| 793 | |||
| 794 | andi. r0,r4,_TIF_NEED_RESCHED | 776 | andi. r0,r4,_TIF_NEED_RESCHED |
| 795 | beq 1f | 777 | beq 1f |
| 796 | bl .restore_interrupts | 778 | bl .restore_interrupts |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e0537693d660..f7bed44ee165 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
| @@ -764,8 +764,8 @@ alignment_common: | |||
| 764 | std r3,_DAR(r1) | 764 | std r3,_DAR(r1) |
| 765 | std r4,_DSISR(r1) | 765 | std r4,_DSISR(r1) |
| 766 | bl .save_nvgprs | 766 | bl .save_nvgprs |
| 767 | DISABLE_INTS | ||
| 767 | addi r3,r1,STACK_FRAME_OVERHEAD | 768 | addi r3,r1,STACK_FRAME_OVERHEAD |
| 768 | ENABLE_INTS | ||
| 769 | bl .alignment_exception | 769 | bl .alignment_exception |
| 770 | b .ret_from_except | 770 | b .ret_from_except |
| 771 | 771 | ||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5ec1b2354ca6..c6c6f3b7f8cd 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -260,11 +260,17 @@ EXPORT_SYMBOL(arch_local_irq_restore); | |||
| 260 | * if they are currently disabled. This is typically called before | 260 | * if they are currently disabled. This is typically called before |
| 261 | * schedule() or do_signal() when returning to userspace. We do it | 261 | * schedule() or do_signal() when returning to userspace. We do it |
| 262 | * in C to avoid the burden of dealing with lockdep etc... | 262 | * in C to avoid the burden of dealing with lockdep etc... |
| 263 | * | ||
| 264 | * NOTE: This is called with interrupts hard disabled but not marked | ||
| 265 | * as such in paca->irq_happened, so we need to resync this. | ||
| 263 | */ | 266 | */ |
| 264 | void restore_interrupts(void) | 267 | void restore_interrupts(void) |
| 265 | { | 268 | { |
| 266 | if (irqs_disabled()) | 269 | if (irqs_disabled()) { |
| 270 | local_paca->irq_happened |= PACA_IRQ_HARD_DIS; | ||
| 267 | local_irq_enable(); | 271 | local_irq_enable(); |
| 272 | } else | ||
| 273 | __hard_irq_enable(); | ||
| 268 | } | 274 | } |
| 269 | 275 | ||
| 270 | #endif /* CONFIG_PPC64 */ | 276 | #endif /* CONFIG_PPC64 */ |
| @@ -330,14 +336,10 @@ void migrate_irqs(void) | |||
| 330 | 336 | ||
| 331 | alloc_cpumask_var(&mask, GFP_KERNEL); | 337 | alloc_cpumask_var(&mask, GFP_KERNEL); |
| 332 | 338 | ||
| 333 | for_each_irq(irq) { | 339 | for_each_irq_desc(irq, desc) { |
| 334 | struct irq_data *data; | 340 | struct irq_data *data; |
| 335 | struct irq_chip *chip; | 341 | struct irq_chip *chip; |
| 336 | 342 | ||
| 337 | desc = irq_to_desc(irq); | ||
| 338 | if (!desc) | ||
| 339 | continue; | ||
| 340 | |||
| 341 | data = irq_desc_get_irq_data(desc); | 343 | data = irq_desc_get_irq_data(desc); |
| 342 | if (irqd_is_per_cpu(data)) | 344 | if (irqd_is_per_cpu(data)) |
| 343 | continue; | 345 | continue; |
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index c957b1202bdc..5df777794403 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
| @@ -23,14 +23,11 @@ | |||
| 23 | 23 | ||
| 24 | void machine_kexec_mask_interrupts(void) { | 24 | void machine_kexec_mask_interrupts(void) { |
| 25 | unsigned int i; | 25 | unsigned int i; |
| 26 | struct irq_desc *desc; | ||
| 26 | 27 | ||
| 27 | for_each_irq(i) { | 28 | for_each_irq_desc(i, desc) { |
| 28 | struct irq_desc *desc = irq_to_desc(i); | ||
| 29 | struct irq_chip *chip; | 29 | struct irq_chip *chip; |
| 30 | 30 | ||
| 31 | if (!desc) | ||
| 32 | continue; | ||
| 33 | |||
| 34 | chip = irq_desc_get_chip(desc); | 31 | chip = irq_desc_get_chip(desc); |
| 35 | if (!chip) | 32 | if (!chip) |
| 36 | continue; | 33 | continue; |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 6aa0c663e247..158972341a2d 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) | |||
| 248 | addr, regs->nip, regs->link, code); | 248 | addr, regs->nip, regs->link, code); |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | if (!arch_irq_disabled_regs(regs)) | 251 | if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs)) |
| 252 | local_irq_enable(); | 252 | local_irq_enable(); |
| 253 | 253 | ||
| 254 | memset(&info, 0, sizeof(info)); | 254 | memset(&info, 0, sizeof(info)); |
| @@ -1019,7 +1019,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
| 1019 | return; | 1019 | return; |
| 1020 | } | 1020 | } |
| 1021 | 1021 | ||
| 1022 | local_irq_enable(); | 1022 | /* We restore the interrupt state now */ |
| 1023 | if (!arch_irq_disabled_regs(regs)) | ||
| 1024 | local_irq_enable(); | ||
| 1023 | 1025 | ||
| 1024 | #ifdef CONFIG_MATH_EMULATION | 1026 | #ifdef CONFIG_MATH_EMULATION |
| 1025 | /* (reason & REASON_ILLEGAL) would be the obvious thing here, | 1027 | /* (reason & REASON_ILLEGAL) would be the obvious thing here, |
| @@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs) | |||
| 1069 | { | 1071 | { |
| 1070 | int sig, code, fixed = 0; | 1072 | int sig, code, fixed = 0; |
| 1071 | 1073 | ||
| 1074 | /* We restore the interrupt state now */ | ||
| 1075 | if (!arch_irq_disabled_regs(regs)) | ||
| 1076 | local_irq_enable(); | ||
| 1077 | |||
| 1072 | /* we don't implement logging of alignment exceptions */ | 1078 | /* we don't implement logging of alignment exceptions */ |
| 1073 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) | 1079 | if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) |
| 1074 | fixed = fix_alignment(regs); | 1080 | fixed = fix_alignment(regs); |
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index d09f3e8e6867..85825b5401e5 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c | |||
| @@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) | |||
| 114 | pr_devel("axon_msi: woff %x roff %x msi %x\n", | 114 | pr_devel("axon_msi: woff %x roff %x msi %x\n", |
| 115 | write_offset, msic->read_offset, msi); | 115 | write_offset, msic->read_offset, msi); |
| 116 | 116 | ||
| 117 | if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) { | 117 | if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { |
| 118 | generic_handle_irq(msi); | 118 | generic_handle_irq(msi); |
| 119 | msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); | 119 | msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); |
| 120 | } else { | 120 | } else { |
| @@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
| 276 | if (rc) | 276 | if (rc) |
| 277 | return rc; | 277 | return rc; |
| 278 | 278 | ||
| 279 | /* We rely on being able to stash a virq in a u16 */ | ||
| 280 | BUILD_BUG_ON(NR_IRQS > 65536); | ||
| 281 | |||
| 282 | list_for_each_entry(entry, &dev->msi_list, list) { | 279 | list_for_each_entry(entry, &dev->msi_list, list) { |
| 283 | virq = irq_create_direct_mapping(msic->irq_domain); | 280 | virq = irq_create_direct_mapping(msic->irq_domain); |
| 284 | if (virq == NO_IRQ) { | 281 | if (virq == NO_IRQ) { |
| @@ -392,7 +389,8 @@ static int axon_msi_probe(struct platform_device *device) | |||
| 392 | } | 389 | } |
| 393 | memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); | 390 | memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); |
| 394 | 391 | ||
| 395 | msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); | 392 | /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ |
| 393 | msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); | ||
| 396 | if (!msic->irq_domain) { | 394 | if (!msic->irq_domain) { |
| 397 | printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", | 395 | printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", |
| 398 | dn->full_name); | 396 | dn->full_name); |
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c index f9a48af335cb..8c6dc42ecf65 100644 --- a/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/arch/powerpc/platforms/cell/beat_interrupt.c | |||
| @@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void) | |||
| 248 | { | 248 | { |
| 249 | int i; | 249 | int i; |
| 250 | 250 | ||
| 251 | for (i = 1; i < NR_IRQS; i++) | 251 | for (i = 1; i < nr_irqs; i++) |
| 252 | beat_destruct_irq_plug(i); | 252 | beat_destruct_irq_plug(i); |
| 253 | } | 253 | } |
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 66ad93de1d55..c4e630576ff2 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c | |||
| @@ -57,9 +57,9 @@ static int max_real_irqs; | |||
| 57 | 57 | ||
| 58 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); | 58 | static DEFINE_RAW_SPINLOCK(pmac_pic_lock); |
| 59 | 59 | ||
| 60 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | 60 | /* The max irq number this driver deals with is 128; see max_irqs */ |
| 61 | static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; | 61 | static DECLARE_BITMAP(ppc_lost_interrupts, 128); |
| 62 | static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | 62 | static DECLARE_BITMAP(ppc_cached_irq_mask, 128); |
| 63 | static int pmac_irq_cascade = -1; | 63 | static int pmac_irq_cascade = -1; |
| 64 | static struct irq_domain *pmac_pic_host; | 64 | static struct irq_domain *pmac_pic_host; |
| 65 | 65 | ||
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index aadbe4f6d537..178a5f300bc9 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
| @@ -30,9 +30,9 @@ config PPC_SPLPAR | |||
| 30 | two or more partitions. | 30 | two or more partitions. |
| 31 | 31 | ||
| 32 | config EEH | 32 | config EEH |
| 33 | bool "PCI Extended Error Handling (EEH)" if EXPERT | 33 | bool |
| 34 | depends on PPC_PSERIES && PCI | 34 | depends on PPC_PSERIES && PCI |
| 35 | default y if !EXPERT | 35 | default y |
| 36 | 36 | ||
| 37 | config PSERIES_MSI | 37 | config PSERIES_MSI |
| 38 | bool | 38 | bool |
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index d3be961e2ae7..10386b676d87 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c | |||
| @@ -51,8 +51,7 @@ | |||
| 51 | static intctl_cpm2_t __iomem *cpm2_intctl; | 51 | static intctl_cpm2_t __iomem *cpm2_intctl; |
| 52 | 52 | ||
| 53 | static struct irq_domain *cpm2_pic_host; | 53 | static struct irq_domain *cpm2_pic_host; |
| 54 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | 54 | static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */ |
| 55 | static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | ||
| 56 | 55 | ||
| 57 | static const u_char irq_to_siureg[] = { | 56 | static const u_char irq_to_siureg[] = { |
| 58 | 1, 1, 1, 1, 1, 1, 1, 1, | 57 | 1, 1, 1, 1, 1, 1, 1, 1, |
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c index d5f5416be310..b724622c3a0b 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/sysdev/mpc8xx_pic.c | |||
| @@ -18,69 +18,45 @@ | |||
| 18 | extern int cpm_get_irq(struct pt_regs *regs); | 18 | extern int cpm_get_irq(struct pt_regs *regs); |
| 19 | 19 | ||
| 20 | static struct irq_domain *mpc8xx_pic_host; | 20 | static struct irq_domain *mpc8xx_pic_host; |
| 21 | #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) | 21 | static unsigned long mpc8xx_cached_irq_mask; |
| 22 | static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; | ||
| 23 | static sysconf8xx_t __iomem *siu_reg; | 22 | static sysconf8xx_t __iomem *siu_reg; |
| 24 | 23 | ||
| 25 | int cpm_get_irq(struct pt_regs *regs); | 24 | static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d) |
| 25 | { | ||
| 26 | return 0x80000000 >> irqd_to_hwirq(d); | ||
| 27 | } | ||
| 26 | 28 | ||
| 27 | static void mpc8xx_unmask_irq(struct irq_data *d) | 29 | static void mpc8xx_unmask_irq(struct irq_data *d) |
| 28 | { | 30 | { |
| 29 | int bit, word; | 31 | mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); |
| 30 | unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); | 32 | out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); |
| 31 | |||
| 32 | bit = irq_nr & 0x1f; | ||
| 33 | word = irq_nr >> 5; | ||
| 34 | |||
| 35 | ppc_cached_irq_mask[word] |= (1 << (31-bit)); | ||
| 36 | out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); | ||
| 37 | } | 33 | } |
| 38 | 34 | ||
| 39 | static void mpc8xx_mask_irq(struct irq_data *d) | 35 | static void mpc8xx_mask_irq(struct irq_data *d) |
| 40 | { | 36 | { |
| 41 | int bit, word; | 37 | mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d); |
| 42 | unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); | 38 | out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); |
| 43 | |||
| 44 | bit = irq_nr & 0x1f; | ||
| 45 | word = irq_nr >> 5; | ||
| 46 | |||
| 47 | ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); | ||
| 48 | out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); | ||
| 49 | } | 39 | } |
| 50 | 40 | ||
| 51 | static void mpc8xx_ack(struct irq_data *d) | 41 | static void mpc8xx_ack(struct irq_data *d) |
| 52 | { | 42 | { |
| 53 | int bit; | 43 | out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d)); |
| 54 | unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); | ||
| 55 | |||
| 56 | bit = irq_nr & 0x1f; | ||
| 57 | out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); | ||
| 58 | } | 44 | } |
| 59 | 45 | ||
| 60 | static void mpc8xx_end_irq(struct irq_data *d) | 46 | static void mpc8xx_end_irq(struct irq_data *d) |
| 61 | { | 47 | { |
| 62 | int bit, word; | 48 | mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); |
| 63 | unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); | 49 | out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); |
| 64 | |||
| 65 | bit = irq_nr & 0x1f; | ||
| 66 | word = irq_nr >> 5; | ||
| 67 | |||
| 68 | ppc_cached_irq_mask[word] |= (1 << (31-bit)); | ||
| 69 | out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); | ||
| 70 | } | 50 | } |
| 71 | 51 | ||
| 72 | static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) | 52 | static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) |
| 73 | { | 53 | { |
| 74 | if (flow_type & IRQ_TYPE_EDGE_FALLING) { | 54 | /* only external IRQ senses are programmable */ |
| 75 | irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); | 55 | if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) { |
| 76 | unsigned int siel = in_be32(&siu_reg->sc_siel); | 56 | unsigned int siel = in_be32(&siu_reg->sc_siel); |
| 77 | 57 | siel |= mpc8xx_irqd_to_bit(d); | |
| 78 | /* only external IRQ senses are programmable */ | 58 | out_be32(&siu_reg->sc_siel, siel); |
| 79 | if ((hw & 1) == 0) { | 59 | __irq_set_handler_locked(d->irq, handle_edge_irq); |
| 80 | siel |= (0x80000000 >> hw); | ||
| 81 | out_be32(&siu_reg->sc_siel, siel); | ||
| 82 | __irq_set_handler_locked(d->irq, handle_edge_irq); | ||
| 83 | } | ||
| 84 | } | 60 | } |
| 85 | return 0; | 61 | return 0; |
| 86 | } | 62 | } |
| @@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct, | |||
| 132 | IRQ_TYPE_EDGE_FALLING, | 108 | IRQ_TYPE_EDGE_FALLING, |
| 133 | }; | 109 | }; |
| 134 | 110 | ||
| 111 | if (intspec[0] > 0x1f) | ||
| 112 | return 0; | ||
| 113 | |||
| 135 | *out_hwirq = intspec[0]; | 114 | *out_hwirq = intspec[0]; |
| 136 | if (intsize > 1 && intspec[1] < 4) | 115 | if (intsize > 1 && intspec[1] < 4) |
| 137 | *out_flags = map_pic_senses[intspec[1]]; | 116 | *out_flags = map_pic_senses[intspec[1]]; |
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index ea5e204e3450..cd1d18db92c6 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c | |||
| @@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void) | |||
| 188 | { | 188 | { |
| 189 | int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); | 189 | int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); |
| 190 | unsigned int irq, virq; | 190 | unsigned int irq, virq; |
| 191 | struct irq_desc *desc; | ||
| 191 | 192 | ||
| 192 | /* If we used to be the default server, move to the new "boot_cpuid" */ | 193 | /* If we used to be the default server, move to the new "boot_cpuid" */ |
| 193 | if (hw_cpu == xics_default_server) | 194 | if (hw_cpu == xics_default_server) |
| @@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void) | |||
| 202 | /* Allow IPIs again... */ | 203 | /* Allow IPIs again... */ |
| 203 | icp_ops->set_priority(DEFAULT_PRIORITY); | 204 | icp_ops->set_priority(DEFAULT_PRIORITY); |
| 204 | 205 | ||
| 205 | for_each_irq(virq) { | 206 | for_each_irq_desc(virq, desc) { |
| 206 | struct irq_desc *desc; | ||
| 207 | struct irq_chip *chip; | 207 | struct irq_chip *chip; |
| 208 | long server; | 208 | long server; |
| 209 | unsigned long flags; | 209 | unsigned long flags; |
| @@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void) | |||
| 212 | /* We can't set affinity on ISA interrupts */ | 212 | /* We can't set affinity on ISA interrupts */ |
| 213 | if (virq < NUM_ISA_INTERRUPTS) | 213 | if (virq < NUM_ISA_INTERRUPTS) |
| 214 | continue; | 214 | continue; |
| 215 | desc = irq_to_desc(virq); | ||
| 216 | /* We only need to migrate enabled IRQS */ | 215 | /* We only need to migrate enabled IRQS */ |
| 217 | if (!desc || !desc->action) | 216 | if (!desc->action) |
| 218 | continue; | 217 | continue; |
| 219 | if (desc->irq_data.domain != xics_host) | 218 | if (desc->irq_data.domain != xics_host) |
| 220 | continue; | 219 | continue; |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 08ebe901bb59..654755a990df 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
| @@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
| 469 | tty = NULL; | 469 | tty = NULL; |
| 470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 470 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
| 471 | if (!ZS_IS_OPEN(uap_a)) { | 471 | if (!ZS_IS_OPEN(uap_a)) { |
| 472 | pmz_debug("ChanA interrupt while open !\n"); | 472 | pmz_debug("ChanA interrupt while not open !\n"); |
| 473 | goto skip_a; | 473 | goto skip_a; |
| 474 | } | 474 | } |
| 475 | write_zsreg(uap_a, R0, RES_H_IUS); | 475 | write_zsreg(uap_a, R0, RES_H_IUS); |
| @@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) | |||
| 493 | spin_lock(&uap_b->port.lock); | 493 | spin_lock(&uap_b->port.lock); |
| 494 | tty = NULL; | 494 | tty = NULL; |
| 495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 495 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
| 496 | if (!ZS_IS_OPEN(uap_a)) { | 496 | if (!ZS_IS_OPEN(uap_b)) { |
| 497 | pmz_debug("ChanB interrupt while open !\n"); | 497 | pmz_debug("ChanB interrupt while not open !\n"); |
| 498 | goto skip_b; | 498 | goto skip_b; |
| 499 | } | 499 | } |
| 500 | write_zsreg(uap_b, R0, RES_H_IUS); | 500 | write_zsreg(uap_b, R0, RES_H_IUS); |
