diff options
Diffstat (limited to 'arch/mips/kernel')
34 files changed, 220 insertions, 175 deletions
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index c901c22d7ad0..8d006ec65677 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/kbuild.h> | 16 | #include <linux/kbuild.h> |
17 | #include <linux/suspend.h> | ||
17 | #include <asm/ptrace.h> | 18 | #include <asm/ptrace.h> |
18 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
19 | 20 | ||
@@ -326,3 +327,15 @@ void output_octeon_cop2_state_defines(void) | |||
326 | BLANK(); | 327 | BLANK(); |
327 | } | 328 | } |
328 | #endif | 329 | #endif |
330 | |||
331 | #ifdef CONFIG_HIBERNATION | ||
332 | void output_pbe_defines(void) | ||
333 | { | ||
334 | COMMENT(" Linux struct pbe offsets. "); | ||
335 | OFFSET(PBE_ADDRESS, pbe, address); | ||
336 | OFFSET(PBE_ORIG_ADDRESS, pbe, orig_address); | ||
337 | OFFSET(PBE_NEXT, pbe, next); | ||
338 | DEFINE(PBE_SIZE, sizeof(struct pbe)); | ||
339 | BLANK(); | ||
340 | } | ||
341 | #endif | ||
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index e1333d7319e2..ff448233dab5 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c | |||
@@ -53,6 +53,23 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | |||
53 | #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) | 53 | #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) |
54 | 54 | ||
55 | #include <asm/processor.h> | 55 | #include <asm/processor.h> |
56 | |||
57 | /* | ||
58 | * When this file is selected, we are definitely running a 64bit kernel. | ||
59 | * So using the right regs define in asm/reg.h | ||
60 | */ | ||
61 | #define WANT_COMPAT_REG_H | ||
62 | |||
63 | /* These MUST be defined before elf.h gets included */ | ||
64 | extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs); | ||
65 | #define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs); | ||
66 | #define ELF_CORE_COPY_TASK_REGS(_tsk, _dest) \ | ||
67 | ({ \ | ||
68 | int __res = 1; \ | ||
69 | elf32_core_copy_regs(*(_dest), task_pt_regs(_tsk)); \ | ||
70 | __res; \ | ||
71 | }) | ||
72 | |||
56 | #include <linux/module.h> | 73 | #include <linux/module.h> |
57 | #include <linux/elfcore.h> | 74 | #include <linux/elfcore.h> |
58 | #include <linux/compat.h> | 75 | #include <linux/compat.h> |
@@ -110,9 +127,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) | |||
110 | value->tv_usec = rem / NSEC_PER_USEC; | 127 | value->tv_usec = rem / NSEC_PER_USEC; |
111 | } | 128 | } |
112 | 129 | ||
113 | #undef ELF_CORE_COPY_REGS | ||
114 | #define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs); | ||
115 | |||
116 | void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs) | 130 | void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs) |
117 | { | 131 | { |
118 | int i; | 132 | int i; |
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c index a5182a207696..e02f79b1eb51 100644 --- a/arch/mips/kernel/cevt-bcm1480.c +++ b/arch/mips/kernel/cevt-bcm1480.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/clockchips.h> | 18 | #include <linux/clockchips.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/percpu.h> | 20 | #include <linux/percpu.h> |
21 | #include <linux/smp.h> | ||
21 | 22 | ||
22 | #include <asm/addrspace.h> | 23 | #include <asm/addrspace.h> |
23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c index 1ada45ea0700..6996da4d74a2 100644 --- a/arch/mips/kernel/cevt-ds1287.c +++ b/arch/mips/kernel/cevt-ds1287.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * DS1287 clockevent driver | 2 | * DS1287 clockevent driver |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c index e9b787feedcb..92351e00ae0e 100644 --- a/arch/mips/kernel/cevt-gt641xx.c +++ b/arch/mips/kernel/cevt-gt641xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * GT641xx clockevent routines. | 2 | * GT641xx clockevent routines. |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 0015e442572b..2652362ce047 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/clockchips.h> | 9 | #include <linux/clockchips.h> |
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/percpu.h> | 11 | #include <linux/percpu.h> |
12 | #include <linux/smp.h> | ||
12 | 13 | ||
13 | #include <asm/smtc_ipi.h> | 14 | #include <asm/smtc_ipi.h> |
14 | #include <asm/time.h> | 15 | #include <asm/time.h> |
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c index 340f53e5c6b1..ac5903d1b20e 100644 --- a/arch/mips/kernel/cevt-sb1250.c +++ b/arch/mips/kernel/cevt-sb1250.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/clockchips.h> | 18 | #include <linux/clockchips.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/percpu.h> | 20 | #include <linux/percpu.h> |
21 | #include <linux/smp.h> | ||
21 | 22 | ||
22 | #include <asm/addrspace.h> | 23 | #include <asm/addrspace.h> |
23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c index df6f5bc60572..98bd7de75778 100644 --- a/arch/mips/kernel/cevt-smtc.c +++ b/arch/mips/kernel/cevt-smtc.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/clockchips.h> | 10 | #include <linux/clockchips.h> |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/percpu.h> | 12 | #include <linux/percpu.h> |
13 | #include <linux/smp.h> | ||
13 | 14 | ||
14 | #include <asm/smtc_ipi.h> | 15 | #include <asm/smtc_ipi.h> |
15 | #include <asm/time.h> | 16 | #include <asm/time.h> |
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c index 2e911e3da8d3..0037f21baf0d 100644 --- a/arch/mips/kernel/cevt-txx9.c +++ b/arch/mips/kernel/cevt-txx9.c | |||
@@ -20,22 +20,29 @@ | |||
20 | #define TIMER_CCD 0 /* 1/2 */ | 20 | #define TIMER_CCD 0 /* 1/2 */ |
21 | #define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD)) | 21 | #define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD)) |
22 | 22 | ||
23 | static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr; | 23 | struct txx9_clocksource { |
24 | struct clocksource cs; | ||
25 | struct txx9_tmr_reg __iomem *tmrptr; | ||
26 | }; | ||
24 | 27 | ||
25 | static cycle_t txx9_cs_read(struct clocksource *cs) | 28 | static cycle_t txx9_cs_read(struct clocksource *cs) |
26 | { | 29 | { |
27 | return __raw_readl(&txx9_cs_tmrptr->trr); | 30 | struct txx9_clocksource *txx9_cs = |
31 | container_of(cs, struct txx9_clocksource, cs); | ||
32 | return __raw_readl(&txx9_cs->tmrptr->trr); | ||
28 | } | 33 | } |
29 | 34 | ||
30 | /* Use 1 bit smaller width to use full bits in that width */ | 35 | /* Use 1 bit smaller width to use full bits in that width */ |
31 | #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1) | 36 | #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1) |
32 | 37 | ||
33 | static struct clocksource txx9_clocksource = { | 38 | static struct txx9_clocksource txx9_clocksource = { |
34 | .name = "TXx9", | 39 | .cs = { |
35 | .rating = 200, | 40 | .name = "TXx9", |
36 | .read = txx9_cs_read, | 41 | .rating = 200, |
37 | .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS), | 42 | .read = txx9_cs_read, |
38 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 43 | .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS), |
44 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
45 | }, | ||
39 | }; | 46 | }; |
40 | 47 | ||
41 | void __init txx9_clocksource_init(unsigned long baseaddr, | 48 | void __init txx9_clocksource_init(unsigned long baseaddr, |
@@ -43,8 +50,8 @@ void __init txx9_clocksource_init(unsigned long baseaddr, | |||
43 | { | 50 | { |
44 | struct txx9_tmr_reg __iomem *tmrptr; | 51 | struct txx9_tmr_reg __iomem *tmrptr; |
45 | 52 | ||
46 | clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk)); | 53 | clocksource_set_clock(&txx9_clocksource.cs, TIMER_CLK(imbusclk)); |
47 | clocksource_register(&txx9_clocksource); | 54 | clocksource_register(&txx9_clocksource.cs); |
48 | 55 | ||
49 | tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); | 56 | tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); |
50 | __raw_writel(TCR_BASE, &tmrptr->tcr); | 57 | __raw_writel(TCR_BASE, &tmrptr->tcr); |
@@ -53,10 +60,13 @@ void __init txx9_clocksource_init(unsigned long baseaddr, | |||
53 | __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr); | 60 | __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr); |
54 | __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra); | 61 | __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra); |
55 | __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); | 62 | __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); |
56 | txx9_cs_tmrptr = tmrptr; | 63 | txx9_clocksource.tmrptr = tmrptr; |
57 | } | 64 | } |
58 | 65 | ||
59 | static struct txx9_tmr_reg __iomem *txx9_tmrptr; | 66 | struct txx9_clock_event_device { |
67 | struct clock_event_device cd; | ||
68 | struct txx9_tmr_reg __iomem *tmrptr; | ||
69 | }; | ||
60 | 70 | ||
61 | static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr) | 71 | static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr) |
62 | { | 72 | { |
@@ -69,7 +79,9 @@ static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr) | |||
69 | static void txx9tmr_set_mode(enum clock_event_mode mode, | 79 | static void txx9tmr_set_mode(enum clock_event_mode mode, |
70 | struct clock_event_device *evt) | 80 | struct clock_event_device *evt) |
71 | { | 81 | { |
72 | struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; | 82 | struct txx9_clock_event_device *txx9_cd = |
83 | container_of(evt, struct txx9_clock_event_device, cd); | ||
84 | struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr; | ||
73 | 85 | ||
74 | txx9tmr_stop_and_clear(tmrptr); | 86 | txx9tmr_stop_and_clear(tmrptr); |
75 | switch (mode) { | 87 | switch (mode) { |
@@ -99,7 +111,9 @@ static void txx9tmr_set_mode(enum clock_event_mode mode, | |||
99 | static int txx9tmr_set_next_event(unsigned long delta, | 111 | static int txx9tmr_set_next_event(unsigned long delta, |
100 | struct clock_event_device *evt) | 112 | struct clock_event_device *evt) |
101 | { | 113 | { |
102 | struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; | 114 | struct txx9_clock_event_device *txx9_cd = |
115 | container_of(evt, struct txx9_clock_event_device, cd); | ||
116 | struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr; | ||
103 | 117 | ||
104 | txx9tmr_stop_and_clear(tmrptr); | 118 | txx9tmr_stop_and_clear(tmrptr); |
105 | /* start timer */ | 119 | /* start timer */ |
@@ -108,18 +122,22 @@ static int txx9tmr_set_next_event(unsigned long delta, | |||
108 | return 0; | 122 | return 0; |
109 | } | 123 | } |
110 | 124 | ||
111 | static struct clock_event_device txx9tmr_clock_event_device = { | 125 | static struct txx9_clock_event_device txx9_clock_event_device = { |
112 | .name = "TXx9", | 126 | .cd = { |
113 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 127 | .name = "TXx9", |
114 | .rating = 200, | 128 | .features = CLOCK_EVT_FEAT_PERIODIC | |
115 | .set_mode = txx9tmr_set_mode, | 129 | CLOCK_EVT_FEAT_ONESHOT, |
116 | .set_next_event = txx9tmr_set_next_event, | 130 | .rating = 200, |
131 | .set_mode = txx9tmr_set_mode, | ||
132 | .set_next_event = txx9tmr_set_next_event, | ||
133 | }, | ||
117 | }; | 134 | }; |
118 | 135 | ||
119 | static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id) | 136 | static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id) |
120 | { | 137 | { |
121 | struct clock_event_device *cd = &txx9tmr_clock_event_device; | 138 | struct txx9_clock_event_device *txx9_cd = dev_id; |
122 | struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; | 139 | struct clock_event_device *cd = &txx9_cd->cd; |
140 | struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr; | ||
123 | 141 | ||
124 | __raw_writel(0, &tmrptr->tisr); /* ack interrupt */ | 142 | __raw_writel(0, &tmrptr->tisr); /* ack interrupt */ |
125 | cd->event_handler(cd); | 143 | cd->event_handler(cd); |
@@ -130,19 +148,20 @@ static struct irqaction txx9tmr_irq = { | |||
130 | .handler = txx9tmr_interrupt, | 148 | .handler = txx9tmr_interrupt, |
131 | .flags = IRQF_DISABLED | IRQF_PERCPU, | 149 | .flags = IRQF_DISABLED | IRQF_PERCPU, |
132 | .name = "txx9tmr", | 150 | .name = "txx9tmr", |
151 | .dev_id = &txx9_clock_event_device, | ||
133 | }; | 152 | }; |
134 | 153 | ||
135 | void __init txx9_clockevent_init(unsigned long baseaddr, int irq, | 154 | void __init txx9_clockevent_init(unsigned long baseaddr, int irq, |
136 | unsigned int imbusclk) | 155 | unsigned int imbusclk) |
137 | { | 156 | { |
138 | struct clock_event_device *cd = &txx9tmr_clock_event_device; | 157 | struct clock_event_device *cd = &txx9_clock_event_device.cd; |
139 | struct txx9_tmr_reg __iomem *tmrptr; | 158 | struct txx9_tmr_reg __iomem *tmrptr; |
140 | 159 | ||
141 | tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); | 160 | tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); |
142 | txx9tmr_stop_and_clear(tmrptr); | 161 | txx9tmr_stop_and_clear(tmrptr); |
143 | __raw_writel(TIMER_CCD, &tmrptr->ccdr); | 162 | __raw_writel(TIMER_CCD, &tmrptr->ccdr); |
144 | __raw_writel(0, &tmrptr->itmr); | 163 | __raw_writel(0, &tmrptr->itmr); |
145 | txx9_tmrptr = tmrptr; | 164 | txx9_clock_event_device.tmrptr = tmrptr; |
146 | 165 | ||
147 | clockevent_set_clock(cd, TIMER_CLK(imbusclk)); | 166 | clockevent_set_clock(cd, TIMER_CLK(imbusclk)); |
148 | cd->max_delta_ns = | 167 | cd->max_delta_ns = |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b13b8eb30596..1abe9905c9c1 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/ptrace.h> | 16 | #include <linux/ptrace.h> |
17 | #include <linux/smp.h> | ||
17 | #include <linux/stddef.h> | 18 | #include <linux/stddef.h> |
18 | 19 | ||
19 | #include <asm/bugs.h> | 20 | #include <asm/bugs.h> |
diff --git a/arch/mips/kernel/csrc-ioasic.c b/arch/mips/kernel/csrc-ioasic.c index b551f48d3a07..23da108506b0 100644 --- a/arch/mips/kernel/csrc-ioasic.c +++ b/arch/mips/kernel/csrc-ioasic.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * DEC I/O ASIC's counter clocksource | 2 | * DEC I/O ASIC's counter clocksource |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 492a0a8d70fb..531ce7b16124 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S | |||
@@ -188,7 +188,8 @@ NESTED(kernel_entry, 16, sp) # kernel entry point | |||
188 | 188 | ||
189 | MTC0 zero, CP0_CONTEXT # clear context register | 189 | MTC0 zero, CP0_CONTEXT # clear context register |
190 | PTR_LA $28, init_thread_union | 190 | PTR_LA $28, init_thread_union |
191 | PTR_LI sp, _THREAD_SIZE - 32 | 191 | /* Set the SP after an empty pt_regs. */ |
192 | PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE | ||
192 | PTR_ADDU sp, $28 | 193 | PTR_ADDU sp, $28 |
193 | set_saved_sp sp, t0, t1 | 194 | set_saved_sp sp, t0, t1 |
194 | PTR_SUBU sp, 4 * SZREG # init stack pointer | 195 | PTR_SUBU sp, 4 * SZREG # init stack pointer |
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index ed20e7fe65e3..f7d8d5d0ddbf 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/interrupt.h> | 7 | #include <linux/interrupt.h> |
8 | #include <linux/jiffies.h> | 8 | #include <linux/jiffies.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/smp.h> | ||
10 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
11 | 12 | ||
12 | #include <asm/delay.h> | 13 | #include <asm/delay.h> |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 3f43c2e3aa5a..d2072cd38592 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | #include <linux/bitmap.h> | 3 | #include <linux/bitmap.h> |
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/smp.h> | ||
5 | 6 | ||
6 | #include <asm/io.h> | 7 | #include <asm/io.h> |
7 | #include <asm/gic.h> | 8 | #include <asm/gic.h> |
@@ -106,9 +107,7 @@ static unsigned int gic_irq_startup(unsigned int irq) | |||
106 | { | 107 | { |
107 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 108 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
108 | irq -= _irqbase; | 109 | irq -= _irqbase; |
109 | /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */ | 110 | GIC_SET_INTR_MASK(irq, 1); |
110 | GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))), | ||
111 | 1 << (irq % 32)); | ||
112 | return 0; | 111 | return 0; |
113 | } | 112 | } |
114 | 113 | ||
@@ -119,8 +118,7 @@ static void gic_irq_ack(unsigned int irq) | |||
119 | #endif | 118 | #endif |
120 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 119 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
121 | irq -= _irqbase; | 120 | irq -= _irqbase; |
122 | GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))), | 121 | GIC_CLR_INTR_MASK(irq, 1); |
123 | 1 << (irq % 32)); | ||
124 | 122 | ||
125 | if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) { | 123 | if (_intrmap[irq].trigtype == GIC_TRIG_EDGE) { |
126 | if (!gic_wedgeb2bok) | 124 | if (!gic_wedgeb2bok) |
@@ -137,18 +135,14 @@ static void gic_mask_irq(unsigned int irq) | |||
137 | { | 135 | { |
138 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 136 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
139 | irq -= _irqbase; | 137 | irq -= _irqbase; |
140 | /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */ | 138 | GIC_CLR_INTR_MASK(irq, 1); |
141 | GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_RMASK_31_0_OFS + (irq / 32))), | ||
142 | 1 << (irq % 32)); | ||
143 | } | 139 | } |
144 | 140 | ||
145 | static void gic_unmask_irq(unsigned int irq) | 141 | static void gic_unmask_irq(unsigned int irq) |
146 | { | 142 | { |
147 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); | 143 | pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq); |
148 | irq -= _irqbase; | 144 | irq -= _irqbase; |
149 | /* FIXME: this is wrong for !GICISWORDLITTLEENDIAN */ | 145 | GIC_SET_INTR_MASK(irq, 1); |
150 | GICWRITE(GIC_REG_ADDR(SHARED, (GIC_SH_SMASK_31_0_OFS + (irq / 32))), | ||
151 | 1 << (irq % 32)); | ||
152 | } | 146 | } |
153 | 147 | ||
154 | #ifdef CONFIG_SMP | 148 | #ifdef CONFIG_SMP |
@@ -253,6 +247,10 @@ static void __init gic_basic_init(void) | |||
253 | if (cpu == X) | 247 | if (cpu == X) |
254 | continue; | 248 | continue; |
255 | 249 | ||
250 | if (cpu == 0 && i != 0 && _intrmap[i].intrnum == 0 && | ||
251 | _intrmap[i].ipiflag == 0) | ||
252 | continue; | ||
253 | |||
256 | setup_intr(_intrmap[i].intrnum, | 254 | setup_intr(_intrmap[i].intrnum, |
257 | _intrmap[i].cpunum, | 255 | _intrmap[i].cpunum, |
258 | _intrmap[i].pin, | 256 | _intrmap[i].pin, |
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c index 1b81b131f43c..ebcc5f7ad9c2 100644 --- a/arch/mips/kernel/irq-gt641xx.c +++ b/arch/mips/kernel/irq-gt641xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * GT641xx IRQ routines. | 2 | * GT641xx IRQ routines. |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | 4 | * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c index a4d1462c27f7..9b78029bea70 100644 --- a/arch/mips/kernel/irq_txx9.c +++ b/arch/mips/kernel/irq_txx9.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/mips/kernel/irq_txx9.c | ||
3 | * | ||
4 | * Based on linux/arch/mips/jmr3927/rbhma3100/irq.c, | 2 | * Based on linux/arch/mips/jmr3927/rbhma3100/irq.c, |
5 | * linux/arch/mips/tx4927/common/tx4927_irq.c, | 3 | * linux/arch/mips/tx4927/common/tx4927_irq.c, |
6 | * linux/arch/mips/tx4938/common/irq.c | 4 | * linux/arch/mips/tx4938/common/irq.c |
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 6e152c80cd4a..50c9bb880667 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kgdb.h> | 26 | #include <linux/kgdb.h> |
27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | #include <linux/smp.h> | ||
29 | #include <asm/inst.h> | 30 | #include <asm/inst.h> |
30 | #include <asm/fpu.h> | 31 | #include <asm/fpu.h> |
31 | #include <asm/cacheflush.h> | 32 | #include <asm/cacheflush.h> |
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 3e9100dcc12d..6f51dda87fce 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c | |||
@@ -98,7 +98,8 @@ static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v) | |||
98 | static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) | 98 | static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) |
99 | { | 99 | { |
100 | if (v % 4) { | 100 | if (v % 4) { |
101 | printk(KERN_ERR "module %s: dangerous relocation\n", me->name); | 101 | pr_err("module %s: dangerous R_MIPS_26 REL relocation\n", |
102 | me->name); | ||
102 | return -ENOEXEC; | 103 | return -ENOEXEC; |
103 | } | 104 | } |
104 | 105 | ||
@@ -118,7 +119,8 @@ static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v) | |||
118 | static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) | 119 | static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v) |
119 | { | 120 | { |
120 | if (v % 4) { | 121 | if (v % 4) { |
121 | printk(KERN_ERR "module %s: dangerous relocation\n", me->name); | 122 | pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n", |
123 | me->name); | ||
122 | return -ENOEXEC; | 124 | return -ENOEXEC; |
123 | } | 125 | } |
124 | 126 | ||
@@ -222,7 +224,7 @@ static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v) | |||
222 | return 0; | 224 | return 0; |
223 | 225 | ||
224 | out_danger: | 226 | out_danger: |
225 | printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name); | 227 | pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name); |
226 | 228 | ||
227 | return -ENOEXEC; | 229 | return -ENOEXEC; |
228 | } | 230 | } |
@@ -301,7 +303,7 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, | |||
301 | /* This is the symbol it is referring to */ | 303 | /* This is the symbol it is referring to */ |
302 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr | 304 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr |
303 | + ELF_MIPS_R_SYM(rel[i]); | 305 | + ELF_MIPS_R_SYM(rel[i]); |
304 | if (!sym->st_value) { | 306 | if (IS_ERR_VALUE(sym->st_value)) { |
305 | /* Ignore unresolved weak symbol */ | 307 | /* Ignore unresolved weak symbol */ |
306 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) | 308 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) |
307 | continue; | 309 | continue; |
@@ -341,7 +343,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, | |||
341 | /* This is the symbol it is referring to */ | 343 | /* This is the symbol it is referring to */ |
342 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr | 344 | sym = (Elf_Sym *)sechdrs[symindex].sh_addr |
343 | + ELF_MIPS_R_SYM(rel[i]); | 345 | + ELF_MIPS_R_SYM(rel[i]); |
344 | if (!sym->st_value) { | 346 | if (IS_ERR_VALUE(sym->st_value)) { |
345 | /* Ignore unresolved weak symbol */ | 347 | /* Ignore unresolved weak symbol */ |
346 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) | 348 | if (ELF_ST_BIND(sym->st_info) == STB_WEAK) |
347 | continue; | 349 | continue; |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index e0a4ac18fa07..26109c4d5170 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/mips/kernel/proc.c | ||
3 | * | ||
4 | * Copyright (C) 1995, 1996, 2001 Ralf Baechle | 2 | * Copyright (C) 1995, 1996, 2001 Ralf Baechle |
5 | * Copyright (C) 2001, 2004 MIPS Technologies, Inc. | 3 | * Copyright (C) 2001, 2004 MIPS Technologies, Inc. |
6 | * Copyright (C) 2004 Maciej W. Rozycki | 4 | * Copyright (C) 2004 Maciej W. Rozycki |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 1eaaa450e20c..f3d73e1831c1 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -50,10 +50,15 @@ | |||
50 | */ | 50 | */ |
51 | void __noreturn cpu_idle(void) | 51 | void __noreturn cpu_idle(void) |
52 | { | 52 | { |
53 | int cpu; | ||
54 | |||
55 | /* CPU is going idle. */ | ||
56 | cpu = smp_processor_id(); | ||
57 | |||
53 | /* endless idle loop with no priority at all */ | 58 | /* endless idle loop with no priority at all */ |
54 | while (1) { | 59 | while (1) { |
55 | tick_nohz_stop_sched_tick(1); | 60 | tick_nohz_stop_sched_tick(1); |
56 | while (!need_resched()) { | 61 | while (!need_resched() && cpu_online(cpu)) { |
57 | #ifdef CONFIG_MIPS_MT_SMTC | 62 | #ifdef CONFIG_MIPS_MT_SMTC |
58 | extern void smtc_idle_loop_hook(void); | 63 | extern void smtc_idle_loop_hook(void); |
59 | 64 | ||
@@ -62,6 +67,12 @@ void __noreturn cpu_idle(void) | |||
62 | if (cpu_wait) | 67 | if (cpu_wait) |
63 | (*cpu_wait)(); | 68 | (*cpu_wait)(); |
64 | } | 69 | } |
70 | #ifdef CONFIG_HOTPLUG_CPU | ||
71 | if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) && | ||
72 | (system_state == SYSTEM_RUNNING || | ||
73 | system_state == SYSTEM_BOOTING)) | ||
74 | play_dead(); | ||
75 | #endif | ||
65 | tick_nohz_restart_sched_tick(); | 76 | tick_nohz_restart_sched_tick(); |
66 | preempt_enable_no_resched(); | 77 | preempt_enable_no_resched(); |
67 | schedule(); | 78 | schedule(); |
@@ -104,7 +115,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
104 | { | 115 | { |
105 | struct thread_info *ti = task_thread_info(p); | 116 | struct thread_info *ti = task_thread_info(p); |
106 | struct pt_regs *childregs; | 117 | struct pt_regs *childregs; |
107 | long childksp; | 118 | unsigned long childksp; |
108 | p->set_child_tid = p->clear_child_tid = NULL; | 119 | p->set_child_tid = p->clear_child_tid = NULL; |
109 | 120 | ||
110 | childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; | 121 | childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; |
@@ -121,6 +132,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
121 | 132 | ||
122 | /* set up new TSS. */ | 133 | /* set up new TSS. */ |
123 | childregs = (struct pt_regs *) childksp - 1; | 134 | childregs = (struct pt_regs *) childksp - 1; |
135 | /* Put the stack after the struct pt_regs. */ | ||
136 | childksp = (unsigned long) childregs; | ||
124 | *childregs = *regs; | 137 | *childregs = *regs; |
125 | childregs->regs[7] = 0; /* Clear error flag */ | 138 | childregs->regs[7] = 0; /* Clear error flag */ |
126 | 139 | ||
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index c4f9ac17474a..32644b4a0714 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/ptrace.h> | 23 | #include <linux/ptrace.h> |
24 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/user.h> | 25 | #include <linux/user.h> |
27 | #include <linux/security.h> | 26 | #include <linux/security.h> |
28 | 27 | ||
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 0b31b9bda048..b57082123536 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -652,6 +652,9 @@ einval: li v0, -ENOSYS | |||
652 | sys sys_inotify_init1 1 | 652 | sys sys_inotify_init1 1 |
653 | sys sys_preadv 6 /* 4330 */ | 653 | sys sys_preadv 6 /* 4330 */ |
654 | sys sys_pwritev 6 | 654 | sys sys_pwritev 6 |
655 | sys sys_rt_tgsigqueueinfo 4 | ||
656 | sys sys_perf_counter_open 5 | ||
657 | sys sys_accept4 4 | ||
655 | .endm | 658 | .endm |
656 | 659 | ||
657 | /* We pre-compute the number of _instruction_ bytes needed to | 660 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index c647fd6e722f..3d866f24e064 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -489,4 +489,7 @@ sys_call_table: | |||
489 | PTR sys_inotify_init1 | 489 | PTR sys_inotify_init1 |
490 | PTR sys_preadv | 490 | PTR sys_preadv |
491 | PTR sys_pwritev /* 5390 */ | 491 | PTR sys_pwritev /* 5390 */ |
492 | PTR sys_rt_tgsigqueueinfo | ||
493 | PTR sys_perf_counter_open | ||
494 | PTR sys_accept4 | ||
492 | .size sys_call_table,.-sys_call_table | 495 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 93cc672f4522..e855b118a079 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -415,4 +415,7 @@ EXPORT(sysn32_call_table) | |||
415 | PTR sys_inotify_init1 | 415 | PTR sys_inotify_init1 |
416 | PTR sys_preadv | 416 | PTR sys_preadv |
417 | PTR sys_pwritev | 417 | PTR sys_pwritev |
418 | PTR compat_sys_rt_tgsigqueueinfo /* 5295 */ | ||
419 | PTR sys_perf_counter_open | ||
420 | PTR sys_accept4 | ||
418 | .size sysn32_call_table,.-sysn32_call_table | 421 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index a5598b2339dd..0c49f1a660be 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -535,4 +535,7 @@ sys_call_table: | |||
535 | PTR sys_inotify_init1 | 535 | PTR sys_inotify_init1 |
536 | PTR compat_sys_preadv /* 4330 */ | 536 | PTR compat_sys_preadv /* 4330 */ |
537 | PTR compat_sys_pwritev | 537 | PTR compat_sys_pwritev |
538 | PTR compat_sys_rt_tgsigqueueinfo | ||
539 | PTR sys_perf_counter_open | ||
540 | PTR sys_accept4 | ||
538 | .size sys_call_table,.-sys_call_table | 541 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index f27beca4b26d..ad0ff5dc4d59 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/smp.h> | ||
23 | #include <linux/cpumask.h> | 24 | #include <linux/cpumask.h> |
24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
25 | #include <linux/compiler.h> | 26 | #include <linux/compiler.h> |
@@ -36,80 +37,24 @@ | |||
36 | #include <asm/mipsregs.h> | 37 | #include <asm/mipsregs.h> |
37 | #include <asm/mipsmtregs.h> | 38 | #include <asm/mipsmtregs.h> |
38 | #include <asm/mips_mt.h> | 39 | #include <asm/mips_mt.h> |
39 | 40 | #include <asm/amon.h> | |
40 | /* | 41 | #include <asm/gic.h> |
41 | * Crude manipulation of the CPU masks to control which | ||
42 | * which CPU's are brought online during initialisation | ||
43 | * | ||
44 | * Beware... this needs to be called after CPU discovery | ||
45 | * but before CPU bringup | ||
46 | */ | ||
47 | static int __init allowcpus(char *str) | ||
48 | { | ||
49 | cpumask_t cpu_allow_map; | ||
50 | char buf[256]; | ||
51 | int len; | ||
52 | |||
53 | cpus_clear(cpu_allow_map); | ||
54 | if (cpulist_parse(str, &cpu_allow_map) == 0) { | ||
55 | cpu_set(0, cpu_allow_map); | ||
56 | cpus_and(cpu_possible_map, cpu_possible_map, cpu_allow_map); | ||
57 | len = cpulist_scnprintf(buf, sizeof(buf)-1, &cpu_possible_map); | ||
58 | buf[len] = '\0'; | ||
59 | pr_debug("Allowable CPUs: %s\n", buf); | ||
60 | return 1; | ||
61 | } else | ||
62 | return 0; | ||
63 | } | ||
64 | __setup("allowcpus=", allowcpus); | ||
65 | 42 | ||
66 | static void ipi_call_function(unsigned int cpu) | 43 | static void ipi_call_function(unsigned int cpu) |
67 | { | 44 | { |
68 | unsigned int action = 0; | ||
69 | |||
70 | pr_debug("CPU%d: %s cpu %d status %08x\n", | 45 | pr_debug("CPU%d: %s cpu %d status %08x\n", |
71 | smp_processor_id(), __func__, cpu, read_c0_status()); | 46 | smp_processor_id(), __func__, cpu, read_c0_status()); |
72 | 47 | ||
73 | switch (cpu) { | 48 | gic_send_ipi(plat_ipi_call_int_xlate(cpu)); |
74 | case 0: | ||
75 | action = GIC_IPI_EXT_INTR_CALLFNC_VPE0; | ||
76 | break; | ||
77 | case 1: | ||
78 | action = GIC_IPI_EXT_INTR_CALLFNC_VPE1; | ||
79 | break; | ||
80 | case 2: | ||
81 | action = GIC_IPI_EXT_INTR_CALLFNC_VPE2; | ||
82 | break; | ||
83 | case 3: | ||
84 | action = GIC_IPI_EXT_INTR_CALLFNC_VPE3; | ||
85 | break; | ||
86 | } | ||
87 | gic_send_ipi(action); | ||
88 | } | 49 | } |
89 | 50 | ||
90 | 51 | ||
91 | static void ipi_resched(unsigned int cpu) | 52 | static void ipi_resched(unsigned int cpu) |
92 | { | 53 | { |
93 | unsigned int action = 0; | ||
94 | |||
95 | pr_debug("CPU%d: %s cpu %d status %08x\n", | 54 | pr_debug("CPU%d: %s cpu %d status %08x\n", |
96 | smp_processor_id(), __func__, cpu, read_c0_status()); | 55 | smp_processor_id(), __func__, cpu, read_c0_status()); |
97 | 56 | ||
98 | switch (cpu) { | 57 | gic_send_ipi(plat_ipi_resched_int_xlate(cpu)); |
99 | case 0: | ||
100 | action = GIC_IPI_EXT_INTR_RESCHED_VPE0; | ||
101 | break; | ||
102 | case 1: | ||
103 | action = GIC_IPI_EXT_INTR_RESCHED_VPE1; | ||
104 | break; | ||
105 | case 2: | ||
106 | action = GIC_IPI_EXT_INTR_RESCHED_VPE2; | ||
107 | break; | ||
108 | case 3: | ||
109 | action = GIC_IPI_EXT_INTR_RESCHED_VPE3; | ||
110 | break; | ||
111 | } | ||
112 | gic_send_ipi(action); | ||
113 | } | 58 | } |
114 | 59 | ||
115 | /* | 60 | /* |
@@ -205,7 +150,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle) | |||
205 | (unsigned long)(gp + sizeof(struct thread_info))); | 150 | (unsigned long)(gp + sizeof(struct thread_info))); |
206 | #endif | 151 | #endif |
207 | 152 | ||
208 | amon_cpu_start(cpu, pc, sp, gp, a0); | 153 | amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0); |
209 | } | 154 | } |
210 | 155 | ||
211 | /* | 156 | /* |
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c index 878e3733bbb2..2508d55d68fd 100644 --- a/arch/mips/kernel/smp-up.c +++ b/arch/mips/kernel/smp-up.c | |||
@@ -55,6 +55,18 @@ static void __init up_prepare_cpus(unsigned int max_cpus) | |||
55 | { | 55 | { |
56 | } | 56 | } |
57 | 57 | ||
58 | #ifdef CONFIG_HOTPLUG_CPU | ||
59 | static int up_cpu_disable(void) | ||
60 | { | ||
61 | return -ENOSYS; | ||
62 | } | ||
63 | |||
64 | static void up_cpu_die(unsigned int cpu) | ||
65 | { | ||
66 | BUG(); | ||
67 | } | ||
68 | #endif | ||
69 | |||
58 | struct plat_smp_ops up_smp_ops = { | 70 | struct plat_smp_ops up_smp_ops = { |
59 | .send_ipi_single = up_send_ipi_single, | 71 | .send_ipi_single = up_send_ipi_single, |
60 | .send_ipi_mask = up_send_ipi_mask, | 72 | .send_ipi_mask = up_send_ipi_mask, |
@@ -64,4 +76,8 @@ struct plat_smp_ops up_smp_ops = { | |||
64 | .boot_secondary = up_boot_secondary, | 76 | .boot_secondary = up_boot_secondary, |
65 | .smp_setup = up_smp_setup, | 77 | .smp_setup = up_smp_setup, |
66 | .prepare_cpus = up_prepare_cpus, | 78 | .prepare_cpus = up_prepare_cpus, |
79 | #ifdef CONFIG_HOTPLUG_CPU | ||
80 | .cpu_disable = up_cpu_disable, | ||
81 | .cpu_die = up_cpu_die, | ||
82 | #endif | ||
67 | }; | 83 | }; |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index c937506a03aa..bc7d9b05e2f4 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/smp.h> | ||
25 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
26 | #include <linux/threads.h> | 27 | #include <linux/threads.h> |
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
@@ -44,7 +45,7 @@ | |||
44 | #include <asm/mipsmtregs.h> | 45 | #include <asm/mipsmtregs.h> |
45 | #endif /* CONFIG_MIPS_MT_SMTC */ | 46 | #endif /* CONFIG_MIPS_MT_SMTC */ |
46 | 47 | ||
47 | static volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ | 48 | volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ |
48 | int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ | 49 | int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ |
49 | int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ | 50 | int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ |
50 | 51 | ||
@@ -200,6 +201,8 @@ void __devinit smp_prepare_boot_cpu(void) | |||
200 | * and keep control until "cpu_online(cpu)" is set. Note: cpu is | 201 | * and keep control until "cpu_online(cpu)" is set. Note: cpu is |
201 | * physical, not logical. | 202 | * physical, not logical. |
202 | */ | 203 | */ |
204 | static struct task_struct *cpu_idle_thread[NR_CPUS]; | ||
205 | |||
203 | int __cpuinit __cpu_up(unsigned int cpu) | 206 | int __cpuinit __cpu_up(unsigned int cpu) |
204 | { | 207 | { |
205 | struct task_struct *idle; | 208 | struct task_struct *idle; |
@@ -209,9 +212,16 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
209 | * The following code is purely to make sure | 212 | * The following code is purely to make sure |
210 | * Linux can schedule processes on this slave. | 213 | * Linux can schedule processes on this slave. |
211 | */ | 214 | */ |
212 | idle = fork_idle(cpu); | 215 | if (!cpu_idle_thread[cpu]) { |
213 | if (IS_ERR(idle)) | 216 | idle = fork_idle(cpu); |
214 | panic(KERN_ERR "Fork failed for CPU %d", cpu); | 217 | cpu_idle_thread[cpu] = idle; |
218 | |||
219 | if (IS_ERR(idle)) | ||
220 | panic(KERN_ERR "Fork failed for CPU %d", cpu); | ||
221 | } else { | ||
222 | idle = cpu_idle_thread[cpu]; | ||
223 | init_idle(idle, cpu); | ||
224 | } | ||
215 | 225 | ||
216 | mp_ops->boot_secondary(cpu, idle); | 226 | mp_ops->boot_secondary(cpu, idle); |
217 | 227 | ||
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 5f5af7d4c890..c16bb6d6c25c 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/clockchips.h> | 20 | #include <linux/clockchips.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/smp.h> | ||
23 | #include <linux/cpumask.h> | 24 | #include <linux/cpumask.h> |
24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
25 | #include <linux/kernel_stat.h> | 26 | #include <linux/kernel_stat.h> |
@@ -464,11 +465,8 @@ void smtc_prepare_cpus(int cpus) | |||
464 | smtc_configure_tlb(); | 465 | smtc_configure_tlb(); |
465 | 466 | ||
466 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { | 467 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { |
467 | /* | 468 | if (tcpervpe[vpe] == 0) |
468 | * Set the MVP bits. | 469 | continue; |
469 | */ | ||
470 | settc(tc); | ||
471 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_MVP); | ||
472 | if (vpe != 0) | 470 | if (vpe != 0) |
473 | printk(", "); | 471 | printk(", "); |
474 | printk("VPE %d: TC", vpe); | 472 | printk("VPE %d: TC", vpe); |
@@ -487,6 +485,12 @@ void smtc_prepare_cpus(int cpus) | |||
487 | } | 485 | } |
488 | if (vpe != 0) { | 486 | if (vpe != 0) { |
489 | /* | 487 | /* |
488 | * Allow this VPE to control others. | ||
489 | */ | ||
490 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | | ||
491 | VPECONF0_MVP); | ||
492 | |||
493 | /* | ||
490 | * Clear any stale software interrupts from VPE's Cause | 494 | * Clear any stale software interrupts from VPE's Cause |
491 | */ | 495 | */ |
492 | write_vpe_c0_cause(0); | 496 | write_vpe_c0_cause(0); |
@@ -924,6 +928,7 @@ void ipi_decode(struct smtc_ipi *pipi) | |||
924 | int irq = MIPS_CPU_IRQ_BASE + 1; | 928 | int irq = MIPS_CPU_IRQ_BASE + 1; |
925 | 929 | ||
926 | smtc_ipi_nq(&freeIPIq, pipi); | 930 | smtc_ipi_nq(&freeIPIq, pipi); |
931 | |||
927 | switch (type_copy) { | 932 | switch (type_copy) { |
928 | case SMTC_CLOCK_TICK: | 933 | case SMTC_CLOCK_TICK: |
929 | irq_enter(); | 934 | irq_enter(); |
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c index 58f5cd76c8c3..d52ff77baf3f 100644 --- a/arch/mips/kernel/stacktrace.c +++ b/arch/mips/kernel/stacktrace.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/mips/kernel/stacktrace.c | ||
3 | * | ||
4 | * Stack trace management functions | 2 | * Stack trace management functions |
5 | * | 3 | * |
6 | * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 4 | * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> |
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 9021108eb9c1..05dd170a83f7 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Count register synchronisation. | 2 | * Count register synchronisation. |
3 | * | 3 | * |
4 | * All CPUs will have their count registers synchronised to the CPU0 expirelo | 4 | * All CPUs will have their count registers synchronised to the CPU0 next time |
5 | * value. This can cause a small timewarp for CPU0. All other CPU's should | 5 | * value. This can cause a small timewarp for CPU0. All other CPU's should |
6 | * not have done anything significant (but they may have had interrupts | 6 | * not have done anything significant (but they may have had interrupts |
7 | * enabled briefly - prom_smp_finish() should not be responsible for enabling | 7 | * enabled briefly - prom_smp_finish() should not be responsible for enabling |
@@ -13,21 +13,22 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/irqflags.h> | 15 | #include <linux/irqflags.h> |
16 | #include <linux/r4k-timer.h> | 16 | #include <linux/cpumask.h> |
17 | 17 | ||
18 | #include <asm/r4k-timer.h> | ||
18 | #include <asm/atomic.h> | 19 | #include <asm/atomic.h> |
19 | #include <asm/barrier.h> | 20 | #include <asm/barrier.h> |
20 | #include <asm/cpumask.h> | ||
21 | #include <asm/mipsregs.h> | 21 | #include <asm/mipsregs.h> |
22 | 22 | ||
23 | static atomic_t __initdata count_start_flag = ATOMIC_INIT(0); | 23 | static atomic_t __cpuinitdata count_start_flag = ATOMIC_INIT(0); |
24 | static atomic_t __initdata count_count_start = ATOMIC_INIT(0); | 24 | static atomic_t __cpuinitdata count_count_start = ATOMIC_INIT(0); |
25 | static atomic_t __initdata count_count_stop = ATOMIC_INIT(0); | 25 | static atomic_t __cpuinitdata count_count_stop = ATOMIC_INIT(0); |
26 | static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0); | ||
26 | 27 | ||
27 | #define COUNTON 100 | 28 | #define COUNTON 100 |
28 | #define NR_LOOPS 5 | 29 | #define NR_LOOPS 5 |
29 | 30 | ||
30 | void __init synchronise_count_master(void) | 31 | void __cpuinit synchronise_count_master(void) |
31 | { | 32 | { |
32 | int i; | 33 | int i; |
33 | unsigned long flags; | 34 | unsigned long flags; |
@@ -42,19 +43,20 @@ void __init synchronise_count_master(void) | |||
42 | return; | 43 | return; |
43 | #endif | 44 | #endif |
44 | 45 | ||
45 | pr_info("Checking COUNT synchronization across %u CPUs: ", | 46 | printk(KERN_INFO "Synchronize counters across %u CPUs: ", |
46 | num_online_cpus()); | 47 | num_online_cpus()); |
47 | 48 | ||
48 | local_irq_save(flags); | 49 | local_irq_save(flags); |
49 | 50 | ||
50 | /* | 51 | /* |
51 | * Notify the slaves that it's time to start | 52 | * Notify the slaves that it's time to start |
52 | */ | 53 | */ |
54 | atomic_set(&count_reference, read_c0_count()); | ||
53 | atomic_set(&count_start_flag, 1); | 55 | atomic_set(&count_start_flag, 1); |
54 | smp_wmb(); | 56 | smp_wmb(); |
55 | 57 | ||
56 | /* Count will be initialised to expirelo for all CPU's */ | 58 | /* Count will be initialised to current timer for all CPU's */ |
57 | initcount = expirelo; | 59 | initcount = read_c0_count(); |
58 | 60 | ||
59 | /* | 61 | /* |
60 | * We loop a few times to get a primed instruction cache, | 62 | * We loop a few times to get a primed instruction cache, |
@@ -106,7 +108,7 @@ void __init synchronise_count_master(void) | |||
106 | printk("done.\n"); | 108 | printk("done.\n"); |
107 | } | 109 | } |
108 | 110 | ||
109 | void __init synchronise_count_slave(void) | 111 | void __cpuinit synchronise_count_slave(void) |
110 | { | 112 | { |
111 | int i; | 113 | int i; |
112 | unsigned long flags; | 114 | unsigned long flags; |
@@ -131,8 +133,8 @@ void __init synchronise_count_slave(void) | |||
131 | while (!atomic_read(&count_start_flag)) | 133 | while (!atomic_read(&count_start_flag)) |
132 | mb(); | 134 | mb(); |
133 | 135 | ||
134 | /* Count will be initialised to expirelo for all CPU's */ | 136 | /* Count will be initialised to next expire for all CPU's */ |
135 | initcount = expirelo; | 137 | initcount = atomic_read(&count_reference); |
136 | 138 | ||
137 | ncpus = num_online_cpus(); | 139 | ncpus = num_online_cpus(); |
138 | for (i = 0; i < NR_LOOPS; i++) { | 140 | for (i = 0; i < NR_LOOPS; i++) { |
@@ -156,4 +158,3 @@ void __init synchronise_count_slave(void) | |||
156 | local_irq_restore(flags); | 158 | local_irq_restore(flags); |
157 | } | 159 | } |
158 | #undef NR_LOOPS | 160 | #undef NR_LOOPS |
159 | #endif | ||
diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c index 660e44ed44d7..cf3eb61fad12 100644 --- a/arch/mips/kernel/topology.c +++ b/arch/mips/kernel/topology.c | |||
@@ -17,7 +17,10 @@ static int __init topology_init(void) | |||
17 | #endif /* CONFIG_NUMA */ | 17 | #endif /* CONFIG_NUMA */ |
18 | 18 | ||
19 | for_each_present_cpu(i) { | 19 | for_each_present_cpu(i) { |
20 | ret = register_cpu(&per_cpu(cpu_devices, i), i); | 20 | struct cpu *c = &per_cpu(cpu_devices, i); |
21 | |||
22 | c->hotpluggable = 1; | ||
23 | ret = register_cpu(c, i); | ||
21 | if (ret) | 24 | if (ret) |
22 | printk(KERN_WARNING "topology_init: register_cpu %d " | 25 | printk(KERN_WARNING "topology_init: register_cpu %d " |
23 | "failed (%d)\n", i, ret); | 26 | "failed (%d)\n", i, ret); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index e83da174b533..08f1edf355e8 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1502,7 +1502,7 @@ void __cpuinit per_cpu_trap_init(void) | |||
1502 | status_set); | 1502 | status_set); |
1503 | 1503 | ||
1504 | if (cpu_has_mips_r2) { | 1504 | if (cpu_has_mips_r2) { |
1505 | unsigned int enable = 0x0000000f; | 1505 | unsigned int enable = 0x0000000f | cpu_hwrena_impl_bits; |
1506 | 1506 | ||
1507 | if (!noulri && cpu_has_userlocal) | 1507 | if (!noulri && cpu_has_userlocal) |
1508 | enable |= (1 << 29); | 1508 | enable |= (1 << 29); |
@@ -1510,10 +1510,6 @@ void __cpuinit per_cpu_trap_init(void) | |||
1510 | write_c0_hwrena(enable); | 1510 | write_c0_hwrena(enable); |
1511 | } | 1511 | } |
1512 | 1512 | ||
1513 | #ifdef CONFIG_CPU_CAVIUM_OCTEON | ||
1514 | write_c0_hwrena(0xc000000f); /* Octeon has register 30 and 31 */ | ||
1515 | #endif | ||
1516 | |||
1517 | #ifdef CONFIG_MIPS_MT_SMTC | 1513 | #ifdef CONFIG_MIPS_MT_SMTC |
1518 | if (!secondaryTC) { | 1514 | if (!secondaryTC) { |
1519 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1515 | #endif /* CONFIG_MIPS_MT_SMTC */ |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 3ca5f42e819d..9a1ab7e87fd4 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -73,7 +73,7 @@ static int major; | |||
73 | static const int minor = 1; /* fixed for now */ | 73 | static const int minor = 1; /* fixed for now */ |
74 | 74 | ||
75 | #ifdef CONFIG_MIPS_APSP_KSPD | 75 | #ifdef CONFIG_MIPS_APSP_KSPD |
76 | static struct kspd_notifications kspd_events; | 76 | static struct kspd_notifications kspd_events; |
77 | static int kspd_events_reqd = 0; | 77 | static int kspd_events_reqd = 0; |
78 | #endif | 78 | #endif |
79 | 79 | ||
@@ -155,10 +155,9 @@ struct { | |||
155 | }; | 155 | }; |
156 | 156 | ||
157 | static void release_progmem(void *ptr); | 157 | static void release_progmem(void *ptr); |
158 | extern void save_gp_address(unsigned int secbase, unsigned int rel); | ||
159 | 158 | ||
160 | /* get the vpe associated with this minor */ | 159 | /* get the vpe associated with this minor */ |
161 | struct vpe *get_vpe(int minor) | 160 | static struct vpe *get_vpe(int minor) |
162 | { | 161 | { |
163 | struct vpe *v; | 162 | struct vpe *v; |
164 | 163 | ||
@@ -174,7 +173,7 @@ struct vpe *get_vpe(int minor) | |||
174 | } | 173 | } |
175 | 174 | ||
176 | /* get the vpe associated with this minor */ | 175 | /* get the vpe associated with this minor */ |
177 | struct tc *get_tc(int index) | 176 | static struct tc *get_tc(int index) |
178 | { | 177 | { |
179 | struct tc *t; | 178 | struct tc *t; |
180 | 179 | ||
@@ -186,20 +185,8 @@ struct tc *get_tc(int index) | |||
186 | return NULL; | 185 | return NULL; |
187 | } | 186 | } |
188 | 187 | ||
189 | struct tc *get_tc_unused(void) | ||
190 | { | ||
191 | struct tc *t; | ||
192 | |||
193 | list_for_each_entry(t, &vpecontrol.tc_list, list) { | ||
194 | if (t->state == TC_STATE_UNUSED) | ||
195 | return t; | ||
196 | } | ||
197 | |||
198 | return NULL; | ||
199 | } | ||
200 | |||
201 | /* allocate a vpe and associate it with this minor (or index) */ | 188 | /* allocate a vpe and associate it with this minor (or index) */ |
202 | struct vpe *alloc_vpe(int minor) | 189 | static struct vpe *alloc_vpe(int minor) |
203 | { | 190 | { |
204 | struct vpe *v; | 191 | struct vpe *v; |
205 | 192 | ||
@@ -216,7 +203,7 @@ struct vpe *alloc_vpe(int minor) | |||
216 | } | 203 | } |
217 | 204 | ||
218 | /* allocate a tc. At startup only tc0 is running, all other can be halted. */ | 205 | /* allocate a tc. At startup only tc0 is running, all other can be halted. */ |
219 | struct tc *alloc_tc(int index) | 206 | static struct tc *alloc_tc(int index) |
220 | { | 207 | { |
221 | struct tc *tc; | 208 | struct tc *tc; |
222 | 209 | ||
@@ -232,7 +219,7 @@ out: | |||
232 | } | 219 | } |
233 | 220 | ||
234 | /* clean up and free everything */ | 221 | /* clean up and free everything */ |
235 | void release_vpe(struct vpe *v) | 222 | static void release_vpe(struct vpe *v) |
236 | { | 223 | { |
237 | list_del(&v->list); | 224 | list_del(&v->list); |
238 | if (v->load_addr) | 225 | if (v->load_addr) |
@@ -240,7 +227,7 @@ void release_vpe(struct vpe *v) | |||
240 | kfree(v); | 227 | kfree(v); |
241 | } | 228 | } |
242 | 229 | ||
243 | void dump_mtregs(void) | 230 | static void dump_mtregs(void) |
244 | { | 231 | { |
245 | unsigned long val; | 232 | unsigned long val; |
246 | 233 | ||
@@ -327,7 +314,8 @@ static void layout_sections(struct module *mod, const Elf_Ehdr * hdr, | |||
327 | || (s->sh_flags & masks[m][1]) | 314 | || (s->sh_flags & masks[m][1]) |
328 | || s->sh_entsize != ~0UL) | 315 | || s->sh_entsize != ~0UL) |
329 | continue; | 316 | continue; |
330 | s->sh_entsize = get_offset(&mod->core_size, s); | 317 | s->sh_entsize = |
318 | get_offset((unsigned long *)&mod->core_size, s); | ||
331 | } | 319 | } |
332 | 320 | ||
333 | if (m == 0) | 321 | if (m == 0) |
@@ -461,16 +449,15 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
461 | { | 449 | { |
462 | unsigned long insnlo = *location; | 450 | unsigned long insnlo = *location; |
463 | Elf32_Addr val, vallo; | 451 | Elf32_Addr val, vallo; |
452 | struct mips_hi16 *l, *next; | ||
464 | 453 | ||
465 | /* Sign extend the addend we extract from the lo insn. */ | 454 | /* Sign extend the addend we extract from the lo insn. */ |
466 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; | 455 | vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; |
467 | 456 | ||
468 | if (mips_hi16_list != NULL) { | 457 | if (mips_hi16_list != NULL) { |
469 | struct mips_hi16 *l; | ||
470 | 458 | ||
471 | l = mips_hi16_list; | 459 | l = mips_hi16_list; |
472 | while (l != NULL) { | 460 | while (l != NULL) { |
473 | struct mips_hi16 *next; | ||
474 | unsigned long insn; | 461 | unsigned long insn; |
475 | 462 | ||
476 | /* | 463 | /* |
@@ -480,7 +467,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
480 | printk(KERN_DEBUG "VPE loader: " | 467 | printk(KERN_DEBUG "VPE loader: " |
481 | "apply_r_mips_lo16/hi16: \t" | 468 | "apply_r_mips_lo16/hi16: \t" |
482 | "inconsistent value information\n"); | 469 | "inconsistent value information\n"); |
483 | return -ENOEXEC; | 470 | goto out_free; |
484 | } | 471 | } |
485 | 472 | ||
486 | /* | 473 | /* |
@@ -518,6 +505,16 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
518 | *location = insnlo; | 505 | *location = insnlo; |
519 | 506 | ||
520 | return 0; | 507 | return 0; |
508 | |||
509 | out_free: | ||
510 | while (l != NULL) { | ||
511 | next = l->next; | ||
512 | kfree(l); | ||
513 | l = next; | ||
514 | } | ||
515 | mips_hi16_list = NULL; | ||
516 | |||
517 | return -ENOEXEC; | ||
521 | } | 518 | } |
522 | 519 | ||
523 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, | 520 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, |
@@ -541,7 +538,7 @@ static char *rstrs[] = { | |||
541 | [R_MIPS_PC16] = "MIPS_PC16" | 538 | [R_MIPS_PC16] = "MIPS_PC16" |
542 | }; | 539 | }; |
543 | 540 | ||
544 | int apply_relocations(Elf32_Shdr *sechdrs, | 541 | static int apply_relocations(Elf32_Shdr *sechdrs, |
545 | const char *strtab, | 542 | const char *strtab, |
546 | unsigned int symindex, | 543 | unsigned int symindex, |
547 | unsigned int relsec, | 544 | unsigned int relsec, |
@@ -586,7 +583,7 @@ int apply_relocations(Elf32_Shdr *sechdrs, | |||
586 | return 0; | 583 | return 0; |
587 | } | 584 | } |
588 | 585 | ||
589 | void save_gp_address(unsigned int secbase, unsigned int rel) | 586 | static inline void save_gp_address(unsigned int secbase, unsigned int rel) |
590 | { | 587 | { |
591 | gp_addr = secbase + rel; | 588 | gp_addr = secbase + rel; |
592 | gp_offs = gp_addr - (secbase & 0xffff0000); | 589 | gp_offs = gp_addr - (secbase & 0xffff0000); |
@@ -1387,7 +1384,7 @@ static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, | |||
1387 | return len; | 1384 | return len; |
1388 | 1385 | ||
1389 | out_einval: | 1386 | out_einval: |
1390 | return -EINVAL;; | 1387 | return -EINVAL; |
1391 | } | 1388 | } |
1392 | 1389 | ||
1393 | static struct device_attribute vpe_class_attributes[] = { | 1390 | static struct device_attribute vpe_class_attributes[] = { |