From db283aa4b3dfbbfdd09e27689589d8d190b300aa Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 10 May 2012 12:58:24 +1000 Subject: [PATCH] --- yaml --- r: 305375 b: refs/heads/master c: b48d441a8ab8a89bd32a3a981a05b8a26905dfc7 h: refs/heads/master i: 305373: b47a4c46e206cc54abbf40844295ca9d73e0617e 305371: 833bd7f40b62bbffcf4c075400173ab17300c632 305367: 402e239af02a81594609a0c22ccdb209b87e6013 305359: 2bc56929281db5698e1fbbf3affc29f54b58665e 305343: 9ae7c620880643258e6ca2e38d723e16c068f8fd v: v3 --- [refs] | 2 +- .../arch/powerpc/include/asm/exception-64s.h | 7 --- trunk/arch/powerpc/include/asm/irq.h | 4 -- trunk/arch/powerpc/include/asm/thread_info.h | 1 - trunk/arch/powerpc/kernel/entry_64.S | 18 ------ trunk/arch/powerpc/kernel/exceptions-64s.S | 2 +- trunk/arch/powerpc/kernel/irq.c | 14 +++-- trunk/arch/powerpc/kernel/machine_kexec.c | 7 +-- trunk/arch/powerpc/kernel/traps.c | 10 ++- trunk/arch/powerpc/platforms/cell/axon_msi.c | 8 +-- .../powerpc/platforms/cell/beat_interrupt.c | 2 +- trunk/arch/powerpc/platforms/powermac/pic.c | 6 +- trunk/arch/powerpc/platforms/pseries/Kconfig | 4 +- trunk/arch/powerpc/sysdev/cpm2_pic.c | 3 +- trunk/arch/powerpc/sysdev/mpc8xx_pic.c | 61 ++++++------------- trunk/arch/powerpc/sysdev/xics/xics-common.c | 7 +-- trunk/drivers/macintosh/windfarm_pm91.c | 2 +- trunk/drivers/macintosh/windfarm_smu_sat.c | 6 +- trunk/drivers/tty/serial/pmac_zilog.c | 6 +- 19 files changed, 60 insertions(+), 110 deletions(-) diff --git a/[refs] b/[refs] index 901a007577ec..622df2f3b928 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dce4c92d69db53ed0e09191428f17ac9a14ad248 +refs/heads/master: b48d441a8ab8a89bd32a3a981a05b8a26905dfc7 diff --git a/trunk/arch/powerpc/include/asm/exception-64s.h b/trunk/arch/powerpc/include/asm/exception-64s.h index 548da3aa0a30..d58fc4e4149c 100644 --- a/trunk/arch/powerpc/include/asm/exception-64s.h +++ b/trunk/arch/powerpc/include/asm/exception-64s.h @@ -288,13 +288,6 @@ label##_hv: \ /* Exception addition: Hard disable interrupts */ #define DISABLE_INTS SOFT_DISABLE_INTS(r10,r11) -/* Exception addition: Keep interrupt state */ -#define ENABLE_INTS \ - ld r11,PACAKMSR(r13); \ - ld r12,_MSR(r1); \ - rlwimi r11,r12,0,MSR_EE; \ - mtmsrd r11,1 - #define ADD_NVGPRS \ bl .save_nvgprs diff --git a/trunk/arch/powerpc/include/asm/irq.h b/trunk/arch/powerpc/include/asm/irq.h index e648af92ced1..0e40843a1c6e 100644 --- a/trunk/arch/powerpc/include/asm/irq.h +++ b/trunk/arch/powerpc/include/asm/irq.h @@ -18,10 +18,6 @@ #include -/* Define a way to iterate across irqs. */ -#define for_each_irq(i) \ - for ((i) = 0; (i) < NR_IRQS; ++(i)) - extern atomic_t ppc_n_lost_interrupts; /* This number is used when no interrupt has been assigned */ diff --git a/trunk/arch/powerpc/include/asm/thread_info.h b/trunk/arch/powerpc/include/asm/thread_info.h index 4a741c7efd02..bcebc7571791 100644 --- a/trunk/arch/powerpc/include/asm/thread_info.h +++ b/trunk/arch/powerpc/include/asm/thread_info.h @@ -126,7 +126,6 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NOERROR (1<irq_happened, so we need to resync this. */ void restore_interrupts(void) { - if (irqs_disabled()) + if (irqs_disabled()) { + local_paca->irq_happened |= PACA_IRQ_HARD_DIS; local_irq_enable(); + } else + __hard_irq_enable(); } #endif /* CONFIG_PPC64 */ @@ -330,14 +336,10 @@ void migrate_irqs(void) alloc_cpumask_var(&mask, GFP_KERNEL); - for_each_irq(irq) { + for_each_irq_desc(irq, desc) { struct irq_data *data; struct irq_chip *chip; - desc = irq_to_desc(irq); - if (!desc) - continue; - data = irq_desc_get_irq_data(desc); if (irqd_is_per_cpu(data)) continue; diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index c957b1202bdc..5df777794403 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -23,14 +23,11 @@ void machine_kexec_mask_interrupts(void) { unsigned int i; + struct irq_desc *desc; - for_each_irq(i) { - struct irq_desc *desc = irq_to_desc(i); + for_each_irq_desc(i, desc) { struct irq_chip *chip; - if (!desc) - continue; - chip = irq_desc_get_chip(desc); if (!chip) continue; diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 6aa0c663e247..158972341a2d 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -248,7 +248,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) addr, regs->nip, regs->link, code); } - if (!arch_irq_disabled_regs(regs)) + if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs)) local_irq_enable(); memset(&info, 0, sizeof(info)); @@ -1019,7 +1019,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) return; } - local_irq_enable(); + /* We restore the interrupt state now */ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); #ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, @@ -1069,6 +1071,10 @@ void alignment_exception(struct pt_regs *regs) { int sig, code, fixed = 0; + /* We restore the interrupt state now */ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); + /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) fixed = fix_alignment(regs); diff --git a/trunk/arch/powerpc/platforms/cell/axon_msi.c b/trunk/arch/powerpc/platforms/cell/axon_msi.c index d09f3e8e6867..85825b5401e5 100644 --- a/trunk/arch/powerpc/platforms/cell/axon_msi.c +++ b/trunk/arch/powerpc/platforms/cell/axon_msi.c @@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) pr_devel("axon_msi: woff %x roff %x msi %x\n", write_offset, msic->read_offset, msi); - if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) { + if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { generic_handle_irq(msi); msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); } else { @@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (rc) return rc; - /* We rely on being able to stash a virq in a u16 */ - BUILD_BUG_ON(NR_IRQS > 65536); - list_for_each_entry(entry, &dev->msi_list, list) { virq = irq_create_direct_mapping(msic->irq_domain); if (virq == NO_IRQ) { @@ -392,7 +389,8 @@ static int axon_msi_probe(struct platform_device *device) } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); - msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); + /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ + msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); if (!msic->irq_domain) { printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", dn->full_name); diff --git a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c index f9a48af335cb..8c6dc42ecf65 100644 --- a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c @@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void) { int i; - for (i = 1; i < NR_IRQS; i++) + for (i = 1; i < nr_irqs; i++) beat_destruct_irq_plug(i); } diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 66ad93de1d55..c4e630576ff2 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -57,9 +57,9 @@ static int max_real_irqs; static DEFINE_RAW_SPINLOCK(pmac_pic_lock); -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +/* The max irq number this driver deals with is 128; see max_irqs */ +static DECLARE_BITMAP(ppc_lost_interrupts, 128); +static DECLARE_BITMAP(ppc_cached_irq_mask, 128); static int pmac_irq_cascade = -1; static struct irq_domain *pmac_pic_host; diff --git a/trunk/arch/powerpc/platforms/pseries/Kconfig b/trunk/arch/powerpc/platforms/pseries/Kconfig index aadbe4f6d537..178a5f300bc9 100644 --- a/trunk/arch/powerpc/platforms/pseries/Kconfig +++ b/trunk/arch/powerpc/platforms/pseries/Kconfig @@ -30,9 +30,9 @@ config PPC_SPLPAR two or more partitions. config EEH - bool "PCI Extended Error Handling (EEH)" if EXPERT + bool depends on PPC_PSERIES && PCI - default y if !EXPERT + default y config PSERIES_MSI bool diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.c b/trunk/arch/powerpc/sysdev/cpm2_pic.c index d3be961e2ae7..10386b676d87 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.c +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.c @@ -51,8 +51,7 @@ static intctl_cpm2_t __iomem *cpm2_intctl; static struct irq_domain *cpm2_pic_host; -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */ static const u_char irq_to_siureg[] = { 1, 1, 1, 1, 1, 1, 1, 1, diff --git a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c index d5f5416be310..b724622c3a0b 100644 --- a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c @@ -18,69 +18,45 @@ extern int cpm_get_irq(struct pt_regs *regs); static struct irq_domain *mpc8xx_pic_host; -#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +static unsigned long mpc8xx_cached_irq_mask; static sysconf8xx_t __iomem *siu_reg; -int cpm_get_irq(struct pt_regs *regs); +static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d) +{ + return 0x80000000 >> irqd_to_hwirq(d); +} static void mpc8xx_unmask_irq(struct irq_data *d) { - int bit, word; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] |= (1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); + mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); } static void mpc8xx_mask_irq(struct irq_data *d) { - int bit, word; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); + mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); } static void mpc8xx_ack(struct irq_data *d) { - int bit; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); + out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d)); } static void mpc8xx_end_irq(struct irq_data *d) { - int bit, word; - unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); - - bit = irq_nr & 0x1f; - word = irq_nr >> 5; - - ppc_cached_irq_mask[word] |= (1 << (31-bit)); - out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); + mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); } static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) { - if (flow_type & IRQ_TYPE_EDGE_FALLING) { - irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); + /* only external IRQ senses are programmable */ + if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) { unsigned int siel = in_be32(&siu_reg->sc_siel); - - /* only external IRQ senses are programmable */ - if ((hw & 1) == 0) { - siel |= (0x80000000 >> hw); - out_be32(&siu_reg->sc_siel, siel); - __irq_set_handler_locked(d->irq, handle_edge_irq); - } + siel |= mpc8xx_irqd_to_bit(d); + out_be32(&siu_reg->sc_siel, siel); + __irq_set_handler_locked(d->irq, handle_edge_irq); } return 0; } @@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct, IRQ_TYPE_EDGE_FALLING, }; + if (intspec[0] > 0x1f) + return 0; + *out_hwirq = intspec[0]; if (intsize > 1 && intspec[1] < 4) *out_flags = map_pic_senses[intspec[1]]; diff --git a/trunk/arch/powerpc/sysdev/xics/xics-common.c b/trunk/arch/powerpc/sysdev/xics/xics-common.c index ea5e204e3450..cd1d18db92c6 100644 --- a/trunk/arch/powerpc/sysdev/xics/xics-common.c +++ b/trunk/arch/powerpc/sysdev/xics/xics-common.c @@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void) { int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); unsigned int irq, virq; + struct irq_desc *desc; /* If we used to be the default server, move to the new "boot_cpuid" */ if (hw_cpu == xics_default_server) @@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void) /* Allow IPIs again... */ icp_ops->set_priority(DEFAULT_PRIORITY); - for_each_irq(virq) { - struct irq_desc *desc; + for_each_irq_desc(virq, desc) { struct irq_chip *chip; long server; unsigned long flags; @@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void) /* We can't set affinity on ISA interrupts */ if (virq < NUM_ISA_INTERRUPTS) continue; - desc = irq_to_desc(virq); /* We only need to migrate enabled IRQS */ - if (!desc || !desc->action) + if (!desc->action) continue; if (desc->irq_data.domain != xics_host) continue; diff --git a/trunk/drivers/macintosh/windfarm_pm91.c b/trunk/drivers/macintosh/windfarm_pm91.c index e18002bcc1c3..7653603cb00e 100644 --- a/trunk/drivers/macintosh/windfarm_pm91.c +++ b/trunk/drivers/macintosh/windfarm_pm91.c @@ -234,7 +234,7 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) return; } - rc = wf_sensor_get(&sensor_cpu_power, &power); + rc = wf_sensor_get(sensor_cpu_power, &power); if (rc) { printk(KERN_WARNING "windfarm: CPU power sensor error %d\n", rc); diff --git a/trunk/drivers/macintosh/windfarm_smu_sat.c b/trunk/drivers/macintosh/windfarm_smu_sat.c index 72dfe191235b..426e810233d7 100644 --- a/trunk/drivers/macintosh/windfarm_smu_sat.c +++ b/trunk/drivers/macintosh/windfarm_smu_sat.c @@ -204,7 +204,7 @@ static struct wf_sensor_ops wf_sat_ops = { static int wf_sat_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct device_node *dev = client->dev.platform_data; + struct device_node *dev = client->dev.of_node; struct wf_sat *sat; struct wf_sat_sensor *sens; const u32 *reg; @@ -287,7 +287,7 @@ static int wf_sat_probe(struct i2c_client *client, sens->sat = sat; sens->sens.ops = &wf_sat_ops; sens->sens.name = (char *) (sens + 1); - snprintf(sens->sens.name, 16, "%s-%d", name, cpu); + snprintf((char *)sens->sens.name, 16, "%s-%d", name, cpu); if (wf_register_sensor(&sens->sens)) kfree(sens); @@ -314,7 +314,7 @@ static int wf_sat_probe(struct i2c_client *client, sens->sat = sat; sens->sens.ops = &wf_sat_ops; sens->sens.name = (char *) (sens + 1); - snprintf(sens->sens.name, 16, "cpu-power-%d", cpu); + snprintf((char *)sens->sens.name, 16, "cpu-power-%d", cpu); if (wf_register_sensor(&sens->sens)) kfree(sens); diff --git a/trunk/drivers/tty/serial/pmac_zilog.c b/trunk/drivers/tty/serial/pmac_zilog.c index 08ebe901bb59..654755a990df 100644 --- a/trunk/drivers/tty/serial/pmac_zilog.c +++ b/trunk/drivers/tty/serial/pmac_zilog.c @@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) tty = NULL; if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { if (!ZS_IS_OPEN(uap_a)) { - pmz_debug("ChanA interrupt while open !\n"); + pmz_debug("ChanA interrupt while not open !\n"); goto skip_a; } write_zsreg(uap_a, R0, RES_H_IUS); @@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) spin_lock(&uap_b->port.lock); tty = NULL; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { - if (!ZS_IS_OPEN(uap_a)) { - pmz_debug("ChanB interrupt while open !\n"); + if (!ZS_IS_OPEN(uap_b)) { + pmz_debug("ChanB interrupt while not open !\n"); goto skip_b; } write_zsreg(uap_b, R0, RES_H_IUS);