diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/cevt-bcm1480.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-ds1287.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-gt641xx.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-r4k.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-sb1250.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-smtc.c | 3 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-txx9.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 8 | ||||
-rw-r--r-- | arch/mips/kernel/head.S | 1 | ||||
-rw-r--r-- | arch/mips/kernel/i8253.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/irq-gic.c | 114 | ||||
-rw-r--r-- | arch/mips/kernel/linux32.c | 6 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-o32.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 34 | ||||
-rw-r--r-- | arch/mips/kernel/spram.c | 5 | ||||
-rw-r--r-- | arch/mips/kernel/vpe.c | 2 |
16 files changed, 94 insertions, 97 deletions
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c index e02f79b1eb5..bfea327c636 100644 --- a/arch/mips/kernel/cevt-bcm1480.c +++ b/arch/mips/kernel/cevt-bcm1480.c @@ -144,7 +144,7 @@ void __cpuinit sb1480_clockevent_init(void) bcm1480_unmask_irq(cpu, irq); action->handler = sibyte_counter_handler; - action->flags = IRQF_DISABLED | IRQF_PERCPU; + action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER; action->name = name; action->dev_id = cd; diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c index 6996da4d74a..00a4da277cb 100644 --- a/arch/mips/kernel/cevt-ds1287.c +++ b/arch/mips/kernel/cevt-ds1287.c @@ -107,7 +107,7 @@ static irqreturn_t ds1287_interrupt(int irq, void *dev_id) static struct irqaction ds1287_irqaction = { .handler = ds1287_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, .name = "ds1287", }; diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c index 92351e00ae0..f5d265eb6ea 100644 --- a/arch/mips/kernel/cevt-gt641xx.c +++ b/arch/mips/kernel/cevt-gt641xx.c @@ -113,7 +113,7 @@ static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id) static struct irqaction gt641xx_timer0_irqaction = { .handler = gt641xx_timer0_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, .name = "gt641xx_timer0", }; diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 2652362ce04..b469ad05d52 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -83,7 +83,7 @@ out: struct irqaction c0_compare_irqaction = { .handler = c0_compare_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, .name = "timer", }; diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c index ac5903d1b20..da78eeaea6e 100644 --- a/arch/mips/kernel/cevt-sb1250.c +++ b/arch/mips/kernel/cevt-sb1250.c @@ -143,7 +143,7 @@ void __cpuinit sb1250_clockevent_init(void) sb1250_unmask_irq(cpu, irq); action->handler = sibyte_counter_handler; - action->flags = IRQF_DISABLED | IRQF_PERCPU; + action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER; action->name = name; action->dev_id = cd; diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c index 98bd7de7577..b102e4f1630 100644 --- a/arch/mips/kernel/cevt-smtc.c +++ b/arch/mips/kernel/cevt-smtc.c @@ -173,11 +173,12 @@ void smtc_distribute_timer(int vpe) unsigned int mtflags; int cpu; struct clock_event_device *cd; - unsigned long nextstamp = 0L; + unsigned long nextstamp; unsigned long reference; repeat: + nextstamp = 0L; for_each_online_cpu(cpu) { /* * Find virtual CPUs within the current VPE who have diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c index 0037f21baf0..218ee6bda93 100644 --- a/arch/mips/kernel/cevt-txx9.c +++ b/arch/mips/kernel/cevt-txx9.c @@ -146,7 +146,7 @@ static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id) static struct irqaction txx9tmr_irq = { .handler = txx9tmr_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU, + .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER, .name = "txx9tmr", .dev_id = &txx9_clock_event_device, }; diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index f709657e4dc..7a51866068a 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -23,7 +23,7 @@ #include <asm/mipsregs.h> #include <asm/system.h> #include <asm/watch.h> - +#include <asm/spram.h> /* * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, * the implementation of the "wait" feature differs between CPU families. This @@ -711,12 +711,6 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c) mips_probe_watch_registers(c); } -#ifdef CONFIG_CPU_MIPSR2 -extern void spram_config(void); -#else -static inline void spram_config(void) {} -#endif - static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) { decode_configs(c); diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 531ce7b1612..ea695d9605e 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -191,6 +191,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point /* Set the SP after an empty pt_regs. */ PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE PTR_ADDU sp, $28 + back_to_back_c0_hazard set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index f7d8d5d0ddb..ed5c441615e 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -98,7 +98,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING, + .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, .name = "timer" }; diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index d2072cd3859..b181f2f0ea8 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c @@ -14,38 +14,23 @@ static unsigned long _gic_base; -static unsigned int _irqbase, _mapsize, numvpes, numintrs; -static struct gic_intr_map *_intrmap; +static unsigned int _irqbase; +static unsigned int gic_irq_flags[GIC_NUM_INTRS]; +#define GIC_IRQ_FLAG_EDGE 0x0001 -static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; +struct gic_pcpu_mask pcpu_masks[NR_CPUS]; static struct gic_pending_regs pending_regs[NR_CPUS]; static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; -#define gic_wedgeb2bok 0 /* - * Can GIC handle b2b writes to wedge register? - */ -#if gic_wedgeb2bok == 0 -static DEFINE_SPINLOCK(gic_wedgeb2b_lock); -#endif - void gic_send_ipi(unsigned int intr) { -#if gic_wedgeb2bok == 0 - unsigned long flags; -#endif pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__, read_c0_status()); - if (!gic_wedgeb2bok) - spin_lock_irqsave(&gic_wedgeb2b_lock, flags); GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); - if (!gic_wedgeb2bok) { - (void) GIC_REG(SHARED, GIC_SH_CONFIG); - spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags); - } } /* This is Malta specific and needs to be exported */ -static void vpe_local_setup(unsigned int numvpes) +static void __init vpe_local_setup(unsigned int numvpes) { int i; unsigned long timer_interrupt = 5, perf_interrupt = 5; @@ -105,44 +90,34 @@ unsigned int gic_get_int(void) static unsigned int gic_irq_startup(unsigned int irq) { - pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_SET_INTR_MASK(irq, 1); + pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); + GIC_SET_INTR_MASK(irq); return 0; } static void gic_irq_ack(unsigned int irq) { -#if gic_wedgeb2bok == 0 - unsigned long flags; -#endif - pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_CLR_INTR_MASK(irq, 1); + pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); + GIC_CLR_INTR_MASK(irq); - if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) { - if (!gic_wedgeb2bok) - spin_lock_irqsave(&gic_wedgeb2b_lock, flags); + if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE) GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); - if (!gic_wedgeb2bok) { - (void) GIC_REG(SHARED, GIC_SH_CONFIG); - spin_unlock_irqrestore(&gic_wedgeb2b_lock, flags); - } - } } static void gic_mask_irq(unsigned int irq) { - pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_CLR_INTR_MASK(irq, 1); + pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); + GIC_CLR_INTR_MASK(irq); } static void gic_unmask_irq(unsigned int irq) { - pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); irq -= _irqbase; - GIC_SET_INTR_MASK(irq, 1); + pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); + GIC_SET_INTR_MASK(irq); } #ifdef CONFIG_SMP @@ -155,9 +130,8 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) unsigned long flags; int i; - pr_debug(KERN_DEBUG "%s called\n", __func__); irq -= _irqbase; - + pr_debug(KERN_DEBUG "%s(%d) called\n", __func__, irq); cpumask_and(&tmp, cpumask, cpu_online_mask); if (cpus_empty(tmp)) return -1; @@ -168,13 +142,6 @@ static int gic_set_affinity(unsigned int irq, const struct cpumask *cpumask) /* Re-route this IRQ */ GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); - /* - * FIXME: assumption that _intrmap is ordered and has no holes - */ - - /* Update the intr_map */ - _intrmap[irq].cpunum = first_cpu(tmp); - /* Update the pcpu_masks */ for (i = 0; i < NR_CPUS; i++) clear_bit(irq, pcpu_masks[i].pcpu_mask); @@ -201,8 +168,9 @@ static struct irq_chip gic_irq_controller = { #endif }; -static void __init setup_intr(unsigned int intr, unsigned int cpu, - unsigned int pin, unsigned int polarity, unsigned int trigtype) +static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, + unsigned int pin, unsigned int polarity, unsigned int trigtype, + unsigned int flags) { /* Setup Intr to Pin mapping */ if (pin & GIC_MAP_TO_NMI_MSK) { @@ -227,38 +195,43 @@ static void __init setup_intr(unsigned int intr, unsigned int cpu, GIC_SET_TRIGGER(intr, trigtype); /* Init Intr Masks */ - GIC_SET_INTR_MASK(intr, 0); + GIC_CLR_INTR_MASK(intr); + /* Initialise per-cpu Interrupt software masks */ + if (flags & GIC_FLAG_IPI) + set_bit(intr, pcpu_masks[cpu].pcpu_mask); + if (flags & GIC_FLAG_TRANSPARENT) + GIC_SET_INTR_MASK(intr); + if (trigtype == GIC_TRIG_EDGE) + gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE; } -static void __init gic_basic_init(void) +static void __init gic_basic_init(int numintrs, int numvpes, + struct gic_intr_map *intrmap, int mapsize) { unsigned int i, cpu; /* Setup defaults */ - for (i = 0; i < GIC_NUM_INTRS; i++) { + for (i = 0; i < numintrs; i++) { GIC_SET_POLARITY(i, GIC_POL_POS); GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); - GIC_SET_INTR_MASK(i, 0); + GIC_CLR_INTR_MASK(i); + if (i < GIC_NUM_INTRS) + gic_irq_flags[i] = 0; } /* Setup specifics */ - for (i = 0; i < _mapsize; i++) { - cpu = _intrmap[i].cpunum; + for (i = 0; i < mapsize; i++) { + cpu = intrmap[i].cpunum; if (cpu == X) continue; - - if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 && - _intrmap[i].ipiflag == 0) + if (cpu == 0 && i != 0 && intrmap[i].flags == 0) continue; - - setup_intr(_intrmap[i].intrnum, - _intrmap[i].cpunum, - _intrmap[i].pin, - _intrmap[i].polarity, - _intrmap[i].trigtype); - /* Initialise per-cpu Interrupt software masks */ - if (_intrmap[i].ipiflag) - set_bit(_intrmap[i].intrnum, pcpu_masks[cpu].pcpu_mask); + gic_setup_intr(i, + intrmap[i].cpunum, + intrmap[i].pin, + intrmap[i].polarity, + intrmap[i].trigtype, + intrmap[i].flags); } vpe_local_setup(numvpes); @@ -273,12 +246,11 @@ void __init gic_init(unsigned long gic_base_addr, unsigned int irqbase) { unsigned int gicconfig; + int numvpes, numintrs; _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, gic_addrspace_size); _irqbase = irqbase; - _intrmap = intr_map; - _mapsize = intr_map_size; GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> @@ -290,5 +262,5 @@ void __init gic_init(unsigned long gic_base_addr, pr_debug("%s called\n", __func__); - gic_basic_init(); + gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); } diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 6242bc68add..b77fefaff9d 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -428,3 +428,9 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); } + +asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf, + size_t len) +{ + return sys_lookup_dcookie(merge_64(a0, a1), buf, len); +} diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index d0eff53d7cb..23b842be83e 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -450,7 +450,7 @@ sys_call_table: PTR sys_io_submit PTR sys_io_cancel /* 4245 */ PTR sys_exit_group - PTR sys_lookup_dcookie + PTR sys32_lookup_dcookie PTR sys_epoll_create PTR sys_epoll_ctl PTR sys_epoll_wait /* 4250 */ @@ -505,7 +505,7 @@ sys_call_table: PTR sys_fchmodat PTR sys_faccessat /* 4300 */ PTR compat_sys_pselect6 - PTR sys_ppoll + PTR compat_sys_ppoll PTR sys_unshare PTR sys_splice PTR sys32_sync_file_range /* 4305 */ diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 4d181df44a4..24630fd8ef6 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -75,7 +75,6 @@ unsigned long irq_hwmask[NR_IRQS]; asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; - /* * Number of InterProcessor Interrupt (IPI) message buffers to allocate */ @@ -388,6 +387,7 @@ void smtc_prepare_cpus(int cpus) IPIQ[i].head = IPIQ[i].tail = NULL; spin_lock_init(&IPIQ[i].lock); IPIQ[i].depth = 0; + IPIQ[i].resched_flag = 0; /* No reschedules queued initially */ } /* cpu_data index starts at zero */ @@ -741,11 +741,24 @@ void smtc_forward_irq(unsigned int irq) static void smtc_ipi_qdump(void) { int i; + struct smtc_ipi *temp; for (i = 0; i < NR_CPUS ;i++) { - printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n", + pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n", i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail, IPIQ[i].depth); + temp = IPIQ[i].head; + + while (temp != IPIQ[i].tail) { + pr_debug("%d %d %d: ", temp->type, temp->dest, + (int)temp->arg); +#ifdef SMTC_IPI_DEBUG + pr_debug("%u %lu\n", temp->sender, temp->stamp); +#else + pr_debug("\n"); +#endif + temp = temp->flink; + } } } @@ -784,11 +797,16 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) int mtflags; unsigned long tcrestart; extern void r4k_wait_irqoff(void), __pastwait(void); + int set_resched_flag = (type == LINUX_SMP_IPI && + action == SMP_RESCHEDULE_YOURSELF); if (cpu == smp_processor_id()) { printk("Cannot Send IPI to self!\n"); return; } + if (set_resched_flag && IPIQ[cpu].resched_flag != 0) + return; /* There is a reschedule queued already */ + /* Set up a descriptor, to be delivered either promptly or queued */ pipi = smtc_ipi_dq(&freeIPIq); if (pipi == NULL) { @@ -801,6 +819,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) pipi->dest = cpu; if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { /* If not on same VPE, enqueue and send cross-VPE interrupt */ + IPIQ[cpu].resched_flag |= set_resched_flag; smtc_ipi_nq(&IPIQ[cpu], pipi); LOCK_CORE_PRA(); settc(cpu_data[cpu].tc_id); @@ -847,6 +866,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) */ write_tc_c0_tchalt(0); UNLOCK_CORE_PRA(); + IPIQ[cpu].resched_flag |= set_resched_flag; smtc_ipi_nq(&IPIQ[cpu], pipi); } else { postdirect: @@ -996,12 +1016,15 @@ void deferred_smtc_ipi(void) * already enabled. */ local_irq_save(flags); - spin_lock(&q->lock); pipi = __smtc_ipi_dq(q); spin_unlock(&q->lock); - if (pipi != NULL) + if (pipi != NULL) { + if (pipi->type == LINUX_SMP_IPI && + (int)pipi->arg == SMP_RESCHEDULE_YOURSELF) + IPIQ[cpu].resched_flag = 0; ipi_decode(pipi); + } /* * The use of the __raw_local restore isn't * as obviously necessary here as in smtc_ipi_replay(), @@ -1082,6 +1105,9 @@ static irqreturn_t ipi_interrupt(int irq, void *dev_idm) * with interrupts off */ local_irq_save(flags); + if (pipi->type == LINUX_SMP_IPI && + (int)pipi->arg == SMP_RESCHEDULE_YOURSELF) + IPIQ[cpu].resched_flag = 0; ipi_decode(pipi); local_irq_restore(flags); } diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c index 6ddb507a87e..1821d12a641 100644 --- a/arch/mips/kernel/spram.c +++ b/arch/mips/kernel/spram.c @@ -13,7 +13,6 @@ #include <linux/ptrace.h> #include <linux/stddef.h> -#include <asm/cpu.h> #include <asm/fpu.h> #include <asm/mipsregs.h> #include <asm/system.h> @@ -198,8 +197,7 @@ static __cpuinit void probe_spram(char *type, offset += 2 * SPRAM_TAG_STRIDE; } } - -__cpuinit void spram_config(void) +void __cpuinit spram_config(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config0; @@ -208,6 +206,7 @@ __cpuinit void spram_config(void) case CPU_24K: case CPU_34K: case CPU_74K: + case CPU_1004K: config0 = read_c0_config(); /* FIXME: addresses are Malta specific */ if (config0 & (1<<24)) { diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 03092ab2a29..60477529362 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -1116,8 +1116,6 @@ static int vpe_open(struct inode *inode, struct file *filp) v->shared_ptr = NULL; v->__start = 0; - unlock_kernel(); - return 0; } |