diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-gt641xx.c | 12 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-r4k.c | 45 | ||||
-rw-r--r-- | arch/mips/kernel/cevt-txx9.c | 171 | ||||
-rw-r--r-- | arch/mips/kernel/irixsig.c | 8 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 18 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace32.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 57 | ||||
-rw-r--r-- | arch/mips/kernel/syscall.c | 9 | ||||
-rw-r--r-- | arch/mips/kernel/time.c | 17 | ||||
-rw-r--r-- | arch/mips/kernel/vmlinux.lds.S | 32 | ||||
-rw-r--r-- | arch/mips/kernel/vpe.c | 4 |
12 files changed, 307 insertions, 71 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index d7745c8976f6..3196509a28d5 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -10,6 +10,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ | |||
10 | 10 | ||
11 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o | 11 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o |
12 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o | 12 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o |
13 | obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o | ||
13 | 14 | ||
14 | binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ | 15 | binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ |
15 | irix5sys.o sysirix.o | 16 | irix5sys.o sysirix.o |
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c index 4c651b2680f9..c36772631fe0 100644 --- a/arch/mips/kernel/cevt-gt641xx.c +++ b/arch/mips/kernel/cevt-gt641xx.c | |||
@@ -49,10 +49,9 @@ int gt641xx_timer0_state(void) | |||
49 | static int gt641xx_timer0_set_next_event(unsigned long delta, | 49 | static int gt641xx_timer0_set_next_event(unsigned long delta, |
50 | struct clock_event_device *evt) | 50 | struct clock_event_device *evt) |
51 | { | 51 | { |
52 | unsigned long flags; | ||
53 | u32 ctrl; | 52 | u32 ctrl; |
54 | 53 | ||
55 | spin_lock_irqsave(>641xx_timer_lock, flags); | 54 | spin_lock(>641xx_timer_lock); |
56 | 55 | ||
57 | ctrl = GT_READ(GT_TC_CONTROL_OFS); | 56 | ctrl = GT_READ(GT_TC_CONTROL_OFS); |
58 | ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); | 57 | ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); |
@@ -61,7 +60,7 @@ static int gt641xx_timer0_set_next_event(unsigned long delta, | |||
61 | GT_WRITE(GT_TC0_OFS, delta); | 60 | GT_WRITE(GT_TC0_OFS, delta); |
62 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); | 61 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); |
63 | 62 | ||
64 | spin_unlock_irqrestore(>641xx_timer_lock, flags); | 63 | spin_unlock(>641xx_timer_lock); |
65 | 64 | ||
66 | return 0; | 65 | return 0; |
67 | } | 66 | } |
@@ -69,10 +68,9 @@ static int gt641xx_timer0_set_next_event(unsigned long delta, | |||
69 | static void gt641xx_timer0_set_mode(enum clock_event_mode mode, | 68 | static void gt641xx_timer0_set_mode(enum clock_event_mode mode, |
70 | struct clock_event_device *evt) | 69 | struct clock_event_device *evt) |
71 | { | 70 | { |
72 | unsigned long flags; | ||
73 | u32 ctrl; | 71 | u32 ctrl; |
74 | 72 | ||
75 | spin_lock_irqsave(>641xx_timer_lock, flags); | 73 | spin_lock(>641xx_timer_lock); |
76 | 74 | ||
77 | ctrl = GT_READ(GT_TC_CONTROL_OFS); | 75 | ctrl = GT_READ(GT_TC_CONTROL_OFS); |
78 | ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); | 76 | ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); |
@@ -90,7 +88,7 @@ static void gt641xx_timer0_set_mode(enum clock_event_mode mode, | |||
90 | 88 | ||
91 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); | 89 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); |
92 | 90 | ||
93 | spin_unlock_irqrestore(>641xx_timer_lock, flags); | 91 | spin_unlock(>641xx_timer_lock); |
94 | } | 92 | } |
95 | 93 | ||
96 | static void gt641xx_timer0_event_handler(struct clock_event_device *dev) | 94 | static void gt641xx_timer0_event_handler(struct clock_event_device *dev) |
@@ -133,9 +131,9 @@ static int __init gt641xx_timer0_clockevent_init(void) | |||
133 | 131 | ||
134 | cd = >641xx_timer0_clockevent; | 132 | cd = >641xx_timer0_clockevent; |
135 | cd->rating = 200 + gt641xx_base_clock / 10000000; | 133 | cd->rating = 200 + gt641xx_base_clock / 10000000; |
134 | clockevent_set_clock(cd, gt641xx_base_clock); | ||
136 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | 135 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); |
137 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | 136 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); |
138 | clockevent_set_clock(cd, gt641xx_base_clock); | ||
139 | 137 | ||
140 | clockevents_register_device(>641xx_timer0_clockevent); | 138 | clockevents_register_device(>641xx_timer0_clockevent); |
141 | 139 | ||
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index ae2984fff580..bab935a3d74b 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -28,7 +28,7 @@ static int mips_next_event(unsigned long delta, | |||
28 | cnt = read_c0_count(); | 28 | cnt = read_c0_count(); |
29 | cnt += delta; | 29 | cnt += delta; |
30 | write_c0_compare(cnt); | 30 | write_c0_compare(cnt); |
31 | res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0; | 31 | res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; |
32 | #ifdef CONFIG_MIPS_MT_SMTC | 32 | #ifdef CONFIG_MIPS_MT_SMTC |
33 | evpe(vpflags); | 33 | evpe(vpflags); |
34 | local_irq_restore(flags); | 34 | local_irq_restore(flags); |
@@ -179,7 +179,7 @@ static int c0_compare_int_pending(void) | |||
179 | 179 | ||
180 | static int c0_compare_int_usable(void) | 180 | static int c0_compare_int_usable(void) |
181 | { | 181 | { |
182 | const unsigned int delta = 0x300000; | 182 | unsigned int delta; |
183 | unsigned int cnt; | 183 | unsigned int cnt; |
184 | 184 | ||
185 | /* | 185 | /* |
@@ -192,11 +192,17 @@ static int c0_compare_int_usable(void) | |||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | cnt = read_c0_count(); | 195 | for (delta = 0x10; delta <= 0x400000; delta <<= 1) { |
196 | cnt += delta; | 196 | cnt = read_c0_count(); |
197 | write_c0_compare(cnt); | 197 | cnt += delta; |
198 | write_c0_compare(cnt); | ||
199 | irq_disable_hazard(); | ||
200 | if ((int)(read_c0_count() - cnt) < 0) | ||
201 | break; | ||
202 | /* increase delta if the timer was already expired */ | ||
203 | } | ||
198 | 204 | ||
199 | while ((long)(read_c0_count() - cnt) <= 0) | 205 | while ((int)(read_c0_count() - cnt) <= 0) |
200 | ; /* Wait for expiry */ | 206 | ; /* Wait for expiry */ |
201 | 207 | ||
202 | if (!c0_compare_int_pending()) | 208 | if (!c0_compare_int_pending()) |
@@ -218,9 +224,9 @@ void __cpuinit mips_clockevent_init(void) | |||
218 | uint64_t mips_freq = mips_hpt_frequency; | 224 | uint64_t mips_freq = mips_hpt_frequency; |
219 | unsigned int cpu = smp_processor_id(); | 225 | unsigned int cpu = smp_processor_id(); |
220 | struct clock_event_device *cd; | 226 | struct clock_event_device *cd; |
221 | unsigned int irq = MIPS_CPU_IRQ_BASE + 7; | 227 | unsigned int irq; |
222 | 228 | ||
223 | if (!cpu_has_counter) | 229 | if (!cpu_has_counter || !mips_hpt_frequency) |
224 | return; | 230 | return; |
225 | 231 | ||
226 | #ifdef CONFIG_MIPS_MT_SMTC | 232 | #ifdef CONFIG_MIPS_MT_SMTC |
@@ -237,6 +243,15 @@ void __cpuinit mips_clockevent_init(void) | |||
237 | if (!c0_compare_int_usable()) | 243 | if (!c0_compare_int_usable()) |
238 | return; | 244 | return; |
239 | 245 | ||
246 | /* | ||
247 | * With vectored interrupts things are getting platform specific. | ||
248 | * get_c0_compare_int is a hook to allow a platform to return the | ||
249 | * interrupt number of it's liking. | ||
250 | */ | ||
251 | irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | ||
252 | if (get_c0_compare_int) | ||
253 | irq = get_c0_compare_int(); | ||
254 | |||
240 | cd = &per_cpu(mips_clockevent_device, cpu); | 255 | cd = &per_cpu(mips_clockevent_device, cpu); |
241 | 256 | ||
242 | cd->name = "MIPS"; | 257 | cd->name = "MIPS"; |
@@ -261,13 +276,15 @@ void __cpuinit mips_clockevent_init(void) | |||
261 | 276 | ||
262 | clockevents_register_device(cd); | 277 | clockevents_register_device(cd); |
263 | 278 | ||
264 | if (!cp0_timer_irq_installed) { | 279 | if (!cp0_timer_irq_installed) |
280 | return; | ||
281 | |||
282 | cp0_timer_irq_installed = 1; | ||
283 | |||
265 | #ifdef CONFIG_MIPS_MT_SMTC | 284 | #ifdef CONFIG_MIPS_MT_SMTC |
266 | #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) | 285 | #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) |
267 | setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); | 286 | setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); |
268 | #else | 287 | #else |
269 | setup_irq(irq, &c0_compare_irqaction); | 288 | setup_irq(irq, &c0_compare_irqaction); |
270 | #endif /* CONFIG_MIPS_MT_SMTC */ | 289 | #endif |
271 | cp0_timer_irq_installed = 1; | ||
272 | } | ||
273 | } | 290 | } |
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c new file mode 100644 index 000000000000..795cb8fb0d74 --- /dev/null +++ b/arch/mips/kernel/cevt-txx9.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Based on linux/arch/mips/kernel/cevt-r4k.c, | ||
7 | * linux/arch/mips/jmr3927/rbhma3100/setup.c | ||
8 | * | ||
9 | * Copyright 2001 MontaVista Software Inc. | ||
10 | * Copyright (C) 2000-2001 Toshiba Corporation | ||
11 | * Copyright (C) 2007 MIPS Technologies, Inc. | ||
12 | * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org> | ||
13 | */ | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <asm/time.h> | ||
17 | #include <asm/txx9tmr.h> | ||
18 | |||
19 | #define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL) | ||
20 | #define TIMER_CCD 0 /* 1/2 */ | ||
21 | #define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD)) | ||
22 | |||
23 | static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr; | ||
24 | |||
25 | static cycle_t txx9_cs_read(void) | ||
26 | { | ||
27 | return __raw_readl(&txx9_cs_tmrptr->trr); | ||
28 | } | ||
29 | |||
30 | /* Use 1 bit smaller width to use full bits in that width */ | ||
31 | #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1) | ||
32 | |||
33 | static struct clocksource txx9_clocksource = { | ||
34 | .name = "TXx9", | ||
35 | .rating = 200, | ||
36 | .read = txx9_cs_read, | ||
37 | .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS), | ||
38 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
39 | }; | ||
40 | |||
41 | void __init txx9_clocksource_init(unsigned long baseaddr, | ||
42 | unsigned int imbusclk) | ||
43 | { | ||
44 | struct txx9_tmr_reg __iomem *tmrptr; | ||
45 | |||
46 | clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk)); | ||
47 | clocksource_register(&txx9_clocksource); | ||
48 | |||
49 | tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); | ||
50 | __raw_writel(TCR_BASE, &tmrptr->tcr); | ||
51 | __raw_writel(0, &tmrptr->tisr); | ||
52 | __raw_writel(TIMER_CCD, &tmrptr->ccdr); | ||
53 | __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr); | ||
54 | __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra); | ||
55 | __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); | ||
56 | txx9_cs_tmrptr = tmrptr; | ||
57 | } | ||
58 | |||
59 | static struct txx9_tmr_reg __iomem *txx9_tmrptr; | ||
60 | |||
61 | static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr) | ||
62 | { | ||
63 | /* stop and reset counter */ | ||
64 | __raw_writel(TCR_BASE, &tmrptr->tcr); | ||
65 | /* clear pending interrupt */ | ||
66 | __raw_writel(0, &tmrptr->tisr); | ||
67 | } | ||
68 | |||
69 | static void txx9tmr_set_mode(enum clock_event_mode mode, | ||
70 | struct clock_event_device *evt) | ||
71 | { | ||
72 | struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; | ||
73 | |||
74 | txx9tmr_stop_and_clear(tmrptr); | ||
75 | switch (mode) { | ||
76 | case CLOCK_EVT_MODE_PERIODIC: | ||
77 | __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE, | ||
78 | &tmrptr->itmr); | ||
79 | /* start timer */ | ||
80 | __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >> | ||
81 | evt->shift, | ||
82 | &tmrptr->cpra); | ||
83 | __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); | ||
84 | break; | ||
85 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
86 | case CLOCK_EVT_MODE_UNUSED: | ||
87 | __raw_writel(0, &tmrptr->itmr); | ||
88 | break; | ||
89 | case CLOCK_EVT_MODE_ONESHOT: | ||
90 | __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr); | ||
91 | break; | ||
92 | case CLOCK_EVT_MODE_RESUME: | ||
93 | __raw_writel(TIMER_CCD, &tmrptr->ccdr); | ||
94 | __raw_writel(0, &tmrptr->itmr); | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | static int txx9tmr_set_next_event(unsigned long delta, | ||
100 | struct clock_event_device *evt) | ||
101 | { | ||
102 | struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; | ||
103 | |||
104 | txx9tmr_stop_and_clear(tmrptr); | ||
105 | /* start timer */ | ||
106 | __raw_writel(delta, &tmrptr->cpra); | ||
107 | __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static struct clock_event_device txx9tmr_clock_event_device = { | ||
112 | .name = "TXx9", | ||
113 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
114 | .rating = 200, | ||
115 | .cpumask = CPU_MASK_CPU0, | ||
116 | .set_mode = txx9tmr_set_mode, | ||
117 | .set_next_event = txx9tmr_set_next_event, | ||
118 | }; | ||
119 | |||
120 | static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id) | ||
121 | { | ||
122 | struct clock_event_device *cd = &txx9tmr_clock_event_device; | ||
123 | struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr; | ||
124 | |||
125 | __raw_writel(0, &tmrptr->tisr); /* ack interrupt */ | ||
126 | cd->event_handler(cd); | ||
127 | return IRQ_HANDLED; | ||
128 | } | ||
129 | |||
130 | static struct irqaction txx9tmr_irq = { | ||
131 | .handler = txx9tmr_interrupt, | ||
132 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
133 | .name = "txx9tmr", | ||
134 | }; | ||
135 | |||
136 | void __init txx9_clockevent_init(unsigned long baseaddr, int irq, | ||
137 | unsigned int imbusclk) | ||
138 | { | ||
139 | struct clock_event_device *cd = &txx9tmr_clock_event_device; | ||
140 | struct txx9_tmr_reg __iomem *tmrptr; | ||
141 | |||
142 | tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); | ||
143 | txx9tmr_stop_and_clear(tmrptr); | ||
144 | __raw_writel(TIMER_CCD, &tmrptr->ccdr); | ||
145 | __raw_writel(0, &tmrptr->itmr); | ||
146 | txx9_tmrptr = tmrptr; | ||
147 | |||
148 | clockevent_set_clock(cd, TIMER_CLK(imbusclk)); | ||
149 | cd->max_delta_ns = | ||
150 | clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd); | ||
151 | cd->min_delta_ns = clockevent_delta2ns(0xf, cd); | ||
152 | cd->irq = irq; | ||
153 | clockevents_register_device(cd); | ||
154 | setup_irq(irq, &txx9tmr_irq); | ||
155 | printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n", | ||
156 | baseaddr, irq); | ||
157 | } | ||
158 | |||
159 | void __init txx9_tmr_init(unsigned long baseaddr) | ||
160 | { | ||
161 | struct txx9_tmr_reg __iomem *tmrptr; | ||
162 | |||
163 | tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg)); | ||
164 | __raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr); | ||
165 | __raw_writel(0, &tmrptr->tisr); | ||
166 | __raw_writel(0xffffffff, &tmrptr->cpra); | ||
167 | __raw_writel(0, &tmrptr->itmr); | ||
168 | __raw_writel(0, &tmrptr->ccdr); | ||
169 | __raw_writel(0, &tmrptr->pgmr); | ||
170 | iounmap(tmrptr); | ||
171 | } | ||
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index a0a91056fda7..33506ff25910 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c | |||
@@ -24,8 +24,12 @@ | |||
24 | 24 | ||
25 | #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) | 25 | #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) |
26 | 26 | ||
27 | #define _IRIX_NSIG 128 | ||
28 | #define _IRIX_NSIG_BPW BITS_PER_LONG | ||
29 | #define _IRIX_NSIG_WORDS (_IRIX_NSIG / _IRIX_NSIG_BPW) | ||
30 | |||
27 | typedef struct { | 31 | typedef struct { |
28 | unsigned long sig[4]; | 32 | unsigned long sig[_IRIX_NSIG_WORDS]; |
29 | } irix_sigset_t; | 33 | } irix_sigset_t; |
30 | 34 | ||
31 | struct sigctx_irix5 { | 35 | struct sigctx_irix5 { |
@@ -527,7 +531,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set, | |||
527 | 531 | ||
528 | expire = schedule_timeout_interruptible(expire); | 532 | expire = schedule_timeout_interruptible(expire); |
529 | 533 | ||
530 | for (i=0; i<=4; i++) | 534 | for (i=0; i < _IRIX_NSIG_WORDS; i++) |
531 | tmp |= (current->pending.signal.sig[i] & kset.sig[i]); | 535 | tmp |= (current->pending.signal.sig[i] & kset.sig[i]); |
532 | 536 | ||
533 | if (tmp) | 537 | if (tmp) |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 999f7853de26..35234b92b9a5 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -65,13 +65,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data) | |||
65 | regs = task_pt_regs(child); | 65 | regs = task_pt_regs(child); |
66 | 66 | ||
67 | for (i = 0; i < 32; i++) | 67 | for (i = 0; i < 32; i++) |
68 | __put_user(regs->regs[i], data + i); | 68 | __put_user((long)regs->regs[i], data + i); |
69 | __put_user(regs->lo, data + EF_LO - EF_R0); | 69 | __put_user((long)regs->lo, data + EF_LO - EF_R0); |
70 | __put_user(regs->hi, data + EF_HI - EF_R0); | 70 | __put_user((long)regs->hi, data + EF_HI - EF_R0); |
71 | __put_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0); | 71 | __put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0); |
72 | __put_user(regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0); | 72 | __put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0); |
73 | __put_user(regs->cp0_status, data + EF_CP0_STATUS - EF_R0); | 73 | __put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0); |
74 | __put_user(regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0); | 74 | __put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0); |
75 | 75 | ||
76 | return 0; | 76 | return 0; |
77 | } | 77 | } |
@@ -390,11 +390,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
390 | } | 390 | } |
391 | 391 | ||
392 | case PTRACE_GETREGS: | 392 | case PTRACE_GETREGS: |
393 | ret = ptrace_getregs(child, (__u64 __user *) data); | 393 | ret = ptrace_getregs(child, (__s64 __user *) data); |
394 | break; | 394 | break; |
395 | 395 | ||
396 | case PTRACE_SETREGS: | 396 | case PTRACE_SETREGS: |
397 | ret = ptrace_setregs(child, (__u64 __user *) data); | 397 | ret = ptrace_setregs(child, (__s64 __user *) data); |
398 | break; | 398 | break; |
399 | 399 | ||
400 | case PTRACE_GETFPREGS: | 400 | case PTRACE_GETFPREGS: |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index f2bffed94fa3..76818be6ba7c 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -346,11 +346,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
346 | } | 346 | } |
347 | 347 | ||
348 | case PTRACE_GETREGS: | 348 | case PTRACE_GETREGS: |
349 | ret = ptrace_getregs(child, (__u64 __user *) (__u64) data); | 349 | ret = ptrace_getregs(child, (__s64 __user *) (__u64) data); |
350 | break; | 350 | break; |
351 | 351 | ||
352 | case PTRACE_SETREGS: | 352 | case PTRACE_SETREGS: |
353 | ret = ptrace_setregs(child, (__u64 __user *) (__u64) data); | 353 | ret = ptrace_setregs(child, (__s64 __user *) (__u64) data); |
354 | break; | 354 | break; |
355 | 355 | ||
356 | case PTRACE_GETFPREGS: | 356 | case PTRACE_GETFPREGS: |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index a8c1a698d588..9c92d42996cb 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -88,11 +88,19 @@ unsigned int smtc_status = 0; | |||
88 | 88 | ||
89 | /* Boot command line configuration overrides */ | 89 | /* Boot command line configuration overrides */ |
90 | 90 | ||
91 | static int vpe0limit; | ||
91 | static int ipibuffers = 0; | 92 | static int ipibuffers = 0; |
92 | static int nostlb = 0; | 93 | static int nostlb = 0; |
93 | static int asidmask = 0; | 94 | static int asidmask = 0; |
94 | unsigned long smtc_asid_mask = 0xff; | 95 | unsigned long smtc_asid_mask = 0xff; |
95 | 96 | ||
97 | static int __init vpe0tcs(char *str) | ||
98 | { | ||
99 | get_option(&str, &vpe0limit); | ||
100 | |||
101 | return 1; | ||
102 | } | ||
103 | |||
96 | static int __init ipibufs(char *str) | 104 | static int __init ipibufs(char *str) |
97 | { | 105 | { |
98 | get_option(&str, &ipibuffers); | 106 | get_option(&str, &ipibuffers); |
@@ -125,6 +133,7 @@ static int __init asidmask_set(char *str) | |||
125 | return 1; | 133 | return 1; |
126 | } | 134 | } |
127 | 135 | ||
136 | __setup("vpe0tcs=", vpe0tcs); | ||
128 | __setup("ipibufs=", ipibufs); | 137 | __setup("ipibufs=", ipibufs); |
129 | __setup("nostlb", stlb_disable); | 138 | __setup("nostlb", stlb_disable); |
130 | __setup("asidmask=", asidmask_set); | 139 | __setup("asidmask=", asidmask_set); |
@@ -340,7 +349,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | |||
340 | 349 | ||
341 | void mipsmt_prepare_cpus(void) | 350 | void mipsmt_prepare_cpus(void) |
342 | { | 351 | { |
343 | int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu; | 352 | int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu; |
344 | unsigned long flags; | 353 | unsigned long flags; |
345 | unsigned long val; | 354 | unsigned long val; |
346 | int nipi; | 355 | int nipi; |
@@ -401,8 +410,39 @@ void mipsmt_prepare_cpus(void) | |||
401 | ntc = NR_CPUS; | 410 | ntc = NR_CPUS; |
402 | if (tclimit > 0 && ntc > tclimit) | 411 | if (tclimit > 0 && ntc > tclimit) |
403 | ntc = tclimit; | 412 | ntc = tclimit; |
404 | tcpervpe = ntc / nvpe; | 413 | slop = ntc % nvpe; |
405 | slop = ntc % nvpe; /* Residual TCs, < NVPE */ | 414 | for (i = 0; i < nvpe; i++) { |
415 | tcpervpe[i] = ntc / nvpe; | ||
416 | if (slop) { | ||
417 | if((slop - i) > 0) tcpervpe[i]++; | ||
418 | } | ||
419 | } | ||
420 | /* Handle command line override for VPE0 */ | ||
421 | if (vpe0limit > ntc) vpe0limit = ntc; | ||
422 | if (vpe0limit > 0) { | ||
423 | int slopslop; | ||
424 | if (vpe0limit < tcpervpe[0]) { | ||
425 | /* Reducing TC count - distribute to others */ | ||
426 | slop = tcpervpe[0] - vpe0limit; | ||
427 | slopslop = slop % (nvpe - 1); | ||
428 | tcpervpe[0] = vpe0limit; | ||
429 | for (i = 1; i < nvpe; i++) { | ||
430 | tcpervpe[i] += slop / (nvpe - 1); | ||
431 | if(slopslop && ((slopslop - (i - 1) > 0))) | ||
432 | tcpervpe[i]++; | ||
433 | } | ||
434 | } else if (vpe0limit > tcpervpe[0]) { | ||
435 | /* Increasing TC count - steal from others */ | ||
436 | slop = vpe0limit - tcpervpe[0]; | ||
437 | slopslop = slop % (nvpe - 1); | ||
438 | tcpervpe[0] = vpe0limit; | ||
439 | for (i = 1; i < nvpe; i++) { | ||
440 | tcpervpe[i] -= slop / (nvpe - 1); | ||
441 | if(slopslop && ((slopslop - (i - 1) > 0))) | ||
442 | tcpervpe[i]--; | ||
443 | } | ||
444 | } | ||
445 | } | ||
406 | 446 | ||
407 | /* Set up shared TLB */ | 447 | /* Set up shared TLB */ |
408 | smtc_configure_tlb(); | 448 | smtc_configure_tlb(); |
@@ -416,7 +456,7 @@ void mipsmt_prepare_cpus(void) | |||
416 | if (vpe != 0) | 456 | if (vpe != 0) |
417 | printk(", "); | 457 | printk(", "); |
418 | printk("VPE %d: TC", vpe); | 458 | printk("VPE %d: TC", vpe); |
419 | for (i = 0; i < tcpervpe; i++) { | 459 | for (i = 0; i < tcpervpe[vpe]; i++) { |
420 | /* | 460 | /* |
421 | * TC 0 is bound to VPE 0 at reset, | 461 | * TC 0 is bound to VPE 0 at reset, |
422 | * and is presumably executing this | 462 | * and is presumably executing this |
@@ -429,15 +469,6 @@ void mipsmt_prepare_cpus(void) | |||
429 | printk(" %d", tc); | 469 | printk(" %d", tc); |
430 | tc++; | 470 | tc++; |
431 | } | 471 | } |
432 | if (slop) { | ||
433 | if (tc != 0) { | ||
434 | smtc_tc_setup(vpe, tc, cpu); | ||
435 | cpu++; | ||
436 | } | ||
437 | printk(" %d", tc); | ||
438 | tc++; | ||
439 | slop--; | ||
440 | } | ||
441 | if (vpe != 0) { | 472 | if (vpe != 0) { |
442 | /* | 473 | /* |
443 | * Clear any stale software interrupts from VPE's Cause | 474 | * Clear any stale software interrupts from VPE's Cause |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index b95fe93dd646..af1bdc897488 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -73,7 +73,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
73 | 73 | ||
74 | task_size = STACK_TOP; | 74 | task_size = STACK_TOP; |
75 | 75 | ||
76 | if (len > task_size) | ||
77 | return -ENOMEM; | ||
78 | |||
76 | if (flags & MAP_FIXED) { | 79 | if (flags & MAP_FIXED) { |
80 | /* Even MAP_FIXED mappings must reside within task_size. */ | ||
81 | if (task_size - len < addr) | ||
82 | return -EINVAL; | ||
83 | |||
77 | /* | 84 | /* |
78 | * We do not accept a shared mapping if it would violate | 85 | * We do not accept a shared mapping if it would violate |
79 | * cache aliasing constraints. | 86 | * cache aliasing constraints. |
@@ -83,8 +90,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
83 | return addr; | 90 | return addr; |
84 | } | 91 | } |
85 | 92 | ||
86 | if (len > task_size) | ||
87 | return -ENOMEM; | ||
88 | do_color_align = 0; | 93 | do_color_align = 0; |
89 | if (filp || (flags & MAP_SHARED)) | 94 | if (filp || (flags & MAP_SHARED)) |
90 | do_color_align = 1; | 95 | do_color_align = 1; |
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 6c6849a8f136..27228f583dae 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | #include <linux/bug.h> | ||
14 | #include <linux/clockchips.h> | 15 | #include <linux/clockchips.h> |
15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
@@ -115,10 +116,6 @@ EXPORT_SYMBOL(perf_irq); | |||
115 | * (only needed if you intended to use cpu counter as timer interrupt | 116 | * (only needed if you intended to use cpu counter as timer interrupt |
116 | * source) | 117 | * source) |
117 | * 2) calculate a couple of cached variables for later usage | 118 | * 2) calculate a couple of cached variables for later usage |
118 | * 3) plat_timer_setup() - | ||
119 | * a) (optional) over-write any choices made above by time_init(). | ||
120 | * b) machine specific code should setup the timer irqaction. | ||
121 | * c) enable the timer interrupt | ||
122 | */ | 119 | */ |
123 | 120 | ||
124 | unsigned int mips_hpt_frequency; | 121 | unsigned int mips_hpt_frequency; |
@@ -221,8 +218,18 @@ void __init __weak plat_time_init(void) | |||
221 | { | 218 | { |
222 | } | 219 | } |
223 | 220 | ||
224 | void __init __weak plat_timer_setup(struct irqaction *irq) | 221 | /* |
222 | * This function exists in order to cause an error due to a duplicate | ||
223 | * definition if platform code should have its own implementation. The hook | ||
224 | * to use instead is plat_time_init. plat_time_init does not receive the | ||
225 | * irqaction pointer argument anymore. This is because any function which | ||
226 | * initializes an interrupt timer now takes care of its own request_irq rsp. | ||
227 | * setup_irq calls and each clock_event_device should use its own | ||
228 | * struct irqrequest. | ||
229 | */ | ||
230 | void __init plat_timer_setup(struct irqaction *irq) | ||
225 | { | 231 | { |
232 | BUG(); | ||
226 | } | 233 | } |
227 | 234 | ||
228 | void __init time_init(void) | 235 | void __init time_init(void) |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2781cff1485e..5fc2398bdb76 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -63,21 +63,23 @@ SECTIONS | |||
63 | 63 | ||
64 | /* writeable */ | 64 | /* writeable */ |
65 | .data : { /* Data */ | 65 | .data : { /* Data */ |
66 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ | 66 | . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ |
67 | /* | 67 | /* |
68 | * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which | 68 | * This ALIGN is needed as a workaround for a bug a |
69 | * limits the maximum alignment to at most 32kB and results in the following | 69 | * gcc bug upto 4.1 which limits the maximum alignment |
70 | * warning: | 70 | * to at most 32kB and results in the following |
71 | * | 71 | * warning: |
72 | * CC arch/mips/kernel/init_task.o | 72 | * |
73 | * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’ | 73 | * CC arch/mips/kernel/init_task.o |
74 | * is greater than maximum object file alignment. Using 32768 | 74 | * arch/mips/kernel/init_task.c:30: warning: alignment |
75 | */ | 75 | * of ‘init_thread_union’ is greater than maximum |
76 | . = ALIGN(_PAGE_SIZE); | 76 | * object file alignment. Using 32768 |
77 | *(.data.init_task) | 77 | */ |
78 | 78 | . = ALIGN(_PAGE_SIZE); | |
79 | DATA_DATA | 79 | *(.data.init_task) |
80 | CONSTRUCTORS | 80 | |
81 | DATA_DATA | ||
82 | CONSTRUCTORS | ||
81 | } | 83 | } |
82 | _gp = . + 0x8000; | 84 | _gp = . + 0x8000; |
83 | .lit8 : { | 85 | .lit8 : { |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index df8cbe4c7c0d..436a64ff3989 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -942,8 +942,8 @@ static int vpe_elfload(struct vpe * v) | |||
942 | if (phdr->p_type != PT_LOAD) | 942 | if (phdr->p_type != PT_LOAD) |
943 | continue; | 943 | continue; |
944 | 944 | ||
945 | memcpy((void *)phdr->p_vaddr, (char *)hdr + phdr->p_offset, phdr->p_filesz); | 945 | memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz); |
946 | memset((void *)phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); | 946 | memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); |
947 | phdr++; | 947 | phdr++; |
948 | } | 948 | } |
949 | 949 | ||