aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-30 14:07:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-30 14:07:53 -0400
commitfbf717629ff03f110f177d244933276423f99a27 (patch)
treea51c1d4cf8d1ce5684fb704996a8b60ee97ee9de
parent84e92ef4f7addba97ff54810d1602b47d7c00ca4 (diff)
parent810b4de25e53459323ff48957b0162b48d6cbd57 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc fixes from Benjamin Herrenschmidt: "Here are a handful more fixes for powerpc. The irq stuff are all regression fixes, and Gavin's patch is a simple compile fix." * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: tty/serial/pmac_zilog: Fix "nobody cared" IRQ message powerpc/pseries: Rivet CONFIG_EEH for pSeries platform powerpc/irqdomain: Fix broken NR_IRQ references powerpc/8xx: Fix NR_IRQ bugs and refactor 8xx interrupt controller
-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/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/xics/xics-common.c7
-rw-r--r--drivers/tty/serial/pmac_zilog.c6
11 files changed, 39 insertions, 75 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/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/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);