aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c3
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c61
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c7
3 files changed, 24 insertions, 47 deletions
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/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;