aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/irq.h4
-rw-r--r--arch/powerpc/kernel/irq.c6
-rw-r--r--arch/powerpc/kernel/machine_kexec.c7
-rw-r--r--arch/powerpc/net/bpf_jit.h8
-rw-r--r--arch/powerpc/net/bpf_jit_64.S108
-rw-r--r--arch/powerpc/net/bpf_jit_comp.c26
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c8
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c2
-rw-r--r--arch/powerpc/platforms/powermac/pic.c6
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig4
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c3
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c61
-rw-r--r--arch/powerpc/sysdev/scom.c1
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c7
14 files changed, 148 insertions, 103 deletions
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
25extern atomic_t ppc_n_lost_interrupts; 21extern 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/irq.c b/arch/powerpc/kernel/irq.c
index 5ec1b2354ca6..43eb74fcedde 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -330,14 +330,10 @@ void migrate_irqs(void)
330 330
331 alloc_cpumask_var(&mask, GFP_KERNEL); 331 alloc_cpumask_var(&mask, GFP_KERNEL);
332 332
333 for_each_irq(irq) { 333 for_each_irq_desc(irq, desc) {
334 struct irq_data *data; 334 struct irq_data *data;
335 struct irq_chip *chip; 335 struct irq_chip *chip;
336 336
337 desc = irq_to_desc(irq);
338 if (!desc)
339 continue;
340
341 data = irq_desc_get_irq_data(desc); 337 data = irq_desc_get_irq_data(desc);
342 if (irqd_is_per_cpu(data)) 338 if (irqd_is_per_cpu(data))
343 continue; 339 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
24void machine_kexec_mask_interrupts(void) { 24void 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/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index af1ab5e9a691..5c3cf2d04e41 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -48,7 +48,13 @@
48/* 48/*
49 * Assembly helpers from arch/powerpc/net/bpf_jit.S: 49 * Assembly helpers from arch/powerpc/net/bpf_jit.S:
50 */ 50 */
51extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; 51#define DECLARE_LOAD_FUNC(func) \
52 extern u8 func[], func##_negative_offset[], func##_positive_offset[]
53
54DECLARE_LOAD_FUNC(sk_load_word);
55DECLARE_LOAD_FUNC(sk_load_half);
56DECLARE_LOAD_FUNC(sk_load_byte);
57DECLARE_LOAD_FUNC(sk_load_byte_msh);
52 58
53#define FUNCTION_DESCR_SIZE 24 59#define FUNCTION_DESCR_SIZE 24
54 60
diff --git a/arch/powerpc/net/bpf_jit_64.S b/arch/powerpc/net/bpf_jit_64.S
index ff4506e85cce..55ba3855a97f 100644
--- a/arch/powerpc/net/bpf_jit_64.S
+++ b/arch/powerpc/net/bpf_jit_64.S
@@ -31,14 +31,13 @@
31 * then branch directly to slow_path_XXX if required. (In fact, could 31 * then branch directly to slow_path_XXX if required. (In fact, could
32 * load a spare GPR with the address of slow_path_generic and pass size 32 * load a spare GPR with the address of slow_path_generic and pass size
33 * as an argument, making the call site a mtlr, li and bllr.) 33 * as an argument, making the call site a mtlr, li and bllr.)
34 *
35 * Technically, the "is addr < 0" check is unnecessary & slowing down
36 * the ABS path, as it's statically checked on generation.
37 */ 34 */
38 .globl sk_load_word 35 .globl sk_load_word
39sk_load_word: 36sk_load_word:
40 cmpdi r_addr, 0 37 cmpdi r_addr, 0
41 blt bpf_error 38 blt bpf_slow_path_word_neg
39 .globl sk_load_word_positive_offset
40sk_load_word_positive_offset:
42 /* Are we accessing past headlen? */ 41 /* Are we accessing past headlen? */
43 subi r_scratch1, r_HL, 4 42 subi r_scratch1, r_HL, 4
44 cmpd r_scratch1, r_addr 43 cmpd r_scratch1, r_addr
@@ -51,7 +50,9 @@ sk_load_word:
51 .globl sk_load_half 50 .globl sk_load_half
52sk_load_half: 51sk_load_half:
53 cmpdi r_addr, 0 52 cmpdi r_addr, 0
54 blt bpf_error 53 blt bpf_slow_path_half_neg
54 .globl sk_load_half_positive_offset
55sk_load_half_positive_offset:
55 subi r_scratch1, r_HL, 2 56 subi r_scratch1, r_HL, 2
56 cmpd r_scratch1, r_addr 57 cmpd r_scratch1, r_addr
57 blt bpf_slow_path_half 58 blt bpf_slow_path_half
@@ -61,7 +62,9 @@ sk_load_half:
61 .globl sk_load_byte 62 .globl sk_load_byte
62sk_load_byte: 63sk_load_byte:
63 cmpdi r_addr, 0 64 cmpdi r_addr, 0
64 blt bpf_error 65 blt bpf_slow_path_byte_neg
66 .globl sk_load_byte_positive_offset
67sk_load_byte_positive_offset:
65 cmpd r_HL, r_addr 68 cmpd r_HL, r_addr
66 ble bpf_slow_path_byte 69 ble bpf_slow_path_byte
67 lbzx r_A, r_D, r_addr 70 lbzx r_A, r_D, r_addr
@@ -69,22 +72,20 @@ sk_load_byte:
69 72
70/* 73/*
71 * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf) 74 * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf)
72 * r_addr is the offset value, already known positive 75 * r_addr is the offset value
73 */ 76 */
74 .globl sk_load_byte_msh 77 .globl sk_load_byte_msh
75sk_load_byte_msh: 78sk_load_byte_msh:
79 cmpdi r_addr, 0
80 blt bpf_slow_path_byte_msh_neg
81 .globl sk_load_byte_msh_positive_offset
82sk_load_byte_msh_positive_offset:
76 cmpd r_HL, r_addr 83 cmpd r_HL, r_addr
77 ble bpf_slow_path_byte_msh 84 ble bpf_slow_path_byte_msh
78 lbzx r_X, r_D, r_addr 85 lbzx r_X, r_D, r_addr
79 rlwinm r_X, r_X, 2, 32-4-2, 31-2 86 rlwinm r_X, r_X, 2, 32-4-2, 31-2
80 blr 87 blr
81 88
82bpf_error:
83 /* Entered with cr0 = lt */
84 li r3, 0
85 /* Generated code will 'blt epilogue', returning 0. */
86 blr
87
88/* Call out to skb_copy_bits: 89/* Call out to skb_copy_bits:
89 * We'll need to back up our volatile regs first; we have 90 * We'll need to back up our volatile regs first; we have
90 * local variable space at r1+(BPF_PPC_STACK_BASIC). 91 * local variable space at r1+(BPF_PPC_STACK_BASIC).
@@ -136,3 +137,84 @@ bpf_slow_path_byte_msh:
136 lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1) 137 lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
137 rlwinm r_X, r_X, 2, 32-4-2, 31-2 138 rlwinm r_X, r_X, 2, 32-4-2, 31-2
138 blr 139 blr
140
141/* Call out to bpf_internal_load_pointer_neg_helper:
142 * We'll need to back up our volatile regs first; we have
143 * local variable space at r1+(BPF_PPC_STACK_BASIC).
144 * Allocate a new stack frame here to remain ABI-compliant in
145 * stashing LR.
146 */
147#define sk_negative_common(SIZE) \
148 mflr r0; \
149 std r0, 16(r1); \
150 /* R3 goes in parameter space of caller's frame */ \
151 std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
152 std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
153 std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
154 stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \
155 /* R3 = r_skb, as passed */ \
156 mr r4, r_addr; \
157 li r5, SIZE; \
158 bl bpf_internal_load_pointer_neg_helper; \
159 /* R3 != 0 on success */ \
160 addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
161 ld r0, 16(r1); \
162 ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
163 ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
164 mtlr r0; \
165 cmpldi r3, 0; \
166 beq bpf_error_slow; /* cr0 = EQ */ \
167 mr r_addr, r3; \
168 ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
169 /* Great success! */
170
171bpf_slow_path_word_neg:
172 lis r_scratch1,-32 /* SKF_LL_OFF */
173 cmpd r_addr, r_scratch1 /* addr < SKF_* */
174 blt bpf_error /* cr0 = LT */
175 .globl sk_load_word_negative_offset
176sk_load_word_negative_offset:
177 sk_negative_common(4)
178 lwz r_A, 0(r_addr)
179 blr
180
181bpf_slow_path_half_neg:
182 lis r_scratch1,-32 /* SKF_LL_OFF */
183 cmpd r_addr, r_scratch1 /* addr < SKF_* */
184 blt bpf_error /* cr0 = LT */
185 .globl sk_load_half_negative_offset
186sk_load_half_negative_offset:
187 sk_negative_common(2)
188 lhz r_A, 0(r_addr)
189 blr
190
191bpf_slow_path_byte_neg:
192 lis r_scratch1,-32 /* SKF_LL_OFF */
193 cmpd r_addr, r_scratch1 /* addr < SKF_* */
194 blt bpf_error /* cr0 = LT */
195 .globl sk_load_byte_negative_offset
196sk_load_byte_negative_offset:
197 sk_negative_common(1)
198 lbz r_A, 0(r_addr)
199 blr
200
201bpf_slow_path_byte_msh_neg:
202 lis r_scratch1,-32 /* SKF_LL_OFF */
203 cmpd r_addr, r_scratch1 /* addr < SKF_* */
204 blt bpf_error /* cr0 = LT */
205 .globl sk_load_byte_msh_negative_offset
206sk_load_byte_msh_negative_offset:
207 sk_negative_common(1)
208 lbz r_X, 0(r_addr)
209 rlwinm r_X, r_X, 2, 32-4-2, 31-2
210 blr
211
212bpf_error_slow:
213 /* fabricate a cr0 = lt */
214 li r_scratch1, -1
215 cmpdi r_scratch1, 0
216bpf_error:
217 /* Entered with cr0 = lt */
218 li r3, 0
219 /* Generated code will 'blt epilogue', returning 0. */
220 blr
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 73619d3aeb6c..2dc8b1484845 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
127 PPC_BLR(); 127 PPC_BLR();
128} 128}
129 129
130#define CHOOSE_LOAD_FUNC(K, func) \
131 ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
132
130/* Assemble the body code between the prologue & epilogue. */ 133/* Assemble the body code between the prologue & epilogue. */
131static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, 134static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
132 struct codegen_context *ctx, 135 struct codegen_context *ctx,
@@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
391 394
392 /*** Absolute loads from packet header/data ***/ 395 /*** Absolute loads from packet header/data ***/
393 case BPF_S_LD_W_ABS: 396 case BPF_S_LD_W_ABS:
394 func = sk_load_word; 397 func = CHOOSE_LOAD_FUNC(K, sk_load_word);
395 goto common_load; 398 goto common_load;
396 case BPF_S_LD_H_ABS: 399 case BPF_S_LD_H_ABS:
397 func = sk_load_half; 400 func = CHOOSE_LOAD_FUNC(K, sk_load_half);
398 goto common_load; 401 goto common_load;
399 case BPF_S_LD_B_ABS: 402 case BPF_S_LD_B_ABS:
400 func = sk_load_byte; 403 func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
401 common_load: 404 common_load:
402 /* 405 /* Load from [K]. */
403 * Load from [K]. Reference with the (negative)
404 * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
405 */
406 ctx->seen |= SEEN_DATAREF; 406 ctx->seen |= SEEN_DATAREF;
407 if ((int)K < 0)
408 return -ENOTSUPP;
409 PPC_LI64(r_scratch1, func); 407 PPC_LI64(r_scratch1, func);
410 PPC_MTLR(r_scratch1); 408 PPC_MTLR(r_scratch1);
411 PPC_LI32(r_addr, K); 409 PPC_LI32(r_addr, K);
@@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
429 common_load_ind: 427 common_load_ind:
430 /* 428 /*
431 * Load from [X + K]. Negative offsets are tested for 429 * Load from [X + K]. Negative offsets are tested for
432 * in the helper functions, and result in a 'ret 0'. 430 * in the helper functions.
433 */ 431 */
434 ctx->seen |= SEEN_DATAREF | SEEN_XREG; 432 ctx->seen |= SEEN_DATAREF | SEEN_XREG;
435 PPC_LI64(r_scratch1, func); 433 PPC_LI64(r_scratch1, func);
@@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
443 break; 441 break;
444 442
445 case BPF_S_LDX_B_MSH: 443 case BPF_S_LDX_B_MSH:
446 /* 444 func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
447 * x86 version drops packet (RET 0) when K<0, whereas
448 * interpreter does allow K<0 (__load_pointer, special
449 * ancillary data). common_load returns ENOTSUPP if K<0,
450 * so we fall back to interpreter & filter works.
451 */
452 func = sk_load_byte_msh;
453 goto common_load; 445 goto common_load;
454 break; 446 break;
455 447
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
58static DEFINE_RAW_SPINLOCK(pmac_pic_lock); 58static 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 */
61static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; 61static DECLARE_BITMAP(ppc_lost_interrupts, 128);
62static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; 62static DECLARE_BITMAP(ppc_cached_irq_mask, 128);
63static int pmac_irq_cascade = -1; 63static int pmac_irq_cascade = -1;
64static struct irq_domain *pmac_pic_host; 64static 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
32config EEH 32config 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
37config PSERIES_MSI 37config 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 @@
51static intctl_cpm2_t __iomem *cpm2_intctl; 51static intctl_cpm2_t __iomem *cpm2_intctl;
52 52
53static struct irq_domain *cpm2_pic_host; 53static struct irq_domain *cpm2_pic_host;
54#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 54static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */
55static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
56 55
57static const u_char irq_to_siureg[] = { 56static 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 @@
18extern int cpm_get_irq(struct pt_regs *regs); 18extern int cpm_get_irq(struct pt_regs *regs);
19 19
20static struct irq_domain *mpc8xx_pic_host; 20static struct irq_domain *mpc8xx_pic_host;
21#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) 21static unsigned long mpc8xx_cached_irq_mask;
22static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
23static sysconf8xx_t __iomem *siu_reg; 22static sysconf8xx_t __iomem *siu_reg;
24 23
25int cpm_get_irq(struct pt_regs *regs); 24static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d)
25{
26 return 0x80000000 >> irqd_to_hwirq(d);
27}
26 28
27static void mpc8xx_unmask_irq(struct irq_data *d) 29static 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
39static void mpc8xx_mask_irq(struct irq_data *d) 35static 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
51static void mpc8xx_ack(struct irq_data *d) 41static 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
60static void mpc8xx_end_irq(struct irq_data *d) 46static 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
72static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) 52static 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/scom.c b/arch/powerpc/sysdev/scom.c
index 49a3ece1c6b3..702256a1ca11 100644
--- a/arch/powerpc/sysdev/scom.c
+++ b/arch/powerpc/sysdev/scom.c
@@ -22,6 +22,7 @@
22#include <linux/debugfs.h> 22#include <linux/debugfs.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <asm/debug.h>
25#include <asm/prom.h> 26#include <asm/prom.h>
26#include <asm/scom.h> 27#include <asm/scom.h>
27 28
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;