diff options
183 files changed, 5679 insertions, 1693 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index af0e9393bf68..309c47b91598 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -282,6 +282,13 @@ Why: Not used in-tree. The current out-of-tree users used it to | |||
282 | out-of-tree driver. | 282 | out-of-tree driver. |
283 | Who: Thomas Gleixner <tglx@linutronix.de> | 283 | Who: Thomas Gleixner <tglx@linutronix.de> |
284 | 284 | ||
285 | ---------------------------- | ||
286 | |||
287 | What: usedac i386 kernel parameter | ||
288 | When: 2.6.27 | ||
289 | Why: replaced by allowdac and no dac combination | ||
290 | Who: Glauber Costa <gcosta@redhat.com> | ||
291 | |||
285 | --------------------------- | 292 | --------------------------- |
286 | 293 | ||
287 | What: /sys/o2cb symlink | 294 | What: /sys/o2cb symlink |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 4b0f1ae31a4c..f4839606988b 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1280,8 +1280,16 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1280 | noexec [IA-64] | 1280 | noexec [IA-64] |
1281 | 1281 | ||
1282 | noexec [X86-32,X86-64] | 1282 | noexec [X86-32,X86-64] |
1283 | On X86-32 available only on PAE configured kernels. | ||
1283 | noexec=on: enable non-executable mappings (default) | 1284 | noexec=on: enable non-executable mappings (default) |
1284 | noexec=off: disable nn-executable mappings | 1285 | noexec=off: disable non-executable mappings |
1286 | |||
1287 | noexec32 [X86-64] | ||
1288 | This affects only 32-bit executables. | ||
1289 | noexec32=on: enable non-executable mappings (default) | ||
1290 | read doesn't imply executable mappings | ||
1291 | noexec32=off: disable non-executable mappings | ||
1292 | read implies executable mappings | ||
1285 | 1293 | ||
1286 | nofxsr [BUGS=X86-32] Disables x86 floating point extended | 1294 | nofxsr [BUGS=X86-32] Disables x86 floating point extended |
1287 | register save and restore. The kernel will only save | 1295 | register save and restore. The kernel will only save |
diff --git a/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c b/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c new file mode 100644 index 000000000000..f8e8e95e81fd --- /dev/null +++ b/Documentation/prctl/disable-tsc-ctxt-sw-stress-test.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...) | ||
3 | * | ||
4 | * Tests if the control register is updated correctly | ||
5 | * at context switches | ||
6 | * | ||
7 | * Warning: this test will cause a very high load for a few seconds | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <unistd.h> | ||
14 | #include <signal.h> | ||
15 | #include <inttypes.h> | ||
16 | #include <wait.h> | ||
17 | |||
18 | |||
19 | #include <sys/prctl.h> | ||
20 | #include <linux/prctl.h> | ||
21 | |||
22 | /* Get/set the process' ability to use the timestamp counter instruction */ | ||
23 | #ifndef PR_GET_TSC | ||
24 | #define PR_GET_TSC 25 | ||
25 | #define PR_SET_TSC 26 | ||
26 | # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */ | ||
27 | # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */ | ||
28 | #endif | ||
29 | |||
30 | uint64_t rdtsc() { | ||
31 | uint32_t lo, hi; | ||
32 | /* We cannot use "=A", since this would use %rax on x86_64 */ | ||
33 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
34 | return (uint64_t)hi << 32 | lo; | ||
35 | } | ||
36 | |||
37 | void sigsegv_expect(int sig) | ||
38 | { | ||
39 | /* */ | ||
40 | } | ||
41 | |||
42 | void segvtask(void) | ||
43 | { | ||
44 | if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0) | ||
45 | { | ||
46 | perror("prctl"); | ||
47 | exit(0); | ||
48 | } | ||
49 | signal(SIGSEGV, sigsegv_expect); | ||
50 | alarm(10); | ||
51 | rdtsc(); | ||
52 | fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n"); | ||
53 | exit(0); | ||
54 | } | ||
55 | |||
56 | |||
57 | void sigsegv_fail(int sig) | ||
58 | { | ||
59 | fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n"); | ||
60 | exit(0); | ||
61 | } | ||
62 | |||
63 | void rdtsctask(void) | ||
64 | { | ||
65 | if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0) | ||
66 | { | ||
67 | perror("prctl"); | ||
68 | exit(0); | ||
69 | } | ||
70 | signal(SIGSEGV, sigsegv_fail); | ||
71 | alarm(10); | ||
72 | for(;;) rdtsc(); | ||
73 | } | ||
74 | |||
75 | |||
76 | int main(int argc, char **argv) | ||
77 | { | ||
78 | int n_tasks = 100, i; | ||
79 | |||
80 | fprintf(stderr, "[No further output means we're allright]\n"); | ||
81 | |||
82 | for (i=0; i<n_tasks; i++) | ||
83 | if (fork() == 0) | ||
84 | { | ||
85 | if (i & 1) | ||
86 | segvtask(); | ||
87 | else | ||
88 | rdtsctask(); | ||
89 | } | ||
90 | |||
91 | for (i=0; i<n_tasks; i++) | ||
92 | wait(NULL); | ||
93 | |||
94 | exit(0); | ||
95 | } | ||
96 | |||
diff --git a/Documentation/prctl/disable-tsc-on-off-stress-test.c b/Documentation/prctl/disable-tsc-on-off-stress-test.c new file mode 100644 index 000000000000..1fcd91445375 --- /dev/null +++ b/Documentation/prctl/disable-tsc-on-off-stress-test.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...) | ||
3 | * | ||
4 | * Tests if the control register is updated correctly | ||
5 | * when set with prctl() | ||
6 | * | ||
7 | * Warning: this test will cause a very high load for a few seconds | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <stdio.h> | ||
12 | #include <stdlib.h> | ||
13 | #include <unistd.h> | ||
14 | #include <signal.h> | ||
15 | #include <inttypes.h> | ||
16 | #include <wait.h> | ||
17 | |||
18 | |||
19 | #include <sys/prctl.h> | ||
20 | #include <linux/prctl.h> | ||
21 | |||
22 | /* Get/set the process' ability to use the timestamp counter instruction */ | ||
23 | #ifndef PR_GET_TSC | ||
24 | #define PR_GET_TSC 25 | ||
25 | #define PR_SET_TSC 26 | ||
26 | # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */ | ||
27 | # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */ | ||
28 | #endif | ||
29 | |||
30 | /* snippet from wikipedia :-) */ | ||
31 | |||
32 | uint64_t rdtsc() { | ||
33 | uint32_t lo, hi; | ||
34 | /* We cannot use "=A", since this would use %rax on x86_64 */ | ||
35 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
36 | return (uint64_t)hi << 32 | lo; | ||
37 | } | ||
38 | |||
39 | int should_segv = 0; | ||
40 | |||
41 | void sigsegv_cb(int sig) | ||
42 | { | ||
43 | if (!should_segv) | ||
44 | { | ||
45 | fprintf(stderr, "FATAL ERROR, rdtsc() failed while enabled\n"); | ||
46 | exit(0); | ||
47 | } | ||
48 | if (prctl(PR_SET_TSC, PR_TSC_ENABLE) < 0) | ||
49 | { | ||
50 | perror("prctl"); | ||
51 | exit(0); | ||
52 | } | ||
53 | should_segv = 0; | ||
54 | |||
55 | rdtsc(); | ||
56 | } | ||
57 | |||
58 | void task(void) | ||
59 | { | ||
60 | signal(SIGSEGV, sigsegv_cb); | ||
61 | alarm(10); | ||
62 | for(;;) | ||
63 | { | ||
64 | rdtsc(); | ||
65 | if (should_segv) | ||
66 | { | ||
67 | fprintf(stderr, "FATAL ERROR, rdtsc() succeeded while disabled\n"); | ||
68 | exit(0); | ||
69 | } | ||
70 | if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV) < 0) | ||
71 | { | ||
72 | perror("prctl"); | ||
73 | exit(0); | ||
74 | } | ||
75 | should_segv = 1; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | |||
80 | int main(int argc, char **argv) | ||
81 | { | ||
82 | int n_tasks = 100, i; | ||
83 | |||
84 | fprintf(stderr, "[No further output means we're allright]\n"); | ||
85 | |||
86 | for (i=0; i<n_tasks; i++) | ||
87 | if (fork() == 0) | ||
88 | task(); | ||
89 | |||
90 | for (i=0; i<n_tasks; i++) | ||
91 | wait(NULL); | ||
92 | |||
93 | exit(0); | ||
94 | } | ||
95 | |||
diff --git a/Documentation/prctl/disable-tsc-test.c b/Documentation/prctl/disable-tsc-test.c new file mode 100644 index 000000000000..843c81eac235 --- /dev/null +++ b/Documentation/prctl/disable-tsc-test.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * Tests for prctl(PR_GET_TSC, ...) / prctl(PR_SET_TSC, ...) | ||
3 | * | ||
4 | * Basic test to test behaviour of PR_GET_TSC and PR_SET_TSC | ||
5 | */ | ||
6 | |||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <unistd.h> | ||
10 | #include <signal.h> | ||
11 | #include <inttypes.h> | ||
12 | |||
13 | |||
14 | #include <sys/prctl.h> | ||
15 | #include <linux/prctl.h> | ||
16 | |||
17 | /* Get/set the process' ability to use the timestamp counter instruction */ | ||
18 | #ifndef PR_GET_TSC | ||
19 | #define PR_GET_TSC 25 | ||
20 | #define PR_SET_TSC 26 | ||
21 | # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */ | ||
22 | # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */ | ||
23 | #endif | ||
24 | |||
25 | const char *tsc_names[] = | ||
26 | { | ||
27 | [0] = "[not set]", | ||
28 | [PR_TSC_ENABLE] = "PR_TSC_ENABLE", | ||
29 | [PR_TSC_SIGSEGV] = "PR_TSC_SIGSEGV", | ||
30 | }; | ||
31 | |||
32 | uint64_t rdtsc() { | ||
33 | uint32_t lo, hi; | ||
34 | /* We cannot use "=A", since this would use %rax on x86_64 */ | ||
35 | __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | ||
36 | return (uint64_t)hi << 32 | lo; | ||
37 | } | ||
38 | |||
39 | void sigsegv_cb(int sig) | ||
40 | { | ||
41 | int tsc_val = 0; | ||
42 | |||
43 | printf("[ SIG_SEGV ]\n"); | ||
44 | printf("prctl(PR_GET_TSC, &tsc_val); "); | ||
45 | fflush(stdout); | ||
46 | |||
47 | if ( prctl(PR_GET_TSC, &tsc_val) == -1) | ||
48 | perror("prctl"); | ||
49 | |||
50 | printf("tsc_val == %s\n", tsc_names[tsc_val]); | ||
51 | printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n"); | ||
52 | fflush(stdout); | ||
53 | if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1) | ||
54 | perror("prctl"); | ||
55 | |||
56 | printf("rdtsc() == "); | ||
57 | } | ||
58 | |||
59 | int main(int argc, char **argv) | ||
60 | { | ||
61 | int tsc_val = 0; | ||
62 | |||
63 | signal(SIGSEGV, sigsegv_cb); | ||
64 | |||
65 | printf("rdtsc() == %llu\n", (unsigned long long)rdtsc()); | ||
66 | printf("prctl(PR_GET_TSC, &tsc_val); "); | ||
67 | fflush(stdout); | ||
68 | |||
69 | if ( prctl(PR_GET_TSC, &tsc_val) == -1) | ||
70 | perror("prctl"); | ||
71 | |||
72 | printf("tsc_val == %s\n", tsc_names[tsc_val]); | ||
73 | printf("rdtsc() == %llu\n", (unsigned long long)rdtsc()); | ||
74 | printf("prctl(PR_SET_TSC, PR_TSC_ENABLE)\n"); | ||
75 | fflush(stdout); | ||
76 | |||
77 | if ( prctl(PR_SET_TSC, PR_TSC_ENABLE) == -1) | ||
78 | perror("prctl"); | ||
79 | |||
80 | printf("rdtsc() == %llu\n", (unsigned long long)rdtsc()); | ||
81 | printf("prctl(PR_SET_TSC, PR_TSC_SIGSEGV)\n"); | ||
82 | fflush(stdout); | ||
83 | |||
84 | if ( prctl(PR_SET_TSC, PR_TSC_SIGSEGV) == -1) | ||
85 | perror("prctl"); | ||
86 | |||
87 | printf("rdtsc() == "); | ||
88 | fflush(stdout); | ||
89 | printf("%llu\n", (unsigned long long)rdtsc()); | ||
90 | fflush(stdout); | ||
91 | |||
92 | exit(EXIT_SUCCESS); | ||
93 | } | ||
94 | |||
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8d2cd1de5726..6a679c3e15e8 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -167,6 +167,12 @@ config CPU_SUBTYPE_SH7263 | |||
167 | select CPU_SH2A | 167 | select CPU_SH2A |
168 | select CPU_HAS_FPU | 168 | select CPU_HAS_FPU |
169 | 169 | ||
170 | config CPU_SUBTYPE_MXG | ||
171 | bool "Support MX-G processor" | ||
172 | select CPU_SH2A | ||
173 | help | ||
174 | Select MX-G if running on an R8A03022BG part. | ||
175 | |||
170 | # SH-3 Processor Support | 176 | # SH-3 Processor Support |
171 | 177 | ||
172 | config CPU_SUBTYPE_SH7705 | 178 | config CPU_SUBTYPE_SH7705 |
@@ -270,6 +276,15 @@ config CPU_SUBTYPE_SH4_202 | |||
270 | 276 | ||
271 | # SH-4A Processor Support | 277 | # SH-4A Processor Support |
272 | 278 | ||
279 | config CPU_SUBTYPE_SH7723 | ||
280 | bool "Support SH7723 processor" | ||
281 | select CPU_SH4A | ||
282 | select CPU_SHX2 | ||
283 | select ARCH_SPARSEMEM_ENABLE | ||
284 | select SYS_SUPPORTS_NUMA | ||
285 | help | ||
286 | Select SH7723 if you have an SH-MobileR2 CPU. | ||
287 | |||
273 | config CPU_SUBTYPE_SH7763 | 288 | config CPU_SUBTYPE_SH7763 |
274 | bool "Support SH7763 processor" | 289 | bool "Support SH7763 processor" |
275 | select CPU_SH4A | 290 | select CPU_SH4A |
@@ -366,6 +381,14 @@ config SH_7619_SOLUTION_ENGINE | |||
366 | Select 7619 SolutionEngine if configuring for a Hitachi SH7619 | 381 | Select 7619 SolutionEngine if configuring for a Hitachi SH7619 |
367 | evaluation board. | 382 | evaluation board. |
368 | 383 | ||
384 | config SH_7721_SOLUTION_ENGINE | ||
385 | bool "SolutionEngine7721" | ||
386 | select SOLUTION_ENGINE | ||
387 | depends on CPU_SUBTYPE_SH7721 | ||
388 | help | ||
389 | Select 7721 SolutionEngine if configuring for a Hitachi SH7721 | ||
390 | evaluation board. | ||
391 | |||
369 | config SH_7722_SOLUTION_ENGINE | 392 | config SH_7722_SOLUTION_ENGINE |
370 | bool "SolutionEngine7722" | 393 | bool "SolutionEngine7722" |
371 | select SOLUTION_ENGINE | 394 | select SOLUTION_ENGINE |
@@ -560,7 +583,7 @@ config SH_TMU | |||
560 | config SH_CMT | 583 | config SH_CMT |
561 | def_bool y | 584 | def_bool y |
562 | prompt "CMT timer support" | 585 | prompt "CMT timer support" |
563 | depends on CPU_SH2 | 586 | depends on CPU_SH2 && !CPU_SUBTYPE_MXG |
564 | help | 587 | help |
565 | This enables the use of the CMT as the system timer. | 588 | This enables the use of the CMT as the system timer. |
566 | 589 | ||
@@ -578,6 +601,7 @@ config SH_TIMER_IRQ | |||
578 | default "86" if CPU_SUBTYPE_SH7619 | 601 | default "86" if CPU_SUBTYPE_SH7619 |
579 | default "140" if CPU_SUBTYPE_SH7206 | 602 | default "140" if CPU_SUBTYPE_SH7206 |
580 | default "142" if CPU_SUBTYPE_SH7203 | 603 | default "142" if CPU_SUBTYPE_SH7203 |
604 | default "238" if CPU_SUBTYPE_MXG | ||
581 | default "16" | 605 | default "16" |
582 | 606 | ||
583 | config SH_PCLK_FREQ | 607 | config SH_PCLK_FREQ |
@@ -585,10 +609,10 @@ config SH_PCLK_FREQ | |||
585 | default "27000000" if CPU_SUBTYPE_SH7343 | 609 | default "27000000" if CPU_SUBTYPE_SH7343 |
586 | default "31250000" if CPU_SUBTYPE_SH7619 | 610 | default "31250000" if CPU_SUBTYPE_SH7619 |
587 | default "32000000" if CPU_SUBTYPE_SH7722 | 611 | default "32000000" if CPU_SUBTYPE_SH7722 |
588 | default "33333333" if CPU_SUBTYPE_SH7770 || \ | 612 | default "33333333" if CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7723 || \ |
589 | CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ | 613 | CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ |
590 | CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \ | 614 | CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \ |
591 | CPU_SUBTYPE_SH7263 | 615 | CPU_SUBTYPE_SH7263 || CPU_SUBTYPE_MXG |
592 | default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R | 616 | default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R |
593 | default "66000000" if CPU_SUBTYPE_SH4_202 | 617 | default "66000000" if CPU_SUBTYPE_SH4_202 |
594 | default "50000000" | 618 | default "50000000" |
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 5dcb74b947a9..d9d28f9dd0db 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug | |||
@@ -29,16 +29,17 @@ config EARLY_SCIF_CONSOLE | |||
29 | config EARLY_SCIF_CONSOLE_PORT | 29 | config EARLY_SCIF_CONSOLE_PORT |
30 | hex | 30 | hex |
31 | depends on EARLY_SCIF_CONSOLE | 31 | depends on EARLY_SCIF_CONSOLE |
32 | default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 | ||
33 | default "0xffe00000" if CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 | ||
34 | default "0xffea0000" if CPU_SUBTYPE_SH7785 | ||
35 | default "0xfffe8000" if CPU_SUBTYPE_SH7203 | ||
36 | default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263 | ||
37 | default "0xf8420000" if CPU_SUBTYPE_SH7619 | ||
38 | default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 | 32 | default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 |
39 | default "0xa4430000" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721 | 33 | default "0xa4430000" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721 |
34 | default "0xf8420000" if CPU_SUBTYPE_SH7619 | ||
35 | default "0xff804000" if CPU_SUBTYPE_MXG | ||
40 | default "0xffc30000" if CPU_SUBTYPE_SHX3 | 36 | default "0xffc30000" if CPU_SUBTYPE_SHX3 |
37 | default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \ | ||
38 | CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 | ||
41 | default "0xffe80000" if CPU_SH4 | 39 | default "0xffe80000" if CPU_SH4 |
40 | default "0xffea0000" if CPU_SUBTYPE_SH7785 | ||
41 | default "0xfffe8000" if CPU_SUBTYPE_SH7203 | ||
42 | default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263 | ||
42 | default "0x00000000" | 43 | default "0x00000000" |
43 | 44 | ||
44 | config EARLY_PRINTK | 45 | config EARLY_PRINTK |
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index cffc92b1bf2e..bb06f83e6239 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -107,6 +107,7 @@ machdir-$(CONFIG_SH_7722_SOLUTION_ENGINE) += se/7722 | |||
107 | machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) += se/7751 | 107 | machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) += se/7751 |
108 | machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) += se/7780 | 108 | machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) += se/7780 |
109 | machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) += se/7343 | 109 | machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) += se/7343 |
110 | machdir-$(CONFIG_SH_7721_SOLUTION_ENGINE) += se/7721 | ||
110 | machdir-$(CONFIG_SH_HP6XX) += hp6xx | 111 | machdir-$(CONFIG_SH_HP6XX) += hp6xx |
111 | machdir-$(CONFIG_SH_DREAMCAST) += dreamcast | 112 | machdir-$(CONFIG_SH_DREAMCAST) += dreamcast |
112 | machdir-$(CONFIG_SH_MPC1211) += mpc1211 | 113 | machdir-$(CONFIG_SH_MPC1211) += mpc1211 |
diff --git a/arch/sh/boards/renesas/migor/setup.c b/arch/sh/boards/renesas/migor/setup.c index 21ab8c8fb590..00d52a20d8a5 100644 --- a/arch/sh/boards/renesas/migor/setup.c +++ b/arch/sh/boards/renesas/migor/setup.c | |||
@@ -10,8 +10,14 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/input.h> | ||
14 | #include <linux/mtd/physmap.h> | ||
15 | #include <linux/mtd/nand.h> | ||
16 | #include <linux/i2c.h> | ||
13 | #include <asm/machvec.h> | 17 | #include <asm/machvec.h> |
14 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/sh_keysc.h> | ||
20 | #include <asm/migor.h> | ||
15 | 21 | ||
16 | /* Address IRQ Size Bus Description | 22 | /* Address IRQ Size Bus Description |
17 | * 0x00000000 64MB 16 NOR Flash (SP29PL256N) | 23 | * 0x00000000 64MB 16 NOR Flash (SP29PL256N) |
@@ -23,9 +29,9 @@ | |||
23 | 29 | ||
24 | static struct resource smc91x_eth_resources[] = { | 30 | static struct resource smc91x_eth_resources[] = { |
25 | [0] = { | 31 | [0] = { |
26 | .name = "smc91x-regs" , | 32 | .name = "SMC91C111" , |
27 | .start = P2SEGADDR(0x10000300), | 33 | .start = 0x10000300, |
28 | .end = P2SEGADDR(0x1000030f), | 34 | .end = 0x1000030f, |
29 | .flags = IORESOURCE_MEM, | 35 | .flags = IORESOURCE_MEM, |
30 | }, | 36 | }, |
31 | [1] = { | 37 | [1] = { |
@@ -40,19 +46,202 @@ static struct platform_device smc91x_eth_device = { | |||
40 | .resource = smc91x_eth_resources, | 46 | .resource = smc91x_eth_resources, |
41 | }; | 47 | }; |
42 | 48 | ||
49 | static struct sh_keysc_info sh_keysc_info = { | ||
50 | .mode = SH_KEYSC_MODE_2, /* KEYOUT0->4, KEYIN1->5 */ | ||
51 | .scan_timing = 3, | ||
52 | .delay = 5, | ||
53 | .keycodes = { | ||
54 | 0, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_ENTER, | ||
55 | 0, KEY_F, KEY_C, KEY_D, KEY_H, KEY_1, | ||
56 | 0, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, | ||
57 | 0, KEY_7, KEY_8, KEY_9, KEY_S, KEY_0, | ||
58 | 0, KEY_P, KEY_STOP, KEY_REWIND, KEY_PLAY, KEY_FASTFORWARD, | ||
59 | }, | ||
60 | }; | ||
61 | |||
62 | static struct resource sh_keysc_resources[] = { | ||
63 | [0] = { | ||
64 | .start = 0x044b0000, | ||
65 | .end = 0x044b000f, | ||
66 | .flags = IORESOURCE_MEM, | ||
67 | }, | ||
68 | [1] = { | ||
69 | .start = 79, | ||
70 | .flags = IORESOURCE_IRQ, | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | static struct platform_device sh_keysc_device = { | ||
75 | .name = "sh_keysc", | ||
76 | .num_resources = ARRAY_SIZE(sh_keysc_resources), | ||
77 | .resource = sh_keysc_resources, | ||
78 | .dev = { | ||
79 | .platform_data = &sh_keysc_info, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | static struct mtd_partition migor_nor_flash_partitions[] = | ||
84 | { | ||
85 | { | ||
86 | .name = "uboot", | ||
87 | .offset = 0, | ||
88 | .size = (1 * 1024 * 1024), | ||
89 | .mask_flags = MTD_WRITEABLE, /* Read-only */ | ||
90 | }, | ||
91 | { | ||
92 | .name = "rootfs", | ||
93 | .offset = MTDPART_OFS_APPEND, | ||
94 | .size = (15 * 1024 * 1024), | ||
95 | }, | ||
96 | { | ||
97 | .name = "other", | ||
98 | .offset = MTDPART_OFS_APPEND, | ||
99 | .size = MTDPART_SIZ_FULL, | ||
100 | }, | ||
101 | }; | ||
102 | |||
103 | static struct physmap_flash_data migor_nor_flash_data = { | ||
104 | .width = 2, | ||
105 | .parts = migor_nor_flash_partitions, | ||
106 | .nr_parts = ARRAY_SIZE(migor_nor_flash_partitions), | ||
107 | }; | ||
108 | |||
109 | static struct resource migor_nor_flash_resources[] = { | ||
110 | [0] = { | ||
111 | .name = "NOR Flash", | ||
112 | .start = 0x00000000, | ||
113 | .end = 0x03ffffff, | ||
114 | .flags = IORESOURCE_MEM, | ||
115 | } | ||
116 | }; | ||
117 | |||
118 | static struct platform_device migor_nor_flash_device = { | ||
119 | .name = "physmap-flash", | ||
120 | .resource = migor_nor_flash_resources, | ||
121 | .num_resources = ARRAY_SIZE(migor_nor_flash_resources), | ||
122 | .dev = { | ||
123 | .platform_data = &migor_nor_flash_data, | ||
124 | }, | ||
125 | }; | ||
126 | |||
127 | static struct mtd_partition migor_nand_flash_partitions[] = { | ||
128 | { | ||
129 | .name = "nanddata1", | ||
130 | .offset = 0x0, | ||
131 | .size = 512 * 1024 * 1024, | ||
132 | }, | ||
133 | { | ||
134 | .name = "nanddata2", | ||
135 | .offset = MTDPART_OFS_APPEND, | ||
136 | .size = 512 * 1024 * 1024, | ||
137 | }, | ||
138 | }; | ||
139 | |||
140 | static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd, | ||
141 | unsigned int ctrl) | ||
142 | { | ||
143 | struct nand_chip *chip = mtd->priv; | ||
144 | |||
145 | if (cmd == NAND_CMD_NONE) | ||
146 | return; | ||
147 | |||
148 | if (ctrl & NAND_CLE) | ||
149 | writeb(cmd, chip->IO_ADDR_W + 0x00400000); | ||
150 | else if (ctrl & NAND_ALE) | ||
151 | writeb(cmd, chip->IO_ADDR_W + 0x00800000); | ||
152 | else | ||
153 | writeb(cmd, chip->IO_ADDR_W); | ||
154 | } | ||
155 | |||
156 | static int migor_nand_flash_ready(struct mtd_info *mtd) | ||
157 | { | ||
158 | return ctrl_inb(PORT_PADR) & 0x02; /* PTA1 */ | ||
159 | } | ||
160 | |||
161 | struct platform_nand_data migor_nand_flash_data = { | ||
162 | .chip = { | ||
163 | .nr_chips = 1, | ||
164 | .partitions = migor_nand_flash_partitions, | ||
165 | .nr_partitions = ARRAY_SIZE(migor_nand_flash_partitions), | ||
166 | .chip_delay = 20, | ||
167 | .part_probe_types = (const char *[]) { "cmdlinepart", NULL }, | ||
168 | }, | ||
169 | .ctrl = { | ||
170 | .dev_ready = migor_nand_flash_ready, | ||
171 | .cmd_ctrl = migor_nand_flash_cmd_ctl, | ||
172 | }, | ||
173 | }; | ||
174 | |||
175 | static struct resource migor_nand_flash_resources[] = { | ||
176 | [0] = { | ||
177 | .name = "NAND Flash", | ||
178 | .start = 0x18000000, | ||
179 | .end = 0x18ffffff, | ||
180 | .flags = IORESOURCE_MEM, | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | static struct platform_device migor_nand_flash_device = { | ||
185 | .name = "gen_nand", | ||
186 | .resource = migor_nand_flash_resources, | ||
187 | .num_resources = ARRAY_SIZE(migor_nand_flash_resources), | ||
188 | .dev = { | ||
189 | .platform_data = &migor_nand_flash_data, | ||
190 | } | ||
191 | }; | ||
192 | |||
43 | static struct platform_device *migor_devices[] __initdata = { | 193 | static struct platform_device *migor_devices[] __initdata = { |
44 | &smc91x_eth_device, | 194 | &smc91x_eth_device, |
195 | &sh_keysc_device, | ||
196 | &migor_nor_flash_device, | ||
197 | &migor_nand_flash_device, | ||
198 | }; | ||
199 | |||
200 | static struct i2c_board_info __initdata migor_i2c_devices[] = { | ||
201 | { | ||
202 | I2C_BOARD_INFO("rtc-rs5c372", 0x32), | ||
203 | .type = "rs5c372b", | ||
204 | }, | ||
205 | { | ||
206 | I2C_BOARD_INFO("migor_ts", 0x51), | ||
207 | .irq = 38, /* IRQ6 */ | ||
208 | }, | ||
45 | }; | 209 | }; |
46 | 210 | ||
47 | static int __init migor_devices_setup(void) | 211 | static int __init migor_devices_setup(void) |
48 | { | 212 | { |
213 | i2c_register_board_info(0, migor_i2c_devices, | ||
214 | ARRAY_SIZE(migor_i2c_devices)); | ||
215 | |||
49 | return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); | 216 | return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices)); |
50 | } | 217 | } |
51 | __initcall(migor_devices_setup); | 218 | __initcall(migor_devices_setup); |
52 | 219 | ||
53 | static void __init migor_setup(char **cmdline_p) | 220 | static void __init migor_setup(char **cmdline_p) |
54 | { | 221 | { |
55 | ctrl_outw(0x1000, 0xa4050110); /* Enable IRQ0 in PJCR */ | 222 | /* SMC91C111 - Enable IRQ0 */ |
223 | ctrl_outw(ctrl_inw(PORT_PJCR) & ~0x0003, PORT_PJCR); | ||
224 | |||
225 | /* KEYSC */ | ||
226 | ctrl_outw(ctrl_inw(PORT_PYCR) & ~0x0fff, PORT_PYCR); | ||
227 | ctrl_outw(ctrl_inw(PORT_PZCR) & ~0x0ff0, PORT_PZCR); | ||
228 | ctrl_outw(ctrl_inw(PORT_PSELA) & ~0x4100, PORT_PSELA); | ||
229 | ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA); | ||
230 | ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC); | ||
231 | ctrl_outl(ctrl_inl(MSTPCR2) & ~0x00004000, MSTPCR2); | ||
232 | |||
233 | /* NAND Flash */ | ||
234 | ctrl_outw(ctrl_inw(PORT_PXCR) & 0x0fff, PORT_PXCR); | ||
235 | ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x00000600) | 0x00000200, | ||
236 | BSC_CS6ABCR); | ||
237 | |||
238 | /* I2C */ | ||
239 | ctrl_outl(ctrl_inl(MSTPCR1) & ~0x00000200, MSTPCR1); | ||
240 | |||
241 | /* Touch Panel - Enable IRQ6 */ | ||
242 | ctrl_outw(ctrl_inw(PORT_PZCR) & ~0xc, PORT_PZCR); | ||
243 | ctrl_outw((ctrl_inw(PORT_PSELA) | 0x8000), PORT_PSELA); | ||
244 | ctrl_outw((ctrl_inw(PORT_HIZCRC) & ~0x4000), PORT_HIZCRC); | ||
56 | } | 245 | } |
57 | 246 | ||
58 | static struct sh_machine_vector mv_migor __initmv = { | 247 | static struct sh_machine_vector mv_migor __initmv = { |
diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c index 1f8f073f27be..68f0ad1b637d 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c | |||
@@ -18,31 +18,44 @@ enum { | |||
18 | UNUSED = 0, | 18 | UNUSED = 0, |
19 | 19 | ||
20 | /* board specific interrupt sources */ | 20 | /* board specific interrupt sources */ |
21 | AX88796, /* Ethernet controller */ | 21 | CF, /* Compact Flash */ |
22 | CF, /* Compact Flash */ | 22 | TP, /* Touch panel */ |
23 | PSW, /* Push Switch */ | 23 | SCIF1, /* FPGA SCIF1 */ |
24 | EXT1, /* EXT1n IRQ */ | 24 | SCIF0, /* FPGA SCIF0 */ |
25 | EXT4, /* EXT4n IRQ */ | 25 | SMBUS, /* SMBUS */ |
26 | RTC, /* RTC Alarm */ | ||
27 | AX88796, /* Ethernet controller */ | ||
28 | PSW, /* Push Switch */ | ||
29 | |||
30 | /* external bus connector */ | ||
31 | EXT1, EXT2, EXT4, EXT5, EXT6, | ||
26 | }; | 32 | }; |
27 | 33 | ||
28 | static struct intc_vect vectors[] __initdata = { | 34 | static struct intc_vect vectors[] __initdata = { |
29 | INTC_IRQ(CF, IRQ_CF), | 35 | INTC_IRQ(CF, IRQ_CF), |
30 | INTC_IRQ(PSW, IRQ_PSW), | 36 | INTC_IRQ(TP, IRQ_TP), |
37 | INTC_IRQ(SCIF1, IRQ_SCIF1), | ||
38 | INTC_IRQ(SCIF0, IRQ_SCIF0), | ||
39 | INTC_IRQ(SMBUS, IRQ_SMBUS), | ||
40 | INTC_IRQ(RTC, IRQ_RTC), | ||
31 | INTC_IRQ(AX88796, IRQ_AX88796), | 41 | INTC_IRQ(AX88796, IRQ_AX88796), |
32 | INTC_IRQ(EXT1, IRQ_EXT1), | 42 | INTC_IRQ(PSW, IRQ_PSW), |
33 | INTC_IRQ(EXT4, IRQ_EXT4), | 43 | |
44 | INTC_IRQ(EXT1, IRQ_EXT1), INTC_IRQ(EXT2, IRQ_EXT2), | ||
45 | INTC_IRQ(EXT4, IRQ_EXT4), INTC_IRQ(EXT5, IRQ_EXT5), | ||
46 | INTC_IRQ(EXT6, IRQ_EXT6), | ||
34 | }; | 47 | }; |
35 | 48 | ||
36 | static struct intc_mask_reg mask_registers[] __initdata = { | 49 | static struct intc_mask_reg mask_registers[] __initdata = { |
37 | { 0xa4000000, 0, 16, /* IRLMSK */ | 50 | { 0xa4000000, 0, 16, /* IRLMSK */ |
38 | { 0, 0, 0, 0, CF, 0, 0, 0, | 51 | { SCIF0, SCIF1, RTC, 0, CF, 0, TP, SMBUS, |
39 | 0, 0, 0, EXT4, 0, EXT1, PSW, AX88796 } }, | 52 | 0, EXT6, EXT5, EXT4, EXT2, EXT1, PSW, AX88796 } }, |
40 | }; | 53 | }; |
41 | 54 | ||
42 | static unsigned char irl2irq[HL_NR_IRL] __initdata = { | 55 | static unsigned char irl2irq[HL_NR_IRL] __initdata = { |
43 | 0, IRQ_CF, 0, 0, | 56 | 0, IRQ_CF, IRQ_TP, IRQ_SCIF1, |
44 | 0, 0, 0, 0, | 57 | IRQ_SCIF0, IRQ_SMBUS, IRQ_RTC, IRQ_EXT6, |
45 | 0, IRQ_EXT4, 0, IRQ_EXT1, | 58 | IRQ_EXT5, IRQ_EXT4, IRQ_EXT2, IRQ_EXT1, |
46 | 0, IRQ_AX88796, IRQ_PSW, | 59 | 0, IRQ_AX88796, IRQ_PSW, |
47 | }; | 60 | }; |
48 | 61 | ||
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index 2f68bea7890c..a5c5e9236501 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Renesas Solutions Highlander Support. | 4 | * Renesas Solutions Highlander Support. |
5 | * | 5 | * |
6 | * Copyright (C) 2002 Atom Create Engineering Co., Ltd. | 6 | * Copyright (C) 2002 Atom Create Engineering Co., Ltd. |
7 | * Copyright (C) 2005 - 2007 Paul Mundt | 7 | * Copyright (C) 2005 - 2008 Paul Mundt |
8 | * | 8 | * |
9 | * This contains support for the R7780RP-1, R7780MP, and R7785RP | 9 | * This contains support for the R7780RP-1, R7780MP, and R7785RP |
10 | * Highlander modules. | 10 | * Highlander modules. |
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/ata_platform.h> | 18 | #include <linux/ata_platform.h> |
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/i2c.h> | ||
20 | #include <net/ax88796.h> | 21 | #include <net/ax88796.h> |
21 | #include <asm/machvec.h> | 22 | #include <asm/machvec.h> |
22 | #include <asm/r7780rp.h> | 23 | #include <asm/r7780rp.h> |
@@ -176,11 +177,38 @@ static struct platform_device ax88796_device = { | |||
176 | .resource = ax88796_resources, | 177 | .resource = ax88796_resources, |
177 | }; | 178 | }; |
178 | 179 | ||
180 | static struct resource smbus_resources[] = { | ||
181 | [0] = { | ||
182 | .start = PA_SMCR, | ||
183 | .end = PA_SMCR + 0x100 - 1, | ||
184 | .flags = IORESOURCE_MEM, | ||
185 | }, | ||
186 | [1] = { | ||
187 | .start = IRQ_SMBUS, | ||
188 | .end = IRQ_SMBUS, | ||
189 | .flags = IORESOURCE_IRQ, | ||
190 | }, | ||
191 | }; | ||
192 | |||
193 | static struct platform_device smbus_device = { | ||
194 | .name = "i2c-highlander", | ||
195 | .id = 0, | ||
196 | .num_resources = ARRAY_SIZE(smbus_resources), | ||
197 | .resource = smbus_resources, | ||
198 | }; | ||
199 | |||
200 | static struct i2c_board_info __initdata highlander_i2c_devices[] = { | ||
201 | { | ||
202 | I2C_BOARD_INFO("rtc-rs5c372", 0x32), | ||
203 | .type = "r2025sd", | ||
204 | }, | ||
205 | }; | ||
179 | 206 | ||
180 | static struct platform_device *r7780rp_devices[] __initdata = { | 207 | static struct platform_device *r7780rp_devices[] __initdata = { |
181 | &r8a66597_usb_host_device, | 208 | &r8a66597_usb_host_device, |
182 | &m66592_usb_peripheral_device, | 209 | &m66592_usb_peripheral_device, |
183 | &heartbeat_device, | 210 | &heartbeat_device, |
211 | &smbus_device, | ||
184 | #ifndef CONFIG_SH_R7780RP | 212 | #ifndef CONFIG_SH_R7780RP |
185 | &ax88796_device, | 213 | &ax88796_device, |
186 | #endif | 214 | #endif |
@@ -199,12 +227,20 @@ static struct trapped_io cf_trapped_io = { | |||
199 | 227 | ||
200 | static int __init r7780rp_devices_setup(void) | 228 | static int __init r7780rp_devices_setup(void) |
201 | { | 229 | { |
230 | int ret = 0; | ||
231 | |||
202 | #ifndef CONFIG_SH_R7780RP | 232 | #ifndef CONFIG_SH_R7780RP |
203 | if (register_trapped_io(&cf_trapped_io) == 0) | 233 | if (register_trapped_io(&cf_trapped_io) == 0) |
204 | platform_device_register(&cf_ide_device); | 234 | ret |= platform_device_register(&cf_ide_device); |
205 | #endif | 235 | #endif |
206 | return platform_add_devices(r7780rp_devices, | 236 | |
237 | ret |= platform_add_devices(r7780rp_devices, | ||
207 | ARRAY_SIZE(r7780rp_devices)); | 238 | ARRAY_SIZE(r7780rp_devices)); |
239 | |||
240 | ret |= i2c_register_board_info(0, highlander_i2c_devices, | ||
241 | ARRAY_SIZE(highlander_i2c_devices)); | ||
242 | |||
243 | return ret; | ||
208 | } | 244 | } |
209 | device_initcall(r7780rp_devices_setup); | 245 | device_initcall(r7780rp_devices_setup); |
210 | 246 | ||
diff --git a/arch/sh/boards/se/7721/Makefile b/arch/sh/boards/se/7721/Makefile new file mode 100644 index 000000000000..7f09030980b3 --- /dev/null +++ b/arch/sh/boards/se/7721/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-y := setup.o irq.o | |||
diff --git a/arch/sh/boards/se/7721/irq.c b/arch/sh/boards/se/7721/irq.c new file mode 100644 index 000000000000..c4fdd622bf8b --- /dev/null +++ b/arch/sh/boards/se/7721/irq.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/se/7721/irq.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/irq.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <asm/se7721.h> | ||
15 | |||
16 | enum { | ||
17 | UNUSED = 0, | ||
18 | |||
19 | /* board specific interrupt sources */ | ||
20 | MRSHPC, | ||
21 | }; | ||
22 | |||
23 | static struct intc_vect vectors[] __initdata = { | ||
24 | INTC_IRQ(MRSHPC, MRSHPC_IRQ0), | ||
25 | }; | ||
26 | |||
27 | static struct intc_prio_reg prio_registers[] __initdata = { | ||
28 | { FPGA_ILSR6, 0, 8, 4, /* IRLMSK */ | ||
29 | { 0, MRSHPC } }, | ||
30 | }; | ||
31 | |||
32 | static DECLARE_INTC_DESC(intc_desc, "SE7721", vectors, | ||
33 | NULL, NULL, prio_registers, NULL); | ||
34 | |||
35 | /* | ||
36 | * Initialize IRQ setting | ||
37 | */ | ||
38 | void __init init_se7721_IRQ(void) | ||
39 | { | ||
40 | /* PPCR */ | ||
41 | ctrl_outw(ctrl_inw(0xa4050118) & ~0x00ff, 0xa4050118); | ||
42 | |||
43 | register_intc_controller(&intc_desc); | ||
44 | intc_set_priority(MRSHPC_IRQ0, 0xf - MRSHPC_IRQ0); | ||
45 | } | ||
diff --git a/arch/sh/boards/se/7721/setup.c b/arch/sh/boards/se/7721/setup.c new file mode 100644 index 000000000000..1be3e92752f7 --- /dev/null +++ b/arch/sh/boards/se/7721/setup.c | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/boards/se/7721/setup.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
5 | * | ||
6 | * Hitachi UL SolutionEngine 7721 Support. | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | * | ||
12 | */ | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <asm/machvec.h> | ||
16 | #include <asm/se7721.h> | ||
17 | #include <asm/io.h> | ||
18 | #include <asm/heartbeat.h> | ||
19 | |||
20 | static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; | ||
21 | |||
22 | static struct heartbeat_data heartbeat_data = { | ||
23 | .bit_pos = heartbeat_bit_pos, | ||
24 | .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), | ||
25 | .regsize = 16, | ||
26 | }; | ||
27 | |||
28 | static struct resource heartbeat_resources[] = { | ||
29 | [0] = { | ||
30 | .start = PA_LED, | ||
31 | .end = PA_LED, | ||
32 | .flags = IORESOURCE_MEM, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static struct platform_device heartbeat_device = { | ||
37 | .name = "heartbeat", | ||
38 | .id = -1, | ||
39 | .dev = { | ||
40 | .platform_data = &heartbeat_data, | ||
41 | }, | ||
42 | .num_resources = ARRAY_SIZE(heartbeat_resources), | ||
43 | .resource = heartbeat_resources, | ||
44 | }; | ||
45 | |||
46 | static struct resource cf_ide_resources[] = { | ||
47 | [0] = { | ||
48 | .start = PA_MRSHPC_IO + 0x1f0, | ||
49 | .end = PA_MRSHPC_IO + 0x1f0 + 8 , | ||
50 | .flags = IORESOURCE_IO, | ||
51 | }, | ||
52 | [1] = { | ||
53 | .start = PA_MRSHPC_IO + 0x1f0 + 0x206, | ||
54 | .end = PA_MRSHPC_IO + 0x1f0 + 8 + 0x206 + 8, | ||
55 | .flags = IORESOURCE_IO, | ||
56 | }, | ||
57 | [2] = { | ||
58 | .start = MRSHPC_IRQ0, | ||
59 | .flags = IORESOURCE_IRQ, | ||
60 | }, | ||
61 | }; | ||
62 | |||
63 | static struct platform_device cf_ide_device = { | ||
64 | .name = "pata_platform", | ||
65 | .id = -1, | ||
66 | .num_resources = ARRAY_SIZE(cf_ide_resources), | ||
67 | .resource = cf_ide_resources, | ||
68 | }; | ||
69 | |||
70 | static struct platform_device *se7721_devices[] __initdata = { | ||
71 | &cf_ide_device, | ||
72 | &heartbeat_device | ||
73 | }; | ||
74 | |||
75 | static int __init se7721_devices_setup(void) | ||
76 | { | ||
77 | return platform_add_devices(se7721_devices, | ||
78 | ARRAY_SIZE(se7721_devices)); | ||
79 | } | ||
80 | device_initcall(se7721_devices_setup); | ||
81 | |||
82 | static void __init se7721_setup(char **cmdline_p) | ||
83 | { | ||
84 | /* for USB */ | ||
85 | ctrl_outw(0x0000, 0xA405010C); /* PGCR */ | ||
86 | ctrl_outw(0x0000, 0xA405010E); /* PHCR */ | ||
87 | ctrl_outw(0x00AA, 0xA4050118); /* PPCR */ | ||
88 | ctrl_outw(0x0000, 0xA4050124); /* PSELA */ | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * The Machine Vector | ||
93 | */ | ||
94 | struct sh_machine_vector mv_se7721 __initmv = { | ||
95 | .mv_name = "Solution Engine 7721", | ||
96 | .mv_setup = se7721_setup, | ||
97 | .mv_nr_irqs = 109, | ||
98 | .mv_init_irq = init_se7721_IRQ, | ||
99 | }; | ||
diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c index b1a3d9d0172f..33f6ee71f848 100644 --- a/arch/sh/boards/se/7722/setup.c +++ b/arch/sh/boards/se/7722/setup.c | |||
@@ -13,10 +13,12 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/ata_platform.h> | 15 | #include <linux/ata_platform.h> |
16 | #include <linux/input.h> | ||
16 | #include <asm/machvec.h> | 17 | #include <asm/machvec.h> |
17 | #include <asm/se7722.h> | 18 | #include <asm/se7722.h> |
18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
19 | #include <asm/heartbeat.h> | 20 | #include <asm/heartbeat.h> |
21 | #include <asm/sh_keysc.h> | ||
20 | 22 | ||
21 | /* Heartbeat */ | 23 | /* Heartbeat */ |
22 | static struct heartbeat_data heartbeat_data = { | 24 | static struct heartbeat_data heartbeat_data = { |
@@ -92,10 +94,47 @@ static struct platform_device cf_ide_device = { | |||
92 | .resource = cf_ide_resources, | 94 | .resource = cf_ide_resources, |
93 | }; | 95 | }; |
94 | 96 | ||
97 | static struct sh_keysc_info sh_keysc_info = { | ||
98 | .mode = SH_KEYSC_MODE_1, /* KEYOUT0->5, KEYIN0->4 */ | ||
99 | .scan_timing = 3, | ||
100 | .delay = 5, | ||
101 | .keycodes = { /* SW1 -> SW30 */ | ||
102 | KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, | ||
103 | KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, | ||
104 | KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, | ||
105 | KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, | ||
106 | KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, | ||
107 | KEY_Z, | ||
108 | KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE, /* life */ | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | static struct resource sh_keysc_resources[] = { | ||
113 | [0] = { | ||
114 | .start = 0x044b0000, | ||
115 | .end = 0x044b000f, | ||
116 | .flags = IORESOURCE_MEM, | ||
117 | }, | ||
118 | [1] = { | ||
119 | .start = 79, | ||
120 | .flags = IORESOURCE_IRQ, | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | static struct platform_device sh_keysc_device = { | ||
125 | .name = "sh_keysc", | ||
126 | .num_resources = ARRAY_SIZE(sh_keysc_resources), | ||
127 | .resource = sh_keysc_resources, | ||
128 | .dev = { | ||
129 | .platform_data = &sh_keysc_info, | ||
130 | }, | ||
131 | }; | ||
132 | |||
95 | static struct platform_device *se7722_devices[] __initdata = { | 133 | static struct platform_device *se7722_devices[] __initdata = { |
96 | &heartbeat_device, | 134 | &heartbeat_device, |
97 | &smc91x_eth_device, | 135 | &smc91x_eth_device, |
98 | &cf_ide_device, | 136 | &cf_ide_device, |
137 | &sh_keysc_device, | ||
99 | }; | 138 | }; |
100 | 139 | ||
101 | static int __init se7722_devices_setup(void) | 140 | static int __init se7722_devices_setup(void) |
@@ -136,6 +175,8 @@ static void __init se7722_setup(char **cmdline_p) | |||
136 | ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */ | 175 | ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */ |
137 | ctrl_outw(0x0000, PORT_PYCR); | 176 | ctrl_outw(0x0000, PORT_PYCR); |
138 | ctrl_outw(0x0000, PORT_PZCR); | 177 | ctrl_outw(0x0000, PORT_PZCR); |
178 | ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA); | ||
179 | ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC); | ||
139 | } | 180 | } |
140 | 181 | ||
141 | /* | 182 | /* |
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig new file mode 100644 index 000000000000..f3d4ca0caa46 --- /dev/null +++ b/arch/sh/configs/se7721_defconfig | |||
@@ -0,0 +1,1085 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.25-rc5 | ||
4 | # Fri Mar 21 12:05:31 2008 | ||
5 | # | ||
6 | CONFIG_SUPERH=y | ||
7 | CONFIG_SUPERH32=y | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
10 | CONFIG_GENERIC_HWEIGHT=y | ||
11 | CONFIG_GENERIC_HARDIRQS=y | ||
12 | CONFIG_GENERIC_IRQ_PROBE=y | ||
13 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
14 | CONFIG_GENERIC_TIME=y | ||
15 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
16 | CONFIG_STACKTRACE_SUPPORT=y | ||
17 | CONFIG_LOCKDEP_SUPPORT=y | ||
18 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
19 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
20 | CONFIG_ARCH_NO_VIRT_TO_BUS=y | ||
21 | CONFIG_ARCH_SUPPORTS_AOUT=y | ||
22 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
23 | |||
24 | # | ||
25 | # General setup | ||
26 | # | ||
27 | CONFIG_EXPERIMENTAL=y | ||
28 | CONFIG_BROKEN_ON_SMP=y | ||
29 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
30 | CONFIG_LOCALVERSION="" | ||
31 | # CONFIG_LOCALVERSION_AUTO is not set | ||
32 | # CONFIG_SWAP is not set | ||
33 | CONFIG_SYSVIPC=y | ||
34 | CONFIG_SYSVIPC_SYSCTL=y | ||
35 | CONFIG_POSIX_MQUEUE=y | ||
36 | CONFIG_BSD_PROCESS_ACCT=y | ||
37 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
38 | # CONFIG_TASKSTATS is not set | ||
39 | # CONFIG_AUDIT is not set | ||
40 | # CONFIG_IKCONFIG is not set | ||
41 | CONFIG_LOG_BUF_SHIFT=14 | ||
42 | # CONFIG_CGROUPS is not set | ||
43 | CONFIG_GROUP_SCHED=y | ||
44 | CONFIG_FAIR_GROUP_SCHED=y | ||
45 | # CONFIG_RT_GROUP_SCHED is not set | ||
46 | CONFIG_USER_SCHED=y | ||
47 | # CONFIG_CGROUP_SCHED is not set | ||
48 | CONFIG_SYSFS_DEPRECATED=y | ||
49 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
50 | # CONFIG_RELAY is not set | ||
51 | # CONFIG_NAMESPACES is not set | ||
52 | # CONFIG_BLK_DEV_INITRD is not set | ||
53 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
54 | CONFIG_SYSCTL=y | ||
55 | CONFIG_EMBEDDED=y | ||
56 | CONFIG_UID16=y | ||
57 | CONFIG_SYSCTL_SYSCALL=y | ||
58 | CONFIG_KALLSYMS=y | ||
59 | CONFIG_KALLSYMS_ALL=y | ||
60 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
61 | CONFIG_HOTPLUG=y | ||
62 | CONFIG_PRINTK=y | ||
63 | # CONFIG_BUG is not set | ||
64 | CONFIG_ELF_CORE=y | ||
65 | CONFIG_COMPAT_BRK=y | ||
66 | # CONFIG_BASE_FULL is not set | ||
67 | CONFIG_FUTEX=y | ||
68 | CONFIG_ANON_INODES=y | ||
69 | CONFIG_EPOLL=y | ||
70 | CONFIG_SIGNALFD=y | ||
71 | CONFIG_TIMERFD=y | ||
72 | CONFIG_EVENTFD=y | ||
73 | # CONFIG_SHMEM is not set | ||
74 | CONFIG_VM_EVENT_COUNTERS=y | ||
75 | CONFIG_SLAB=y | ||
76 | # CONFIG_SLUB is not set | ||
77 | # CONFIG_SLOB is not set | ||
78 | # CONFIG_PROFILING is not set | ||
79 | # CONFIG_MARKERS is not set | ||
80 | CONFIG_HAVE_OPROFILE=y | ||
81 | # CONFIG_HAVE_KPROBES is not set | ||
82 | # CONFIG_HAVE_KRETPROBES is not set | ||
83 | CONFIG_PROC_PAGE_MONITOR=y | ||
84 | CONFIG_SLABINFO=y | ||
85 | CONFIG_RT_MUTEXES=y | ||
86 | CONFIG_TINY_SHMEM=y | ||
87 | CONFIG_BASE_SMALL=1 | ||
88 | CONFIG_MODULES=y | ||
89 | # CONFIG_MODULE_UNLOAD is not set | ||
90 | # CONFIG_MODVERSIONS is not set | ||
91 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
92 | # CONFIG_KMOD is not set | ||
93 | CONFIG_BLOCK=y | ||
94 | # CONFIG_LBD is not set | ||
95 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
96 | # CONFIG_LSF is not set | ||
97 | # CONFIG_BLK_DEV_BSG is not set | ||
98 | |||
99 | # | ||
100 | # IO Schedulers | ||
101 | # | ||
102 | CONFIG_IOSCHED_NOOP=y | ||
103 | # CONFIG_IOSCHED_AS is not set | ||
104 | # CONFIG_IOSCHED_DEADLINE is not set | ||
105 | # CONFIG_IOSCHED_CFQ is not set | ||
106 | # CONFIG_DEFAULT_AS is not set | ||
107 | # CONFIG_DEFAULT_DEADLINE is not set | ||
108 | # CONFIG_DEFAULT_CFQ is not set | ||
109 | CONFIG_DEFAULT_NOOP=y | ||
110 | CONFIG_DEFAULT_IOSCHED="noop" | ||
111 | CONFIG_CLASSIC_RCU=y | ||
112 | |||
113 | # | ||
114 | # System type | ||
115 | # | ||
116 | CONFIG_CPU_SH3=y | ||
117 | # CONFIG_CPU_SUBTYPE_SH7619 is not set | ||
118 | # CONFIG_CPU_SUBTYPE_SH7203 is not set | ||
119 | # CONFIG_CPU_SUBTYPE_SH7206 is not set | ||
120 | # CONFIG_CPU_SUBTYPE_SH7263 is not set | ||
121 | # CONFIG_CPU_SUBTYPE_MXG is not set | ||
122 | # CONFIG_CPU_SUBTYPE_SH7705 is not set | ||
123 | # CONFIG_CPU_SUBTYPE_SH7706 is not set | ||
124 | # CONFIG_CPU_SUBTYPE_SH7707 is not set | ||
125 | # CONFIG_CPU_SUBTYPE_SH7708 is not set | ||
126 | # CONFIG_CPU_SUBTYPE_SH7709 is not set | ||
127 | # CONFIG_CPU_SUBTYPE_SH7710 is not set | ||
128 | # CONFIG_CPU_SUBTYPE_SH7712 is not set | ||
129 | # CONFIG_CPU_SUBTYPE_SH7720 is not set | ||
130 | CONFIG_CPU_SUBTYPE_SH7721=y | ||
131 | # CONFIG_CPU_SUBTYPE_SH7750 is not set | ||
132 | # CONFIG_CPU_SUBTYPE_SH7091 is not set | ||
133 | # CONFIG_CPU_SUBTYPE_SH7750R is not set | ||
134 | # CONFIG_CPU_SUBTYPE_SH7750S is not set | ||
135 | # CONFIG_CPU_SUBTYPE_SH7751 is not set | ||
136 | # CONFIG_CPU_SUBTYPE_SH7751R is not set | ||
137 | # CONFIG_CPU_SUBTYPE_SH7760 is not set | ||
138 | # CONFIG_CPU_SUBTYPE_SH4_202 is not set | ||
139 | # CONFIG_CPU_SUBTYPE_SH7763 is not set | ||
140 | # CONFIG_CPU_SUBTYPE_SH7770 is not set | ||
141 | # CONFIG_CPU_SUBTYPE_SH7780 is not set | ||
142 | # CONFIG_CPU_SUBTYPE_SH7785 is not set | ||
143 | # CONFIG_CPU_SUBTYPE_SHX3 is not set | ||
144 | # CONFIG_CPU_SUBTYPE_SH7343 is not set | ||
145 | # CONFIG_CPU_SUBTYPE_SH7722 is not set | ||
146 | # CONFIG_CPU_SUBTYPE_SH7366 is not set | ||
147 | # CONFIG_CPU_SUBTYPE_SH5_101 is not set | ||
148 | # CONFIG_CPU_SUBTYPE_SH5_103 is not set | ||
149 | |||
150 | # | ||
151 | # Memory management options | ||
152 | # | ||
153 | CONFIG_QUICKLIST=y | ||
154 | CONFIG_MMU=y | ||
155 | CONFIG_PAGE_OFFSET=0x80000000 | ||
156 | CONFIG_MEMORY_START=0x0c000000 | ||
157 | CONFIG_MEMORY_SIZE=0x02000000 | ||
158 | CONFIG_29BIT=y | ||
159 | CONFIG_VSYSCALL=y | ||
160 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
161 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||
162 | CONFIG_ARCH_SPARSEMEM_DEFAULT=y | ||
163 | CONFIG_MAX_ACTIVE_REGIONS=1 | ||
164 | CONFIG_ARCH_POPULATES_NODE_MAP=y | ||
165 | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | ||
166 | CONFIG_PAGE_SIZE_4KB=y | ||
167 | # CONFIG_PAGE_SIZE_8KB is not set | ||
168 | # CONFIG_PAGE_SIZE_64KB is not set | ||
169 | CONFIG_SELECT_MEMORY_MODEL=y | ||
170 | CONFIG_FLATMEM_MANUAL=y | ||
171 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
172 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
173 | CONFIG_FLATMEM=y | ||
174 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
175 | CONFIG_SPARSEMEM_STATIC=y | ||
176 | # CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set | ||
177 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
178 | # CONFIG_RESOURCES_64BIT is not set | ||
179 | CONFIG_ZONE_DMA_FLAG=0 | ||
180 | CONFIG_NR_QUICK=2 | ||
181 | |||
182 | # | ||
183 | # Cache configuration | ||
184 | # | ||
185 | # CONFIG_SH_DIRECT_MAPPED is not set | ||
186 | CONFIG_CACHE_WRITEBACK=y | ||
187 | # CONFIG_CACHE_WRITETHROUGH is not set | ||
188 | # CONFIG_CACHE_OFF is not set | ||
189 | |||
190 | # | ||
191 | # Processor features | ||
192 | # | ||
193 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
194 | # CONFIG_CPU_BIG_ENDIAN is not set | ||
195 | # CONFIG_SH_FPU_EMU is not set | ||
196 | # CONFIG_SH_DSP is not set | ||
197 | # CONFIG_SH_ADC is not set | ||
198 | CONFIG_CPU_HAS_INTEVT=y | ||
199 | CONFIG_CPU_HAS_SR_RB=y | ||
200 | CONFIG_CPU_HAS_DSP=y | ||
201 | |||
202 | # | ||
203 | # Board support | ||
204 | # | ||
205 | CONFIG_SOLUTION_ENGINE=y | ||
206 | CONFIG_SH_7721_SOLUTION_ENGINE=y | ||
207 | |||
208 | # | ||
209 | # Timer and clock configuration | ||
210 | # | ||
211 | CONFIG_SH_TMU=y | ||
212 | CONFIG_SH_TIMER_IRQ=16 | ||
213 | CONFIG_SH_PCLK_FREQ=33333333 | ||
214 | # CONFIG_TICK_ONESHOT is not set | ||
215 | # CONFIG_NO_HZ is not set | ||
216 | # CONFIG_HIGH_RES_TIMERS is not set | ||
217 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
218 | |||
219 | # | ||
220 | # CPU Frequency scaling | ||
221 | # | ||
222 | # CONFIG_CPU_FREQ is not set | ||
223 | |||
224 | # | ||
225 | # DMA support | ||
226 | # | ||
227 | # CONFIG_SH_DMA is not set | ||
228 | |||
229 | # | ||
230 | # Companion Chips | ||
231 | # | ||
232 | |||
233 | # | ||
234 | # Additional SuperH Device Drivers | ||
235 | # | ||
236 | CONFIG_HEARTBEAT=y | ||
237 | # CONFIG_PUSH_SWITCH is not set | ||
238 | |||
239 | # | ||
240 | # Kernel features | ||
241 | # | ||
242 | # CONFIG_HZ_100 is not set | ||
243 | CONFIG_HZ_250=y | ||
244 | # CONFIG_HZ_300 is not set | ||
245 | # CONFIG_HZ_1000 is not set | ||
246 | CONFIG_HZ=250 | ||
247 | # CONFIG_SCHED_HRTICK is not set | ||
248 | # CONFIG_KEXEC is not set | ||
249 | # CONFIG_CRASH_DUMP is not set | ||
250 | # CONFIG_PREEMPT_NONE is not set | ||
251 | CONFIG_PREEMPT_VOLUNTARY=y | ||
252 | # CONFIG_PREEMPT is not set | ||
253 | CONFIG_GUSA=y | ||
254 | # CONFIG_GUSA_RB is not set | ||
255 | |||
256 | # | ||
257 | # Boot options | ||
258 | # | ||
259 | CONFIG_ZERO_PAGE_OFFSET=0x00001000 | ||
260 | CONFIG_BOOT_LINK_OFFSET=0x00800000 | ||
261 | CONFIG_CMDLINE_BOOL=y | ||
262 | CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda2" | ||
263 | |||
264 | # | ||
265 | # Bus options | ||
266 | # | ||
267 | CONFIG_CF_ENABLER=y | ||
268 | # CONFIG_CF_AREA5 is not set | ||
269 | CONFIG_CF_AREA6=y | ||
270 | CONFIG_CF_BASE_ADDR=0xb8000000 | ||
271 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
272 | # CONFIG_PCCARD is not set | ||
273 | |||
274 | # | ||
275 | # Executable file formats | ||
276 | # | ||
277 | CONFIG_BINFMT_ELF=y | ||
278 | # CONFIG_BINFMT_MISC is not set | ||
279 | |||
280 | # | ||
281 | # Networking | ||
282 | # | ||
283 | CONFIG_NET=y | ||
284 | |||
285 | # | ||
286 | # Networking options | ||
287 | # | ||
288 | CONFIG_PACKET=y | ||
289 | CONFIG_PACKET_MMAP=y | ||
290 | CONFIG_UNIX=y | ||
291 | CONFIG_XFRM=y | ||
292 | # CONFIG_XFRM_USER is not set | ||
293 | # CONFIG_XFRM_SUB_POLICY is not set | ||
294 | # CONFIG_XFRM_MIGRATE is not set | ||
295 | # CONFIG_XFRM_STATISTICS is not set | ||
296 | CONFIG_NET_KEY=y | ||
297 | # CONFIG_NET_KEY_MIGRATE is not set | ||
298 | CONFIG_INET=y | ||
299 | CONFIG_IP_MULTICAST=y | ||
300 | CONFIG_IP_ADVANCED_ROUTER=y | ||
301 | CONFIG_ASK_IP_FIB_HASH=y | ||
302 | # CONFIG_IP_FIB_TRIE is not set | ||
303 | CONFIG_IP_FIB_HASH=y | ||
304 | CONFIG_IP_MULTIPLE_TABLES=y | ||
305 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
306 | CONFIG_IP_ROUTE_VERBOSE=y | ||
307 | CONFIG_IP_PNP=y | ||
308 | CONFIG_IP_PNP_DHCP=y | ||
309 | # CONFIG_IP_PNP_BOOTP is not set | ||
310 | # CONFIG_IP_PNP_RARP is not set | ||
311 | # CONFIG_NET_IPIP is not set | ||
312 | # CONFIG_NET_IPGRE is not set | ||
313 | CONFIG_IP_MROUTE=y | ||
314 | CONFIG_IP_PIMSM_V1=y | ||
315 | CONFIG_IP_PIMSM_V2=y | ||
316 | # CONFIG_ARPD is not set | ||
317 | CONFIG_SYN_COOKIES=y | ||
318 | CONFIG_INET_AH=y | ||
319 | CONFIG_INET_ESP=y | ||
320 | CONFIG_INET_IPCOMP=y | ||
321 | CONFIG_INET_XFRM_TUNNEL=y | ||
322 | CONFIG_INET_TUNNEL=y | ||
323 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
324 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
325 | CONFIG_INET_XFRM_MODE_BEET=y | ||
326 | # CONFIG_INET_LRO is not set | ||
327 | # CONFIG_INET_DIAG is not set | ||
328 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
329 | CONFIG_TCP_CONG_CUBIC=y | ||
330 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
331 | # CONFIG_TCP_MD5SIG is not set | ||
332 | # CONFIG_IPV6 is not set | ||
333 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
334 | # CONFIG_INET6_TUNNEL is not set | ||
335 | # CONFIG_NETWORK_SECMARK is not set | ||
336 | # CONFIG_NETFILTER is not set | ||
337 | # CONFIG_IP_DCCP is not set | ||
338 | # CONFIG_IP_SCTP is not set | ||
339 | # CONFIG_TIPC is not set | ||
340 | # CONFIG_ATM is not set | ||
341 | # CONFIG_BRIDGE is not set | ||
342 | # CONFIG_VLAN_8021Q is not set | ||
343 | # CONFIG_DECNET is not set | ||
344 | # CONFIG_LLC2 is not set | ||
345 | # CONFIG_IPX is not set | ||
346 | # CONFIG_ATALK is not set | ||
347 | # CONFIG_X25 is not set | ||
348 | # CONFIG_LAPB is not set | ||
349 | # CONFIG_ECONET is not set | ||
350 | # CONFIG_WAN_ROUTER is not set | ||
351 | CONFIG_NET_SCHED=y | ||
352 | |||
353 | # | ||
354 | # Queueing/Scheduling | ||
355 | # | ||
356 | CONFIG_NET_SCH_CBQ=y | ||
357 | CONFIG_NET_SCH_HTB=y | ||
358 | CONFIG_NET_SCH_HFSC=y | ||
359 | CONFIG_NET_SCH_PRIO=y | ||
360 | # CONFIG_NET_SCH_RR is not set | ||
361 | CONFIG_NET_SCH_RED=y | ||
362 | CONFIG_NET_SCH_SFQ=y | ||
363 | CONFIG_NET_SCH_TEQL=y | ||
364 | CONFIG_NET_SCH_TBF=y | ||
365 | CONFIG_NET_SCH_GRED=y | ||
366 | CONFIG_NET_SCH_DSMARK=y | ||
367 | CONFIG_NET_SCH_NETEM=y | ||
368 | |||
369 | # | ||
370 | # Classification | ||
371 | # | ||
372 | CONFIG_NET_CLS=y | ||
373 | # CONFIG_NET_CLS_BASIC is not set | ||
374 | CONFIG_NET_CLS_TCINDEX=y | ||
375 | CONFIG_NET_CLS_ROUTE4=y | ||
376 | CONFIG_NET_CLS_ROUTE=y | ||
377 | CONFIG_NET_CLS_FW=y | ||
378 | # CONFIG_NET_CLS_U32 is not set | ||
379 | # CONFIG_NET_CLS_RSVP is not set | ||
380 | # CONFIG_NET_CLS_RSVP6 is not set | ||
381 | # CONFIG_NET_CLS_FLOW is not set | ||
382 | # CONFIG_NET_EMATCH is not set | ||
383 | # CONFIG_NET_CLS_ACT is not set | ||
384 | CONFIG_NET_CLS_IND=y | ||
385 | CONFIG_NET_SCH_FIFO=y | ||
386 | |||
387 | # | ||
388 | # Network testing | ||
389 | # | ||
390 | # CONFIG_NET_PKTGEN is not set | ||
391 | # CONFIG_HAMRADIO is not set | ||
392 | # CONFIG_CAN is not set | ||
393 | # CONFIG_IRDA is not set | ||
394 | # CONFIG_BT is not set | ||
395 | # CONFIG_AF_RXRPC is not set | ||
396 | CONFIG_FIB_RULES=y | ||
397 | |||
398 | # | ||
399 | # Wireless | ||
400 | # | ||
401 | # CONFIG_CFG80211 is not set | ||
402 | # CONFIG_WIRELESS_EXT is not set | ||
403 | # CONFIG_MAC80211 is not set | ||
404 | # CONFIG_IEEE80211 is not set | ||
405 | # CONFIG_RFKILL is not set | ||
406 | # CONFIG_NET_9P is not set | ||
407 | |||
408 | # | ||
409 | # Device Drivers | ||
410 | # | ||
411 | |||
412 | # | ||
413 | # Generic Driver Options | ||
414 | # | ||
415 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
416 | CONFIG_STANDALONE=y | ||
417 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
418 | CONFIG_FW_LOADER=y | ||
419 | # CONFIG_DEBUG_DRIVER is not set | ||
420 | # CONFIG_DEBUG_DEVRES is not set | ||
421 | # CONFIG_SYS_HYPERVISOR is not set | ||
422 | # CONFIG_CONNECTOR is not set | ||
423 | CONFIG_MTD=y | ||
424 | # CONFIG_MTD_DEBUG is not set | ||
425 | CONFIG_MTD_CONCAT=y | ||
426 | CONFIG_MTD_PARTITIONS=y | ||
427 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
428 | # CONFIG_MTD_CMDLINE_PARTS is not set | ||
429 | |||
430 | # | ||
431 | # User Modules And Translation Layers | ||
432 | # | ||
433 | CONFIG_MTD_CHAR=y | ||
434 | CONFIG_MTD_BLKDEVS=y | ||
435 | CONFIG_MTD_BLOCK=y | ||
436 | # CONFIG_FTL is not set | ||
437 | # CONFIG_NFTL is not set | ||
438 | # CONFIG_INFTL is not set | ||
439 | # CONFIG_RFD_FTL is not set | ||
440 | # CONFIG_SSFDC is not set | ||
441 | # CONFIG_MTD_OOPS is not set | ||
442 | |||
443 | # | ||
444 | # RAM/ROM/Flash chip drivers | ||
445 | # | ||
446 | CONFIG_MTD_CFI=y | ||
447 | # CONFIG_MTD_JEDECPROBE is not set | ||
448 | CONFIG_MTD_GEN_PROBE=y | ||
449 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
450 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
451 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
452 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
453 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
454 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
455 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
456 | CONFIG_MTD_CFI_I1=y | ||
457 | CONFIG_MTD_CFI_I2=y | ||
458 | # CONFIG_MTD_CFI_I4 is not set | ||
459 | # CONFIG_MTD_CFI_I8 is not set | ||
460 | # CONFIG_MTD_CFI_INTELEXT is not set | ||
461 | CONFIG_MTD_CFI_AMDSTD=y | ||
462 | # CONFIG_MTD_CFI_STAA is not set | ||
463 | CONFIG_MTD_CFI_UTIL=y | ||
464 | # CONFIG_MTD_RAM is not set | ||
465 | # CONFIG_MTD_ROM is not set | ||
466 | # CONFIG_MTD_ABSENT is not set | ||
467 | |||
468 | # | ||
469 | # Mapping drivers for chip access | ||
470 | # | ||
471 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
472 | # CONFIG_MTD_PHYSMAP is not set | ||
473 | # CONFIG_MTD_PLATRAM is not set | ||
474 | |||
475 | # | ||
476 | # Self-contained MTD device drivers | ||
477 | # | ||
478 | # CONFIG_MTD_SLRAM is not set | ||
479 | # CONFIG_MTD_PHRAM is not set | ||
480 | # CONFIG_MTD_MTDRAM is not set | ||
481 | # CONFIG_MTD_BLOCK2MTD is not set | ||
482 | |||
483 | # | ||
484 | # Disk-On-Chip Device Drivers | ||
485 | # | ||
486 | # CONFIG_MTD_DOC2000 is not set | ||
487 | # CONFIG_MTD_DOC2001 is not set | ||
488 | # CONFIG_MTD_DOC2001PLUS is not set | ||
489 | # CONFIG_MTD_NAND is not set | ||
490 | # CONFIG_MTD_ONENAND is not set | ||
491 | |||
492 | # | ||
493 | # UBI - Unsorted block images | ||
494 | # | ||
495 | # CONFIG_MTD_UBI is not set | ||
496 | # CONFIG_PARPORT is not set | ||
497 | CONFIG_BLK_DEV=y | ||
498 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
499 | # CONFIG_BLK_DEV_LOOP is not set | ||
500 | # CONFIG_BLK_DEV_NBD is not set | ||
501 | # CONFIG_BLK_DEV_UB is not set | ||
502 | # CONFIG_BLK_DEV_RAM is not set | ||
503 | # CONFIG_CDROM_PKTCDVD is not set | ||
504 | # CONFIG_ATA_OVER_ETH is not set | ||
505 | CONFIG_MISC_DEVICES=y | ||
506 | # CONFIG_EEPROM_93CX6 is not set | ||
507 | # CONFIG_ENCLOSURE_SERVICES is not set | ||
508 | CONFIG_HAVE_IDE=y | ||
509 | # CONFIG_IDE is not set | ||
510 | |||
511 | # | ||
512 | # SCSI device support | ||
513 | # | ||
514 | # CONFIG_RAID_ATTRS is not set | ||
515 | CONFIG_SCSI=y | ||
516 | CONFIG_SCSI_DMA=y | ||
517 | # CONFIG_SCSI_TGT is not set | ||
518 | # CONFIG_SCSI_NETLINK is not set | ||
519 | CONFIG_SCSI_PROC_FS=y | ||
520 | |||
521 | # | ||
522 | # SCSI support type (disk, tape, CD-ROM) | ||
523 | # | ||
524 | CONFIG_BLK_DEV_SD=y | ||
525 | # CONFIG_CHR_DEV_ST is not set | ||
526 | # CONFIG_CHR_DEV_OSST is not set | ||
527 | # CONFIG_BLK_DEV_SR is not set | ||
528 | # CONFIG_CHR_DEV_SG is not set | ||
529 | # CONFIG_CHR_DEV_SCH is not set | ||
530 | |||
531 | # | ||
532 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
533 | # | ||
534 | CONFIG_SCSI_MULTI_LUN=y | ||
535 | # CONFIG_SCSI_CONSTANTS is not set | ||
536 | # CONFIG_SCSI_LOGGING is not set | ||
537 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
538 | CONFIG_SCSI_WAIT_SCAN=m | ||
539 | |||
540 | # | ||
541 | # SCSI Transports | ||
542 | # | ||
543 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
544 | # CONFIG_SCSI_FC_ATTRS is not set | ||
545 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
546 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
547 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
548 | # CONFIG_SCSI_LOWLEVEL is not set | ||
549 | CONFIG_ATA=y | ||
550 | # CONFIG_ATA_NONSTANDARD is not set | ||
551 | # CONFIG_SATA_MV is not set | ||
552 | CONFIG_PATA_PLATFORM=y | ||
553 | # CONFIG_MD is not set | ||
554 | CONFIG_NETDEVICES=y | ||
555 | # CONFIG_NETDEVICES_MULTIQUEUE is not set | ||
556 | # CONFIG_DUMMY is not set | ||
557 | # CONFIG_BONDING is not set | ||
558 | # CONFIG_MACVLAN is not set | ||
559 | # CONFIG_EQUALIZER is not set | ||
560 | # CONFIG_TUN is not set | ||
561 | # CONFIG_VETH is not set | ||
562 | # CONFIG_NET_ETHERNET is not set | ||
563 | CONFIG_NETDEV_1000=y | ||
564 | # CONFIG_E1000E_ENABLED is not set | ||
565 | CONFIG_NETDEV_10000=y | ||
566 | |||
567 | # | ||
568 | # Wireless LAN | ||
569 | # | ||
570 | # CONFIG_WLAN_PRE80211 is not set | ||
571 | # CONFIG_WLAN_80211 is not set | ||
572 | |||
573 | # | ||
574 | # USB Network Adapters | ||
575 | # | ||
576 | # CONFIG_USB_CATC is not set | ||
577 | # CONFIG_USB_KAWETH is not set | ||
578 | # CONFIG_USB_PEGASUS is not set | ||
579 | # CONFIG_USB_RTL8150 is not set | ||
580 | # CONFIG_USB_USBNET is not set | ||
581 | # CONFIG_WAN is not set | ||
582 | # CONFIG_PPP is not set | ||
583 | # CONFIG_SLIP is not set | ||
584 | # CONFIG_NETCONSOLE is not set | ||
585 | # CONFIG_NETPOLL is not set | ||
586 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
587 | # CONFIG_ISDN is not set | ||
588 | # CONFIG_PHONE is not set | ||
589 | |||
590 | # | ||
591 | # Input device support | ||
592 | # | ||
593 | CONFIG_INPUT=y | ||
594 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
595 | # CONFIG_INPUT_POLLDEV is not set | ||
596 | |||
597 | # | ||
598 | # Userland interfaces | ||
599 | # | ||
600 | CONFIG_INPUT_MOUSEDEV=y | ||
601 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
602 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
603 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
604 | # CONFIG_INPUT_JOYDEV is not set | ||
605 | CONFIG_INPUT_EVDEV=y | ||
606 | # CONFIG_INPUT_EVBUG is not set | ||
607 | |||
608 | # | ||
609 | # Input Device Drivers | ||
610 | # | ||
611 | CONFIG_INPUT_KEYBOARD=y | ||
612 | # CONFIG_KEYBOARD_ATKBD is not set | ||
613 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
614 | # CONFIG_KEYBOARD_LKKBD is not set | ||
615 | # CONFIG_KEYBOARD_XTKBD is not set | ||
616 | # CONFIG_KEYBOARD_NEWTON is not set | ||
617 | # CONFIG_KEYBOARD_STOWAWAY is not set | ||
618 | # CONFIG_KEYBOARD_SH_KEYSC is not set | ||
619 | CONFIG_INPUT_MOUSE=y | ||
620 | # CONFIG_MOUSE_PS2 is not set | ||
621 | # CONFIG_MOUSE_SERIAL is not set | ||
622 | # CONFIG_MOUSE_APPLETOUCH is not set | ||
623 | # CONFIG_MOUSE_VSXXXAA is not set | ||
624 | # CONFIG_INPUT_JOYSTICK is not set | ||
625 | # CONFIG_INPUT_TABLET is not set | ||
626 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
627 | # CONFIG_INPUT_MISC is not set | ||
628 | |||
629 | # | ||
630 | # Hardware I/O ports | ||
631 | # | ||
632 | # CONFIG_SERIO is not set | ||
633 | # CONFIG_GAMEPORT is not set | ||
634 | |||
635 | # | ||
636 | # Character devices | ||
637 | # | ||
638 | # CONFIG_VT is not set | ||
639 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
640 | |||
641 | # | ||
642 | # Serial drivers | ||
643 | # | ||
644 | # CONFIG_SERIAL_8250 is not set | ||
645 | |||
646 | # | ||
647 | # Non-8250 serial port support | ||
648 | # | ||
649 | CONFIG_SERIAL_SH_SCI=y | ||
650 | CONFIG_SERIAL_SH_SCI_NR_UARTS=2 | ||
651 | CONFIG_SERIAL_SH_SCI_CONSOLE=y | ||
652 | CONFIG_SERIAL_CORE=y | ||
653 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
654 | CONFIG_UNIX98_PTYS=y | ||
655 | # CONFIG_LEGACY_PTYS is not set | ||
656 | # CONFIG_IPMI_HANDLER is not set | ||
657 | # CONFIG_HW_RANDOM is not set | ||
658 | # CONFIG_R3964 is not set | ||
659 | # CONFIG_RAW_DRIVER is not set | ||
660 | # CONFIG_TCG_TPM is not set | ||
661 | # CONFIG_I2C is not set | ||
662 | |||
663 | # | ||
664 | # SPI support | ||
665 | # | ||
666 | # CONFIG_SPI is not set | ||
667 | # CONFIG_SPI_MASTER is not set | ||
668 | # CONFIG_W1 is not set | ||
669 | # CONFIG_POWER_SUPPLY is not set | ||
670 | # CONFIG_HWMON is not set | ||
671 | CONFIG_THERMAL=y | ||
672 | # CONFIG_WATCHDOG is not set | ||
673 | |||
674 | # | ||
675 | # Sonics Silicon Backplane | ||
676 | # | ||
677 | CONFIG_SSB_POSSIBLE=y | ||
678 | # CONFIG_SSB is not set | ||
679 | |||
680 | # | ||
681 | # Multifunction device drivers | ||
682 | # | ||
683 | # CONFIG_MFD_SM501 is not set | ||
684 | |||
685 | # | ||
686 | # Multimedia devices | ||
687 | # | ||
688 | # CONFIG_VIDEO_DEV is not set | ||
689 | # CONFIG_DVB_CORE is not set | ||
690 | # CONFIG_DAB is not set | ||
691 | |||
692 | # | ||
693 | # Graphics support | ||
694 | # | ||
695 | # CONFIG_VGASTATE is not set | ||
696 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
697 | # CONFIG_FB is not set | ||
698 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
699 | |||
700 | # | ||
701 | # Display device support | ||
702 | # | ||
703 | # CONFIG_DISPLAY_SUPPORT is not set | ||
704 | |||
705 | # | ||
706 | # Sound | ||
707 | # | ||
708 | # CONFIG_SOUND is not set | ||
709 | CONFIG_HID_SUPPORT=y | ||
710 | CONFIG_HID=y | ||
711 | # CONFIG_HID_DEBUG is not set | ||
712 | # CONFIG_HIDRAW is not set | ||
713 | |||
714 | # | ||
715 | # USB Input Devices | ||
716 | # | ||
717 | CONFIG_USB_HID=y | ||
718 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set | ||
719 | # CONFIG_HID_FF is not set | ||
720 | # CONFIG_USB_HIDDEV is not set | ||
721 | CONFIG_USB_SUPPORT=y | ||
722 | CONFIG_USB_ARCH_HAS_HCD=y | ||
723 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
724 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
725 | CONFIG_USB=y | ||
726 | # CONFIG_USB_DEBUG is not set | ||
727 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
728 | |||
729 | # | ||
730 | # Miscellaneous USB options | ||
731 | # | ||
732 | # CONFIG_USB_DEVICEFS is not set | ||
733 | CONFIG_USB_DEVICE_CLASS=y | ||
734 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
735 | # CONFIG_USB_OTG is not set | ||
736 | |||
737 | # | ||
738 | # USB Host Controller Drivers | ||
739 | # | ||
740 | # CONFIG_USB_ISP116X_HCD is not set | ||
741 | CONFIG_USB_OHCI_HCD=y | ||
742 | # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set | ||
743 | # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set | ||
744 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
745 | # CONFIG_USB_SL811_HCD is not set | ||
746 | # CONFIG_USB_R8A66597_HCD is not set | ||
747 | |||
748 | # | ||
749 | # USB Device Class drivers | ||
750 | # | ||
751 | # CONFIG_USB_ACM is not set | ||
752 | # CONFIG_USB_PRINTER is not set | ||
753 | |||
754 | # | ||
755 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
756 | # | ||
757 | |||
758 | # | ||
759 | # may also be needed; see USB_STORAGE Help for more information | ||
760 | # | ||
761 | CONFIG_USB_STORAGE=y | ||
762 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
763 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
764 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
765 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
766 | # CONFIG_USB_STORAGE_DPCM is not set | ||
767 | # CONFIG_USB_STORAGE_USBAT is not set | ||
768 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
769 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
770 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
771 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
772 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
773 | # CONFIG_USB_STORAGE_KARMA is not set | ||
774 | # CONFIG_USB_LIBUSUAL is not set | ||
775 | |||
776 | # | ||
777 | # USB Imaging devices | ||
778 | # | ||
779 | # CONFIG_USB_MDC800 is not set | ||
780 | # CONFIG_USB_MICROTEK is not set | ||
781 | CONFIG_USB_MON=y | ||
782 | |||
783 | # | ||
784 | # USB port drivers | ||
785 | # | ||
786 | # CONFIG_USB_SERIAL is not set | ||
787 | |||
788 | # | ||
789 | # USB Miscellaneous drivers | ||
790 | # | ||
791 | # CONFIG_USB_EMI62 is not set | ||
792 | # CONFIG_USB_EMI26 is not set | ||
793 | # CONFIG_USB_ADUTUX is not set | ||
794 | # CONFIG_USB_AUERSWALD is not set | ||
795 | # CONFIG_USB_RIO500 is not set | ||
796 | # CONFIG_USB_LEGOTOWER is not set | ||
797 | # CONFIG_USB_LCD is not set | ||
798 | # CONFIG_USB_BERRY_CHARGE is not set | ||
799 | # CONFIG_USB_LED is not set | ||
800 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
801 | # CONFIG_USB_CYTHERM is not set | ||
802 | # CONFIG_USB_PHIDGET is not set | ||
803 | # CONFIG_USB_IDMOUSE is not set | ||
804 | # CONFIG_USB_FTDI_ELAN is not set | ||
805 | # CONFIG_USB_APPLEDISPLAY is not set | ||
806 | # CONFIG_USB_LD is not set | ||
807 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
808 | # CONFIG_USB_IOWARRIOR is not set | ||
809 | # CONFIG_USB_GADGET is not set | ||
810 | # CONFIG_MMC is not set | ||
811 | # CONFIG_MEMSTICK is not set | ||
812 | CONFIG_NEW_LEDS=y | ||
813 | CONFIG_LEDS_CLASS=y | ||
814 | |||
815 | # | ||
816 | # LED drivers | ||
817 | # | ||
818 | |||
819 | # | ||
820 | # LED Triggers | ||
821 | # | ||
822 | CONFIG_LEDS_TRIGGERS=y | ||
823 | # CONFIG_LEDS_TRIGGER_TIMER is not set | ||
824 | # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set | ||
825 | # CONFIG_RTC_CLASS is not set | ||
826 | |||
827 | # | ||
828 | # Userspace I/O | ||
829 | # | ||
830 | # CONFIG_UIO is not set | ||
831 | |||
832 | # | ||
833 | # File systems | ||
834 | # | ||
835 | CONFIG_EXT2_FS=y | ||
836 | CONFIG_EXT2_FS_XATTR=y | ||
837 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
838 | CONFIG_EXT2_FS_SECURITY=y | ||
839 | # CONFIG_EXT2_FS_XIP is not set | ||
840 | CONFIG_EXT3_FS=y | ||
841 | CONFIG_EXT3_FS_XATTR=y | ||
842 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
843 | # CONFIG_EXT3_FS_SECURITY is not set | ||
844 | # CONFIG_EXT4DEV_FS is not set | ||
845 | CONFIG_JBD=y | ||
846 | CONFIG_FS_MBCACHE=y | ||
847 | # CONFIG_REISERFS_FS is not set | ||
848 | # CONFIG_JFS_FS is not set | ||
849 | CONFIG_FS_POSIX_ACL=y | ||
850 | # CONFIG_XFS_FS is not set | ||
851 | # CONFIG_GFS2_FS is not set | ||
852 | # CONFIG_OCFS2_FS is not set | ||
853 | # CONFIG_DNOTIFY is not set | ||
854 | # CONFIG_INOTIFY is not set | ||
855 | # CONFIG_QUOTA is not set | ||
856 | # CONFIG_AUTOFS_FS is not set | ||
857 | # CONFIG_AUTOFS4_FS is not set | ||
858 | # CONFIG_FUSE_FS is not set | ||
859 | |||
860 | # | ||
861 | # CD-ROM/DVD Filesystems | ||
862 | # | ||
863 | # CONFIG_ISO9660_FS is not set | ||
864 | # CONFIG_UDF_FS is not set | ||
865 | |||
866 | # | ||
867 | # DOS/FAT/NT Filesystems | ||
868 | # | ||
869 | CONFIG_FAT_FS=y | ||
870 | CONFIG_MSDOS_FS=y | ||
871 | CONFIG_VFAT_FS=y | ||
872 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
873 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
874 | # CONFIG_NTFS_FS is not set | ||
875 | |||
876 | # | ||
877 | # Pseudo filesystems | ||
878 | # | ||
879 | CONFIG_PROC_FS=y | ||
880 | # CONFIG_PROC_KCORE is not set | ||
881 | CONFIG_PROC_SYSCTL=y | ||
882 | CONFIG_SYSFS=y | ||
883 | CONFIG_TMPFS=y | ||
884 | # CONFIG_TMPFS_POSIX_ACL is not set | ||
885 | # CONFIG_HUGETLBFS is not set | ||
886 | # CONFIG_HUGETLB_PAGE is not set | ||
887 | # CONFIG_CONFIGFS_FS is not set | ||
888 | |||
889 | # | ||
890 | # Miscellaneous filesystems | ||
891 | # | ||
892 | # CONFIG_ADFS_FS is not set | ||
893 | # CONFIG_AFFS_FS is not set | ||
894 | # CONFIG_HFS_FS is not set | ||
895 | # CONFIG_HFSPLUS_FS is not set | ||
896 | # CONFIG_BEFS_FS is not set | ||
897 | # CONFIG_BFS_FS is not set | ||
898 | # CONFIG_EFS_FS is not set | ||
899 | CONFIG_JFFS2_FS=y | ||
900 | CONFIG_JFFS2_FS_DEBUG=0 | ||
901 | CONFIG_JFFS2_FS_WRITEBUFFER=y | ||
902 | # CONFIG_JFFS2_FS_WBUF_VERIFY is not set | ||
903 | # CONFIG_JFFS2_SUMMARY is not set | ||
904 | # CONFIG_JFFS2_FS_XATTR is not set | ||
905 | # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set | ||
906 | CONFIG_JFFS2_ZLIB=y | ||
907 | # CONFIG_JFFS2_LZO is not set | ||
908 | CONFIG_JFFS2_RTIME=y | ||
909 | # CONFIG_JFFS2_RUBIN is not set | ||
910 | CONFIG_CRAMFS=y | ||
911 | # CONFIG_VXFS_FS is not set | ||
912 | # CONFIG_MINIX_FS is not set | ||
913 | # CONFIG_HPFS_FS is not set | ||
914 | # CONFIG_QNX4FS_FS is not set | ||
915 | # CONFIG_ROMFS_FS is not set | ||
916 | # CONFIG_SYSV_FS is not set | ||
917 | # CONFIG_UFS_FS is not set | ||
918 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
919 | |||
920 | # | ||
921 | # Partition Types | ||
922 | # | ||
923 | # CONFIG_PARTITION_ADVANCED is not set | ||
924 | CONFIG_MSDOS_PARTITION=y | ||
925 | CONFIG_NLS=y | ||
926 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
927 | CONFIG_NLS_CODEPAGE_437=y | ||
928 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
929 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
930 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
931 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
932 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
933 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
934 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
935 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
936 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
937 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
938 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
939 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
940 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
941 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
942 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
943 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
944 | CONFIG_NLS_CODEPAGE_932=y | ||
945 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
946 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
947 | # CONFIG_NLS_ISO8859_8 is not set | ||
948 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
949 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
950 | # CONFIG_NLS_ASCII is not set | ||
951 | CONFIG_NLS_ISO8859_1=y | ||
952 | # CONFIG_NLS_ISO8859_2 is not set | ||
953 | # CONFIG_NLS_ISO8859_3 is not set | ||
954 | # CONFIG_NLS_ISO8859_4 is not set | ||
955 | # CONFIG_NLS_ISO8859_5 is not set | ||
956 | # CONFIG_NLS_ISO8859_6 is not set | ||
957 | # CONFIG_NLS_ISO8859_7 is not set | ||
958 | # CONFIG_NLS_ISO8859_9 is not set | ||
959 | # CONFIG_NLS_ISO8859_13 is not set | ||
960 | # CONFIG_NLS_ISO8859_14 is not set | ||
961 | # CONFIG_NLS_ISO8859_15 is not set | ||
962 | # CONFIG_NLS_KOI8_R is not set | ||
963 | # CONFIG_NLS_KOI8_U is not set | ||
964 | # CONFIG_NLS_UTF8 is not set | ||
965 | # CONFIG_DLM is not set | ||
966 | |||
967 | # | ||
968 | # Kernel hacking | ||
969 | # | ||
970 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
971 | # CONFIG_PRINTK_TIME is not set | ||
972 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
973 | CONFIG_ENABLE_MUST_CHECK=y | ||
974 | # CONFIG_MAGIC_SYSRQ is not set | ||
975 | # CONFIG_UNUSED_SYMBOLS is not set | ||
976 | # CONFIG_DEBUG_FS is not set | ||
977 | # CONFIG_HEADERS_CHECK is not set | ||
978 | CONFIG_DEBUG_KERNEL=y | ||
979 | # CONFIG_DEBUG_SHIRQ is not set | ||
980 | # CONFIG_DETECT_SOFTLOCKUP is not set | ||
981 | CONFIG_SCHED_DEBUG=y | ||
982 | # CONFIG_SCHEDSTATS is not set | ||
983 | # CONFIG_TIMER_STATS is not set | ||
984 | # CONFIG_DEBUG_SLAB is not set | ||
985 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
986 | # CONFIG_RT_MUTEX_TESTER is not set | ||
987 | # CONFIG_DEBUG_SPINLOCK is not set | ||
988 | # CONFIG_DEBUG_MUTEXES is not set | ||
989 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
990 | # CONFIG_PROVE_LOCKING is not set | ||
991 | # CONFIG_LOCK_STAT is not set | ||
992 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
993 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
994 | # CONFIG_DEBUG_KOBJECT is not set | ||
995 | CONFIG_DEBUG_INFO=y | ||
996 | # CONFIG_DEBUG_VM is not set | ||
997 | # CONFIG_DEBUG_LIST is not set | ||
998 | # CONFIG_DEBUG_SG is not set | ||
999 | CONFIG_FRAME_POINTER=y | ||
1000 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
1001 | # CONFIG_RCU_TORTURE_TEST is not set | ||
1002 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
1003 | # CONFIG_FAULT_INJECTION is not set | ||
1004 | # CONFIG_SAMPLES is not set | ||
1005 | # CONFIG_SH_STANDARD_BIOS is not set | ||
1006 | # CONFIG_EARLY_SCIF_CONSOLE is not set | ||
1007 | # CONFIG_DEBUG_BOOTMEM is not set | ||
1008 | # CONFIG_DEBUG_STACKOVERFLOW is not set | ||
1009 | # CONFIG_DEBUG_STACK_USAGE is not set | ||
1010 | # CONFIG_4KSTACKS is not set | ||
1011 | # CONFIG_IRQSTACKS is not set | ||
1012 | # CONFIG_SH_KGDB is not set | ||
1013 | |||
1014 | # | ||
1015 | # Security options | ||
1016 | # | ||
1017 | # CONFIG_KEYS is not set | ||
1018 | # CONFIG_SECURITY is not set | ||
1019 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
1020 | CONFIG_CRYPTO=y | ||
1021 | CONFIG_CRYPTO_ALGAPI=y | ||
1022 | CONFIG_CRYPTO_AEAD=y | ||
1023 | CONFIG_CRYPTO_BLKCIPHER=y | ||
1024 | # CONFIG_CRYPTO_SEQIV is not set | ||
1025 | CONFIG_CRYPTO_HASH=y | ||
1026 | CONFIG_CRYPTO_MANAGER=y | ||
1027 | CONFIG_CRYPTO_HMAC=y | ||
1028 | # CONFIG_CRYPTO_XCBC is not set | ||
1029 | # CONFIG_CRYPTO_NULL is not set | ||
1030 | # CONFIG_CRYPTO_MD4 is not set | ||
1031 | CONFIG_CRYPTO_MD5=y | ||
1032 | CONFIG_CRYPTO_SHA1=y | ||
1033 | # CONFIG_CRYPTO_SHA256 is not set | ||
1034 | # CONFIG_CRYPTO_SHA512 is not set | ||
1035 | # CONFIG_CRYPTO_WP512 is not set | ||
1036 | # CONFIG_CRYPTO_TGR192 is not set | ||
1037 | # CONFIG_CRYPTO_GF128MUL is not set | ||
1038 | # CONFIG_CRYPTO_ECB is not set | ||
1039 | CONFIG_CRYPTO_CBC=y | ||
1040 | # CONFIG_CRYPTO_PCBC is not set | ||
1041 | # CONFIG_CRYPTO_LRW is not set | ||
1042 | # CONFIG_CRYPTO_XTS is not set | ||
1043 | # CONFIG_CRYPTO_CTR is not set | ||
1044 | # CONFIG_CRYPTO_GCM is not set | ||
1045 | # CONFIG_CRYPTO_CCM is not set | ||
1046 | # CONFIG_CRYPTO_CRYPTD is not set | ||
1047 | CONFIG_CRYPTO_DES=y | ||
1048 | # CONFIG_CRYPTO_FCRYPT is not set | ||
1049 | # CONFIG_CRYPTO_BLOWFISH is not set | ||
1050 | # CONFIG_CRYPTO_TWOFISH is not set | ||
1051 | # CONFIG_CRYPTO_SERPENT is not set | ||
1052 | # CONFIG_CRYPTO_AES is not set | ||
1053 | # CONFIG_CRYPTO_CAST5 is not set | ||
1054 | # CONFIG_CRYPTO_CAST6 is not set | ||
1055 | # CONFIG_CRYPTO_TEA is not set | ||
1056 | # CONFIG_CRYPTO_ARC4 is not set | ||
1057 | # CONFIG_CRYPTO_KHAZAD is not set | ||
1058 | # CONFIG_CRYPTO_ANUBIS is not set | ||
1059 | # CONFIG_CRYPTO_SEED is not set | ||
1060 | # CONFIG_CRYPTO_SALSA20 is not set | ||
1061 | CONFIG_CRYPTO_DEFLATE=y | ||
1062 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | ||
1063 | # CONFIG_CRYPTO_CRC32C is not set | ||
1064 | # CONFIG_CRYPTO_CAMELLIA is not set | ||
1065 | # CONFIG_CRYPTO_TEST is not set | ||
1066 | CONFIG_CRYPTO_AUTHENC=y | ||
1067 | # CONFIG_CRYPTO_LZO is not set | ||
1068 | CONFIG_CRYPTO_HW=y | ||
1069 | |||
1070 | # | ||
1071 | # Library routines | ||
1072 | # | ||
1073 | CONFIG_BITREVERSE=y | ||
1074 | CONFIG_CRC_CCITT=y | ||
1075 | # CONFIG_CRC16 is not set | ||
1076 | # CONFIG_CRC_ITU_T is not set | ||
1077 | CONFIG_CRC32=y | ||
1078 | # CONFIG_CRC7 is not set | ||
1079 | # CONFIG_LIBCRC32C is not set | ||
1080 | CONFIG_ZLIB_INFLATE=y | ||
1081 | CONFIG_ZLIB_DEFLATE=y | ||
1082 | CONFIG_PLIST=y | ||
1083 | CONFIG_HAS_IOMEM=y | ||
1084 | CONFIG_HAS_IOPORT=y | ||
1085 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c index 1c3b99642e1c..01ff4d05aab0 100644 --- a/arch/sh/kernel/cf-enabler.c +++ b/arch/sh/kernel/cf-enabler.c | |||
@@ -83,6 +83,8 @@ static int __init cf_init_default(void) | |||
83 | #include <asm/se.h> | 83 | #include <asm/se.h> |
84 | #elif defined(CONFIG_SH_7722_SOLUTION_ENGINE) | 84 | #elif defined(CONFIG_SH_7722_SOLUTION_ENGINE) |
85 | #include <asm/se7722.h> | 85 | #include <asm/se7722.h> |
86 | #elif defined(CONFIG_SH_7721_SOLUTION_ENGINE) | ||
87 | #include <asm/se7721.h> | ||
86 | #endif | 88 | #endif |
87 | 89 | ||
88 | /* | 90 | /* |
@@ -99,7 +101,9 @@ static int __init cf_init_default(void) | |||
99 | * 0xB0600000 : I/O | 101 | * 0xB0600000 : I/O |
100 | */ | 102 | */ |
101 | 103 | ||
102 | #if defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE) | 104 | #if defined(CONFIG_SH_SOLUTION_ENGINE) || \ |
105 | defined(CONFIG_SH_7722_SOLUTION_ENGINE) || \ | ||
106 | defined(CONFIG_SH_7721_SOLUTION_ENGINE) | ||
103 | static int __init cf_init_se(void) | 107 | static int __init cf_init_se(void) |
104 | { | 108 | { |
105 | if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0) | 109 | if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0) |
@@ -112,7 +116,7 @@ static int __init cf_init_se(void) | |||
112 | } | 116 | } |
113 | 117 | ||
114 | /* | 118 | /* |
115 | * PC-Card window open | 119 | * PC-Card window open |
116 | * flag == COMMON/ATTRIBUTE/IO | 120 | * flag == COMMON/ATTRIBUTE/IO |
117 | */ | 121 | */ |
118 | /* common window open */ | 122 | /* common window open */ |
@@ -122,7 +126,7 @@ static int __init cf_init_se(void) | |||
122 | ctrl_outw(0x0b00, MRSHPC_MW0CR2); | 126 | ctrl_outw(0x0b00, MRSHPC_MW0CR2); |
123 | else | 127 | else |
124 | /* common mode & bus width 16bit SWAP = 0*/ | 128 | /* common mode & bus width 16bit SWAP = 0*/ |
125 | ctrl_outw(0x0300, MRSHPC_MW0CR2); | 129 | ctrl_outw(0x0300, MRSHPC_MW0CR2); |
126 | 130 | ||
127 | /* attribute window open */ | 131 | /* attribute window open */ |
128 | ctrl_outw(0x8a85, MRSHPC_MW1CR1); | 132 | ctrl_outw(0x8a85, MRSHPC_MW1CR1); |
@@ -155,10 +159,9 @@ static int __init cf_init_se(void) | |||
155 | 159 | ||
156 | int __init cf_init(void) | 160 | int __init cf_init(void) |
157 | { | 161 | { |
158 | if( mach_is_se() || mach_is_7722se() ){ | 162 | if (mach_is_se() || mach_is_7722se() || mach_is_7721se()) |
159 | return cf_init_se(); | 163 | return cf_init_se(); |
160 | } | 164 | |
161 | |||
162 | return cf_init_default(); | 165 | return cf_init_default(); |
163 | } | 166 | } |
164 | 167 | ||
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile index b279cdc3a233..7e2b90cfa7bf 100644 --- a/arch/sh/kernel/cpu/sh2a/Makefile +++ b/arch/sh/kernel/cpu/sh2a/Makefile | |||
@@ -8,6 +8,7 @@ common-y += $(addprefix ../sh2/, ex.o entry.o) | |||
8 | 8 | ||
9 | obj-$(CONFIG_SH_FPU) += fpu.o | 9 | obj-$(CONFIG_SH_FPU) += fpu.o |
10 | 10 | ||
11 | obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o | 11 | obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o |
12 | obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o | 12 | obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o |
13 | obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o | 13 | obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o |
14 | obj-$(CONFIG_CPU_SUBTYPE_MXG) += setup-mxg.o clock-sh7206.o | ||
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c index 6910e2664468..6e79132f6f30 100644 --- a/arch/sh/kernel/cpu/sh2a/probe.c +++ b/arch/sh/kernel/cpu/sh2a/probe.c | |||
@@ -29,6 +29,9 @@ int __init detect_cpu_and_cache_system(void) | |||
29 | boot_cpu_data.type = CPU_SH7206; | 29 | boot_cpu_data.type = CPU_SH7206; |
30 | /* While SH7206 has a DSP.. */ | 30 | /* While SH7206 has a DSP.. */ |
31 | boot_cpu_data.flags |= CPU_HAS_DSP; | 31 | boot_cpu_data.flags |= CPU_HAS_DSP; |
32 | #elif defined(CONFIG_CPU_SUBTYPE_MXG) | ||
33 | boot_cpu_data.type = CPU_MXG; | ||
34 | boot_cpu_data.flags |= CPU_HAS_DSP; | ||
32 | #endif | 35 | #endif |
33 | 36 | ||
34 | boot_cpu_data.dcache.ways = 4; | 37 | boot_cpu_data.dcache.ways = 4; |
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c new file mode 100644 index 000000000000..e611d79fac4c --- /dev/null +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * Renesas MX-G (R8A03022BG) Setup | ||
3 | * | ||
4 | * Copyright (C) 2008 Paul Mundt | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/serial.h> | ||
13 | #include <linux/serial_sci.h> | ||
14 | |||
15 | enum { | ||
16 | UNUSED = 0, | ||
17 | |||
18 | /* interrupt sources */ | ||
19 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, | ||
20 | IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15, | ||
21 | |||
22 | PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7, | ||
23 | |||
24 | SINT8, SINT7, SINT6, SINT5, SINT4, SINT3, SINT2, SINT1, | ||
25 | |||
26 | SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI, | ||
27 | SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI, | ||
28 | |||
29 | MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D, | ||
30 | MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F, | ||
31 | MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U, | ||
32 | MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U, | ||
33 | MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V, | ||
34 | MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V, | ||
35 | MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W, | ||
36 | |||
37 | /* interrupt groups */ | ||
38 | PINT, SCIF0, SCIF1, | ||
39 | MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5 | ||
40 | }; | ||
41 | |||
42 | static struct intc_vect vectors[] __initdata = { | ||
43 | INTC_IRQ(IRQ0, 64), INTC_IRQ(IRQ1, 65), | ||
44 | INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67), | ||
45 | INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69), | ||
46 | INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71), | ||
47 | INTC_IRQ(IRQ8, 72), INTC_IRQ(IRQ9, 73), | ||
48 | INTC_IRQ(IRQ10, 74), INTC_IRQ(IRQ11, 75), | ||
49 | INTC_IRQ(IRQ12, 76), INTC_IRQ(IRQ13, 77), | ||
50 | INTC_IRQ(IRQ14, 78), INTC_IRQ(IRQ15, 79), | ||
51 | |||
52 | INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81), | ||
53 | INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83), | ||
54 | INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85), | ||
55 | INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87), | ||
56 | |||
57 | INTC_IRQ(SINT8, 94), INTC_IRQ(SINT7, 95), | ||
58 | INTC_IRQ(SINT6, 96), INTC_IRQ(SINT5, 97), | ||
59 | INTC_IRQ(SINT4, 98), INTC_IRQ(SINT3, 99), | ||
60 | INTC_IRQ(SINT2, 100), INTC_IRQ(SINT1, 101), | ||
61 | |||
62 | INTC_IRQ(SCIF0_RXI, 220), INTC_IRQ(SCIF0_TXI, 221), | ||
63 | INTC_IRQ(SCIF0_BRI, 222), INTC_IRQ(SCIF0_ERI, 223), | ||
64 | INTC_IRQ(SCIF1_RXI, 224), INTC_IRQ(SCIF1_TXI, 225), | ||
65 | INTC_IRQ(SCIF1_BRI, 226), INTC_IRQ(SCIF1_ERI, 227), | ||
66 | |||
67 | INTC_IRQ(MTU2_TGI0A, 228), INTC_IRQ(MTU2_TGI0B, 229), | ||
68 | INTC_IRQ(MTU2_TGI0C, 230), INTC_IRQ(MTU2_TGI0D, 231), | ||
69 | INTC_IRQ(MTU2_TCI0V, 232), INTC_IRQ(MTU2_TGI0E, 233), | ||
70 | |||
71 | INTC_IRQ(MTU2_TGI0F, 234), INTC_IRQ(MTU2_TGI1A, 235), | ||
72 | INTC_IRQ(MTU2_TGI1B, 236), INTC_IRQ(MTU2_TCI1V, 237), | ||
73 | INTC_IRQ(MTU2_TCI1U, 238), INTC_IRQ(MTU2_TGI2A, 239), | ||
74 | |||
75 | INTC_IRQ(MTU2_TGI2B, 240), INTC_IRQ(MTU2_TCI2V, 241), | ||
76 | INTC_IRQ(MTU2_TCI2U, 242), INTC_IRQ(MTU2_TGI3A, 243), | ||
77 | |||
78 | INTC_IRQ(MTU2_TGI3B, 244), | ||
79 | INTC_IRQ(MTU2_TGI3C, 245), | ||
80 | |||
81 | INTC_IRQ(MTU2_TGI3D, 246), INTC_IRQ(MTU2_TCI3V, 247), | ||
82 | INTC_IRQ(MTU2_TGI4A, 248), INTC_IRQ(MTU2_TGI4B, 249), | ||
83 | INTC_IRQ(MTU2_TGI4C, 250), INTC_IRQ(MTU2_TGI4D, 251), | ||
84 | |||
85 | INTC_IRQ(MTU2_TCI4V, 252), INTC_IRQ(MTU2_TGI5U, 253), | ||
86 | INTC_IRQ(MTU2_TGI5V, 254), INTC_IRQ(MTU2_TGI5W, 255), | ||
87 | }; | ||
88 | |||
89 | static struct intc_group groups[] __initdata = { | ||
90 | INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3, | ||
91 | PINT4, PINT5, PINT6, PINT7), | ||
92 | INTC_GROUP(MTU2_GROUP1, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D, | ||
93 | MTU2_TCI0V, MTU2_TGI0E), | ||
94 | INTC_GROUP(MTU2_GROUP2, MTU2_TGI0F, MTU2_TGI1A, MTU2_TGI1B, | ||
95 | MTU2_TCI1V, MTU2_TCI1U, MTU2_TGI2A), | ||
96 | INTC_GROUP(MTU2_GROUP3, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U, | ||
97 | MTU2_TGI3A), | ||
98 | INTC_GROUP(MTU2_GROUP4, MTU2_TGI3D, MTU2_TCI3V, MTU2_TGI4A, | ||
99 | MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D), | ||
100 | INTC_GROUP(MTU2_GROUP5, MTU2_TCI4V, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W), | ||
101 | INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI), | ||
102 | INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI), | ||
103 | }; | ||
104 | |||
105 | static struct intc_prio_reg prio_registers[] __initdata = { | ||
106 | { 0xfffd9418, 0, 16, 4, /* IPR01 */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, | ||
107 | { 0xfffd941a, 0, 16, 4, /* IPR02 */ { IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
108 | { 0xfffd941c, 0, 16, 4, /* IPR03 */ { IRQ8, IRQ9, IRQ10, IRQ11 } }, | ||
109 | { 0xfffd941e, 0, 16, 4, /* IPR04 */ { IRQ12, IRQ13, IRQ14, IRQ15 } }, | ||
110 | { 0xfffd9420, 0, 16, 4, /* IPR05 */ { PINT, 0, 0, 0 } }, | ||
111 | { 0xfffd9800, 0, 16, 4, /* IPR06 */ { } }, | ||
112 | { 0xfffd9802, 0, 16, 4, /* IPR07 */ { } }, | ||
113 | { 0xfffd9804, 0, 16, 4, /* IPR08 */ { } }, | ||
114 | { 0xfffd9806, 0, 16, 4, /* IPR09 */ { } }, | ||
115 | { 0xfffd9808, 0, 16, 4, /* IPR10 */ { } }, | ||
116 | { 0xfffd980a, 0, 16, 4, /* IPR11 */ { } }, | ||
117 | { 0xfffd980c, 0, 16, 4, /* IPR12 */ { } }, | ||
118 | { 0xfffd980e, 0, 16, 4, /* IPR13 */ { } }, | ||
119 | { 0xfffd9810, 0, 16, 4, /* IPR14 */ { 0, 0, 0, SCIF0 } }, | ||
120 | { 0xfffd9812, 0, 16, 4, /* IPR15 */ | ||
121 | { SCIF1, MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3 } }, | ||
122 | { 0xfffd9814, 0, 16, 4, /* IPR16 */ | ||
123 | { MTU2_TGI3B, MTU2_TGI3C, MTU2_GROUP4, MTU2_GROUP5 } }, | ||
124 | }; | ||
125 | |||
126 | static struct intc_mask_reg mask_registers[] __initdata = { | ||
127 | { 0xfffd9408, 0, 16, /* PINTER */ | ||
128 | { 0, 0, 0, 0, 0, 0, 0, 0, | ||
129 | PINT7, PINT6, PINT5, PINT4, PINT3, PINT2, PINT1, PINT0 } }, | ||
130 | }; | ||
131 | |||
132 | static DECLARE_INTC_DESC(intc_desc, "mxg", vectors, groups, | ||
133 | mask_registers, prio_registers, NULL); | ||
134 | |||
135 | static struct plat_sci_port sci_platform_data[] = { | ||
136 | { | ||
137 | .mapbase = 0xff804000, | ||
138 | .flags = UPF_BOOT_AUTOCONF, | ||
139 | .type = PORT_SCIF, | ||
140 | .irqs = { 223, 220, 221, 222 }, | ||
141 | }, { | ||
142 | .flags = 0, | ||
143 | } | ||
144 | }; | ||
145 | |||
146 | static struct platform_device sci_device = { | ||
147 | .name = "sh-sci", | ||
148 | .id = -1, | ||
149 | .dev = { | ||
150 | .platform_data = sci_platform_data, | ||
151 | }, | ||
152 | }; | ||
153 | |||
154 | static struct platform_device *mxg_devices[] __initdata = { | ||
155 | &sci_device, | ||
156 | }; | ||
157 | |||
158 | static int __init mxg_devices_setup(void) | ||
159 | { | ||
160 | return platform_add_devices(mxg_devices, | ||
161 | ARRAY_SIZE(mxg_devices)); | ||
162 | } | ||
163 | __initcall(mxg_devices_setup); | ||
164 | |||
165 | void __init plat_irq_setup(void) | ||
166 | { | ||
167 | register_intc_controller(&intc_desc); | ||
168 | } | ||
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 9e89984c4f1d..ebceb0dadff5 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c | |||
@@ -53,7 +53,7 @@ int __init detect_cpu_and_cache_system(void) | |||
53 | /* | 53 | /* |
54 | * Setup some generic flags we can probe on SH-4A parts | 54 | * Setup some generic flags we can probe on SH-4A parts |
55 | */ | 55 | */ |
56 | if (((pvr >> 16) & 0xff) == 0x10) { | 56 | if (((pvr >> 24) & 0xff) == 0x10) { |
57 | if ((cvr & 0x10000000) == 0) | 57 | if ((cvr & 0x10000000) == 0) |
58 | boot_cpu_data.flags |= CPU_HAS_DSP; | 58 | boot_cpu_data.flags |= CPU_HAS_DSP; |
59 | 59 | ||
@@ -126,17 +126,22 @@ int __init detect_cpu_and_cache_system(void) | |||
126 | CPU_HAS_LLSC; | 126 | CPU_HAS_LLSC; |
127 | break; | 127 | break; |
128 | case 0x3008: | 128 | case 0x3008: |
129 | if (prr == 0xa0 || prr == 0xa1) { | 129 | boot_cpu_data.icache.ways = 4; |
130 | boot_cpu_data.type = CPU_SH7722; | 130 | boot_cpu_data.dcache.ways = 4; |
131 | boot_cpu_data.icache.ways = 4; | 131 | boot_cpu_data.flags |= CPU_HAS_LLSC; |
132 | boot_cpu_data.dcache.ways = 4; | 132 | |
133 | boot_cpu_data.flags |= CPU_HAS_LLSC; | 133 | switch (prr) { |
134 | } | 134 | case 0x50: |
135 | else if (prr == 0x70) { | 135 | boot_cpu_data.type = CPU_SH7723; |
136 | boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_L2_CACHE; | ||
137 | break; | ||
138 | case 0x70: | ||
136 | boot_cpu_data.type = CPU_SH7366; | 139 | boot_cpu_data.type = CPU_SH7366; |
137 | boot_cpu_data.icache.ways = 4; | 140 | break; |
138 | boot_cpu_data.dcache.ways = 4; | 141 | case 0xa0: |
139 | boot_cpu_data.flags |= CPU_HAS_LLSC; | 142 | case 0xa1: |
143 | boot_cpu_data.type = CPU_SH7722; | ||
144 | break; | ||
140 | } | 145 | } |
141 | break; | 146 | break; |
142 | case 0x4000: /* 1st cut */ | 147 | case 0x4000: /* 1st cut */ |
@@ -215,6 +220,12 @@ int __init detect_cpu_and_cache_system(void) | |||
215 | * SH-4A's have an optional PIPT L2. | 220 | * SH-4A's have an optional PIPT L2. |
216 | */ | 221 | */ |
217 | if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { | 222 | if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { |
223 | /* Bug if we can't decode the L2 info */ | ||
224 | BUG_ON(!(cvr & 0xf)); | ||
225 | |||
226 | /* Silicon and specifications have clearly never met.. */ | ||
227 | cvr ^= 0xf; | ||
228 | |||
218 | /* | 229 | /* |
219 | * Size calculation is much more sensible | 230 | * Size calculation is much more sensible |
220 | * than it is for the L1. | 231 | * than it is for the L1. |
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index 5d890ac8e793..a880e7968750 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o | |||
9 | obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o | 9 | obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o |
10 | obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o | 10 | obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o |
11 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o | 11 | obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o |
12 | obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o | ||
12 | obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o | 13 | obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o |
13 | obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o | 14 | obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o |
14 | 15 | ||
@@ -22,6 +23,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o | |||
22 | clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o | 23 | clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o |
23 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o | 24 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o |
24 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o | 25 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o |
26 | clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o | ||
25 | clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o | 27 | clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o |
26 | clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o | 28 | clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o |
27 | 29 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index b98b4bc93ec9..069314037049 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | |||
@@ -16,13 +16,12 @@ | |||
16 | 16 | ||
17 | static struct resource usbf_resources[] = { | 17 | static struct resource usbf_resources[] = { |
18 | [0] = { | 18 | [0] = { |
19 | .name = "m66592_udc", | 19 | .name = "USBF", |
20 | .start = 0xA4480000, | 20 | .start = 0x04480000, |
21 | .end = 0xA44800FF, | 21 | .end = 0x044800FF, |
22 | .flags = IORESOURCE_MEM, | 22 | .flags = IORESOURCE_MEM, |
23 | }, | 23 | }, |
24 | [1] = { | 24 | [1] = { |
25 | .name = "m66592_udc", | ||
26 | .start = 65, | 25 | .start = 65, |
27 | .end = 65, | 26 | .end = 65, |
28 | .flags = IORESOURCE_IRQ, | 27 | .flags = IORESOURCE_IRQ, |
@@ -40,6 +39,26 @@ static struct platform_device usbf_device = { | |||
40 | .resource = usbf_resources, | 39 | .resource = usbf_resources, |
41 | }; | 40 | }; |
42 | 41 | ||
42 | static struct resource iic_resources[] = { | ||
43 | [0] = { | ||
44 | .name = "IIC", | ||
45 | .start = 0x04470000, | ||
46 | .end = 0x04470017, | ||
47 | .flags = IORESOURCE_MEM, | ||
48 | }, | ||
49 | [1] = { | ||
50 | .start = 96, | ||
51 | .end = 99, | ||
52 | .flags = IORESOURCE_IRQ, | ||
53 | }, | ||
54 | }; | ||
55 | |||
56 | static struct platform_device iic_device = { | ||
57 | .name = "i2c-sh_mobile", | ||
58 | .num_resources = ARRAY_SIZE(iic_resources), | ||
59 | .resource = iic_resources, | ||
60 | }; | ||
61 | |||
43 | static struct plat_sci_port sci_platform_data[] = { | 62 | static struct plat_sci_port sci_platform_data[] = { |
44 | { | 63 | { |
45 | .mapbase = 0xffe00000, | 64 | .mapbase = 0xffe00000, |
@@ -74,6 +93,7 @@ static struct platform_device sci_device = { | |||
74 | 93 | ||
75 | static struct platform_device *sh7722_devices[] __initdata = { | 94 | static struct platform_device *sh7722_devices[] __initdata = { |
76 | &usbf_device, | 95 | &usbf_device, |
96 | &iic_device, | ||
77 | &sci_device, | 97 | &sci_device, |
78 | }; | 98 | }; |
79 | 99 | ||
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c new file mode 100644 index 000000000000..16925cf28db8 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c | |||
@@ -0,0 +1,300 @@ | |||
1 | /* | ||
2 | * SH7723 Setup | ||
3 | * | ||
4 | * Copyright (C) 2008 Paul Mundt | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/serial.h> | ||
13 | #include <linux/mm.h> | ||
14 | #include <linux/serial_sci.h> | ||
15 | #include <asm/mmzone.h> | ||
16 | |||
17 | static struct plat_sci_port sci_platform_data[] = { | ||
18 | { | ||
19 | .mapbase = 0xa4e30000, | ||
20 | .flags = UPF_BOOT_AUTOCONF, | ||
21 | .type = PORT_SCI, | ||
22 | .irqs = { 56, 56, 56, 56 }, | ||
23 | },{ | ||
24 | .mapbase = 0xa4e40000, | ||
25 | .flags = UPF_BOOT_AUTOCONF, | ||
26 | .type = PORT_SCI, | ||
27 | .irqs = { 88, 88, 88, 88 }, | ||
28 | },{ | ||
29 | .mapbase = 0xa4e50000, | ||
30 | .flags = UPF_BOOT_AUTOCONF, | ||
31 | .type = PORT_SCI, | ||
32 | .irqs = { 109, 109, 109, 109 }, | ||
33 | }, { | ||
34 | .flags = 0, | ||
35 | } | ||
36 | }; | ||
37 | |||
38 | static struct platform_device sci_device = { | ||
39 | .name = "sh-sci", | ||
40 | .id = -1, | ||
41 | .dev = { | ||
42 | .platform_data = sci_platform_data, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | static struct resource rtc_resources[] = { | ||
47 | [0] = { | ||
48 | .start = 0xa465fec0, | ||
49 | .end = 0xa465fec0 + 0x58 - 1, | ||
50 | .flags = IORESOURCE_IO, | ||
51 | }, | ||
52 | [1] = { | ||
53 | /* Period IRQ */ | ||
54 | .start = 69, | ||
55 | .flags = IORESOURCE_IRQ, | ||
56 | }, | ||
57 | [2] = { | ||
58 | /* Carry IRQ */ | ||
59 | .start = 70, | ||
60 | .flags = IORESOURCE_IRQ, | ||
61 | }, | ||
62 | [3] = { | ||
63 | /* Alarm IRQ */ | ||
64 | .start = 68, | ||
65 | .flags = IORESOURCE_IRQ, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | static struct platform_device rtc_device = { | ||
70 | .name = "sh-rtc", | ||
71 | .id = -1, | ||
72 | .num_resources = ARRAY_SIZE(rtc_resources), | ||
73 | .resource = rtc_resources, | ||
74 | }; | ||
75 | |||
76 | static struct platform_device *sh7723_devices[] __initdata = { | ||
77 | &sci_device, | ||
78 | &rtc_device, | ||
79 | }; | ||
80 | |||
81 | static int __init sh7723_devices_setup(void) | ||
82 | { | ||
83 | return platform_add_devices(sh7723_devices, | ||
84 | ARRAY_SIZE(sh7723_devices)); | ||
85 | } | ||
86 | __initcall(sh7723_devices_setup); | ||
87 | |||
88 | enum { | ||
89 | UNUSED=0, | ||
90 | |||
91 | /* interrupt sources */ | ||
92 | IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, | ||
93 | HUDI, | ||
94 | DMAC1A_DEI0,DMAC1A_DEI1,DMAC1A_DEI2,DMAC1A_DEI3, | ||
95 | _2DG_TRI,_2DG_INI,_2DG_CEI, | ||
96 | DMAC0A_DEI0,DMAC0A_DEI1,DMAC0A_DEI2,DMAC0A_DEI3, | ||
97 | VIO_CEUI,VIO_BEUI,VIO_VEU2HI,VIO_VOUI, | ||
98 | SCIFA_SCIFA0, | ||
99 | VPU_VPUI, | ||
100 | TPU_TPUI, | ||
101 | ADC_ADI, | ||
102 | USB_USI0, | ||
103 | RTC_ATI,RTC_PRI,RTC_CUI, | ||
104 | DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR, | ||
105 | DMAC0B_DEI4,DMAC0B_DEI5,DMAC0B_DADERR, | ||
106 | KEYSC_KEYI, | ||
107 | SCIF_SCIF0,SCIF_SCIF1,SCIF_SCIF2, | ||
108 | MSIOF_MSIOFI0,MSIOF_MSIOFI1, | ||
109 | SCIFA_SCIFA1, | ||
110 | FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I, | ||
111 | I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI, | ||
112 | SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2, | ||
113 | CMT_CMTI, | ||
114 | TSIF_TSIFI, | ||
115 | SIU_SIUI, | ||
116 | SCIFA_SCIFA2, | ||
117 | TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, | ||
118 | IRDA_IRDAI, | ||
119 | ATAPI_ATAPII, | ||
120 | SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2, | ||
121 | VEU2H1_VEU2HI, | ||
122 | LCDC_LCDCI, | ||
123 | TMU1_TUNI0,TMU1_TUNI1,TMU1_TUNI2, | ||
124 | |||
125 | /* interrupt groups */ | ||
126 | DMAC1A, DMAC0A, VIO, DMAC0B, FLCTL, I2C, _2DG, | ||
127 | SDHI1, RTC, DMAC1B, SDHI0, | ||
128 | }; | ||
129 | |||
130 | static struct intc_vect vectors[] __initdata = { | ||
131 | INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), | ||
132 | INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), | ||
133 | INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), | ||
134 | INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0), | ||
135 | |||
136 | INTC_VECT(DMAC1A_DEI0,0x700), | ||
137 | INTC_VECT(DMAC1A_DEI1,0x720), | ||
138 | INTC_VECT(DMAC1A_DEI2,0x740), | ||
139 | INTC_VECT(DMAC1A_DEI3,0x760), | ||
140 | |||
141 | INTC_VECT(_2DG_TRI, 0x780), | ||
142 | INTC_VECT(_2DG_INI, 0x7A0), | ||
143 | INTC_VECT(_2DG_CEI, 0x7C0), | ||
144 | |||
145 | INTC_VECT(DMAC0A_DEI0,0x800), | ||
146 | INTC_VECT(DMAC0A_DEI1,0x820), | ||
147 | INTC_VECT(DMAC0A_DEI2,0x840), | ||
148 | INTC_VECT(DMAC0A_DEI3,0x860), | ||
149 | |||
150 | INTC_VECT(VIO_CEUI,0x880), | ||
151 | INTC_VECT(VIO_BEUI,0x8A0), | ||
152 | INTC_VECT(VIO_VEU2HI,0x8C0), | ||
153 | INTC_VECT(VIO_VOUI,0x8E0), | ||
154 | |||
155 | INTC_VECT(SCIFA_SCIFA0,0x900), | ||
156 | INTC_VECT(VPU_VPUI,0x920), | ||
157 | INTC_VECT(TPU_TPUI,0x9A0), | ||
158 | INTC_VECT(ADC_ADI,0x9E0), | ||
159 | INTC_VECT(USB_USI0,0xA20), | ||
160 | |||
161 | INTC_VECT(RTC_ATI,0xA80), | ||
162 | INTC_VECT(RTC_PRI,0xAA0), | ||
163 | INTC_VECT(RTC_CUI,0xAC0), | ||
164 | |||
165 | INTC_VECT(DMAC1B_DEI4,0xB00), | ||
166 | INTC_VECT(DMAC1B_DEI5,0xB20), | ||
167 | INTC_VECT(DMAC1B_DADERR,0xB40), | ||
168 | |||
169 | INTC_VECT(DMAC0B_DEI4,0xB80), | ||
170 | INTC_VECT(DMAC0B_DEI5,0xBA0), | ||
171 | INTC_VECT(DMAC0B_DADERR,0xBC0), | ||
172 | |||
173 | INTC_VECT(KEYSC_KEYI,0xBE0), | ||
174 | INTC_VECT(SCIF_SCIF0,0xC00), | ||
175 | INTC_VECT(SCIF_SCIF1,0xC20), | ||
176 | INTC_VECT(SCIF_SCIF2,0xC40), | ||
177 | INTC_VECT(MSIOF_MSIOFI0,0xC80), | ||
178 | INTC_VECT(MSIOF_MSIOFI1,0xCA0), | ||
179 | INTC_VECT(SCIFA_SCIFA1,0xD00), | ||
180 | |||
181 | INTC_VECT(FLCTL_FLSTEI,0xD80), | ||
182 | INTC_VECT(FLCTL_FLTENDI,0xDA0), | ||
183 | INTC_VECT(FLCTL_FLTREQ0I,0xDC0), | ||
184 | INTC_VECT(FLCTL_FLTREQ1I,0xDE0), | ||
185 | |||
186 | INTC_VECT(I2C_ALI,0xE00), | ||
187 | INTC_VECT(I2C_TACKI,0xE20), | ||
188 | INTC_VECT(I2C_WAITI,0xE40), | ||
189 | INTC_VECT(I2C_DTEI,0xE60), | ||
190 | |||
191 | INTC_VECT(SDHI0_SDHII0,0xE80), | ||
192 | INTC_VECT(SDHI0_SDHII1,0xEA0), | ||
193 | INTC_VECT(SDHI0_SDHII2,0xEC0), | ||
194 | |||
195 | INTC_VECT(CMT_CMTI,0xF00), | ||
196 | INTC_VECT(TSIF_TSIFI,0xF20), | ||
197 | INTC_VECT(SIU_SIUI,0xF80), | ||
198 | INTC_VECT(SCIFA_SCIFA2,0xFA0), | ||
199 | |||
200 | INTC_VECT(TMU0_TUNI0,0x400), | ||
201 | INTC_VECT(TMU0_TUNI1,0x420), | ||
202 | INTC_VECT(TMU0_TUNI2,0x440), | ||
203 | |||
204 | INTC_VECT(IRDA_IRDAI,0x480), | ||
205 | INTC_VECT(ATAPI_ATAPII,0x4A0), | ||
206 | |||
207 | INTC_VECT(SDHI1_SDHII0,0x4E0), | ||
208 | INTC_VECT(SDHI1_SDHII1,0x500), | ||
209 | INTC_VECT(SDHI1_SDHII2,0x520), | ||
210 | |||
211 | INTC_VECT(VEU2H1_VEU2HI,0x560), | ||
212 | INTC_VECT(LCDC_LCDCI,0x580), | ||
213 | |||
214 | INTC_VECT(TMU1_TUNI0,0x920), | ||
215 | INTC_VECT(TMU1_TUNI1,0x940), | ||
216 | INTC_VECT(TMU1_TUNI2,0x960), | ||
217 | |||
218 | }; | ||
219 | |||
220 | static struct intc_group groups[] __initdata = { | ||
221 | INTC_GROUP(DMAC1A,DMAC1A_DEI0,DMAC1A_DEI1,DMAC1A_DEI2,DMAC1A_DEI3), | ||
222 | INTC_GROUP(DMAC0A,DMAC0A_DEI0,DMAC0A_DEI1,DMAC0A_DEI2,DMAC0A_DEI3), | ||
223 | INTC_GROUP(VIO, VIO_CEUI,VIO_BEUI,VIO_VEU2HI,VIO_VOUI), | ||
224 | INTC_GROUP(DMAC0B, DMAC0B_DEI4,DMAC0B_DEI5,DMAC0B_DADERR), | ||
225 | INTC_GROUP(FLCTL,FLCTL_FLSTEI,FLCTL_FLTENDI,FLCTL_FLTREQ0I,FLCTL_FLTREQ1I), | ||
226 | INTC_GROUP(I2C,I2C_ALI,I2C_TACKI,I2C_WAITI,I2C_DTEI), | ||
227 | INTC_GROUP(_2DG, _2DG_TRI,_2DG_INI,_2DG_CEI), | ||
228 | INTC_GROUP(SDHI1, SDHI1_SDHII0,SDHI1_SDHII1,SDHI1_SDHII2), | ||
229 | INTC_GROUP(RTC, RTC_ATI,RTC_PRI,RTC_CUI), | ||
230 | INTC_GROUP(DMAC1B, DMAC1B_DEI4,DMAC1B_DEI5,DMAC1B_DADERR), | ||
231 | INTC_GROUP(SDHI0,SDHI0_SDHII0,SDHI0_SDHII1,SDHI0_SDHII2), | ||
232 | }; | ||
233 | |||
234 | static struct intc_mask_reg mask_registers[] __initdata = { | ||
235 | { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ | ||
236 | { 0, TMU1_TUNI2,TMU1_TUNI1,TMU1_TUNI0,0,SDHI1_SDHII2,SDHI1_SDHII1,SDHI1_SDHII0} }, | ||
237 | { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ | ||
238 | { VIO_VOUI, VIO_VEU2HI,VIO_BEUI,VIO_CEUI,DMAC0A_DEI3,DMAC0A_DEI2,DMAC0A_DEI1,DMAC0A_DEI0 } }, | ||
239 | { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ | ||
240 | { 0, 0, 0, VPU_VPUI,0,0,0,SCIFA_SCIFA0 } }, | ||
241 | { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */ | ||
242 | { DMAC1A_DEI3,DMAC1A_DEI2,DMAC1A_DEI1,DMAC1A_DEI0,0,0,0,IRDA_IRDAI } }, | ||
243 | { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */ | ||
244 | { 0,TMU0_TUNI2,TMU0_TUNI1,TMU0_TUNI0,VEU2H1_VEU2HI,0,0,LCDC_LCDCI } }, | ||
245 | { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */ | ||
246 | { KEYSC_KEYI,DMAC0B_DADERR,DMAC0B_DEI5,DMAC0B_DEI4,0,SCIF_SCIF2,SCIF_SCIF1,SCIF_SCIF0 } }, | ||
247 | { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */ | ||
248 | { 0,0,0,SCIFA_SCIFA1,ADC_ADI,0,MSIOF_MSIOFI1,MSIOF_MSIOFI0 } }, | ||
249 | { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */ | ||
250 | { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, | ||
251 | FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } }, | ||
252 | { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ | ||
253 | { 0,SDHI0_SDHII2,SDHI0_SDHII1,SDHI0_SDHII0,0,0,SCIFA_SCIFA2,SIU_SIUI } }, | ||
254 | { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ | ||
255 | { 0, 0, 0, CMT_CMTI, 0, 0, USB_USI0,0 } }, | ||
256 | { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ | ||
257 | { 0, DMAC1B_DADERR,DMAC1B_DEI5,DMAC1B_DEI4,0,RTC_ATI,RTC_PRI,RTC_CUI } }, | ||
258 | { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */ | ||
259 | { 0,_2DG_CEI,_2DG_INI,_2DG_TRI,0,TPU_TPUI,0,TSIF_TSIFI } }, | ||
260 | { 0xa40800b0, 0xa40800f0, 8, /* IMR12 / IMCR12 */ | ||
261 | { 0,0,0,0,0,0,0,ATAPI_ATAPII } }, | ||
262 | { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */ | ||
263 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
264 | }; | ||
265 | |||
266 | static struct intc_prio_reg prio_registers[] __initdata = { | ||
267 | { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, IRDA_IRDAI } }, | ||
268 | { 0xa4080004, 0, 16, 4, /* IPRB */ { VEU2H1_VEU2HI, LCDC_LCDCI, DMAC1A, 0} }, | ||
269 | { 0xa4080008, 0, 16, 4, /* IPRC */ { TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, 0} }, | ||
270 | { 0xa408000c, 0, 16, 4, /* IPRD */ { } }, | ||
271 | { 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0A, VIO, SCIFA_SCIFA0, VPU_VPUI } }, | ||
272 | { 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC_KEYI, DMAC0B, USB_USI0, CMT_CMTI } }, | ||
273 | { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF_SCIF0, SCIF_SCIF1, SCIF_SCIF2,0 } }, | ||
274 | { 0xa408001c, 0, 16, 4, /* IPRH */ { MSIOF_MSIOFI0,MSIOF_MSIOFI1, FLCTL, I2C } }, | ||
275 | { 0xa4080020, 0, 16, 4, /* IPRI */ { SCIFA_SCIFA1,0,TSIF_TSIFI,_2DG } }, | ||
276 | { 0xa4080024, 0, 16, 4, /* IPRJ */ { ADC_ADI,0,SIU_SIUI,SDHI1 } }, | ||
277 | { 0xa4080028, 0, 16, 4, /* IPRK */ { RTC,DMAC1B,0,SDHI0 } }, | ||
278 | { 0xa408002c, 0, 16, 4, /* IPRL */ { SCIFA_SCIFA2,0,TPU_TPUI,ATAPI_ATAPII } }, | ||
279 | { 0xa4140010, 0, 32, 4, /* INTPRI00 */ | ||
280 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
281 | }; | ||
282 | |||
283 | static struct intc_sense_reg sense_registers[] __initdata = { | ||
284 | { 0xa414001c, 16, 2, /* ICR1 */ | ||
285 | { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, | ||
286 | }; | ||
287 | |||
288 | static DECLARE_INTC_DESC(intc_desc, "sh7723", vectors, groups, | ||
289 | mask_registers, prio_registers, sense_registers); | ||
290 | |||
291 | void __init plat_irq_setup(void) | ||
292 | { | ||
293 | register_intc_controller(&intc_desc); | ||
294 | } | ||
295 | |||
296 | void __init plat_mem_setup(void) | ||
297 | { | ||
298 | /* Register the URAM space as Node 1 */ | ||
299 | setup_bootmem_node(1, 0x055f0000, 0x05610000); | ||
300 | } | ||
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 07c988dc9de6..ae2b22219f02 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c | |||
@@ -231,12 +231,6 @@ static struct intc_group groups[] __initdata = { | |||
231 | INTC_GROUP(GPIO, GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3), | 231 | INTC_GROUP(GPIO, GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3), |
232 | }; | 232 | }; |
233 | 233 | ||
234 | static struct intc_prio priorities[] __initdata = { | ||
235 | INTC_PRIO(SCIF0, 3), | ||
236 | INTC_PRIO(SCIF1, 3), | ||
237 | INTC_PRIO(SCIF2, 3), | ||
238 | }; | ||
239 | |||
240 | static struct intc_mask_reg mask_registers[] __initdata = { | 234 | static struct intc_mask_reg mask_registers[] __initdata = { |
241 | { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ | 235 | { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ |
242 | { 0, 0, 0, 0, 0, 0, GPIO, 0, | 236 | { 0, 0, 0, 0, 0, 0, GPIO, 0, |
@@ -270,11 +264,10 @@ static struct intc_prio_reg prio_registers[] __initdata = { | |||
270 | { 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } }, | 264 | { 0xffd400b4, 0, 32, 8, /* INT2PRI13 */ { 0, 0, STIF1, STIF0 } }, |
271 | }; | 265 | }; |
272 | 266 | ||
273 | static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups, priorities, | 267 | static DECLARE_INTC_DESC(intc_desc, "sh7763", vectors, groups, |
274 | mask_registers, prio_registers, NULL); | 268 | mask_registers, prio_registers, NULL); |
275 | 269 | ||
276 | /* Support for external interrupt pins in IRQ mode */ | 270 | /* Support for external interrupt pins in IRQ mode */ |
277 | |||
278 | static struct intc_vect irq_vectors[] __initdata = { | 271 | static struct intc_vect irq_vectors[] __initdata = { |
279 | INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), | 272 | INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), |
280 | INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), | 273 | INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), |
@@ -302,7 +295,6 @@ static DECLARE_INTC_DESC(intc_irq_desc, "sh7763-irq", irq_vectors, | |||
302 | irq_sense_registers); | 295 | irq_sense_registers); |
303 | 296 | ||
304 | /* External interrupt pins in IRL mode */ | 297 | /* External interrupt pins in IRL mode */ |
305 | |||
306 | static struct intc_vect irl_vectors[] __initdata = { | 298 | static struct intc_vect irl_vectors[] __initdata = { |
307 | INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), | 299 | INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), |
308 | INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), | 300 | INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index b9cec48b1808..b73578ee295d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SH7770 Setup | 2 | * SH7770 Setup |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Paul Mundt | 4 | * Copyright (C) 2006 - 2008 Paul Mundt |
5 | * | 5 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 6 | * This file is subject to the terms and conditions of the GNU General Public |
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
@@ -29,6 +29,41 @@ static struct plat_sci_port sci_platform_data[] = { | |||
29 | .type = PORT_SCIF, | 29 | .type = PORT_SCIF, |
30 | .irqs = { 63, 63, 63, 63 }, | 30 | .irqs = { 63, 63, 63, 63 }, |
31 | }, { | 31 | }, { |
32 | .mapbase = 0xff926000, | ||
33 | .flags = UPF_BOOT_AUTOCONF, | ||
34 | .type = PORT_SCIF, | ||
35 | .irqs = { 64, 64, 64, 64 }, | ||
36 | }, { | ||
37 | .mapbase = 0xff927000, | ||
38 | .flags = UPF_BOOT_AUTOCONF, | ||
39 | .type = PORT_SCIF, | ||
40 | .irqs = { 65, 65, 65, 65 }, | ||
41 | }, { | ||
42 | .mapbase = 0xff928000, | ||
43 | .flags = UPF_BOOT_AUTOCONF, | ||
44 | .type = PORT_SCIF, | ||
45 | .irqs = { 66, 66, 66, 66 }, | ||
46 | }, { | ||
47 | .mapbase = 0xff929000, | ||
48 | .flags = UPF_BOOT_AUTOCONF, | ||
49 | .type = PORT_SCIF, | ||
50 | .irqs = { 67, 67, 67, 67 }, | ||
51 | }, { | ||
52 | .mapbase = 0xff92a000, | ||
53 | .flags = UPF_BOOT_AUTOCONF, | ||
54 | .type = PORT_SCIF, | ||
55 | .irqs = { 68, 68, 68, 68 }, | ||
56 | }, { | ||
57 | .mapbase = 0xff92b000, | ||
58 | .flags = UPF_BOOT_AUTOCONF, | ||
59 | .type = PORT_SCIF, | ||
60 | .irqs = { 69, 69, 69, 69 }, | ||
61 | }, { | ||
62 | .mapbase = 0xff92c000, | ||
63 | .flags = UPF_BOOT_AUTOCONF, | ||
64 | .type = PORT_SCIF, | ||
65 | .irqs = { 70, 70, 70, 70 }, | ||
66 | }, { | ||
32 | .flags = 0, | 67 | .flags = 0, |
33 | } | 68 | } |
34 | }; | 69 | }; |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index ff4f54a47c07..284f66f1ebbe 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/kexec.h> | 23 | #include <linux/kexec.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
26 | #include <linux/err.h> | ||
27 | #include <linux/debugfs.h> | ||
26 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
27 | #include <asm/io.h> | 29 | #include <asm/io.h> |
28 | #include <asm/page.h> | 30 | #include <asm/page.h> |
@@ -333,6 +335,7 @@ static const char *cpu_name[] = { | |||
333 | [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785", | 335 | [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785", |
334 | [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3", | 336 | [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3", |
335 | [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103", | 337 | [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103", |
338 | [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723", | ||
336 | [CPU_SH7366] = "SH7366", [CPU_SH_NONE] = "Unknown" | 339 | [CPU_SH7366] = "SH7366", [CPU_SH_NONE] = "Unknown" |
337 | }; | 340 | }; |
338 | 341 | ||
@@ -443,3 +446,15 @@ const struct seq_operations cpuinfo_op = { | |||
443 | .show = show_cpuinfo, | 446 | .show = show_cpuinfo, |
444 | }; | 447 | }; |
445 | #endif /* CONFIG_PROC_FS */ | 448 | #endif /* CONFIG_PROC_FS */ |
449 | |||
450 | struct dentry *sh_debugfs_root; | ||
451 | |||
452 | static int __init sh_debugfs_init(void) | ||
453 | { | ||
454 | sh_debugfs_root = debugfs_create_dir("sh", NULL); | ||
455 | if (IS_ERR(sh_debugfs_root)) | ||
456 | return PTR_ERR(sh_debugfs_root); | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | arch_initcall(sh_debugfs_init); | ||
diff --git a/arch/sh/lib/clear_page.S b/arch/sh/lib/clear_page.S index 3539123fe517..8342bfbde64c 100644 --- a/arch/sh/lib/clear_page.S +++ b/arch/sh/lib/clear_page.S | |||
@@ -27,11 +27,11 @@ ENTRY(clear_page) | |||
27 | mov #0,r0 | 27 | mov #0,r0 |
28 | ! | 28 | ! |
29 | 1: | 29 | 1: |
30 | #if defined(CONFIG_CPU_SH3) | 30 | #if defined(CONFIG_CPU_SH4) |
31 | mov.l r0,@r4 | ||
32 | #elif defined(CONFIG_CPU_SH4) | ||
33 | movca.l r0,@r4 | 31 | movca.l r0,@r4 |
34 | mov r4,r1 | 32 | mov r4,r1 |
33 | #else | ||
34 | mov.l r0,@r4 | ||
35 | #endif | 35 | #endif |
36 | add #32,r4 | 36 | add #32,r4 |
37 | mov.l r0,@-r4 | 37 | mov.l r0,@-r4 |
diff --git a/arch/sh/lib/copy_page.S b/arch/sh/lib/copy_page.S index e002b91c8752..5d12e657be34 100644 --- a/arch/sh/lib/copy_page.S +++ b/arch/sh/lib/copy_page.S | |||
@@ -41,11 +41,11 @@ ENTRY(copy_page) | |||
41 | mov.l @r11+,r5 | 41 | mov.l @r11+,r5 |
42 | mov.l @r11+,r6 | 42 | mov.l @r11+,r6 |
43 | mov.l @r11+,r7 | 43 | mov.l @r11+,r7 |
44 | #if defined(CONFIG_CPU_SH3) | 44 | #if defined(CONFIG_CPU_SH4) |
45 | mov.l r0,@r10 | ||
46 | #elif defined(CONFIG_CPU_SH4) | ||
47 | movca.l r0,@r10 | 45 | movca.l r0,@r10 |
48 | mov r10,r0 | 46 | mov r10,r0 |
47 | #else | ||
48 | mov.l r0,@r10 | ||
49 | #endif | 49 | #endif |
50 | add #32,r10 | 50 | add #32,r10 |
51 | mov.l r7,@-r10 | 51 | mov.l r7,@-r10 |
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c index db6d950b6f5e..c5b56d52b7d2 100644 --- a/arch/sh/mm/cache-debugfs.c +++ b/arch/sh/mm/cache-debugfs.c | |||
@@ -127,13 +127,13 @@ static int __init cache_debugfs_init(void) | |||
127 | { | 127 | { |
128 | struct dentry *dcache_dentry, *icache_dentry; | 128 | struct dentry *dcache_dentry, *icache_dentry; |
129 | 129 | ||
130 | dcache_dentry = debugfs_create_file("dcache", S_IRUSR, NULL, | 130 | dcache_dentry = debugfs_create_file("dcache", S_IRUSR, sh_debugfs_root, |
131 | (unsigned int *)CACHE_TYPE_DCACHE, | 131 | (unsigned int *)CACHE_TYPE_DCACHE, |
132 | &cache_debugfs_fops); | 132 | &cache_debugfs_fops); |
133 | if (IS_ERR(dcache_dentry)) | 133 | if (IS_ERR(dcache_dentry)) |
134 | return PTR_ERR(dcache_dentry); | 134 | return PTR_ERR(dcache_dentry); |
135 | 135 | ||
136 | icache_dentry = debugfs_create_file("icache", S_IRUSR, NULL, | 136 | icache_dentry = debugfs_create_file("icache", S_IRUSR, sh_debugfs_root, |
137 | (unsigned int *)CACHE_TYPE_ICACHE, | 137 | (unsigned int *)CACHE_TYPE_ICACHE, |
138 | &cache_debugfs_fops); | 138 | &cache_debugfs_fops); |
139 | if (IS_ERR(icache_dentry)) { | 139 | if (IS_ERR(icache_dentry)) { |
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index ab81c602295f..0b0ec6e04753 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c | |||
@@ -393,7 +393,7 @@ static int __init pmb_debugfs_init(void) | |||
393 | struct dentry *dentry; | 393 | struct dentry *dentry; |
394 | 394 | ||
395 | dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO, | 395 | dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO, |
396 | NULL, NULL, &pmb_debugfs_fops); | 396 | sh_debugfs_root, NULL, &pmb_debugfs_fops); |
397 | if (IS_ERR(dentry)) | 397 | if (IS_ERR(dentry)) |
398 | return PTR_ERR(dentry); | 398 | return PTR_ERR(dentry); |
399 | 399 | ||
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index d63b93da952d..987c6682bf99 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types | |||
@@ -21,8 +21,9 @@ HD64465 HD64465 | |||
21 | 7206SE SH_7206_SOLUTION_ENGINE | 21 | 7206SE SH_7206_SOLUTION_ENGINE |
22 | 7343SE SH_7343_SOLUTION_ENGINE | 22 | 7343SE SH_7343_SOLUTION_ENGINE |
23 | 7619SE SH_7619_SOLUTION_ENGINE | 23 | 7619SE SH_7619_SOLUTION_ENGINE |
24 | 7722SE SH_7722_SOLUTION_ENGINE | 24 | 7721SE SH_7721_SOLUTION_ENGINE |
25 | 7751SE SH_7751_SOLUTION_ENGINE | 25 | 7722SE SH_7722_SOLUTION_ENGINE |
26 | 7751SE SH_7751_SOLUTION_ENGINE | ||
26 | 7780SE SH_7780_SOLUTION_ENGINE | 27 | 7780SE SH_7780_SOLUTION_ENGINE |
27 | 7751SYSTEMH SH_7751_SYSTEMH | 28 | 7751SYSTEMH SH_7751_SYSTEMH |
28 | HP6XX SH_HP6XX | 29 | HP6XX SH_HP6XX |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 7f30b754bfc3..87a693cf2bb7 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -906,6 +906,15 @@ config X86_64_ACPI_NUMA | |||
906 | help | 906 | help |
907 | Enable ACPI SRAT based node topology detection. | 907 | Enable ACPI SRAT based node topology detection. |
908 | 908 | ||
909 | # Some NUMA nodes have memory ranges that span | ||
910 | # other nodes. Even though a pfn is valid and | ||
911 | # between a node's start and end pfns, it may not | ||
912 | # reside on that node. See memmap_init_zone() | ||
913 | # for details. | ||
914 | config NODES_SPAN_OTHER_NODES | ||
915 | def_bool y | ||
916 | depends on X86_64_ACPI_NUMA | ||
917 | |||
909 | config NUMA_EMU | 918 | config NUMA_EMU |
910 | bool "NUMA emulation" | 919 | bool "NUMA emulation" |
911 | depends on X86_64 && NUMA | 920 | depends on X86_64 && NUMA |
diff --git a/arch/x86/boot/a20.c b/arch/x86/boot/a20.c index 31348d054fca..90943f83e84d 100644 --- a/arch/x86/boot/a20.c +++ b/arch/x86/boot/a20.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/a20.c | ||
13 | * | ||
14 | * Enable A20 gate (return -1 on failure) | 12 | * Enable A20 gate (return -1 on failure) |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/apm.c b/arch/x86/boot/apm.c index c117c7fb859c..7aa6033001f9 100644 --- a/arch/x86/boot/apm.c +++ b/arch/x86/boot/apm.c | |||
@@ -12,8 +12,6 @@ | |||
12 | * ----------------------------------------------------------------------- */ | 12 | * ----------------------------------------------------------------------- */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * arch/i386/boot/apm.c | ||
16 | * | ||
17 | * Get APM BIOS information | 15 | * Get APM BIOS information |
18 | */ | 16 | */ |
19 | 17 | ||
diff --git a/arch/x86/boot/bitops.h b/arch/x86/boot/bitops.h index 8dcc8dc7db88..878e4b9940d9 100644 --- a/arch/x86/boot/bitops.h +++ b/arch/x86/boot/bitops.h | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/bitops.h | ||
13 | * | ||
14 | * Very simple bitops for the boot code. | 12 | * Very simple bitops for the boot code. |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h index 09578070bfba..a34b9982c7cb 100644 --- a/arch/x86/boot/boot.h +++ b/arch/x86/boot/boot.h | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/boot.h | ||
13 | * | ||
14 | * Header file for the real-mode kernel code | 12 | * Header file for the real-mode kernel code |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/cmdline.c b/arch/x86/boot/cmdline.c index 680408a0f463..a1d35634bce0 100644 --- a/arch/x86/boot/cmdline.c +++ b/arch/x86/boot/cmdline.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/cmdline.c | ||
13 | * | ||
14 | * Simple command-line parser for early boot. | 12 | * Simple command-line parser for early boot. |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 036e635f18a3..ba7736cf2ec7 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
@@ -130,7 +130,7 @@ relocated: | |||
130 | /* | 130 | /* |
131 | * Setup the stack for the decompressor | 131 | * Setup the stack for the decompressor |
132 | */ | 132 | */ |
133 | leal stack_end(%ebx), %esp | 133 | leal boot_stack_end(%ebx), %esp |
134 | 134 | ||
135 | /* | 135 | /* |
136 | * Do the decompression, and jump to the new kernel.. | 136 | * Do the decompression, and jump to the new kernel.. |
@@ -142,8 +142,8 @@ relocated: | |||
142 | pushl %eax # input_len | 142 | pushl %eax # input_len |
143 | leal input_data(%ebx), %eax | 143 | leal input_data(%ebx), %eax |
144 | pushl %eax # input_data | 144 | pushl %eax # input_data |
145 | leal _end(%ebx), %eax | 145 | leal boot_heap(%ebx), %eax |
146 | pushl %eax # end of the image as third argument | 146 | pushl %eax # heap area as third argument |
147 | pushl %esi # real mode pointer as second arg | 147 | pushl %esi # real mode pointer as second arg |
148 | call decompress_kernel | 148 | call decompress_kernel |
149 | addl $20, %esp | 149 | addl $20, %esp |
@@ -181,7 +181,10 @@ relocated: | |||
181 | jmp *%ebp | 181 | jmp *%ebp |
182 | 182 | ||
183 | .bss | 183 | .bss |
184 | /* Stack and heap for uncompression */ | ||
184 | .balign 4 | 185 | .balign 4 |
185 | stack: | 186 | boot_heap: |
186 | .fill 4096, 1, 0 | 187 | .fill BOOT_HEAP_SIZE, 1, 0 |
187 | stack_end: | 188 | boot_stack: |
189 | .fill BOOT_STACK_SIZE, 1, 0 | ||
190 | boot_stack_end: | ||
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index e8657b98c902..d8819efac81d 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/segment.h> | 28 | #include <asm/segment.h> |
29 | #include <asm/pgtable.h> | 29 | #include <asm/pgtable.h> |
30 | #include <asm/page.h> | 30 | #include <asm/page.h> |
31 | #include <asm/boot.h> | ||
31 | #include <asm/msr.h> | 32 | #include <asm/msr.h> |
32 | #include <asm/asm-offsets.h> | 33 | #include <asm/asm-offsets.h> |
33 | 34 | ||
@@ -62,7 +63,7 @@ startup_32: | |||
62 | subl $1b, %ebp | 63 | subl $1b, %ebp |
63 | 64 | ||
64 | /* setup a stack and make sure cpu supports long mode. */ | 65 | /* setup a stack and make sure cpu supports long mode. */ |
65 | movl $user_stack_end, %eax | 66 | movl $boot_stack_end, %eax |
66 | addl %ebp, %eax | 67 | addl %ebp, %eax |
67 | movl %eax, %esp | 68 | movl %eax, %esp |
68 | 69 | ||
@@ -243,9 +244,9 @@ ENTRY(startup_64) | |||
243 | /* Copy the compressed kernel to the end of our buffer | 244 | /* Copy the compressed kernel to the end of our buffer |
244 | * where decompression in place becomes safe. | 245 | * where decompression in place becomes safe. |
245 | */ | 246 | */ |
246 | leaq _end(%rip), %r8 | 247 | leaq _end_before_pgt(%rip), %r8 |
247 | leaq _end(%rbx), %r9 | 248 | leaq _end_before_pgt(%rbx), %r9 |
248 | movq $_end /* - $startup_32 */, %rcx | 249 | movq $_end_before_pgt /* - $startup_32 */, %rcx |
249 | 1: subq $8, %r8 | 250 | 1: subq $8, %r8 |
250 | subq $8, %r9 | 251 | subq $8, %r9 |
251 | movq 0(%r8), %rax | 252 | movq 0(%r8), %rax |
@@ -267,14 +268,14 @@ relocated: | |||
267 | */ | 268 | */ |
268 | xorq %rax, %rax | 269 | xorq %rax, %rax |
269 | leaq _edata(%rbx), %rdi | 270 | leaq _edata(%rbx), %rdi |
270 | leaq _end(%rbx), %rcx | 271 | leaq _end_before_pgt(%rbx), %rcx |
271 | subq %rdi, %rcx | 272 | subq %rdi, %rcx |
272 | cld | 273 | cld |
273 | rep | 274 | rep |
274 | stosb | 275 | stosb |
275 | 276 | ||
276 | /* Setup the stack */ | 277 | /* Setup the stack */ |
277 | leaq user_stack_end(%rip), %rsp | 278 | leaq boot_stack_end(%rip), %rsp |
278 | 279 | ||
279 | /* zero EFLAGS after setting rsp */ | 280 | /* zero EFLAGS after setting rsp */ |
280 | pushq $0 | 281 | pushq $0 |
@@ -285,7 +286,7 @@ relocated: | |||
285 | */ | 286 | */ |
286 | pushq %rsi # Save the real mode argument | 287 | pushq %rsi # Save the real mode argument |
287 | movq %rsi, %rdi # real mode address | 288 | movq %rsi, %rdi # real mode address |
288 | leaq _heap(%rip), %rsi # _heap | 289 | leaq boot_heap(%rip), %rsi # malloc area for uncompression |
289 | leaq input_data(%rip), %rdx # input_data | 290 | leaq input_data(%rip), %rdx # input_data |
290 | movl input_len(%rip), %eax | 291 | movl input_len(%rip), %eax |
291 | movq %rax, %rcx # input_len | 292 | movq %rax, %rcx # input_len |
@@ -310,9 +311,12 @@ gdt: | |||
310 | .quad 0x0080890000000000 /* TS descriptor */ | 311 | .quad 0x0080890000000000 /* TS descriptor */ |
311 | .quad 0x0000000000000000 /* TS continued */ | 312 | .quad 0x0000000000000000 /* TS continued */ |
312 | gdt_end: | 313 | gdt_end: |
313 | .bss | 314 | |
314 | /* Stack for uncompression */ | 315 | .bss |
315 | .balign 4 | 316 | /* Stack and heap for uncompression */ |
316 | user_stack: | 317 | .balign 4 |
317 | .fill 4096,4,0 | 318 | boot_heap: |
318 | user_stack_end: | 319 | .fill BOOT_HEAP_SIZE, 1, 0 |
320 | boot_stack: | ||
321 | .fill BOOT_STACK_SIZE, 1, 0 | ||
322 | boot_stack_end: | ||
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index dad4e699f5a3..90456cee47c3 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -217,12 +217,6 @@ static void putstr(const char *); | |||
217 | static memptr free_mem_ptr; | 217 | static memptr free_mem_ptr; |
218 | static memptr free_mem_end_ptr; | 218 | static memptr free_mem_end_ptr; |
219 | 219 | ||
220 | #ifdef CONFIG_X86_64 | ||
221 | #define HEAP_SIZE 0x7000 | ||
222 | #else | ||
223 | #define HEAP_SIZE 0x4000 | ||
224 | #endif | ||
225 | |||
226 | static char *vidmem; | 220 | static char *vidmem; |
227 | static int vidport; | 221 | static int vidport; |
228 | static int lines, cols; | 222 | static int lines, cols; |
@@ -449,7 +443,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
449 | 443 | ||
450 | window = output; /* Output buffer (Normally at 1M) */ | 444 | window = output; /* Output buffer (Normally at 1M) */ |
451 | free_mem_ptr = heap; /* Heap */ | 445 | free_mem_ptr = heap; /* Heap */ |
452 | free_mem_end_ptr = heap + HEAP_SIZE; | 446 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; |
453 | inbuf = input_data; /* Input buffer */ | 447 | inbuf = input_data; /* Input buffer */ |
454 | insize = input_len; | 448 | insize = input_len; |
455 | inptr = 0; | 449 | inptr = 0; |
diff --git a/arch/x86/boot/compressed/vmlinux_64.lds b/arch/x86/boot/compressed/vmlinux_64.lds index 7e5c7209f6cc..bef1ac891bce 100644 --- a/arch/x86/boot/compressed/vmlinux_64.lds +++ b/arch/x86/boot/compressed/vmlinux_64.lds | |||
@@ -39,10 +39,10 @@ SECTIONS | |||
39 | *(.bss.*) | 39 | *(.bss.*) |
40 | *(COMMON) | 40 | *(COMMON) |
41 | . = ALIGN(8); | 41 | . = ALIGN(8); |
42 | _end = . ; | 42 | _end_before_pgt = . ; |
43 | . = ALIGN(4096); | 43 | . = ALIGN(4096); |
44 | pgtable = . ; | 44 | pgtable = . ; |
45 | . = . + 4096 * 6; | 45 | . = . + 4096 * 6; |
46 | _heap = .; | 46 | _ebss = .; |
47 | } | 47 | } |
48 | } | 48 | } |
diff --git a/arch/x86/boot/copy.S b/arch/x86/boot/copy.S index ef127e56a3cf..ef50c84e8b4b 100644 --- a/arch/x86/boot/copy.S +++ b/arch/x86/boot/copy.S | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/copy.S | ||
13 | * | ||
14 | * Memory copy routines | 12 | * Memory copy routines |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c index 2462c88689ed..7804389ee005 100644 --- a/arch/x86/boot/cpucheck.c +++ b/arch/x86/boot/cpucheck.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/cpucheck.c | ||
13 | * | ||
14 | * Check for obligatory CPU features and abort if the features are not | 12 | * Check for obligatory CPU features and abort if the features are not |
15 | * present. This code should be compilable as 16-, 32- or 64-bit | 13 | * present. This code should be compilable as 16-, 32- or 64-bit |
16 | * code, so be very careful with types and inline assembly. | 14 | * code, so be very careful with types and inline assembly. |
diff --git a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c index 8721dc46a0b6..d84a48ece785 100644 --- a/arch/x86/boot/edd.c +++ b/arch/x86/boot/edd.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/edd.c | ||
13 | * | ||
14 | * Get EDD BIOS disk information | 12 | * Get EDD BIOS disk information |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/install.sh b/arch/x86/boot/install.sh index 88d77761d01b..8d60ee15dfd9 100644 --- a/arch/x86/boot/install.sh +++ b/arch/x86/boot/install.sh | |||
@@ -1,7 +1,5 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # | 2 | # |
3 | # arch/i386/boot/install.sh | ||
4 | # | ||
5 | # This file is subject to the terms and conditions of the GNU General Public | 3 | # This file is subject to the terms and conditions of the GNU General Public |
6 | # License. See the file "COPYING" in the main directory of this archive | 4 | # License. See the file "COPYING" in the main directory of this archive |
7 | # for more details. | 5 | # for more details. |
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c index 7828da5cfd07..77569a4a3be1 100644 --- a/arch/x86/boot/main.c +++ b/arch/x86/boot/main.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/main.c | ||
13 | * | ||
14 | * Main module for the real-mode kernel code | 12 | * Main module for the real-mode kernel code |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/mca.c b/arch/x86/boot/mca.c index 68222f2d4b67..911eaae5d696 100644 --- a/arch/x86/boot/mca.c +++ b/arch/x86/boot/mca.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/mca.c | ||
13 | * | ||
14 | * Get the MCA system description table | 12 | * Get the MCA system description table |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c index e77d89f9e8aa..acad32eb4290 100644 --- a/arch/x86/boot/memory.c +++ b/arch/x86/boot/memory.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/memory.c | ||
13 | * | ||
14 | * Memory detection code | 12 | * Memory detection code |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/pm.c b/arch/x86/boot/pm.c index a93cb8bded4d..328956fdb59e 100644 --- a/arch/x86/boot/pm.c +++ b/arch/x86/boot/pm.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/pm.c | ||
13 | * | ||
14 | * Prepare the machine for transition to protected mode. | 12 | * Prepare the machine for transition to protected mode. |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S index f5402d51f7c3..ab049d40a884 100644 --- a/arch/x86/boot/pmjump.S +++ b/arch/x86/boot/pmjump.S | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/pmjump.S | ||
13 | * | ||
14 | * The actual transition into protected mode | 12 | * The actual transition into protected mode |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/printf.c b/arch/x86/boot/printf.c index 7e7e890699be..c1d00c0274c4 100644 --- a/arch/x86/boot/printf.c +++ b/arch/x86/boot/printf.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/printf.c | ||
13 | * | ||
14 | * Oh, it's a waste of space, but oh-so-yummy for debugging. This | 12 | * Oh, it's a waste of space, but oh-so-yummy for debugging. This |
15 | * version of printf() does not include 64-bit support. "Live with | 13 | * version of printf() does not include 64-bit support. "Live with |
16 | * it." | 14 | * it." |
diff --git a/arch/x86/boot/string.c b/arch/x86/boot/string.c index 481a22097781..f94b7a0c2abf 100644 --- a/arch/x86/boot/string.c +++ b/arch/x86/boot/string.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/string.c | ||
13 | * | ||
14 | * Very basic string functions | 12 | * Very basic string functions |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/tty.c b/arch/x86/boot/tty.c index f3f14bd26371..0be77b39328a 100644 --- a/arch/x86/boot/tty.c +++ b/arch/x86/boot/tty.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/tty.c | ||
13 | * | ||
14 | * Very simple screen I/O | 12 | * Very simple screen I/O |
15 | * XXX: Probably should add very simple serial I/O? | 13 | * XXX: Probably should add very simple serial I/O? |
16 | */ | 14 | */ |
diff --git a/arch/x86/boot/version.c b/arch/x86/boot/version.c index c61462f7d9a7..2723d9b5ce43 100644 --- a/arch/x86/boot/version.c +++ b/arch/x86/boot/version.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/version.c | ||
13 | * | ||
14 | * Kernel version string | 12 | * Kernel version string |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c index 39e247e96172..49f26aaaebc8 100644 --- a/arch/x86/boot/video-bios.c +++ b/arch/x86/boot/video-bios.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/video-bios.c | ||
13 | * | ||
14 | * Standard video BIOS modes | 12 | * Standard video BIOS modes |
15 | * | 13 | * |
16 | * We have two options for this; silent and scanned. | 14 | * We have two options for this; silent and scanned. |
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index 5d5a3f6e8b5c..401ad998ad08 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/video-vesa.c | ||
13 | * | ||
14 | * VESA text modes | 12 | * VESA text modes |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c index 330d6589a2ad..40ecb8d7688c 100644 --- a/arch/x86/boot/video-vga.c +++ b/arch/x86/boot/video-vga.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/video-vga.c | ||
13 | * | ||
14 | * Common all-VGA modes | 12 | * Common all-VGA modes |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c index c1c47ba069ef..83598b23093a 100644 --- a/arch/x86/boot/video.c +++ b/arch/x86/boot/video.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/video.c | ||
13 | * | ||
14 | * Select video mode | 12 | * Select video mode |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h index d69347f79e8e..ee63f5d14461 100644 --- a/arch/x86/boot/video.h +++ b/arch/x86/boot/video.h | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/video.h | ||
13 | * | ||
14 | * Header file for the real-mode video probing code | 12 | * Header file for the real-mode video probing code |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/boot/voyager.c b/arch/x86/boot/voyager.c index 6499e3239b41..433909d61e5c 100644 --- a/arch/x86/boot/voyager.c +++ b/arch/x86/boot/voyager.c | |||
@@ -9,8 +9,6 @@ | |||
9 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * arch/i386/boot/voyager.c | ||
13 | * | ||
14 | * Get the Voyager config information | 12 | * Get the Voyager config information |
15 | */ | 13 | */ |
16 | 14 | ||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index c3920ea8ac56..90e092d0af0c 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -22,13 +22,14 @@ obj-y += setup_$(BITS).o i8259_$(BITS).o setup.o | |||
22 | obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o | 22 | obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o |
23 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o | 23 | obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o |
24 | obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o | 24 | obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o |
25 | obj-y += pci-dma_$(BITS).o bootflag.o e820_$(BITS).o | 25 | obj-y += bootflag.o e820_$(BITS).o |
26 | obj-y += quirks.o i8237.o topology.o kdebugfs.o | 26 | obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o |
27 | obj-y += alternative.o i8253.o | 27 | obj-y += alternative.o i8253.o pci-nommu.o |
28 | obj-$(CONFIG_X86_64) += pci-nommu_64.o bugs_64.o | 28 | obj-$(CONFIG_X86_64) += bugs_64.o |
29 | obj-y += tsc_$(BITS).o io_delay.o rtc.o | 29 | obj-y += tsc_$(BITS).o io_delay.o rtc.o |
30 | 30 | ||
31 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o | 31 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o |
32 | obj-y += process.o | ||
32 | obj-y += i387.o | 33 | obj-y += i387.o |
33 | obj-y += ptrace.o | 34 | obj-y += ptrace.o |
34 | obj-y += ds.o | 35 | obj-y += ds.o |
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index c6dc05af8827..c2502eb9aa83 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/i386/kernel/acpi/cstate.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Intel Corporation | 2 | * Copyright (C) 2005 Intel Corporation |
5 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | 3 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> |
6 | * - Added _PDC for SMP C-states on Intel CPUs | 4 | * - Added _PDC for SMP C-states on Intel CPUs |
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index 324eb0cab19c..de2d2e4ebad9 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/i386/kernel/acpi/processor.c | ||
3 | * | ||
4 | * Copyright (C) 2005 Intel Corporation | 2 | * Copyright (C) 2005 Intel Corporation |
5 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | 3 | * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> |
6 | * - Added _PDC for platforms with Intel CPUs | 4 | * - Added _PDC for platforms with Intel CPUs |
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c index 14791ec55cfd..199e4e05e5dc 100644 --- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c | |||
@@ -289,8 +289,8 @@ static int __init cpufreq_p4_init(void) | |||
289 | if (c->x86_vendor != X86_VENDOR_INTEL) | 289 | if (c->x86_vendor != X86_VENDOR_INTEL) |
290 | return -ENODEV; | 290 | return -ENODEV; |
291 | 291 | ||
292 | if (!test_bit(X86_FEATURE_ACPI, c->x86_capability) || | 292 | if (!test_cpu_cap(c, X86_FEATURE_ACPI) || |
293 | !test_bit(X86_FEATURE_ACC, c->x86_capability)) | 293 | !test_cpu_cap(c, X86_FEATURE_ACC)) |
294 | return -ENODEV; | 294 | return -ENODEV; |
295 | 295 | ||
296 | ret = cpufreq_register_driver(&p4clockmod_driver); | 296 | ret = cpufreq_register_driver(&p4clockmod_driver); |
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 9b7e01daa1ca..1f4cc48c14c6 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/i386/kernel/cpu/mcheck/therm_throt.c | ||
3 | * | 2 | * |
4 | * Thermal throttle event support code (such as syslog messaging and rate | 3 | * Thermal throttle event support code (such as syslog messaging and rate |
5 | * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). | 4 | * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). |
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index 0240cd778365..ed733e7cf4e6 100644 --- a/arch/x86/kernel/e820_32.c +++ b/arch/x86/kernel/e820_32.c | |||
@@ -475,7 +475,7 @@ int __init copy_e820_map(struct e820entry *biosmap, int nr_map) | |||
475 | /* | 475 | /* |
476 | * Find the highest page frame number we have available | 476 | * Find the highest page frame number we have available |
477 | */ | 477 | */ |
478 | void __init find_max_pfn(void) | 478 | void __init propagate_e820_map(void) |
479 | { | 479 | { |
480 | int i; | 480 | int i; |
481 | 481 | ||
@@ -704,7 +704,7 @@ static int __init parse_memmap(char *arg) | |||
704 | * size before original memory map is | 704 | * size before original memory map is |
705 | * reset. | 705 | * reset. |
706 | */ | 706 | */ |
707 | find_max_pfn(); | 707 | propagate_e820_map(); |
708 | saved_max_pfn = max_pfn; | 708 | saved_max_pfn = max_pfn; |
709 | #endif | 709 | #endif |
710 | e820.nr_map = 0; | 710 | e820.nr_map = 0; |
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c index 7f6c0c85c8f6..cbd42e51cb08 100644 --- a/arch/x86/kernel/e820_64.c +++ b/arch/x86/kernel/e820_64.c | |||
@@ -96,7 +96,7 @@ void __init early_res_to_bootmem(void) | |||
96 | } | 96 | } |
97 | 97 | ||
98 | /* Check for already reserved areas */ | 98 | /* Check for already reserved areas */ |
99 | static inline int | 99 | static inline int __init |
100 | bad_addr(unsigned long *addrp, unsigned long size, unsigned long align) | 100 | bad_addr(unsigned long *addrp, unsigned long size, unsigned long align) |
101 | { | 101 | { |
102 | int i; | 102 | int i; |
@@ -116,7 +116,7 @@ again: | |||
116 | } | 116 | } |
117 | 117 | ||
118 | /* Check for already reserved areas */ | 118 | /* Check for already reserved areas */ |
119 | static inline int | 119 | static inline int __init |
120 | bad_addr_size(unsigned long *addrp, unsigned long *sizep, unsigned long align) | 120 | bad_addr_size(unsigned long *addrp, unsigned long *sizep, unsigned long align) |
121 | { | 121 | { |
122 | int i; | 122 | int i; |
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c index 759e02bec070..77d424cf68b3 100644 --- a/arch/x86/kernel/efi.c +++ b/arch/x86/kernel/efi.c | |||
@@ -383,6 +383,7 @@ static void __init runtime_code_page_mkexec(void) | |||
383 | { | 383 | { |
384 | efi_memory_desc_t *md; | 384 | efi_memory_desc_t *md; |
385 | void *p; | 385 | void *p; |
386 | u64 addr, npages; | ||
386 | 387 | ||
387 | /* Make EFI runtime service code area executable */ | 388 | /* Make EFI runtime service code area executable */ |
388 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 389 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
@@ -391,7 +392,10 @@ static void __init runtime_code_page_mkexec(void) | |||
391 | if (md->type != EFI_RUNTIME_SERVICES_CODE) | 392 | if (md->type != EFI_RUNTIME_SERVICES_CODE) |
392 | continue; | 393 | continue; |
393 | 394 | ||
394 | set_memory_x(md->virt_addr, md->num_pages); | 395 | addr = md->virt_addr; |
396 | npages = md->num_pages; | ||
397 | memrange_efi_to_native(&addr, &npages); | ||
398 | set_memory_x(addr, npages); | ||
395 | } | 399 | } |
396 | } | 400 | } |
397 | 401 | ||
@@ -408,7 +412,7 @@ void __init efi_enter_virtual_mode(void) | |||
408 | efi_memory_desc_t *md; | 412 | efi_memory_desc_t *md; |
409 | efi_status_t status; | 413 | efi_status_t status; |
410 | unsigned long size; | 414 | unsigned long size; |
411 | u64 end, systab; | 415 | u64 end, systab, addr, npages; |
412 | void *p, *va; | 416 | void *p, *va; |
413 | 417 | ||
414 | efi.systab = NULL; | 418 | efi.systab = NULL; |
@@ -420,7 +424,7 @@ void __init efi_enter_virtual_mode(void) | |||
420 | size = md->num_pages << EFI_PAGE_SHIFT; | 424 | size = md->num_pages << EFI_PAGE_SHIFT; |
421 | end = md->phys_addr + size; | 425 | end = md->phys_addr + size; |
422 | 426 | ||
423 | if ((end >> PAGE_SHIFT) <= max_pfn_mapped) | 427 | if (PFN_UP(end) <= max_pfn_mapped) |
424 | va = __va(md->phys_addr); | 428 | va = __va(md->phys_addr); |
425 | else | 429 | else |
426 | va = efi_ioremap(md->phys_addr, size); | 430 | va = efi_ioremap(md->phys_addr, size); |
@@ -433,8 +437,12 @@ void __init efi_enter_virtual_mode(void) | |||
433 | continue; | 437 | continue; |
434 | } | 438 | } |
435 | 439 | ||
436 | if (!(md->attribute & EFI_MEMORY_WB)) | 440 | if (!(md->attribute & EFI_MEMORY_WB)) { |
437 | set_memory_uc(md->virt_addr, md->num_pages); | 441 | addr = md->virt_addr; |
442 | npages = md->num_pages; | ||
443 | memrange_efi_to_native(&addr, &npages); | ||
444 | set_memory_uc(addr, npages); | ||
445 | } | ||
438 | 446 | ||
439 | systab = (u64) (unsigned long) efi_phys.systab; | 447 | systab = (u64) (unsigned long) efi_phys.systab; |
440 | if (md->phys_addr <= systab && systab < end) { | 448 | if (md->phys_addr <= systab && systab < end) { |
diff --git a/arch/x86/kernel/efi_64.c b/arch/x86/kernel/efi_64.c index d143a1e76b30..d0060fdcccac 100644 --- a/arch/x86/kernel/efi_64.c +++ b/arch/x86/kernel/efi_64.c | |||
@@ -105,14 +105,14 @@ void __init efi_reserve_bootmem(void) | |||
105 | 105 | ||
106 | void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size) | 106 | void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size) |
107 | { | 107 | { |
108 | static unsigned pages_mapped; | 108 | static unsigned pages_mapped __initdata; |
109 | unsigned i, pages; | 109 | unsigned i, pages; |
110 | unsigned long offset; | ||
110 | 111 | ||
111 | /* phys_addr and size must be page aligned */ | 112 | pages = PFN_UP(phys_addr + size) - PFN_DOWN(phys_addr); |
112 | if ((phys_addr & ~PAGE_MASK) || (size & ~PAGE_MASK)) | 113 | offset = phys_addr & ~PAGE_MASK; |
113 | return NULL; | 114 | phys_addr &= PAGE_MASK; |
114 | 115 | ||
115 | pages = size >> PAGE_SHIFT; | ||
116 | if (pages_mapped + pages > MAX_EFI_IO_PAGES) | 116 | if (pages_mapped + pages > MAX_EFI_IO_PAGES) |
117 | return NULL; | 117 | return NULL; |
118 | 118 | ||
@@ -124,5 +124,5 @@ void __iomem * __init efi_ioremap(unsigned long phys_addr, unsigned long size) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \ | 126 | return (void __iomem *)__fix_to_virt(FIX_EFI_IO_MAP_FIRST_PAGE - \ |
127 | (pages_mapped - pages)); | 127 | (pages_mapped - pages)) + offset; |
128 | } | 128 | } |
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 9ba49a26dff8..f0f8934fc303 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/i386/entry.S | ||
3 | * | 2 | * |
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | */ | 4 | */ |
diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 5d77c9cd8e15..ebf13908a743 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c | |||
@@ -61,26 +61,31 @@ int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip) | |||
61 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | | 61 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | |
62 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | | 62 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | |
63 | (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | | 63 | (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | |
64 | (6 << UVH_IPI_INT_DELIVERY_MODE_SHFT); | 64 | APIC_DM_INIT; |
65 | uv_write_global_mmr64(nasid, UVH_IPI_INT, val); | ||
66 | mdelay(10); | ||
67 | |||
68 | val = (1UL << UVH_IPI_INT_SEND_SHFT) | | ||
69 | (phys_apicid << UVH_IPI_INT_APIC_ID_SHFT) | | ||
70 | (((long)start_rip << UVH_IPI_INT_VECTOR_SHFT) >> 12) | | ||
71 | APIC_DM_STARTUP; | ||
65 | uv_write_global_mmr64(nasid, UVH_IPI_INT, val); | 72 | uv_write_global_mmr64(nasid, UVH_IPI_INT, val); |
66 | return 0; | 73 | return 0; |
67 | } | 74 | } |
68 | 75 | ||
69 | static void uv_send_IPI_one(int cpu, int vector) | 76 | static void uv_send_IPI_one(int cpu, int vector) |
70 | { | 77 | { |
71 | unsigned long val, apicid; | 78 | unsigned long val, apicid, lapicid; |
72 | int nasid; | 79 | int nasid; |
73 | 80 | ||
74 | apicid = per_cpu(x86_cpu_to_apicid, cpu); /* ZZZ - cache node-local ? */ | 81 | apicid = per_cpu(x86_cpu_to_apicid, cpu); /* ZZZ - cache node-local ? */ |
82 | lapicid = apicid & 0x3f; /* ZZZ macro needed */ | ||
75 | nasid = uv_apicid_to_nasid(apicid); | 83 | nasid = uv_apicid_to_nasid(apicid); |
76 | val = | 84 | val = |
77 | (1UL << UVH_IPI_INT_SEND_SHFT) | (apicid << | 85 | (1UL << UVH_IPI_INT_SEND_SHFT) | (lapicid << |
78 | UVH_IPI_INT_APIC_ID_SHFT) | | 86 | UVH_IPI_INT_APIC_ID_SHFT) | |
79 | (vector << UVH_IPI_INT_VECTOR_SHFT); | 87 | (vector << UVH_IPI_INT_VECTOR_SHFT); |
80 | uv_write_global_mmr64(nasid, UVH_IPI_INT, val); | 88 | uv_write_global_mmr64(nasid, UVH_IPI_INT, val); |
81 | printk(KERN_DEBUG | ||
82 | "UV: IPI to cpu %d, apicid 0x%lx, vec %d, nasid%d, val 0x%lx\n", | ||
83 | cpu, apicid, vector, nasid, val); | ||
84 | } | 89 | } |
85 | 90 | ||
86 | static void uv_send_IPI_mask(cpumask_t mask, int vector) | 91 | static void uv_send_IPI_mask(cpumask_t mask, int vector) |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index d6d54faa84df..993c76773256 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -146,6 +146,7 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
146 | 146 | ||
147 | reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS"); | 147 | reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS"); |
148 | 148 | ||
149 | #ifdef CONFIG_BLK_DEV_INITRD | ||
149 | /* Reserve INITRD */ | 150 | /* Reserve INITRD */ |
150 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { | 151 | if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { |
151 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; | 152 | unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; |
@@ -153,6 +154,7 @@ void __init x86_64_start_kernel(char * real_mode_data) | |||
153 | unsigned long ramdisk_end = ramdisk_image + ramdisk_size; | 154 | unsigned long ramdisk_end = ramdisk_image + ramdisk_size; |
154 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); | 155 | reserve_early(ramdisk_image, ramdisk_end, "RAMDISK"); |
155 | } | 156 | } |
157 | #endif | ||
156 | 158 | ||
157 | reserve_ebda_region(); | 159 | reserve_ebda_region(); |
158 | 160 | ||
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 826988a6e964..90f038af3adc 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/i386/kernel/head.S -- the 32-bit startup code. | ||
3 | * | 2 | * |
4 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
5 | * | 4 | * |
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 8f8102d967b3..db6839b53195 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
@@ -35,17 +35,18 @@ | |||
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu; | 37 | static unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu; |
38 | unsigned int xstate_size; | ||
39 | static struct i387_fxsave_struct fx_scratch __cpuinitdata; | ||
38 | 40 | ||
39 | void mxcsr_feature_mask_init(void) | 41 | void __cpuinit mxcsr_feature_mask_init(void) |
40 | { | 42 | { |
41 | unsigned long mask = 0; | 43 | unsigned long mask = 0; |
42 | 44 | ||
43 | clts(); | 45 | clts(); |
44 | if (cpu_has_fxsr) { | 46 | if (cpu_has_fxsr) { |
45 | memset(¤t->thread.i387.fxsave, 0, | 47 | memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct)); |
46 | sizeof(struct i387_fxsave_struct)); | 48 | asm volatile("fxsave %0" : : "m" (fx_scratch)); |
47 | asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave)); | 49 | mask = fx_scratch.mxcsr_mask; |
48 | mask = current->thread.i387.fxsave.mxcsr_mask; | ||
49 | if (mask == 0) | 50 | if (mask == 0) |
50 | mask = 0x0000ffbf; | 51 | mask = 0x0000ffbf; |
51 | } | 52 | } |
@@ -53,6 +54,16 @@ void mxcsr_feature_mask_init(void) | |||
53 | stts(); | 54 | stts(); |
54 | } | 55 | } |
55 | 56 | ||
57 | void __init init_thread_xstate(void) | ||
58 | { | ||
59 | if (cpu_has_fxsr) | ||
60 | xstate_size = sizeof(struct i387_fxsave_struct); | ||
61 | #ifdef CONFIG_X86_32 | ||
62 | else | ||
63 | xstate_size = sizeof(struct i387_fsave_struct); | ||
64 | #endif | ||
65 | } | ||
66 | |||
56 | #ifdef CONFIG_X86_64 | 67 | #ifdef CONFIG_X86_64 |
57 | /* | 68 | /* |
58 | * Called at bootup to set up the initial FPU state that is later cloned | 69 | * Called at bootup to set up the initial FPU state that is later cloned |
@@ -61,10 +72,6 @@ void mxcsr_feature_mask_init(void) | |||
61 | void __cpuinit fpu_init(void) | 72 | void __cpuinit fpu_init(void) |
62 | { | 73 | { |
63 | unsigned long oldcr0 = read_cr0(); | 74 | unsigned long oldcr0 = read_cr0(); |
64 | extern void __bad_fxsave_alignment(void); | ||
65 | |||
66 | if (offsetof(struct task_struct, thread.i387.fxsave) & 15) | ||
67 | __bad_fxsave_alignment(); | ||
68 | 75 | ||
69 | set_in_cr4(X86_CR4_OSFXSR); | 76 | set_in_cr4(X86_CR4_OSFXSR); |
70 | set_in_cr4(X86_CR4_OSXMMEXCPT); | 77 | set_in_cr4(X86_CR4_OSXMMEXCPT); |
@@ -84,32 +91,44 @@ void __cpuinit fpu_init(void) | |||
84 | * value at reset if we support XMM instructions and then | 91 | * value at reset if we support XMM instructions and then |
85 | * remeber the current task has used the FPU. | 92 | * remeber the current task has used the FPU. |
86 | */ | 93 | */ |
87 | void init_fpu(struct task_struct *tsk) | 94 | int init_fpu(struct task_struct *tsk) |
88 | { | 95 | { |
89 | if (tsk_used_math(tsk)) { | 96 | if (tsk_used_math(tsk)) { |
90 | if (tsk == current) | 97 | if (tsk == current) |
91 | unlazy_fpu(tsk); | 98 | unlazy_fpu(tsk); |
92 | return; | 99 | return 0; |
100 | } | ||
101 | |||
102 | /* | ||
103 | * Memory allocation at the first usage of the FPU and other state. | ||
104 | */ | ||
105 | if (!tsk->thread.xstate) { | ||
106 | tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep, | ||
107 | GFP_KERNEL); | ||
108 | if (!tsk->thread.xstate) | ||
109 | return -ENOMEM; | ||
93 | } | 110 | } |
94 | 111 | ||
95 | if (cpu_has_fxsr) { | 112 | if (cpu_has_fxsr) { |
96 | memset(&tsk->thread.i387.fxsave, 0, | 113 | struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; |
97 | sizeof(struct i387_fxsave_struct)); | 114 | |
98 | tsk->thread.i387.fxsave.cwd = 0x37f; | 115 | memset(fx, 0, xstate_size); |
116 | fx->cwd = 0x37f; | ||
99 | if (cpu_has_xmm) | 117 | if (cpu_has_xmm) |
100 | tsk->thread.i387.fxsave.mxcsr = MXCSR_DEFAULT; | 118 | fx->mxcsr = MXCSR_DEFAULT; |
101 | } else { | 119 | } else { |
102 | memset(&tsk->thread.i387.fsave, 0, | 120 | struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave; |
103 | sizeof(struct i387_fsave_struct)); | 121 | memset(fp, 0, xstate_size); |
104 | tsk->thread.i387.fsave.cwd = 0xffff037fu; | 122 | fp->cwd = 0xffff037fu; |
105 | tsk->thread.i387.fsave.swd = 0xffff0000u; | 123 | fp->swd = 0xffff0000u; |
106 | tsk->thread.i387.fsave.twd = 0xffffffffu; | 124 | fp->twd = 0xffffffffu; |
107 | tsk->thread.i387.fsave.fos = 0xffff0000u; | 125 | fp->fos = 0xffff0000u; |
108 | } | 126 | } |
109 | /* | 127 | /* |
110 | * Only the device not available exception or ptrace can call init_fpu. | 128 | * Only the device not available exception or ptrace can call init_fpu. |
111 | */ | 129 | */ |
112 | set_stopped_child_used_math(tsk); | 130 | set_stopped_child_used_math(tsk); |
131 | return 0; | ||
113 | } | 132 | } |
114 | 133 | ||
115 | int fpregs_active(struct task_struct *target, const struct user_regset *regset) | 134 | int fpregs_active(struct task_struct *target, const struct user_regset *regset) |
@@ -126,13 +145,17 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, | |||
126 | unsigned int pos, unsigned int count, | 145 | unsigned int pos, unsigned int count, |
127 | void *kbuf, void __user *ubuf) | 146 | void *kbuf, void __user *ubuf) |
128 | { | 147 | { |
148 | int ret; | ||
149 | |||
129 | if (!cpu_has_fxsr) | 150 | if (!cpu_has_fxsr) |
130 | return -ENODEV; | 151 | return -ENODEV; |
131 | 152 | ||
132 | init_fpu(target); | 153 | ret = init_fpu(target); |
154 | if (ret) | ||
155 | return ret; | ||
133 | 156 | ||
134 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 157 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
135 | &target->thread.i387.fxsave, 0, -1); | 158 | &target->thread.xstate->fxsave, 0, -1); |
136 | } | 159 | } |
137 | 160 | ||
138 | int xfpregs_set(struct task_struct *target, const struct user_regset *regset, | 161 | int xfpregs_set(struct task_struct *target, const struct user_regset *regset, |
@@ -144,16 +167,19 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, | |||
144 | if (!cpu_has_fxsr) | 167 | if (!cpu_has_fxsr) |
145 | return -ENODEV; | 168 | return -ENODEV; |
146 | 169 | ||
147 | init_fpu(target); | 170 | ret = init_fpu(target); |
171 | if (ret) | ||
172 | return ret; | ||
173 | |||
148 | set_stopped_child_used_math(target); | 174 | set_stopped_child_used_math(target); |
149 | 175 | ||
150 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 176 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
151 | &target->thread.i387.fxsave, 0, -1); | 177 | &target->thread.xstate->fxsave, 0, -1); |
152 | 178 | ||
153 | /* | 179 | /* |
154 | * mxcsr reserved bits must be masked to zero for security reasons. | 180 | * mxcsr reserved bits must be masked to zero for security reasons. |
155 | */ | 181 | */ |
156 | target->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask; | 182 | target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask; |
157 | 183 | ||
158 | return ret; | 184 | return ret; |
159 | } | 185 | } |
@@ -233,7 +259,7 @@ static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave) | |||
233 | static void | 259 | static void |
234 | convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk) | 260 | convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk) |
235 | { | 261 | { |
236 | struct i387_fxsave_struct *fxsave = &tsk->thread.i387.fxsave; | 262 | struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave; |
237 | struct _fpreg *to = (struct _fpreg *) &env->st_space[0]; | 263 | struct _fpreg *to = (struct _fpreg *) &env->st_space[0]; |
238 | struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0]; | 264 | struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0]; |
239 | int i; | 265 | int i; |
@@ -273,7 +299,7 @@ static void convert_to_fxsr(struct task_struct *tsk, | |||
273 | const struct user_i387_ia32_struct *env) | 299 | const struct user_i387_ia32_struct *env) |
274 | 300 | ||
275 | { | 301 | { |
276 | struct i387_fxsave_struct *fxsave = &tsk->thread.i387.fxsave; | 302 | struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave; |
277 | struct _fpreg *from = (struct _fpreg *) &env->st_space[0]; | 303 | struct _fpreg *from = (struct _fpreg *) &env->st_space[0]; |
278 | struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0]; | 304 | struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0]; |
279 | int i; | 305 | int i; |
@@ -302,15 +328,19 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, | |||
302 | void *kbuf, void __user *ubuf) | 328 | void *kbuf, void __user *ubuf) |
303 | { | 329 | { |
304 | struct user_i387_ia32_struct env; | 330 | struct user_i387_ia32_struct env; |
331 | int ret; | ||
305 | 332 | ||
306 | if (!HAVE_HWFP) | 333 | if (!HAVE_HWFP) |
307 | return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); | 334 | return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); |
308 | 335 | ||
309 | init_fpu(target); | 336 | ret = init_fpu(target); |
337 | if (ret) | ||
338 | return ret; | ||
310 | 339 | ||
311 | if (!cpu_has_fxsr) { | 340 | if (!cpu_has_fxsr) { |
312 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 341 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
313 | &target->thread.i387.fsave, 0, -1); | 342 | &target->thread.xstate->fsave, 0, |
343 | -1); | ||
314 | } | 344 | } |
315 | 345 | ||
316 | if (kbuf && pos == 0 && count == sizeof(env)) { | 346 | if (kbuf && pos == 0 && count == sizeof(env)) { |
@@ -333,12 +363,15 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, | |||
333 | if (!HAVE_HWFP) | 363 | if (!HAVE_HWFP) |
334 | return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf); | 364 | return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf); |
335 | 365 | ||
336 | init_fpu(target); | 366 | ret = init_fpu(target); |
367 | if (ret) | ||
368 | return ret; | ||
369 | |||
337 | set_stopped_child_used_math(target); | 370 | set_stopped_child_used_math(target); |
338 | 371 | ||
339 | if (!cpu_has_fxsr) { | 372 | if (!cpu_has_fxsr) { |
340 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 373 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
341 | &target->thread.i387.fsave, 0, -1); | 374 | &target->thread.xstate->fsave, 0, -1); |
342 | } | 375 | } |
343 | 376 | ||
344 | if (pos > 0 || count < sizeof(env)) | 377 | if (pos > 0 || count < sizeof(env)) |
@@ -358,11 +391,11 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, | |||
358 | static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf) | 391 | static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf) |
359 | { | 392 | { |
360 | struct task_struct *tsk = current; | 393 | struct task_struct *tsk = current; |
394 | struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave; | ||
361 | 395 | ||
362 | unlazy_fpu(tsk); | 396 | unlazy_fpu(tsk); |
363 | tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd; | 397 | fp->status = fp->swd; |
364 | if (__copy_to_user(buf, &tsk->thread.i387.fsave, | 398 | if (__copy_to_user(buf, fp, sizeof(struct i387_fsave_struct))) |
365 | sizeof(struct i387_fsave_struct))) | ||
366 | return -1; | 399 | return -1; |
367 | return 1; | 400 | return 1; |
368 | } | 401 | } |
@@ -370,6 +403,7 @@ static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf) | |||
370 | static int save_i387_fxsave(struct _fpstate_ia32 __user *buf) | 403 | static int save_i387_fxsave(struct _fpstate_ia32 __user *buf) |
371 | { | 404 | { |
372 | struct task_struct *tsk = current; | 405 | struct task_struct *tsk = current; |
406 | struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; | ||
373 | struct user_i387_ia32_struct env; | 407 | struct user_i387_ia32_struct env; |
374 | int err = 0; | 408 | int err = 0; |
375 | 409 | ||
@@ -379,12 +413,12 @@ static int save_i387_fxsave(struct _fpstate_ia32 __user *buf) | |||
379 | if (__copy_to_user(buf, &env, sizeof(env))) | 413 | if (__copy_to_user(buf, &env, sizeof(env))) |
380 | return -1; | 414 | return -1; |
381 | 415 | ||
382 | err |= __put_user(tsk->thread.i387.fxsave.swd, &buf->status); | 416 | err |= __put_user(fx->swd, &buf->status); |
383 | err |= __put_user(X86_FXSR_MAGIC, &buf->magic); | 417 | err |= __put_user(X86_FXSR_MAGIC, &buf->magic); |
384 | if (err) | 418 | if (err) |
385 | return -1; | 419 | return -1; |
386 | 420 | ||
387 | if (__copy_to_user(&buf->_fxsr_env[0], &tsk->thread.i387.fxsave, | 421 | if (__copy_to_user(&buf->_fxsr_env[0], fx, |
388 | sizeof(struct i387_fxsave_struct))) | 422 | sizeof(struct i387_fxsave_struct))) |
389 | return -1; | 423 | return -1; |
390 | return 1; | 424 | return 1; |
@@ -417,7 +451,7 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf) | |||
417 | struct task_struct *tsk = current; | 451 | struct task_struct *tsk = current; |
418 | 452 | ||
419 | clear_fpu(tsk); | 453 | clear_fpu(tsk); |
420 | return __copy_from_user(&tsk->thread.i387.fsave, buf, | 454 | return __copy_from_user(&tsk->thread.xstate->fsave, buf, |
421 | sizeof(struct i387_fsave_struct)); | 455 | sizeof(struct i387_fsave_struct)); |
422 | } | 456 | } |
423 | 457 | ||
@@ -428,10 +462,10 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf) | |||
428 | int err; | 462 | int err; |
429 | 463 | ||
430 | clear_fpu(tsk); | 464 | clear_fpu(tsk); |
431 | err = __copy_from_user(&tsk->thread.i387.fxsave, &buf->_fxsr_env[0], | 465 | err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0], |
432 | sizeof(struct i387_fxsave_struct)); | 466 | sizeof(struct i387_fxsave_struct)); |
433 | /* mxcsr reserved bits must be masked to zero for security reasons */ | 467 | /* mxcsr reserved bits must be masked to zero for security reasons */ |
434 | tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask; | 468 | tsk->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask; |
435 | if (err || __copy_from_user(&env, buf, sizeof(env))) | 469 | if (err || __copy_from_user(&env, buf, sizeof(env))) |
436 | return 1; | 470 | return 1; |
437 | convert_to_fxsr(tsk, &env); | 471 | convert_to_fxsr(tsk, &env); |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 24362ecf5f9a..f47f0eb886b8 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -46,11 +46,7 @@ | |||
46 | #include <asm/apicdef.h> | 46 | #include <asm/apicdef.h> |
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | 48 | ||
49 | #ifdef CONFIG_X86_32 | 49 | #include <mach_ipi.h> |
50 | # include <mach_ipi.h> | ||
51 | #else | ||
52 | # include <asm/mach_apic.h> | ||
53 | #endif | ||
54 | 50 | ||
55 | /* | 51 | /* |
56 | * Put the error code here just in case the user cares: | 52 | * Put the error code here just in case the user cares: |
diff --git a/arch/x86/kernel/nmi_32.c b/arch/x86/kernel/nmi_32.c index 8421d0ac6f22..11b14bbaa61e 100644 --- a/arch/x86/kernel/nmi_32.c +++ b/arch/x86/kernel/nmi_32.c | |||
@@ -321,7 +321,8 @@ EXPORT_SYMBOL(touch_nmi_watchdog); | |||
321 | 321 | ||
322 | extern void die_nmi(struct pt_regs *, const char *msg); | 322 | extern void die_nmi(struct pt_regs *, const char *msg); |
323 | 323 | ||
324 | __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) | 324 | notrace __kprobes int |
325 | nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) | ||
325 | { | 326 | { |
326 | 327 | ||
327 | /* | 328 | /* |
diff --git a/arch/x86/kernel/nmi_64.c b/arch/x86/kernel/nmi_64.c index 11f9130ac513..5a29ded994fa 100644 --- a/arch/x86/kernel/nmi_64.c +++ b/arch/x86/kernel/nmi_64.c | |||
@@ -313,7 +313,8 @@ void touch_nmi_watchdog(void) | |||
313 | } | 313 | } |
314 | EXPORT_SYMBOL(touch_nmi_watchdog); | 314 | EXPORT_SYMBOL(touch_nmi_watchdog); |
315 | 315 | ||
316 | int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) | 316 | notrace __kprobes int |
317 | nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) | ||
317 | { | 318 | { |
318 | int sum; | 319 | int sum; |
319 | int touched = 0; | 320 | int touched = 0; |
@@ -384,7 +385,8 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) | |||
384 | 385 | ||
385 | static unsigned ignore_nmis; | 386 | static unsigned ignore_nmis; |
386 | 387 | ||
387 | asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) | 388 | asmlinkage notrace __kprobes void |
389 | do_nmi(struct pt_regs *regs, long error_code) | ||
388 | { | 390 | { |
389 | nmi_enter(); | 391 | nmi_enter(); |
390 | add_pda(__nmi_count,1); | 392 | add_pda(__nmi_count,1); |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 1b5464c2434f..adb91e4b62da 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -470,10 +470,11 @@ error: | |||
470 | return 0; | 470 | return 0; |
471 | } | 471 | } |
472 | 472 | ||
473 | static dma_addr_t calgary_map_single(struct device *dev, void *vaddr, | 473 | static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr, |
474 | size_t size, int direction) | 474 | size_t size, int direction) |
475 | { | 475 | { |
476 | dma_addr_t dma_handle = bad_dma_address; | 476 | dma_addr_t dma_handle = bad_dma_address; |
477 | void *vaddr = phys_to_virt(paddr); | ||
477 | unsigned long uaddr; | 478 | unsigned long uaddr; |
478 | unsigned int npages; | 479 | unsigned int npages; |
479 | struct iommu_table *tbl = find_iommu_table(dev); | 480 | struct iommu_table *tbl = find_iommu_table(dev); |
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma.c index ada5a0604992..388b113a7d88 100644 --- a/arch/x86/kernel/pci-dma_64.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -1,61 +1,370 @@ | |||
1 | /* | 1 | #include <linux/dma-mapping.h> |
2 | * Dynamic DMA mapping support. | ||
3 | */ | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | #include <linux/mm.h> | ||
7 | #include <linux/string.h> | ||
8 | #include <linux/pci.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/dmar.h> | 2 | #include <linux/dmar.h> |
11 | #include <asm/io.h> | 3 | #include <linux/bootmem.h> |
4 | #include <linux/pci.h> | ||
5 | |||
6 | #include <asm/proto.h> | ||
7 | #include <asm/dma.h> | ||
12 | #include <asm/gart.h> | 8 | #include <asm/gart.h> |
13 | #include <asm/calgary.h> | 9 | #include <asm/calgary.h> |
14 | 10 | ||
15 | int iommu_merge __read_mostly = 0; | 11 | int forbid_dac __read_mostly; |
16 | 12 | EXPORT_SYMBOL(forbid_dac); | |
17 | dma_addr_t bad_dma_address __read_mostly; | ||
18 | EXPORT_SYMBOL(bad_dma_address); | ||
19 | 13 | ||
20 | /* This tells the BIO block layer to assume merging. Default to off | 14 | const struct dma_mapping_ops *dma_ops; |
21 | because we cannot guarantee merging later. */ | 15 | EXPORT_SYMBOL(dma_ops); |
22 | int iommu_bio_merge __read_mostly = 0; | ||
23 | EXPORT_SYMBOL(iommu_bio_merge); | ||
24 | 16 | ||
25 | static int iommu_sac_force __read_mostly = 0; | 17 | int iommu_sac_force __read_mostly = 0; |
26 | 18 | ||
27 | int no_iommu __read_mostly; | ||
28 | #ifdef CONFIG_IOMMU_DEBUG | 19 | #ifdef CONFIG_IOMMU_DEBUG |
29 | int panic_on_overflow __read_mostly = 1; | 20 | int panic_on_overflow __read_mostly = 1; |
30 | int force_iommu __read_mostly = 1; | 21 | int force_iommu __read_mostly = 1; |
31 | #else | 22 | #else |
32 | int panic_on_overflow __read_mostly = 0; | 23 | int panic_on_overflow __read_mostly = 0; |
33 | int force_iommu __read_mostly= 0; | 24 | int force_iommu __read_mostly = 0; |
34 | #endif | 25 | #endif |
35 | 26 | ||
27 | int iommu_merge __read_mostly = 0; | ||
28 | |||
29 | int no_iommu __read_mostly; | ||
36 | /* Set this to 1 if there is a HW IOMMU in the system */ | 30 | /* Set this to 1 if there is a HW IOMMU in the system */ |
37 | int iommu_detected __read_mostly = 0; | 31 | int iommu_detected __read_mostly = 0; |
38 | 32 | ||
33 | /* This tells the BIO block layer to assume merging. Default to off | ||
34 | because we cannot guarantee merging later. */ | ||
35 | int iommu_bio_merge __read_mostly = 0; | ||
36 | EXPORT_SYMBOL(iommu_bio_merge); | ||
37 | |||
38 | dma_addr_t bad_dma_address __read_mostly = 0; | ||
39 | EXPORT_SYMBOL(bad_dma_address); | ||
40 | |||
39 | /* Dummy device used for NULL arguments (normally ISA). Better would | 41 | /* Dummy device used for NULL arguments (normally ISA). Better would |
40 | be probably a smaller DMA mask, but this is bug-to-bug compatible | 42 | be probably a smaller DMA mask, but this is bug-to-bug compatible |
41 | to i386. */ | 43 | to older i386. */ |
42 | struct device fallback_dev = { | 44 | struct device fallback_dev = { |
43 | .bus_id = "fallback device", | 45 | .bus_id = "fallback device", |
44 | .coherent_dma_mask = DMA_32BIT_MASK, | 46 | .coherent_dma_mask = DMA_32BIT_MASK, |
45 | .dma_mask = &fallback_dev.coherent_dma_mask, | 47 | .dma_mask = &fallback_dev.coherent_dma_mask, |
46 | }; | 48 | }; |
47 | 49 | ||
50 | int dma_set_mask(struct device *dev, u64 mask) | ||
51 | { | ||
52 | if (!dev->dma_mask || !dma_supported(dev, mask)) | ||
53 | return -EIO; | ||
54 | |||
55 | *dev->dma_mask = mask; | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | EXPORT_SYMBOL(dma_set_mask); | ||
60 | |||
61 | #ifdef CONFIG_X86_64 | ||
62 | static __initdata void *dma32_bootmem_ptr; | ||
63 | static unsigned long dma32_bootmem_size __initdata = (128ULL<<20); | ||
64 | |||
65 | static int __init parse_dma32_size_opt(char *p) | ||
66 | { | ||
67 | if (!p) | ||
68 | return -EINVAL; | ||
69 | dma32_bootmem_size = memparse(p, &p); | ||
70 | return 0; | ||
71 | } | ||
72 | early_param("dma32_size", parse_dma32_size_opt); | ||
73 | |||
74 | void __init dma32_reserve_bootmem(void) | ||
75 | { | ||
76 | unsigned long size, align; | ||
77 | if (end_pfn <= MAX_DMA32_PFN) | ||
78 | return; | ||
79 | |||
80 | align = 64ULL<<20; | ||
81 | size = round_up(dma32_bootmem_size, align); | ||
82 | dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align, | ||
83 | __pa(MAX_DMA_ADDRESS)); | ||
84 | if (dma32_bootmem_ptr) | ||
85 | dma32_bootmem_size = size; | ||
86 | else | ||
87 | dma32_bootmem_size = 0; | ||
88 | } | ||
89 | static void __init dma32_free_bootmem(void) | ||
90 | { | ||
91 | int node; | ||
92 | |||
93 | if (end_pfn <= MAX_DMA32_PFN) | ||
94 | return; | ||
95 | |||
96 | if (!dma32_bootmem_ptr) | ||
97 | return; | ||
98 | |||
99 | for_each_online_node(node) | ||
100 | free_bootmem_node(NODE_DATA(node), __pa(dma32_bootmem_ptr), | ||
101 | dma32_bootmem_size); | ||
102 | |||
103 | dma32_bootmem_ptr = NULL; | ||
104 | dma32_bootmem_size = 0; | ||
105 | } | ||
106 | |||
107 | void __init pci_iommu_alloc(void) | ||
108 | { | ||
109 | /* free the range so iommu could get some range less than 4G */ | ||
110 | dma32_free_bootmem(); | ||
111 | /* | ||
112 | * The order of these functions is important for | ||
113 | * fall-back/fail-over reasons | ||
114 | */ | ||
115 | #ifdef CONFIG_GART_IOMMU | ||
116 | gart_iommu_hole_init(); | ||
117 | #endif | ||
118 | |||
119 | #ifdef CONFIG_CALGARY_IOMMU | ||
120 | detect_calgary(); | ||
121 | #endif | ||
122 | |||
123 | detect_intel_iommu(); | ||
124 | |||
125 | #ifdef CONFIG_SWIOTLB | ||
126 | pci_swiotlb_init(); | ||
127 | #endif | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | /* | ||
132 | * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter | ||
133 | * documentation. | ||
134 | */ | ||
135 | static __init int iommu_setup(char *p) | ||
136 | { | ||
137 | iommu_merge = 1; | ||
138 | |||
139 | if (!p) | ||
140 | return -EINVAL; | ||
141 | |||
142 | while (*p) { | ||
143 | if (!strncmp(p, "off", 3)) | ||
144 | no_iommu = 1; | ||
145 | /* gart_parse_options has more force support */ | ||
146 | if (!strncmp(p, "force", 5)) | ||
147 | force_iommu = 1; | ||
148 | if (!strncmp(p, "noforce", 7)) { | ||
149 | iommu_merge = 0; | ||
150 | force_iommu = 0; | ||
151 | } | ||
152 | |||
153 | if (!strncmp(p, "biomerge", 8)) { | ||
154 | iommu_bio_merge = 4096; | ||
155 | iommu_merge = 1; | ||
156 | force_iommu = 1; | ||
157 | } | ||
158 | if (!strncmp(p, "panic", 5)) | ||
159 | panic_on_overflow = 1; | ||
160 | if (!strncmp(p, "nopanic", 7)) | ||
161 | panic_on_overflow = 0; | ||
162 | if (!strncmp(p, "merge", 5)) { | ||
163 | iommu_merge = 1; | ||
164 | force_iommu = 1; | ||
165 | } | ||
166 | if (!strncmp(p, "nomerge", 7)) | ||
167 | iommu_merge = 0; | ||
168 | if (!strncmp(p, "forcesac", 8)) | ||
169 | iommu_sac_force = 1; | ||
170 | if (!strncmp(p, "allowdac", 8)) | ||
171 | forbid_dac = 0; | ||
172 | if (!strncmp(p, "nodac", 5)) | ||
173 | forbid_dac = -1; | ||
174 | if (!strncmp(p, "usedac", 6)) { | ||
175 | forbid_dac = -1; | ||
176 | return 1; | ||
177 | } | ||
178 | #ifdef CONFIG_SWIOTLB | ||
179 | if (!strncmp(p, "soft", 4)) | ||
180 | swiotlb = 1; | ||
181 | #endif | ||
182 | |||
183 | #ifdef CONFIG_GART_IOMMU | ||
184 | gart_parse_options(p); | ||
185 | #endif | ||
186 | |||
187 | #ifdef CONFIG_CALGARY_IOMMU | ||
188 | if (!strncmp(p, "calgary", 7)) | ||
189 | use_calgary = 1; | ||
190 | #endif /* CONFIG_CALGARY_IOMMU */ | ||
191 | |||
192 | p += strcspn(p, ","); | ||
193 | if (*p == ',') | ||
194 | ++p; | ||
195 | } | ||
196 | return 0; | ||
197 | } | ||
198 | early_param("iommu", iommu_setup); | ||
199 | |||
200 | #ifdef CONFIG_X86_32 | ||
201 | int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
202 | dma_addr_t device_addr, size_t size, int flags) | ||
203 | { | ||
204 | void __iomem *mem_base = NULL; | ||
205 | int pages = size >> PAGE_SHIFT; | ||
206 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
207 | |||
208 | if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) | ||
209 | goto out; | ||
210 | if (!size) | ||
211 | goto out; | ||
212 | if (dev->dma_mem) | ||
213 | goto out; | ||
214 | |||
215 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
216 | |||
217 | mem_base = ioremap(bus_addr, size); | ||
218 | if (!mem_base) | ||
219 | goto out; | ||
220 | |||
221 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | ||
222 | if (!dev->dma_mem) | ||
223 | goto out; | ||
224 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
225 | if (!dev->dma_mem->bitmap) | ||
226 | goto free1_out; | ||
227 | |||
228 | dev->dma_mem->virt_base = mem_base; | ||
229 | dev->dma_mem->device_base = device_addr; | ||
230 | dev->dma_mem->size = pages; | ||
231 | dev->dma_mem->flags = flags; | ||
232 | |||
233 | if (flags & DMA_MEMORY_MAP) | ||
234 | return DMA_MEMORY_MAP; | ||
235 | |||
236 | return DMA_MEMORY_IO; | ||
237 | |||
238 | free1_out: | ||
239 | kfree(dev->dma_mem); | ||
240 | out: | ||
241 | if (mem_base) | ||
242 | iounmap(mem_base); | ||
243 | return 0; | ||
244 | } | ||
245 | EXPORT_SYMBOL(dma_declare_coherent_memory); | ||
246 | |||
247 | void dma_release_declared_memory(struct device *dev) | ||
248 | { | ||
249 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
250 | |||
251 | if (!mem) | ||
252 | return; | ||
253 | dev->dma_mem = NULL; | ||
254 | iounmap(mem->virt_base); | ||
255 | kfree(mem->bitmap); | ||
256 | kfree(mem); | ||
257 | } | ||
258 | EXPORT_SYMBOL(dma_release_declared_memory); | ||
259 | |||
260 | void *dma_mark_declared_memory_occupied(struct device *dev, | ||
261 | dma_addr_t device_addr, size_t size) | ||
262 | { | ||
263 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
264 | int pos, err; | ||
265 | int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1); | ||
266 | |||
267 | pages >>= PAGE_SHIFT; | ||
268 | |||
269 | if (!mem) | ||
270 | return ERR_PTR(-EINVAL); | ||
271 | |||
272 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | ||
273 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); | ||
274 | if (err != 0) | ||
275 | return ERR_PTR(err); | ||
276 | return mem->virt_base + (pos << PAGE_SHIFT); | ||
277 | } | ||
278 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | ||
279 | |||
280 | static int dma_alloc_from_coherent_mem(struct device *dev, ssize_t size, | ||
281 | dma_addr_t *dma_handle, void **ret) | ||
282 | { | ||
283 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
284 | int order = get_order(size); | ||
285 | |||
286 | if (mem) { | ||
287 | int page = bitmap_find_free_region(mem->bitmap, mem->size, | ||
288 | order); | ||
289 | if (page >= 0) { | ||
290 | *dma_handle = mem->device_base + (page << PAGE_SHIFT); | ||
291 | *ret = mem->virt_base + (page << PAGE_SHIFT); | ||
292 | memset(*ret, 0, size); | ||
293 | } | ||
294 | if (mem->flags & DMA_MEMORY_EXCLUSIVE) | ||
295 | *ret = NULL; | ||
296 | } | ||
297 | return (mem != NULL); | ||
298 | } | ||
299 | |||
300 | static int dma_release_coherent(struct device *dev, int order, void *vaddr) | ||
301 | { | ||
302 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
303 | |||
304 | if (mem && vaddr >= mem->virt_base && vaddr < | ||
305 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { | ||
306 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; | ||
307 | |||
308 | bitmap_release_region(mem->bitmap, page, order); | ||
309 | return 1; | ||
310 | } | ||
311 | return 0; | ||
312 | } | ||
313 | #else | ||
314 | #define dma_alloc_from_coherent_mem(dev, size, handle, ret) (0) | ||
315 | #define dma_release_coherent(dev, order, vaddr) (0) | ||
316 | #endif /* CONFIG_X86_32 */ | ||
317 | |||
318 | int dma_supported(struct device *dev, u64 mask) | ||
319 | { | ||
320 | #ifdef CONFIG_PCI | ||
321 | if (mask > 0xffffffff && forbid_dac > 0) { | ||
322 | printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", | ||
323 | dev->bus_id); | ||
324 | return 0; | ||
325 | } | ||
326 | #endif | ||
327 | |||
328 | if (dma_ops->dma_supported) | ||
329 | return dma_ops->dma_supported(dev, mask); | ||
330 | |||
331 | /* Copied from i386. Doesn't make much sense, because it will | ||
332 | only work for pci_alloc_coherent. | ||
333 | The caller just has to use GFP_DMA in this case. */ | ||
334 | if (mask < DMA_24BIT_MASK) | ||
335 | return 0; | ||
336 | |||
337 | /* Tell the device to use SAC when IOMMU force is on. This | ||
338 | allows the driver to use cheaper accesses in some cases. | ||
339 | |||
340 | Problem with this is that if we overflow the IOMMU area and | ||
341 | return DAC as fallback address the device may not handle it | ||
342 | correctly. | ||
343 | |||
344 | As a special case some controllers have a 39bit address | ||
345 | mode that is as efficient as 32bit (aic79xx). Don't force | ||
346 | SAC for these. Assume all masks <= 40 bits are of this | ||
347 | type. Normally this doesn't make any difference, but gives | ||
348 | more gentle handling of IOMMU overflow. */ | ||
349 | if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { | ||
350 | printk(KERN_INFO "%s: Force SAC with mask %Lx\n", | ||
351 | dev->bus_id, mask); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | return 1; | ||
356 | } | ||
357 | EXPORT_SYMBOL(dma_supported); | ||
358 | |||
48 | /* Allocate DMA memory on node near device */ | 359 | /* Allocate DMA memory on node near device */ |
49 | noinline static void * | 360 | noinline struct page * |
50 | dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order) | 361 | dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order) |
51 | { | 362 | { |
52 | struct page *page; | ||
53 | int node; | 363 | int node; |
54 | 364 | ||
55 | node = dev_to_node(dev); | 365 | node = dev_to_node(dev); |
56 | 366 | ||
57 | page = alloc_pages_node(node, gfp, order); | 367 | return alloc_pages_node(node, gfp, order); |
58 | return page ? page_address(page) : NULL; | ||
59 | } | 368 | } |
60 | 369 | ||
61 | /* | 370 | /* |
@@ -65,9 +374,16 @@ void * | |||
65 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | 374 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, |
66 | gfp_t gfp) | 375 | gfp_t gfp) |
67 | { | 376 | { |
68 | void *memory; | 377 | void *memory = NULL; |
378 | struct page *page; | ||
69 | unsigned long dma_mask = 0; | 379 | unsigned long dma_mask = 0; |
70 | u64 bus; | 380 | dma_addr_t bus; |
381 | |||
382 | /* ignore region specifiers */ | ||
383 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); | ||
384 | |||
385 | if (dma_alloc_from_coherent_mem(dev, size, dma_handle, &memory)) | ||
386 | return memory; | ||
71 | 387 | ||
72 | if (!dev) | 388 | if (!dev) |
73 | dev = &fallback_dev; | 389 | dev = &fallback_dev; |
@@ -82,26 +398,25 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
82 | /* Don't invoke OOM killer */ | 398 | /* Don't invoke OOM killer */ |
83 | gfp |= __GFP_NORETRY; | 399 | gfp |= __GFP_NORETRY; |
84 | 400 | ||
85 | /* Kludge to make it bug-to-bug compatible with i386. i386 | 401 | #ifdef CONFIG_X86_64 |
86 | uses the normal dma_mask for alloc_coherent. */ | ||
87 | dma_mask &= *dev->dma_mask; | ||
88 | |||
89 | /* Why <=? Even when the mask is smaller than 4GB it is often | 402 | /* Why <=? Even when the mask is smaller than 4GB it is often |
90 | larger than 16MB and in this case we have a chance of | 403 | larger than 16MB and in this case we have a chance of |
91 | finding fitting memory in the next higher zone first. If | 404 | finding fitting memory in the next higher zone first. If |
92 | not retry with true GFP_DMA. -AK */ | 405 | not retry with true GFP_DMA. -AK */ |
93 | if (dma_mask <= DMA_32BIT_MASK) | 406 | if (dma_mask <= DMA_32BIT_MASK) |
94 | gfp |= GFP_DMA32; | 407 | gfp |= GFP_DMA32; |
408 | #endif | ||
95 | 409 | ||
96 | again: | 410 | again: |
97 | memory = dma_alloc_pages(dev, gfp, get_order(size)); | 411 | page = dma_alloc_pages(dev, gfp, get_order(size)); |
98 | if (memory == NULL) | 412 | if (page == NULL) |
99 | return NULL; | 413 | return NULL; |
100 | 414 | ||
101 | { | 415 | { |
102 | int high, mmu; | 416 | int high, mmu; |
103 | bus = virt_to_bus(memory); | 417 | bus = page_to_phys(page); |
104 | high = (bus + size) >= dma_mask; | 418 | memory = page_address(page); |
419 | high = (bus + size) >= dma_mask; | ||
105 | mmu = high; | 420 | mmu = high; |
106 | if (force_iommu && !(gfp & GFP_DMA)) | 421 | if (force_iommu && !(gfp & GFP_DMA)) |
107 | mmu = 1; | 422 | mmu = 1; |
@@ -127,7 +442,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
127 | 442 | ||
128 | memset(memory, 0, size); | 443 | memset(memory, 0, size); |
129 | if (!mmu) { | 444 | if (!mmu) { |
130 | *dma_handle = virt_to_bus(memory); | 445 | *dma_handle = bus; |
131 | return memory; | 446 | return memory; |
132 | } | 447 | } |
133 | } | 448 | } |
@@ -139,7 +454,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
139 | } | 454 | } |
140 | 455 | ||
141 | if (dma_ops->map_simple) { | 456 | if (dma_ops->map_simple) { |
142 | *dma_handle = dma_ops->map_simple(dev, memory, | 457 | *dma_handle = dma_ops->map_simple(dev, virt_to_phys(memory), |
143 | size, | 458 | size, |
144 | PCI_DMA_BIDIRECTIONAL); | 459 | PCI_DMA_BIDIRECTIONAL); |
145 | if (*dma_handle != bad_dma_address) | 460 | if (*dma_handle != bad_dma_address) |
@@ -147,7 +462,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
147 | } | 462 | } |
148 | 463 | ||
149 | if (panic_on_overflow) | 464 | if (panic_on_overflow) |
150 | panic("dma_alloc_coherent: IOMMU overflow by %lu bytes\n",size); | 465 | panic("dma_alloc_coherent: IOMMU overflow by %lu bytes\n", |
466 | (unsigned long)size); | ||
151 | free_pages((unsigned long)memory, get_order(size)); | 467 | free_pages((unsigned long)memory, get_order(size)); |
152 | return NULL; | 468 | return NULL; |
153 | } | 469 | } |
@@ -160,153 +476,16 @@ EXPORT_SYMBOL(dma_alloc_coherent); | |||
160 | void dma_free_coherent(struct device *dev, size_t size, | 476 | void dma_free_coherent(struct device *dev, size_t size, |
161 | void *vaddr, dma_addr_t bus) | 477 | void *vaddr, dma_addr_t bus) |
162 | { | 478 | { |
479 | int order = get_order(size); | ||
163 | WARN_ON(irqs_disabled()); /* for portability */ | 480 | WARN_ON(irqs_disabled()); /* for portability */ |
481 | if (dma_release_coherent(dev, order, vaddr)) | ||
482 | return; | ||
164 | if (dma_ops->unmap_single) | 483 | if (dma_ops->unmap_single) |
165 | dma_ops->unmap_single(dev, bus, size, 0); | 484 | dma_ops->unmap_single(dev, bus, size, 0); |
166 | free_pages((unsigned long)vaddr, get_order(size)); | 485 | free_pages((unsigned long)vaddr, order); |
167 | } | 486 | } |
168 | EXPORT_SYMBOL(dma_free_coherent); | 487 | EXPORT_SYMBOL(dma_free_coherent); |
169 | 488 | ||
170 | static int forbid_dac __read_mostly; | ||
171 | |||
172 | int dma_supported(struct device *dev, u64 mask) | ||
173 | { | ||
174 | #ifdef CONFIG_PCI | ||
175 | if (mask > 0xffffffff && forbid_dac > 0) { | ||
176 | |||
177 | |||
178 | |||
179 | printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", dev->bus_id); | ||
180 | return 0; | ||
181 | } | ||
182 | #endif | ||
183 | |||
184 | if (dma_ops->dma_supported) | ||
185 | return dma_ops->dma_supported(dev, mask); | ||
186 | |||
187 | /* Copied from i386. Doesn't make much sense, because it will | ||
188 | only work for pci_alloc_coherent. | ||
189 | The caller just has to use GFP_DMA in this case. */ | ||
190 | if (mask < DMA_24BIT_MASK) | ||
191 | return 0; | ||
192 | |||
193 | /* Tell the device to use SAC when IOMMU force is on. This | ||
194 | allows the driver to use cheaper accesses in some cases. | ||
195 | |||
196 | Problem with this is that if we overflow the IOMMU area and | ||
197 | return DAC as fallback address the device may not handle it | ||
198 | correctly. | ||
199 | |||
200 | As a special case some controllers have a 39bit address | ||
201 | mode that is as efficient as 32bit (aic79xx). Don't force | ||
202 | SAC for these. Assume all masks <= 40 bits are of this | ||
203 | type. Normally this doesn't make any difference, but gives | ||
204 | more gentle handling of IOMMU overflow. */ | ||
205 | if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) { | ||
206 | printk(KERN_INFO "%s: Force SAC with mask %Lx\n", dev->bus_id,mask); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | return 1; | ||
211 | } | ||
212 | EXPORT_SYMBOL(dma_supported); | ||
213 | |||
214 | int dma_set_mask(struct device *dev, u64 mask) | ||
215 | { | ||
216 | if (!dev->dma_mask || !dma_supported(dev, mask)) | ||
217 | return -EIO; | ||
218 | *dev->dma_mask = mask; | ||
219 | return 0; | ||
220 | } | ||
221 | EXPORT_SYMBOL(dma_set_mask); | ||
222 | |||
223 | /* | ||
224 | * See <Documentation/x86_64/boot-options.txt> for the iommu kernel parameter | ||
225 | * documentation. | ||
226 | */ | ||
227 | static __init int iommu_setup(char *p) | ||
228 | { | ||
229 | iommu_merge = 1; | ||
230 | |||
231 | if (!p) | ||
232 | return -EINVAL; | ||
233 | |||
234 | while (*p) { | ||
235 | if (!strncmp(p, "off", 3)) | ||
236 | no_iommu = 1; | ||
237 | /* gart_parse_options has more force support */ | ||
238 | if (!strncmp(p, "force", 5)) | ||
239 | force_iommu = 1; | ||
240 | if (!strncmp(p, "noforce", 7)) { | ||
241 | iommu_merge = 0; | ||
242 | force_iommu = 0; | ||
243 | } | ||
244 | |||
245 | if (!strncmp(p, "biomerge", 8)) { | ||
246 | iommu_bio_merge = 4096; | ||
247 | iommu_merge = 1; | ||
248 | force_iommu = 1; | ||
249 | } | ||
250 | if (!strncmp(p, "panic", 5)) | ||
251 | panic_on_overflow = 1; | ||
252 | if (!strncmp(p, "nopanic", 7)) | ||
253 | panic_on_overflow = 0; | ||
254 | if (!strncmp(p, "merge", 5)) { | ||
255 | iommu_merge = 1; | ||
256 | force_iommu = 1; | ||
257 | } | ||
258 | if (!strncmp(p, "nomerge", 7)) | ||
259 | iommu_merge = 0; | ||
260 | if (!strncmp(p, "forcesac", 8)) | ||
261 | iommu_sac_force = 1; | ||
262 | if (!strncmp(p, "allowdac", 8)) | ||
263 | forbid_dac = 0; | ||
264 | if (!strncmp(p, "nodac", 5)) | ||
265 | forbid_dac = -1; | ||
266 | |||
267 | #ifdef CONFIG_SWIOTLB | ||
268 | if (!strncmp(p, "soft", 4)) | ||
269 | swiotlb = 1; | ||
270 | #endif | ||
271 | |||
272 | #ifdef CONFIG_GART_IOMMU | ||
273 | gart_parse_options(p); | ||
274 | #endif | ||
275 | |||
276 | #ifdef CONFIG_CALGARY_IOMMU | ||
277 | if (!strncmp(p, "calgary", 7)) | ||
278 | use_calgary = 1; | ||
279 | #endif /* CONFIG_CALGARY_IOMMU */ | ||
280 | |||
281 | p += strcspn(p, ","); | ||
282 | if (*p == ',') | ||
283 | ++p; | ||
284 | } | ||
285 | return 0; | ||
286 | } | ||
287 | early_param("iommu", iommu_setup); | ||
288 | |||
289 | void __init pci_iommu_alloc(void) | ||
290 | { | ||
291 | /* | ||
292 | * The order of these functions is important for | ||
293 | * fall-back/fail-over reasons | ||
294 | */ | ||
295 | #ifdef CONFIG_GART_IOMMU | ||
296 | gart_iommu_hole_init(); | ||
297 | #endif | ||
298 | |||
299 | #ifdef CONFIG_CALGARY_IOMMU | ||
300 | detect_calgary(); | ||
301 | #endif | ||
302 | |||
303 | detect_intel_iommu(); | ||
304 | |||
305 | #ifdef CONFIG_SWIOTLB | ||
306 | pci_swiotlb_init(); | ||
307 | #endif | ||
308 | } | ||
309 | |||
310 | static int __init pci_iommu_init(void) | 489 | static int __init pci_iommu_init(void) |
311 | { | 490 | { |
312 | #ifdef CONFIG_CALGARY_IOMMU | 491 | #ifdef CONFIG_CALGARY_IOMMU |
@@ -327,6 +506,8 @@ void pci_iommu_shutdown(void) | |||
327 | { | 506 | { |
328 | gart_iommu_shutdown(); | 507 | gart_iommu_shutdown(); |
329 | } | 508 | } |
509 | /* Must execute after PCI subsystem */ | ||
510 | fs_initcall(pci_iommu_init); | ||
330 | 511 | ||
331 | #ifdef CONFIG_PCI | 512 | #ifdef CONFIG_PCI |
332 | /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ | 513 | /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ |
@@ -334,11 +515,10 @@ void pci_iommu_shutdown(void) | |||
334 | static __devinit void via_no_dac(struct pci_dev *dev) | 515 | static __devinit void via_no_dac(struct pci_dev *dev) |
335 | { | 516 | { |
336 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { | 517 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { |
337 | printk(KERN_INFO "PCI: VIA PCI bridge detected. Disabling DAC.\n"); | 518 | printk(KERN_INFO "PCI: VIA PCI bridge detected." |
519 | "Disabling DAC.\n"); | ||
338 | forbid_dac = 1; | 520 | forbid_dac = 1; |
339 | } | 521 | } |
340 | } | 522 | } |
341 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); | 523 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); |
342 | #endif | 524 | #endif |
343 | /* Must execute after PCI subsystem */ | ||
344 | fs_initcall(pci_iommu_init); | ||
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c deleted file mode 100644 index 51330321a5d3..000000000000 --- a/arch/x86/kernel/pci-dma_32.c +++ /dev/null | |||
@@ -1,177 +0,0 @@ | |||
1 | /* | ||
2 | * Dynamic DMA mapping support. | ||
3 | * | ||
4 | * On i386 there is no hardware dynamic DMA address translation, | ||
5 | * so consistent alloc/free are merely page allocation/freeing. | ||
6 | * The rest of the dynamic DMA mapping interface is implemented | ||
7 | * in asm/pci.h. | ||
8 | */ | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <asm/io.h> | ||
16 | |||
17 | struct dma_coherent_mem { | ||
18 | void *virt_base; | ||
19 | u32 device_base; | ||
20 | int size; | ||
21 | int flags; | ||
22 | unsigned long *bitmap; | ||
23 | }; | ||
24 | |||
25 | void *dma_alloc_coherent(struct device *dev, size_t size, | ||
26 | dma_addr_t *dma_handle, gfp_t gfp) | ||
27 | { | ||
28 | void *ret; | ||
29 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
30 | int order = get_order(size); | ||
31 | /* ignore region specifiers */ | ||
32 | gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); | ||
33 | |||
34 | if (mem) { | ||
35 | int page = bitmap_find_free_region(mem->bitmap, mem->size, | ||
36 | order); | ||
37 | if (page >= 0) { | ||
38 | *dma_handle = mem->device_base + (page << PAGE_SHIFT); | ||
39 | ret = mem->virt_base + (page << PAGE_SHIFT); | ||
40 | memset(ret, 0, size); | ||
41 | return ret; | ||
42 | } | ||
43 | if (mem->flags & DMA_MEMORY_EXCLUSIVE) | ||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) | ||
48 | gfp |= GFP_DMA; | ||
49 | |||
50 | ret = (void *)__get_free_pages(gfp, order); | ||
51 | |||
52 | if (ret != NULL) { | ||
53 | memset(ret, 0, size); | ||
54 | *dma_handle = virt_to_phys(ret); | ||
55 | } | ||
56 | return ret; | ||
57 | } | ||
58 | EXPORT_SYMBOL(dma_alloc_coherent); | ||
59 | |||
60 | void dma_free_coherent(struct device *dev, size_t size, | ||
61 | void *vaddr, dma_addr_t dma_handle) | ||
62 | { | ||
63 | struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL; | ||
64 | int order = get_order(size); | ||
65 | |||
66 | WARN_ON(irqs_disabled()); /* for portability */ | ||
67 | if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) { | ||
68 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; | ||
69 | |||
70 | bitmap_release_region(mem->bitmap, page, order); | ||
71 | } else | ||
72 | free_pages((unsigned long)vaddr, order); | ||
73 | } | ||
74 | EXPORT_SYMBOL(dma_free_coherent); | ||
75 | |||
76 | int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
77 | dma_addr_t device_addr, size_t size, int flags) | ||
78 | { | ||
79 | void __iomem *mem_base = NULL; | ||
80 | int pages = size >> PAGE_SHIFT; | ||
81 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | ||
82 | |||
83 | if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) | ||
84 | goto out; | ||
85 | if (!size) | ||
86 | goto out; | ||
87 | if (dev->dma_mem) | ||
88 | goto out; | ||
89 | |||
90 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
91 | |||
92 | mem_base = ioremap(bus_addr, size); | ||
93 | if (!mem_base) | ||
94 | goto out; | ||
95 | |||
96 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | ||
97 | if (!dev->dma_mem) | ||
98 | goto out; | ||
99 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | ||
100 | if (!dev->dma_mem->bitmap) | ||
101 | goto free1_out; | ||
102 | |||
103 | dev->dma_mem->virt_base = mem_base; | ||
104 | dev->dma_mem->device_base = device_addr; | ||
105 | dev->dma_mem->size = pages; | ||
106 | dev->dma_mem->flags = flags; | ||
107 | |||
108 | if (flags & DMA_MEMORY_MAP) | ||
109 | return DMA_MEMORY_MAP; | ||
110 | |||
111 | return DMA_MEMORY_IO; | ||
112 | |||
113 | free1_out: | ||
114 | kfree(dev->dma_mem); | ||
115 | out: | ||
116 | if (mem_base) | ||
117 | iounmap(mem_base); | ||
118 | return 0; | ||
119 | } | ||
120 | EXPORT_SYMBOL(dma_declare_coherent_memory); | ||
121 | |||
122 | void dma_release_declared_memory(struct device *dev) | ||
123 | { | ||
124 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
125 | |||
126 | if(!mem) | ||
127 | return; | ||
128 | dev->dma_mem = NULL; | ||
129 | iounmap(mem->virt_base); | ||
130 | kfree(mem->bitmap); | ||
131 | kfree(mem); | ||
132 | } | ||
133 | EXPORT_SYMBOL(dma_release_declared_memory); | ||
134 | |||
135 | void *dma_mark_declared_memory_occupied(struct device *dev, | ||
136 | dma_addr_t device_addr, size_t size) | ||
137 | { | ||
138 | struct dma_coherent_mem *mem = dev->dma_mem; | ||
139 | int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
140 | int pos, err; | ||
141 | |||
142 | if (!mem) | ||
143 | return ERR_PTR(-EINVAL); | ||
144 | |||
145 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | ||
146 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages)); | ||
147 | if (err != 0) | ||
148 | return ERR_PTR(err); | ||
149 | return mem->virt_base + (pos << PAGE_SHIFT); | ||
150 | } | ||
151 | EXPORT_SYMBOL(dma_mark_declared_memory_occupied); | ||
152 | |||
153 | #ifdef CONFIG_PCI | ||
154 | /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ | ||
155 | |||
156 | int forbid_dac; | ||
157 | EXPORT_SYMBOL(forbid_dac); | ||
158 | |||
159 | static __devinit void via_no_dac(struct pci_dev *dev) | ||
160 | { | ||
161 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { | ||
162 | printk(KERN_INFO "PCI: VIA PCI bridge detected. Disabling DAC.\n"); | ||
163 | forbid_dac = 1; | ||
164 | } | ||
165 | } | ||
166 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); | ||
167 | |||
168 | static int check_iommu(char *s) | ||
169 | { | ||
170 | if (!strcmp(s, "usedac")) { | ||
171 | forbid_dac = -1; | ||
172 | return 1; | ||
173 | } | ||
174 | return 0; | ||
175 | } | ||
176 | __setup("iommu=", check_iommu); | ||
177 | #endif | ||
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 700e4647dd30..c07455d1695f 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -264,9 +264,9 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | |||
264 | } | 264 | } |
265 | 265 | ||
266 | static dma_addr_t | 266 | static dma_addr_t |
267 | gart_map_simple(struct device *dev, char *buf, size_t size, int dir) | 267 | gart_map_simple(struct device *dev, phys_addr_t paddr, size_t size, int dir) |
268 | { | 268 | { |
269 | dma_addr_t map = dma_map_area(dev, virt_to_bus(buf), size, dir); | 269 | dma_addr_t map = dma_map_area(dev, paddr, size, dir); |
270 | 270 | ||
271 | flush_gart(); | 271 | flush_gart(); |
272 | 272 | ||
@@ -275,18 +275,17 @@ gart_map_simple(struct device *dev, char *buf, size_t size, int dir) | |||
275 | 275 | ||
276 | /* Map a single area into the IOMMU */ | 276 | /* Map a single area into the IOMMU */ |
277 | static dma_addr_t | 277 | static dma_addr_t |
278 | gart_map_single(struct device *dev, void *addr, size_t size, int dir) | 278 | gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir) |
279 | { | 279 | { |
280 | unsigned long phys_mem, bus; | 280 | unsigned long bus; |
281 | 281 | ||
282 | if (!dev) | 282 | if (!dev) |
283 | dev = &fallback_dev; | 283 | dev = &fallback_dev; |
284 | 284 | ||
285 | phys_mem = virt_to_phys(addr); | 285 | if (!need_iommu(dev, paddr, size)) |
286 | if (!need_iommu(dev, phys_mem, size)) | 286 | return paddr; |
287 | return phys_mem; | ||
288 | 287 | ||
289 | bus = gart_map_simple(dev, addr, size, dir); | 288 | bus = gart_map_simple(dev, paddr, size, dir); |
290 | 289 | ||
291 | return bus; | 290 | return bus; |
292 | } | 291 | } |
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu.c index ab08e1832228..aec43d56f49c 100644 --- a/arch/x86/kernel/pci-nommu_64.c +++ b/arch/x86/kernel/pci-nommu.c | |||
@@ -14,7 +14,7 @@ | |||
14 | static int | 14 | static int |
15 | check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) | 15 | check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) |
16 | { | 16 | { |
17 | if (hwdev && bus + size > *hwdev->dma_mask) { | 17 | if (hwdev && bus + size > *hwdev->dma_mask) { |
18 | if (*hwdev->dma_mask >= DMA_32BIT_MASK) | 18 | if (*hwdev->dma_mask >= DMA_32BIT_MASK) |
19 | printk(KERN_ERR | 19 | printk(KERN_ERR |
20 | "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", | 20 | "nommu_%s: overflow %Lx+%zu of device mask %Lx\n", |
@@ -26,19 +26,17 @@ check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size) | |||
26 | } | 26 | } |
27 | 27 | ||
28 | static dma_addr_t | 28 | static dma_addr_t |
29 | nommu_map_single(struct device *hwdev, void *ptr, size_t size, | 29 | nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size, |
30 | int direction) | 30 | int direction) |
31 | { | 31 | { |
32 | dma_addr_t bus = virt_to_bus(ptr); | 32 | dma_addr_t bus = paddr; |
33 | WARN_ON(size == 0); | ||
33 | if (!check_addr("map_single", hwdev, bus, size)) | 34 | if (!check_addr("map_single", hwdev, bus, size)) |
34 | return bad_dma_address; | 35 | return bad_dma_address; |
36 | flush_write_buffers(); | ||
35 | return bus; | 37 | return bus; |
36 | } | 38 | } |
37 | 39 | ||
38 | static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size, | ||
39 | int direction) | ||
40 | { | ||
41 | } | ||
42 | 40 | ||
43 | /* Map a set of buffers described by scatterlist in streaming | 41 | /* Map a set of buffers described by scatterlist in streaming |
44 | * mode for DMA. This is the scatter-gather version of the | 42 | * mode for DMA. This is the scatter-gather version of the |
@@ -61,30 +59,34 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, | |||
61 | struct scatterlist *s; | 59 | struct scatterlist *s; |
62 | int i; | 60 | int i; |
63 | 61 | ||
62 | WARN_ON(nents == 0 || sg[0].length == 0); | ||
63 | |||
64 | for_each_sg(sg, s, nents, i) { | 64 | for_each_sg(sg, s, nents, i) { |
65 | BUG_ON(!sg_page(s)); | 65 | BUG_ON(!sg_page(s)); |
66 | s->dma_address = virt_to_bus(sg_virt(s)); | 66 | s->dma_address = sg_phys(s); |
67 | if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) | 67 | if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) |
68 | return 0; | 68 | return 0; |
69 | s->dma_length = s->length; | 69 | s->dma_length = s->length; |
70 | } | 70 | } |
71 | flush_write_buffers(); | ||
71 | return nents; | 72 | return nents; |
72 | } | 73 | } |
73 | 74 | ||
74 | /* Unmap a set of streaming mode DMA translations. | 75 | /* Make sure we keep the same behaviour */ |
75 | * Again, cpu read rules concerning calls here are the same as for | 76 | static int nommu_mapping_error(dma_addr_t dma_addr) |
76 | * pci_unmap_single() above. | ||
77 | */ | ||
78 | static void nommu_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
79 | int nents, int dir) | ||
80 | { | 77 | { |
78 | #ifdef CONFIG_X86_32 | ||
79 | return 0; | ||
80 | #else | ||
81 | return (dma_addr == bad_dma_address); | ||
82 | #endif | ||
81 | } | 83 | } |
82 | 84 | ||
85 | |||
83 | const struct dma_mapping_ops nommu_dma_ops = { | 86 | const struct dma_mapping_ops nommu_dma_ops = { |
84 | .map_single = nommu_map_single, | 87 | .map_single = nommu_map_single, |
85 | .unmap_single = nommu_unmap_single, | ||
86 | .map_sg = nommu_map_sg, | 88 | .map_sg = nommu_map_sg, |
87 | .unmap_sg = nommu_unmap_sg, | 89 | .mapping_error = nommu_mapping_error, |
88 | .is_phys = 1, | 90 | .is_phys = 1, |
89 | }; | 91 | }; |
90 | 92 | ||
diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c index 82a0a674a003..490da7f4b8d0 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c | |||
@@ -11,11 +11,18 @@ | |||
11 | 11 | ||
12 | int swiotlb __read_mostly; | 12 | int swiotlb __read_mostly; |
13 | 13 | ||
14 | static dma_addr_t | ||
15 | swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, | ||
16 | int direction) | ||
17 | { | ||
18 | return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); | ||
19 | } | ||
20 | |||
14 | const struct dma_mapping_ops swiotlb_dma_ops = { | 21 | const struct dma_mapping_ops swiotlb_dma_ops = { |
15 | .mapping_error = swiotlb_dma_mapping_error, | 22 | .mapping_error = swiotlb_dma_mapping_error, |
16 | .alloc_coherent = swiotlb_alloc_coherent, | 23 | .alloc_coherent = swiotlb_alloc_coherent, |
17 | .free_coherent = swiotlb_free_coherent, | 24 | .free_coherent = swiotlb_free_coherent, |
18 | .map_single = swiotlb_map_single, | 25 | .map_single = swiotlb_map_single_phys, |
19 | .unmap_single = swiotlb_unmap_single, | 26 | .unmap_single = swiotlb_unmap_single, |
20 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, | 27 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, |
21 | .sync_single_for_device = swiotlb_sync_single_for_device, | 28 | .sync_single_for_device = swiotlb_sync_single_for_device, |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c new file mode 100644 index 000000000000..3004d716539d --- /dev/null +++ b/arch/x86/kernel/process.c | |||
@@ -0,0 +1,44 @@ | |||
1 | #include <linux/errno.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/mm.h> | ||
4 | #include <linux/smp.h> | ||
5 | #include <linux/slab.h> | ||
6 | #include <linux/sched.h> | ||
7 | |||
8 | struct kmem_cache *task_xstate_cachep; | ||
9 | |||
10 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | ||
11 | { | ||
12 | *dst = *src; | ||
13 | if (src->thread.xstate) { | ||
14 | dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep, | ||
15 | GFP_KERNEL); | ||
16 | if (!dst->thread.xstate) | ||
17 | return -ENOMEM; | ||
18 | WARN_ON((unsigned long)dst->thread.xstate & 15); | ||
19 | memcpy(dst->thread.xstate, src->thread.xstate, xstate_size); | ||
20 | } | ||
21 | return 0; | ||
22 | } | ||
23 | |||
24 | void free_thread_xstate(struct task_struct *tsk) | ||
25 | { | ||
26 | if (tsk->thread.xstate) { | ||
27 | kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); | ||
28 | tsk->thread.xstate = NULL; | ||
29 | } | ||
30 | } | ||
31 | |||
32 | void free_thread_info(struct thread_info *ti) | ||
33 | { | ||
34 | free_thread_xstate(ti->task); | ||
35 | free_pages((unsigned long)ti, get_order(THREAD_SIZE)); | ||
36 | } | ||
37 | |||
38 | void arch_task_cache_init(void) | ||
39 | { | ||
40 | task_xstate_cachep = | ||
41 | kmem_cache_create("task_xstate", xstate_size, | ||
42 | __alignof__(union thread_xstate), | ||
43 | SLAB_PANIC, NULL); | ||
44 | } | ||
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 3903a8f2eb97..7adad088e373 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/personality.h> | 36 | #include <linux/personality.h> |
37 | #include <linux/tick.h> | 37 | #include <linux/tick.h> |
38 | #include <linux/percpu.h> | 38 | #include <linux/percpu.h> |
39 | #include <linux/prctl.h> | ||
39 | 40 | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | #include <asm/pgtable.h> | 42 | #include <asm/pgtable.h> |
@@ -45,7 +46,6 @@ | |||
45 | #include <asm/processor.h> | 46 | #include <asm/processor.h> |
46 | #include <asm/i387.h> | 47 | #include <asm/i387.h> |
47 | #include <asm/desc.h> | 48 | #include <asm/desc.h> |
48 | #include <asm/vm86.h> | ||
49 | #ifdef CONFIG_MATH_EMULATION | 49 | #ifdef CONFIG_MATH_EMULATION |
50 | #include <asm/math_emu.h> | 50 | #include <asm/math_emu.h> |
51 | #endif | 51 | #endif |
@@ -521,14 +521,18 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | |||
521 | regs->cs = __USER_CS; | 521 | regs->cs = __USER_CS; |
522 | regs->ip = new_ip; | 522 | regs->ip = new_ip; |
523 | regs->sp = new_sp; | 523 | regs->sp = new_sp; |
524 | /* | ||
525 | * Free the old FP and other extended state | ||
526 | */ | ||
527 | free_thread_xstate(current); | ||
524 | } | 528 | } |
525 | EXPORT_SYMBOL_GPL(start_thread); | 529 | EXPORT_SYMBOL_GPL(start_thread); |
526 | 530 | ||
527 | #ifdef CONFIG_SECCOMP | ||
528 | static void hard_disable_TSC(void) | 531 | static void hard_disable_TSC(void) |
529 | { | 532 | { |
530 | write_cr4(read_cr4() | X86_CR4_TSD); | 533 | write_cr4(read_cr4() | X86_CR4_TSD); |
531 | } | 534 | } |
535 | |||
532 | void disable_TSC(void) | 536 | void disable_TSC(void) |
533 | { | 537 | { |
534 | preempt_disable(); | 538 | preempt_disable(); |
@@ -540,11 +544,47 @@ void disable_TSC(void) | |||
540 | hard_disable_TSC(); | 544 | hard_disable_TSC(); |
541 | preempt_enable(); | 545 | preempt_enable(); |
542 | } | 546 | } |
547 | |||
543 | static void hard_enable_TSC(void) | 548 | static void hard_enable_TSC(void) |
544 | { | 549 | { |
545 | write_cr4(read_cr4() & ~X86_CR4_TSD); | 550 | write_cr4(read_cr4() & ~X86_CR4_TSD); |
546 | } | 551 | } |
547 | #endif /* CONFIG_SECCOMP */ | 552 | |
553 | void enable_TSC(void) | ||
554 | { | ||
555 | preempt_disable(); | ||
556 | if (test_and_clear_thread_flag(TIF_NOTSC)) | ||
557 | /* | ||
558 | * Must flip the CPU state synchronously with | ||
559 | * TIF_NOTSC in the current running context. | ||
560 | */ | ||
561 | hard_enable_TSC(); | ||
562 | preempt_enable(); | ||
563 | } | ||
564 | |||
565 | int get_tsc_mode(unsigned long adr) | ||
566 | { | ||
567 | unsigned int val; | ||
568 | |||
569 | if (test_thread_flag(TIF_NOTSC)) | ||
570 | val = PR_TSC_SIGSEGV; | ||
571 | else | ||
572 | val = PR_TSC_ENABLE; | ||
573 | |||
574 | return put_user(val, (unsigned int __user *)adr); | ||
575 | } | ||
576 | |||
577 | int set_tsc_mode(unsigned int val) | ||
578 | { | ||
579 | if (val == PR_TSC_SIGSEGV) | ||
580 | disable_TSC(); | ||
581 | else if (val == PR_TSC_ENABLE) | ||
582 | enable_TSC(); | ||
583 | else | ||
584 | return -EINVAL; | ||
585 | |||
586 | return 0; | ||
587 | } | ||
548 | 588 | ||
549 | static noinline void | 589 | static noinline void |
550 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 590 | __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
@@ -578,7 +618,6 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
578 | set_debugreg(next->debugreg7, 7); | 618 | set_debugreg(next->debugreg7, 7); |
579 | } | 619 | } |
580 | 620 | ||
581 | #ifdef CONFIG_SECCOMP | ||
582 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ | 621 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ |
583 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { | 622 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { |
584 | /* prev and next are different */ | 623 | /* prev and next are different */ |
@@ -587,7 +626,6 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
587 | else | 626 | else |
588 | hard_enable_TSC(); | 627 | hard_enable_TSC(); |
589 | } | 628 | } |
590 | #endif | ||
591 | 629 | ||
592 | #ifdef X86_BTS | 630 | #ifdef X86_BTS |
593 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) | 631 | if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) |
@@ -669,7 +707,7 @@ struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct | |||
669 | 707 | ||
670 | /* we're going to use this soon, after a few expensive things */ | 708 | /* we're going to use this soon, after a few expensive things */ |
671 | if (next_p->fpu_counter > 5) | 709 | if (next_p->fpu_counter > 5) |
672 | prefetch(&next->i387.fxsave); | 710 | prefetch(next->xstate); |
673 | 711 | ||
674 | /* | 712 | /* |
675 | * Reload esp0. | 713 | * Reload esp0. |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e75ccc8a2b87..891af1a1b48a 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/kprobes.h> | 36 | #include <linux/kprobes.h> |
37 | #include <linux/kdebug.h> | 37 | #include <linux/kdebug.h> |
38 | #include <linux/tick.h> | 38 | #include <linux/tick.h> |
39 | #include <linux/prctl.h> | ||
39 | 40 | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | #include <asm/pgtable.h> | 42 | #include <asm/pgtable.h> |
@@ -532,9 +533,71 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) | |||
532 | regs->ss = __USER_DS; | 533 | regs->ss = __USER_DS; |
533 | regs->flags = 0x200; | 534 | regs->flags = 0x200; |
534 | set_fs(USER_DS); | 535 | set_fs(USER_DS); |
536 | /* | ||
537 | * Free the old FP and other extended state | ||
538 | */ | ||
539 | free_thread_xstate(current); | ||
535 | } | 540 | } |
536 | EXPORT_SYMBOL_GPL(start_thread); | 541 | EXPORT_SYMBOL_GPL(start_thread); |
537 | 542 | ||
543 | static void hard_disable_TSC(void) | ||
544 | { | ||
545 | write_cr4(read_cr4() | X86_CR4_TSD); | ||
546 | } | ||
547 | |||
548 | void disable_TSC(void) | ||
549 | { | ||
550 | preempt_disable(); | ||
551 | if (!test_and_set_thread_flag(TIF_NOTSC)) | ||
552 | /* | ||
553 | * Must flip the CPU state synchronously with | ||
554 | * TIF_NOTSC in the current running context. | ||
555 | */ | ||
556 | hard_disable_TSC(); | ||
557 | preempt_enable(); | ||
558 | } | ||
559 | |||
560 | static void hard_enable_TSC(void) | ||
561 | { | ||
562 | write_cr4(read_cr4() & ~X86_CR4_TSD); | ||
563 | } | ||
564 | |||
565 | void enable_TSC(void) | ||
566 | { | ||
567 | preempt_disable(); | ||
568 | if (test_and_clear_thread_flag(TIF_NOTSC)) | ||
569 | /* | ||
570 | * Must flip the CPU state synchronously with | ||
571 | * TIF_NOTSC in the current running context. | ||
572 | */ | ||
573 | hard_enable_TSC(); | ||
574 | preempt_enable(); | ||
575 | } | ||
576 | |||
577 | int get_tsc_mode(unsigned long adr) | ||
578 | { | ||
579 | unsigned int val; | ||
580 | |||
581 | if (test_thread_flag(TIF_NOTSC)) | ||
582 | val = PR_TSC_SIGSEGV; | ||
583 | else | ||
584 | val = PR_TSC_ENABLE; | ||
585 | |||
586 | return put_user(val, (unsigned int __user *)adr); | ||
587 | } | ||
588 | |||
589 | int set_tsc_mode(unsigned int val) | ||
590 | { | ||
591 | if (val == PR_TSC_SIGSEGV) | ||
592 | disable_TSC(); | ||
593 | else if (val == PR_TSC_ENABLE) | ||
594 | enable_TSC(); | ||
595 | else | ||
596 | return -EINVAL; | ||
597 | |||
598 | return 0; | ||
599 | } | ||
600 | |||
538 | /* | 601 | /* |
539 | * This special macro can be used to load a debugging register | 602 | * This special macro can be used to load a debugging register |
540 | */ | 603 | */ |
@@ -572,6 +635,15 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, | |||
572 | loaddebug(next, 7); | 635 | loaddebug(next, 7); |
573 | } | 636 | } |
574 | 637 | ||
638 | if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ | ||
639 | test_tsk_thread_flag(next_p, TIF_NOTSC)) { | ||
640 | /* prev and next are different */ | ||
641 | if (test_tsk_thread_flag(next_p, TIF_NOTSC)) | ||
642 | hard_disable_TSC(); | ||
643 | else | ||
644 | hard_enable_TSC(); | ||
645 | } | ||
646 | |||
575 | if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { | 647 | if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { |
576 | /* | 648 | /* |
577 | * Copy the relevant range of the IO bitmap. | 649 | * Copy the relevant range of the IO bitmap. |
@@ -614,7 +686,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
614 | 686 | ||
615 | /* we're going to use this soon, after a few expensive things */ | 687 | /* we're going to use this soon, after a few expensive things */ |
616 | if (next_p->fpu_counter>5) | 688 | if (next_p->fpu_counter>5) |
617 | prefetch(&next->i387.fxsave); | 689 | prefetch(next->xstate); |
618 | 690 | ||
619 | /* | 691 | /* |
620 | * Reload esp0, LDT and the page table pointer: | 692 | * Reload esp0, LDT and the page table pointer: |
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 9042fb0e36f5..aee0e8200777 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c | |||
@@ -74,8 +74,8 @@ int force_personality32 = 0; | |||
74 | Control non executable heap for 32bit processes. | 74 | Control non executable heap for 32bit processes. |
75 | To control the stack too use noexec=off | 75 | To control the stack too use noexec=off |
76 | 76 | ||
77 | on PROT_READ does not imply PROT_EXEC for 32bit processes | 77 | on PROT_READ does not imply PROT_EXEC for 32bit processes (default) |
78 | off PROT_READ implies PROT_EXEC (default) | 78 | off PROT_READ implies PROT_EXEC |
79 | */ | 79 | */ |
80 | static int __init nonx32_setup(char *str) | 80 | static int __init nonx32_setup(char *str) |
81 | { | 81 | { |
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 5b0bffb7fcc9..1c4799e68718 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -812,10 +812,10 @@ void __init setup_arch(char **cmdline_p) | |||
812 | efi_init(); | 812 | efi_init(); |
813 | 813 | ||
814 | /* update e820 for memory not covered by WB MTRRs */ | 814 | /* update e820 for memory not covered by WB MTRRs */ |
815 | find_max_pfn(); | 815 | propagate_e820_map(); |
816 | mtrr_bp_init(); | 816 | mtrr_bp_init(); |
817 | if (mtrr_trim_uncached_memory(max_pfn)) | 817 | if (mtrr_trim_uncached_memory(max_pfn)) |
818 | find_max_pfn(); | 818 | propagate_e820_map(); |
819 | 819 | ||
820 | max_low_pfn = setup_memory(); | 820 | max_low_pfn = setup_memory(); |
821 | 821 | ||
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 674ef3510cdf..6b8e11f0c15d 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -398,6 +398,8 @@ void __init setup_arch(char **cmdline_p) | |||
398 | 398 | ||
399 | early_res_to_bootmem(); | 399 | early_res_to_bootmem(); |
400 | 400 | ||
401 | dma32_reserve_bootmem(); | ||
402 | |||
401 | #ifdef CONFIG_ACPI_SLEEP | 403 | #ifdef CONFIG_ACPI_SLEEP |
402 | /* | 404 | /* |
403 | * Reserve low memory region for sleep support. | 405 | * Reserve low memory region for sleep support. |
@@ -420,11 +422,14 @@ void __init setup_arch(char **cmdline_p) | |||
420 | unsigned long end_of_mem = end_pfn << PAGE_SHIFT; | 422 | unsigned long end_of_mem = end_pfn << PAGE_SHIFT; |
421 | 423 | ||
422 | if (ramdisk_end <= end_of_mem) { | 424 | if (ramdisk_end <= end_of_mem) { |
423 | reserve_bootmem_generic(ramdisk_image, ramdisk_size); | 425 | /* |
426 | * don't need to reserve again, already reserved early | ||
427 | * in x86_64_start_kernel, and early_res_to_bootmem | ||
428 | * convert that to reserved in bootmem | ||
429 | */ | ||
424 | initrd_start = ramdisk_image + PAGE_OFFSET; | 430 | initrd_start = ramdisk_image + PAGE_OFFSET; |
425 | initrd_end = initrd_start+ramdisk_size; | 431 | initrd_end = initrd_start+ramdisk_size; |
426 | } else { | 432 | } else { |
427 | /* Assumes everything on node 0 */ | ||
428 | free_bootmem(ramdisk_image, ramdisk_size); | 433 | free_bootmem(ramdisk_image, ramdisk_size); |
429 | printk(KERN_ERR "initrd extends beyond end of memory " | 434 | printk(KERN_ERR "initrd extends beyond end of memory " |
430 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", | 435 | "(0x%08lx > 0x%08lx)\ndisabling initrd\n", |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index e6abe8a49b1f..6a925394bc7e 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <asm/mtrr.h> | 61 | #include <asm/mtrr.h> |
62 | #include <asm/nmi.h> | 62 | #include <asm/nmi.h> |
63 | #include <asm/vmi.h> | 63 | #include <asm/vmi.h> |
64 | #include <asm/genapic.h> | ||
64 | #include <linux/mc146818rtc.h> | 65 | #include <linux/mc146818rtc.h> |
65 | 66 | ||
66 | #include <mach_apic.h> | 67 | #include <mach_apic.h> |
@@ -677,6 +678,12 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
677 | unsigned long send_status, accept_status = 0; | 678 | unsigned long send_status, accept_status = 0; |
678 | int maxlvt, num_starts, j; | 679 | int maxlvt, num_starts, j; |
679 | 680 | ||
681 | if (get_uv_system_type() == UV_NON_UNIQUE_APIC) { | ||
682 | send_status = uv_wakeup_secondary(phys_apicid, start_eip); | ||
683 | atomic_set(&init_deasserted, 1); | ||
684 | return send_status; | ||
685 | } | ||
686 | |||
680 | /* | 687 | /* |
681 | * Be paranoid about clearing APIC errors. | 688 | * Be paranoid about clearing APIC errors. |
682 | */ | 689 | */ |
@@ -918,16 +925,19 @@ do_rest: | |||
918 | 925 | ||
919 | atomic_set(&init_deasserted, 0); | 926 | atomic_set(&init_deasserted, 0); |
920 | 927 | ||
921 | Dprintk("Setting warm reset code and vector.\n"); | 928 | if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { |
922 | 929 | ||
923 | store_NMI_vector(&nmi_high, &nmi_low); | 930 | Dprintk("Setting warm reset code and vector.\n"); |
924 | 931 | ||
925 | smpboot_setup_warm_reset_vector(start_ip); | 932 | store_NMI_vector(&nmi_high, &nmi_low); |
926 | /* | 933 | |
927 | * Be paranoid about clearing APIC errors. | 934 | smpboot_setup_warm_reset_vector(start_ip); |
928 | */ | 935 | /* |
929 | apic_write(APIC_ESR, 0); | 936 | * Be paranoid about clearing APIC errors. |
930 | apic_read(APIC_ESR); | 937 | */ |
938 | apic_write(APIC_ESR, 0); | ||
939 | apic_read(APIC_ESR); | ||
940 | } | ||
931 | 941 | ||
932 | /* | 942 | /* |
933 | * Starting actual IPI sequence... | 943 | * Starting actual IPI sequence... |
@@ -966,7 +976,8 @@ do_rest: | |||
966 | else | 976 | else |
967 | /* trampoline code not run */ | 977 | /* trampoline code not run */ |
968 | printk(KERN_ERR "Not responding.\n"); | 978 | printk(KERN_ERR "Not responding.\n"); |
969 | inquire_remote_apic(apicid); | 979 | if (get_uv_system_type() != UV_NON_UNIQUE_APIC) |
980 | inquire_remote_apic(apicid); | ||
970 | } | 981 | } |
971 | } | 982 | } |
972 | 983 | ||
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 65791ca2824a..471e694d6713 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -681,7 +681,7 @@ gp_in_kernel: | |||
681 | } | 681 | } |
682 | } | 682 | } |
683 | 683 | ||
684 | static __kprobes void | 684 | static notrace __kprobes void |
685 | mem_parity_error(unsigned char reason, struct pt_regs *regs) | 685 | mem_parity_error(unsigned char reason, struct pt_regs *regs) |
686 | { | 686 | { |
687 | printk(KERN_EMERG | 687 | printk(KERN_EMERG |
@@ -707,7 +707,7 @@ mem_parity_error(unsigned char reason, struct pt_regs *regs) | |||
707 | clear_mem_error(reason); | 707 | clear_mem_error(reason); |
708 | } | 708 | } |
709 | 709 | ||
710 | static __kprobes void | 710 | static notrace __kprobes void |
711 | io_check_error(unsigned char reason, struct pt_regs *regs) | 711 | io_check_error(unsigned char reason, struct pt_regs *regs) |
712 | { | 712 | { |
713 | unsigned long i; | 713 | unsigned long i; |
@@ -727,7 +727,7 @@ io_check_error(unsigned char reason, struct pt_regs *regs) | |||
727 | outb(reason, 0x61); | 727 | outb(reason, 0x61); |
728 | } | 728 | } |
729 | 729 | ||
730 | static __kprobes void | 730 | static notrace __kprobes void |
731 | unknown_nmi_error(unsigned char reason, struct pt_regs *regs) | 731 | unknown_nmi_error(unsigned char reason, struct pt_regs *regs) |
732 | { | 732 | { |
733 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | 733 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) |
@@ -755,7 +755,7 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs) | |||
755 | 755 | ||
756 | static DEFINE_SPINLOCK(nmi_print_lock); | 756 | static DEFINE_SPINLOCK(nmi_print_lock); |
757 | 757 | ||
758 | void __kprobes die_nmi(struct pt_regs *regs, const char *msg) | 758 | void notrace __kprobes die_nmi(struct pt_regs *regs, const char *msg) |
759 | { | 759 | { |
760 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == NOTIFY_STOP) | 760 | if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == NOTIFY_STOP) |
761 | return; | 761 | return; |
@@ -786,7 +786,7 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg) | |||
786 | do_exit(SIGSEGV); | 786 | do_exit(SIGSEGV); |
787 | } | 787 | } |
788 | 788 | ||
789 | static __kprobes void default_do_nmi(struct pt_regs *regs) | 789 | static notrace __kprobes void default_do_nmi(struct pt_regs *regs) |
790 | { | 790 | { |
791 | unsigned char reason = 0; | 791 | unsigned char reason = 0; |
792 | 792 | ||
@@ -828,7 +828,7 @@ static __kprobes void default_do_nmi(struct pt_regs *regs) | |||
828 | 828 | ||
829 | static int ignore_nmis; | 829 | static int ignore_nmis; |
830 | 830 | ||
831 | __kprobes void do_nmi(struct pt_regs *regs, long error_code) | 831 | notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) |
832 | { | 832 | { |
833 | int cpu; | 833 | int cpu; |
834 | 834 | ||
@@ -1148,9 +1148,22 @@ asmlinkage void math_state_restore(void) | |||
1148 | struct thread_info *thread = current_thread_info(); | 1148 | struct thread_info *thread = current_thread_info(); |
1149 | struct task_struct *tsk = thread->task; | 1149 | struct task_struct *tsk = thread->task; |
1150 | 1150 | ||
1151 | if (!tsk_used_math(tsk)) { | ||
1152 | local_irq_enable(); | ||
1153 | /* | ||
1154 | * does a slab alloc which can sleep | ||
1155 | */ | ||
1156 | if (init_fpu(tsk)) { | ||
1157 | /* | ||
1158 | * ran out of memory! | ||
1159 | */ | ||
1160 | do_group_exit(SIGKILL); | ||
1161 | return; | ||
1162 | } | ||
1163 | local_irq_disable(); | ||
1164 | } | ||
1165 | |||
1151 | clts(); /* Allow maths ops (or we recurse) */ | 1166 | clts(); /* Allow maths ops (or we recurse) */ |
1152 | if (!tsk_used_math(tsk)) | ||
1153 | init_fpu(tsk); | ||
1154 | restore_fpu(tsk); | 1167 | restore_fpu(tsk); |
1155 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ | 1168 | thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ |
1156 | tsk->fpu_counter++; | 1169 | tsk->fpu_counter++; |
@@ -1208,11 +1221,6 @@ void __init trap_init(void) | |||
1208 | #endif | 1221 | #endif |
1209 | set_trap_gate(19, &simd_coprocessor_error); | 1222 | set_trap_gate(19, &simd_coprocessor_error); |
1210 | 1223 | ||
1211 | /* | ||
1212 | * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned. | ||
1213 | * Generate a build-time error if the alignment is wrong. | ||
1214 | */ | ||
1215 | BUILD_BUG_ON(offsetof(struct task_struct, thread.i387.fxsave) & 15); | ||
1216 | if (cpu_has_fxsr) { | 1224 | if (cpu_has_fxsr) { |
1217 | printk(KERN_INFO "Enabling fast FPU save and restore... "); | 1225 | printk(KERN_INFO "Enabling fast FPU save and restore... "); |
1218 | set_in_cr4(X86_CR4_OSFXSR); | 1226 | set_in_cr4(X86_CR4_OSFXSR); |
@@ -1233,6 +1241,7 @@ void __init trap_init(void) | |||
1233 | 1241 | ||
1234 | set_bit(SYSCALL_VECTOR, used_vectors); | 1242 | set_bit(SYSCALL_VECTOR, used_vectors); |
1235 | 1243 | ||
1244 | init_thread_xstate(); | ||
1236 | /* | 1245 | /* |
1237 | * Should be a barrier for any external CPU state: | 1246 | * Should be a barrier for any external CPU state: |
1238 | */ | 1247 | */ |
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 79aa6fc0815c..adff76ea97c4 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -600,7 +600,8 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
600 | oops_end(flags, regs, SIGSEGV); | 600 | oops_end(flags, regs, SIGSEGV); |
601 | } | 601 | } |
602 | 602 | ||
603 | void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) | 603 | notrace __kprobes void |
604 | die_nmi(char *str, struct pt_regs *regs, int do_panic) | ||
604 | { | 605 | { |
605 | unsigned long flags; | 606 | unsigned long flags; |
606 | 607 | ||
@@ -772,7 +773,7 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | |||
772 | die("general protection fault", regs, error_code); | 773 | die("general protection fault", regs, error_code); |
773 | } | 774 | } |
774 | 775 | ||
775 | static __kprobes void | 776 | static notrace __kprobes void |
776 | mem_parity_error(unsigned char reason, struct pt_regs * regs) | 777 | mem_parity_error(unsigned char reason, struct pt_regs * regs) |
777 | { | 778 | { |
778 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", | 779 | printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", |
@@ -796,7 +797,7 @@ mem_parity_error(unsigned char reason, struct pt_regs * regs) | |||
796 | outb(reason, 0x61); | 797 | outb(reason, 0x61); |
797 | } | 798 | } |
798 | 799 | ||
799 | static __kprobes void | 800 | static notrace __kprobes void |
800 | io_check_error(unsigned char reason, struct pt_regs * regs) | 801 | io_check_error(unsigned char reason, struct pt_regs * regs) |
801 | { | 802 | { |
802 | printk("NMI: IOCK error (debug interrupt?)\n"); | 803 | printk("NMI: IOCK error (debug interrupt?)\n"); |
@@ -810,7 +811,7 @@ io_check_error(unsigned char reason, struct pt_regs * regs) | |||
810 | outb(reason, 0x61); | 811 | outb(reason, 0x61); |
811 | } | 812 | } |
812 | 813 | ||
813 | static __kprobes void | 814 | static notrace __kprobes void |
814 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | 815 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) |
815 | { | 816 | { |
816 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | 817 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) |
@@ -827,7 +828,7 @@ unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | |||
827 | 828 | ||
828 | /* Runs on IST stack. This code must keep interrupts off all the time. | 829 | /* Runs on IST stack. This code must keep interrupts off all the time. |
829 | Nested NMIs are prevented by the CPU. */ | 830 | Nested NMIs are prevented by the CPU. */ |
830 | asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs) | 831 | asmlinkage notrace __kprobes void default_do_nmi(struct pt_regs *regs) |
831 | { | 832 | { |
832 | unsigned char reason = 0; | 833 | unsigned char reason = 0; |
833 | int cpu; | 834 | int cpu; |
@@ -1123,11 +1124,24 @@ asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void) | |||
1123 | asmlinkage void math_state_restore(void) | 1124 | asmlinkage void math_state_restore(void) |
1124 | { | 1125 | { |
1125 | struct task_struct *me = current; | 1126 | struct task_struct *me = current; |
1126 | clts(); /* Allow maths ops (or we recurse) */ | ||
1127 | 1127 | ||
1128 | if (!used_math()) | 1128 | if (!used_math()) { |
1129 | init_fpu(me); | 1129 | local_irq_enable(); |
1130 | restore_fpu_checking(&me->thread.i387.fxsave); | 1130 | /* |
1131 | * does a slab alloc which can sleep | ||
1132 | */ | ||
1133 | if (init_fpu(me)) { | ||
1134 | /* | ||
1135 | * ran out of memory! | ||
1136 | */ | ||
1137 | do_group_exit(SIGKILL); | ||
1138 | return; | ||
1139 | } | ||
1140 | local_irq_disable(); | ||
1141 | } | ||
1142 | |||
1143 | clts(); /* Allow maths ops (or we recurse) */ | ||
1144 | restore_fpu_checking(&me->thread.xstate->fxsave); | ||
1131 | task_thread_info(me)->status |= TS_USEDFPU; | 1145 | task_thread_info(me)->status |= TS_USEDFPU; |
1132 | me->fpu_counter++; | 1146 | me->fpu_counter++; |
1133 | } | 1147 | } |
@@ -1163,6 +1177,10 @@ void __init trap_init(void) | |||
1163 | #endif | 1177 | #endif |
1164 | 1178 | ||
1165 | /* | 1179 | /* |
1180 | * initialize the per thread extended state: | ||
1181 | */ | ||
1182 | init_thread_xstate(); | ||
1183 | /* | ||
1166 | * Should be a barrier for any external CPU state. | 1184 | * Should be a barrier for any external CPU state. |
1167 | */ | 1185 | */ |
1168 | cpu_init(); | 1186 | cpu_init(); |
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index 3d7e6e9fa6c2..e4790728b224 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c | |||
@@ -221,9 +221,9 @@ EXPORT_SYMBOL(recalibrate_cpu_khz); | |||
221 | * if the CPU frequency is scaled, TSC-based delays will need a different | 221 | * if the CPU frequency is scaled, TSC-based delays will need a different |
222 | * loops_per_jiffy value to function properly. | 222 | * loops_per_jiffy value to function properly. |
223 | */ | 223 | */ |
224 | static unsigned int ref_freq = 0; | 224 | static unsigned int ref_freq; |
225 | static unsigned long loops_per_jiffy_ref = 0; | 225 | static unsigned long loops_per_jiffy_ref; |
226 | static unsigned long cpu_khz_ref = 0; | 226 | static unsigned long cpu_khz_ref; |
227 | 227 | ||
228 | static int | 228 | static int |
229 | time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) | 229 | time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) |
@@ -283,15 +283,28 @@ core_initcall(cpufreq_tsc); | |||
283 | 283 | ||
284 | /* clock source code */ | 284 | /* clock source code */ |
285 | 285 | ||
286 | static unsigned long current_tsc_khz = 0; | 286 | static unsigned long current_tsc_khz; |
287 | static struct clocksource clocksource_tsc; | ||
287 | 288 | ||
289 | /* | ||
290 | * We compare the TSC to the cycle_last value in the clocksource | ||
291 | * structure to avoid a nasty time-warp issue. This can be observed in | ||
292 | * a very small window right after one CPU updated cycle_last under | ||
293 | * xtime lock and the other CPU reads a TSC value which is smaller | ||
294 | * than the cycle_last reference value due to a TSC which is slighty | ||
295 | * behind. This delta is nowhere else observable, but in that case it | ||
296 | * results in a forward time jump in the range of hours due to the | ||
297 | * unsigned delta calculation of the time keeping core code, which is | ||
298 | * necessary to support wrapping clocksources like pm timer. | ||
299 | */ | ||
288 | static cycle_t read_tsc(void) | 300 | static cycle_t read_tsc(void) |
289 | { | 301 | { |
290 | cycle_t ret; | 302 | cycle_t ret; |
291 | 303 | ||
292 | rdtscll(ret); | 304 | rdtscll(ret); |
293 | 305 | ||
294 | return ret; | 306 | return ret >= clocksource_tsc.cycle_last ? |
307 | ret : clocksource_tsc.cycle_last; | ||
295 | } | 308 | } |
296 | 309 | ||
297 | static struct clocksource clocksource_tsc = { | 310 | static struct clocksource clocksource_tsc = { |
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c index ceeba01e7f47..fcc16e58609e 100644 --- a/arch/x86/kernel/tsc_64.c +++ b/arch/x86/kernel/tsc_64.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <asm/hpet.h> | 11 | #include <asm/hpet.h> |
12 | #include <asm/timex.h> | 12 | #include <asm/timex.h> |
13 | #include <asm/timer.h> | 13 | #include <asm/timer.h> |
14 | #include <asm/vgtod.h> | ||
14 | 15 | ||
15 | static int notsc __initdata = 0; | 16 | static int notsc __initdata = 0; |
16 | 17 | ||
@@ -287,18 +288,34 @@ int __init notsc_setup(char *s) | |||
287 | 288 | ||
288 | __setup("notsc", notsc_setup); | 289 | __setup("notsc", notsc_setup); |
289 | 290 | ||
291 | static struct clocksource clocksource_tsc; | ||
290 | 292 | ||
291 | /* clock source code: */ | 293 | /* |
294 | * We compare the TSC to the cycle_last value in the clocksource | ||
295 | * structure to avoid a nasty time-warp. This can be observed in a | ||
296 | * very small window right after one CPU updated cycle_last under | ||
297 | * xtime/vsyscall_gtod lock and the other CPU reads a TSC value which | ||
298 | * is smaller than the cycle_last reference value due to a TSC which | ||
299 | * is slighty behind. This delta is nowhere else observable, but in | ||
300 | * that case it results in a forward time jump in the range of hours | ||
301 | * due to the unsigned delta calculation of the time keeping core | ||
302 | * code, which is necessary to support wrapping clocksources like pm | ||
303 | * timer. | ||
304 | */ | ||
292 | static cycle_t read_tsc(void) | 305 | static cycle_t read_tsc(void) |
293 | { | 306 | { |
294 | cycle_t ret = (cycle_t)get_cycles(); | 307 | cycle_t ret = (cycle_t)get_cycles(); |
295 | return ret; | 308 | |
309 | return ret >= clocksource_tsc.cycle_last ? | ||
310 | ret : clocksource_tsc.cycle_last; | ||
296 | } | 311 | } |
297 | 312 | ||
298 | static cycle_t __vsyscall_fn vread_tsc(void) | 313 | static cycle_t __vsyscall_fn vread_tsc(void) |
299 | { | 314 | { |
300 | cycle_t ret = (cycle_t)vget_cycles(); | 315 | cycle_t ret = (cycle_t)vget_cycles(); |
301 | return ret; | 316 | |
317 | return ret >= __vsyscall_gtod_data.clock.cycle_last ? | ||
318 | ret : __vsyscall_gtod_data.clock.cycle_last; | ||
302 | } | 319 | } |
303 | 320 | ||
304 | static struct clocksource clocksource_tsc = { | 321 | static struct clocksource clocksource_tsc = { |
diff --git a/arch/x86/mach-visws/visws_apic.c b/arch/x86/mach-visws/visws_apic.c index 710faf71a650..cef9cb1d15ac 100644 --- a/arch/x86/mach-visws/visws_apic.c +++ b/arch/x86/mach-visws/visws_apic.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/i386/mach-visws/visws_apic.c | ||
3 | * | ||
4 | * Copyright (C) 1999 Bent Hagemark, Ingo Molnar | 2 | * Copyright (C) 1999 Bent Hagemark, Ingo Molnar |
5 | * | 3 | * |
6 | * SGI Visual Workstation interrupt controller | 4 | * SGI Visual Workstation interrupt controller |
diff --git a/arch/x86/mach-voyager/voyager_basic.c b/arch/x86/mach-voyager/voyager_basic.c index 6a949e4edde8..46d6f8067690 100644 --- a/arch/x86/mach-voyager/voyager_basic.c +++ b/arch/x86/mach-voyager/voyager_basic.c | |||
@@ -2,8 +2,6 @@ | |||
2 | * | 2 | * |
3 | * Author: J.E.J.Bottomley@HansenPartnership.com | 3 | * Author: J.E.J.Bottomley@HansenPartnership.com |
4 | * | 4 | * |
5 | * linux/arch/i386/kernel/voyager.c | ||
6 | * | ||
7 | * This file contains all the voyager specific routines for getting | 5 | * This file contains all the voyager specific routines for getting |
8 | * initialisation of the architecture to function. For additional | 6 | * initialisation of the architecture to function. For additional |
9 | * features see: | 7 | * features see: |
diff --git a/arch/x86/mach-voyager/voyager_cat.c b/arch/x86/mach-voyager/voyager_cat.c index 17a7904f75b1..ecab9fff0fd1 100644 --- a/arch/x86/mach-voyager/voyager_cat.c +++ b/arch/x86/mach-voyager/voyager_cat.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * | 4 | * |
5 | * Author: J.E.J.Bottomley@HansenPartnership.com | 5 | * Author: J.E.J.Bottomley@HansenPartnership.com |
6 | * | 6 | * |
7 | * linux/arch/i386/kernel/voyager_cat.c | ||
8 | * | ||
9 | * This file contains all the logic for manipulating the CAT bus | 7 | * This file contains all the logic for manipulating the CAT bus |
10 | * in a level 5 machine. | 8 | * in a level 5 machine. |
11 | * | 9 | * |
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index be7235bf105d..96f60c7cd124 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * | 4 | * |
5 | * Author: J.E.J.Bottomley@HansenPartnership.com | 5 | * Author: J.E.J.Bottomley@HansenPartnership.com |
6 | * | 6 | * |
7 | * linux/arch/i386/kernel/voyager_smp.c | ||
8 | * | ||
9 | * This file provides all the same external entries as smp.c but uses | 7 | * This file provides all the same external entries as smp.c but uses |
10 | * the voyager hal to provide the functionality | 8 | * the voyager hal to provide the functionality |
11 | */ | 9 | */ |
diff --git a/arch/x86/mach-voyager/voyager_thread.c b/arch/x86/mach-voyager/voyager_thread.c index c69c931818ed..15464a20fb38 100644 --- a/arch/x86/mach-voyager/voyager_thread.c +++ b/arch/x86/mach-voyager/voyager_thread.c | |||
@@ -4,8 +4,6 @@ | |||
4 | * | 4 | * |
5 | * Author: J.E.J.Bottomley@HansenPartnership.com | 5 | * Author: J.E.J.Bottomley@HansenPartnership.com |
6 | * | 6 | * |
7 | * linux/arch/i386/kernel/voyager_thread.c | ||
8 | * | ||
9 | * This module provides the machine status monitor thread for the | 7 | * This module provides the machine status monitor thread for the |
10 | * voyager architecture. This allows us to monitor the machine | 8 | * voyager architecture. This allows us to monitor the machine |
11 | * environment (temp, voltage, fan function) and the front panel and | 9 | * environment (temp, voltage, fan function) and the front panel and |
diff --git a/arch/x86/math-emu/fpu_entry.c b/arch/x86/math-emu/fpu_entry.c index 4bab3b145392..6e38d877ea77 100644 --- a/arch/x86/math-emu/fpu_entry.c +++ b/arch/x86/math-emu/fpu_entry.c | |||
@@ -678,7 +678,7 @@ int fpregs_soft_set(struct task_struct *target, | |||
678 | unsigned int pos, unsigned int count, | 678 | unsigned int pos, unsigned int count, |
679 | const void *kbuf, const void __user *ubuf) | 679 | const void *kbuf, const void __user *ubuf) |
680 | { | 680 | { |
681 | struct i387_soft_struct *s387 = &target->thread.i387.soft; | 681 | struct i387_soft_struct *s387 = &target->thread.xstate->soft; |
682 | void *space = s387->st_space; | 682 | void *space = s387->st_space; |
683 | int ret; | 683 | int ret; |
684 | int offset, other, i, tags, regnr, tag, newtop; | 684 | int offset, other, i, tags, regnr, tag, newtop; |
@@ -730,7 +730,7 @@ int fpregs_soft_get(struct task_struct *target, | |||
730 | unsigned int pos, unsigned int count, | 730 | unsigned int pos, unsigned int count, |
731 | void *kbuf, void __user *ubuf) | 731 | void *kbuf, void __user *ubuf) |
732 | { | 732 | { |
733 | struct i387_soft_struct *s387 = &target->thread.i387.soft; | 733 | struct i387_soft_struct *s387 = &target->thread.xstate->soft; |
734 | const void *space = s387->st_space; | 734 | const void *space = s387->st_space; |
735 | int ret; | 735 | int ret; |
736 | int offset = (S387->ftop & 7) * 10, other = 80 - offset; | 736 | int offset = (S387->ftop & 7) * 10, other = 80 - offset; |
diff --git a/arch/x86/math-emu/fpu_system.h b/arch/x86/math-emu/fpu_system.h index a3ae28c49ddd..13488fa153e0 100644 --- a/arch/x86/math-emu/fpu_system.h +++ b/arch/x86/math-emu/fpu_system.h | |||
@@ -35,8 +35,8 @@ | |||
35 | #define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \ | 35 | #define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \ |
36 | == (1 << 10)) | 36 | == (1 << 10)) |
37 | 37 | ||
38 | #define I387 (current->thread.i387) | 38 | #define I387 (current->thread.xstate) |
39 | #define FPU_info (I387.soft.info) | 39 | #define FPU_info (I387->soft.info) |
40 | 40 | ||
41 | #define FPU_CS (*(unsigned short *) &(FPU_info->___cs)) | 41 | #define FPU_CS (*(unsigned short *) &(FPU_info->___cs)) |
42 | #define FPU_SS (*(unsigned short *) &(FPU_info->___ss)) | 42 | #define FPU_SS (*(unsigned short *) &(FPU_info->___ss)) |
@@ -46,25 +46,25 @@ | |||
46 | #define FPU_EIP (FPU_info->___eip) | 46 | #define FPU_EIP (FPU_info->___eip) |
47 | #define FPU_ORIG_EIP (FPU_info->___orig_eip) | 47 | #define FPU_ORIG_EIP (FPU_info->___orig_eip) |
48 | 48 | ||
49 | #define FPU_lookahead (I387.soft.lookahead) | 49 | #define FPU_lookahead (I387->soft.lookahead) |
50 | 50 | ||
51 | /* nz if ip_offset and cs_selector are not to be set for the current | 51 | /* nz if ip_offset and cs_selector are not to be set for the current |
52 | instruction. */ | 52 | instruction. */ |
53 | #define no_ip_update (*(u_char *)&(I387.soft.no_update)) | 53 | #define no_ip_update (*(u_char *)&(I387->soft.no_update)) |
54 | #define FPU_rm (*(u_char *)&(I387.soft.rm)) | 54 | #define FPU_rm (*(u_char *)&(I387->soft.rm)) |
55 | 55 | ||
56 | /* Number of bytes of data which can be legally accessed by the current | 56 | /* Number of bytes of data which can be legally accessed by the current |
57 | instruction. This only needs to hold a number <= 108, so a byte will do. */ | 57 | instruction. This only needs to hold a number <= 108, so a byte will do. */ |
58 | #define access_limit (*(u_char *)&(I387.soft.alimit)) | 58 | #define access_limit (*(u_char *)&(I387->soft.alimit)) |
59 | 59 | ||
60 | #define partial_status (I387.soft.swd) | 60 | #define partial_status (I387->soft.swd) |
61 | #define control_word (I387.soft.cwd) | 61 | #define control_word (I387->soft.cwd) |
62 | #define fpu_tag_word (I387.soft.twd) | 62 | #define fpu_tag_word (I387->soft.twd) |
63 | #define registers (I387.soft.st_space) | 63 | #define registers (I387->soft.st_space) |
64 | #define top (I387.soft.ftop) | 64 | #define top (I387->soft.ftop) |
65 | 65 | ||
66 | #define instruction_address (*(struct address *)&I387.soft.fip) | 66 | #define instruction_address (*(struct address *)&I387->soft.fip) |
67 | #define operand_address (*(struct address *)&I387.soft.foo) | 67 | #define operand_address (*(struct address *)&I387->soft.foo) |
68 | 68 | ||
69 | #define FPU_access_ok(x,y,z) if ( !access_ok(x,y,z) ) \ | 69 | #define FPU_access_ok(x,y,z) if ( !access_ok(x,y,z) ) \ |
70 | math_abort(FPU_info,SIGSEGV) | 70 | math_abort(FPU_info,SIGSEGV) |
diff --git a/arch/x86/math-emu/reg_ld_str.c b/arch/x86/math-emu/reg_ld_str.c index 02af772a24db..d597fe7423c9 100644 --- a/arch/x86/math-emu/reg_ld_str.c +++ b/arch/x86/math-emu/reg_ld_str.c | |||
@@ -1180,8 +1180,8 @@ u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d) | |||
1180 | control_word |= 0xffff0040; | 1180 | control_word |= 0xffff0040; |
1181 | partial_status = status_word() | 0xffff0000; | 1181 | partial_status = status_word() | 0xffff0000; |
1182 | fpu_tag_word |= 0xffff0000; | 1182 | fpu_tag_word |= 0xffff0000; |
1183 | I387.soft.fcs &= ~0xf8000000; | 1183 | I387->soft.fcs &= ~0xf8000000; |
1184 | I387.soft.fos |= 0xffff0000; | 1184 | I387->soft.fos |= 0xffff0000; |
1185 | #endif /* PECULIAR_486 */ | 1185 | #endif /* PECULIAR_486 */ |
1186 | if (__copy_to_user(d, &control_word, 7 * 4)) | 1186 | if (__copy_to_user(d, &control_word, 7 * 4)) |
1187 | FPU_abort; | 1187 | FPU_abort; |
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c index eba0bbede7a6..18378850e25a 100644 --- a/arch/x86/mm/discontig_32.c +++ b/arch/x86/mm/discontig_32.c | |||
@@ -120,7 +120,7 @@ int __init get_memcfg_numa_flat(void) | |||
120 | printk("NUMA - single node, flat memory mode\n"); | 120 | printk("NUMA - single node, flat memory mode\n"); |
121 | 121 | ||
122 | /* Run the memory configuration and find the top of memory. */ | 122 | /* Run the memory configuration and find the top of memory. */ |
123 | find_max_pfn(); | 123 | propagate_e820_map(); |
124 | node_start_pfn[0] = 0; | 124 | node_start_pfn[0] = 0; |
125 | node_end_pfn[0] = max_pfn; | 125 | node_end_pfn[0] = max_pfn; |
126 | memory_present(0, 0, max_pfn); | 126 | memory_present(0, 0, max_pfn); |
@@ -134,7 +134,7 @@ int __init get_memcfg_numa_flat(void) | |||
134 | /* | 134 | /* |
135 | * Find the highest page frame number we have available for the node | 135 | * Find the highest page frame number we have available for the node |
136 | */ | 136 | */ |
137 | static void __init find_max_pfn_node(int nid) | 137 | static void __init propagate_e820_map_node(int nid) |
138 | { | 138 | { |
139 | if (node_end_pfn[nid] > max_pfn) | 139 | if (node_end_pfn[nid] > max_pfn) |
140 | node_end_pfn[nid] = max_pfn; | 140 | node_end_pfn[nid] = max_pfn; |
@@ -379,7 +379,7 @@ unsigned long __init setup_memory(void) | |||
379 | printk("High memory starts at vaddr %08lx\n", | 379 | printk("High memory starts at vaddr %08lx\n", |
380 | (ulong) pfn_to_kaddr(highstart_pfn)); | 380 | (ulong) pfn_to_kaddr(highstart_pfn)); |
381 | for_each_online_node(nid) | 381 | for_each_online_node(nid) |
382 | find_max_pfn_node(nid); | 382 | propagate_e820_map_node(nid); |
383 | 383 | ||
384 | memset(NODE_DATA(0), 0, sizeof(struct pglist_data)); | 384 | memset(NODE_DATA(0), 0, sizeof(struct pglist_data)); |
385 | NODE_DATA(0)->bdata = &node0_bdata; | 385 | NODE_DATA(0)->bdata = &node0_bdata; |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 1500dc8d63e4..9ec62da85fd7 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/i386/mm/init.c | ||
3 | * | 2 | * |
4 | * Copyright (C) 1995 Linus Torvalds | 3 | * Copyright (C) 1995 Linus Torvalds |
5 | * | 4 | * |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 1076097dcab2..1ff7906a9a4d 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -47,9 +47,6 @@ | |||
47 | #include <asm/numa.h> | 47 | #include <asm/numa.h> |
48 | #include <asm/cacheflush.h> | 48 | #include <asm/cacheflush.h> |
49 | 49 | ||
50 | const struct dma_mapping_ops *dma_ops; | ||
51 | EXPORT_SYMBOL(dma_ops); | ||
52 | |||
53 | static unsigned long dma_reserve __initdata; | 50 | static unsigned long dma_reserve __initdata; |
54 | 51 | ||
55 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 52 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index c590fd200e29..3a4baf95e24d 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -134,7 +134,7 @@ static void __iomem *__ioremap(resource_size_t phys_addr, unsigned long size, | |||
134 | 134 | ||
135 | if (!phys_addr_valid(phys_addr)) { | 135 | if (!phys_addr_valid(phys_addr)) { |
136 | printk(KERN_WARNING "ioremap: invalid physical address %llx\n", | 136 | printk(KERN_WARNING "ioremap: invalid physical address %llx\n", |
137 | phys_addr); | 137 | (unsigned long long)phys_addr); |
138 | WARN_ON_ONCE(1); | 138 | WARN_ON_ONCE(1); |
139 | return NULL; | 139 | return NULL; |
140 | } | 140 | } |
@@ -187,7 +187,8 @@ static void __iomem *__ioremap(resource_size_t phys_addr, unsigned long size, | |||
187 | new_prot_val == _PAGE_CACHE_WB)) { | 187 | new_prot_val == _PAGE_CACHE_WB)) { |
188 | pr_debug( | 188 | pr_debug( |
189 | "ioremap error for 0x%llx-0x%llx, requested 0x%lx, got 0x%lx\n", | 189 | "ioremap error for 0x%llx-0x%llx, requested 0x%lx, got 0x%lx\n", |
190 | phys_addr, phys_addr + size, | 190 | (unsigned long long)phys_addr, |
191 | (unsigned long long)(phys_addr + size), | ||
191 | prot_val, new_prot_val); | 192 | prot_val, new_prot_val); |
192 | free_memtype(phys_addr, phys_addr + size); | 193 | free_memtype(phys_addr, phys_addr + size); |
193 | return NULL; | 194 | return NULL; |
diff --git a/arch/x86/mm/k8topology_64.c b/arch/x86/mm/k8topology_64.c index 7a2ebce87df5..86808e666f9c 100644 --- a/arch/x86/mm/k8topology_64.c +++ b/arch/x86/mm/k8topology_64.c | |||
@@ -164,7 +164,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) | |||
164 | if (!found) | 164 | if (!found) |
165 | return -1; | 165 | return -1; |
166 | 166 | ||
167 | memnode_shift = compute_hash_shift(nodes, 8); | 167 | memnode_shift = compute_hash_shift(nodes, 8, NULL); |
168 | if (memnode_shift < 0) { | 168 | if (memnode_shift < 0) { |
169 | printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); | 169 | printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); |
170 | return -1; | 170 | return -1; |
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 3f6c53c0e003..9a6892200b27 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -60,7 +60,7 @@ unsigned long __initdata nodemap_size; | |||
60 | * -1 if node overlap or lost ram (shift too big) | 60 | * -1 if node overlap or lost ram (shift too big) |
61 | */ | 61 | */ |
62 | static int __init populate_memnodemap(const struct bootnode *nodes, | 62 | static int __init populate_memnodemap(const struct bootnode *nodes, |
63 | int numnodes, int shift) | 63 | int numnodes, int shift, int *nodeids) |
64 | { | 64 | { |
65 | unsigned long addr, end; | 65 | unsigned long addr, end; |
66 | int i, res = -1; | 66 | int i, res = -1; |
@@ -76,7 +76,12 @@ static int __init populate_memnodemap(const struct bootnode *nodes, | |||
76 | do { | 76 | do { |
77 | if (memnodemap[addr >> shift] != NUMA_NO_NODE) | 77 | if (memnodemap[addr >> shift] != NUMA_NO_NODE) |
78 | return -1; | 78 | return -1; |
79 | memnodemap[addr >> shift] = i; | 79 | |
80 | if (!nodeids) | ||
81 | memnodemap[addr >> shift] = i; | ||
82 | else | ||
83 | memnodemap[addr >> shift] = nodeids[i]; | ||
84 | |||
80 | addr += (1UL << shift); | 85 | addr += (1UL << shift); |
81 | } while (addr < end); | 86 | } while (addr < end); |
82 | res = 1; | 87 | res = 1; |
@@ -139,7 +144,8 @@ static int __init extract_lsb_from_nodes(const struct bootnode *nodes, | |||
139 | return i; | 144 | return i; |
140 | } | 145 | } |
141 | 146 | ||
142 | int __init compute_hash_shift(struct bootnode *nodes, int numnodes) | 147 | int __init compute_hash_shift(struct bootnode *nodes, int numnodes, |
148 | int *nodeids) | ||
143 | { | 149 | { |
144 | int shift; | 150 | int shift; |
145 | 151 | ||
@@ -149,7 +155,7 @@ int __init compute_hash_shift(struct bootnode *nodes, int numnodes) | |||
149 | printk(KERN_DEBUG "NUMA: Using %d for the hash shift.\n", | 155 | printk(KERN_DEBUG "NUMA: Using %d for the hash shift.\n", |
150 | shift); | 156 | shift); |
151 | 157 | ||
152 | if (populate_memnodemap(nodes, numnodes, shift) != 1) { | 158 | if (populate_memnodemap(nodes, numnodes, shift, nodeids) != 1) { |
153 | printk(KERN_INFO "Your memory is not aligned you need to " | 159 | printk(KERN_INFO "Your memory is not aligned you need to " |
154 | "rebuild your kernel with a bigger NODEMAPSIZE " | 160 | "rebuild your kernel with a bigger NODEMAPSIZE " |
155 | "shift=%d\n", shift); | 161 | "shift=%d\n", shift); |
@@ -463,7 +469,7 @@ done: | |||
463 | } | 469 | } |
464 | } | 470 | } |
465 | out: | 471 | out: |
466 | memnode_shift = compute_hash_shift(nodes, num_nodes); | 472 | memnode_shift = compute_hash_shift(nodes, num_nodes, NULL); |
467 | if (memnode_shift < 0) { | 473 | if (memnode_shift < 0) { |
468 | memnode_shift = 0; | 474 | memnode_shift = 0; |
469 | printk(KERN_ERR "No NUMA hash function found. NUMA emulation " | 475 | printk(KERN_ERR "No NUMA hash function found. NUMA emulation " |
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 3165ec0672bd..6fb9e7c6893f 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c | |||
@@ -1,7 +1,3 @@ | |||
1 | /* | ||
2 | * linux/arch/i386/mm/pgtable.c | ||
3 | */ | ||
4 | |||
5 | #include <linux/sched.h> | 1 | #include <linux/sched.h> |
6 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
7 | #include <linux/errno.h> | 3 | #include <linux/errno.h> |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 1bae9c855ceb..fb43d89f46f3 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -32,6 +32,10 @@ static struct bootnode nodes_add[MAX_NUMNODES]; | |||
32 | static int found_add_area __initdata; | 32 | static int found_add_area __initdata; |
33 | int hotadd_percent __initdata = 0; | 33 | int hotadd_percent __initdata = 0; |
34 | 34 | ||
35 | static int num_node_memblks __initdata; | ||
36 | static struct bootnode node_memblk_range[NR_NODE_MEMBLKS] __initdata; | ||
37 | static int memblk_nodeid[NR_NODE_MEMBLKS] __initdata; | ||
38 | |||
35 | /* Too small nodes confuse the VM badly. Usually they result | 39 | /* Too small nodes confuse the VM badly. Usually they result |
36 | from BIOS bugs. */ | 40 | from BIOS bugs. */ |
37 | #define NODE_MIN_SIZE (4*1024*1024) | 41 | #define NODE_MIN_SIZE (4*1024*1024) |
@@ -41,17 +45,17 @@ static __init int setup_node(int pxm) | |||
41 | return acpi_map_pxm_to_node(pxm); | 45 | return acpi_map_pxm_to_node(pxm); |
42 | } | 46 | } |
43 | 47 | ||
44 | static __init int conflicting_nodes(unsigned long start, unsigned long end) | 48 | static __init int conflicting_memblks(unsigned long start, unsigned long end) |
45 | { | 49 | { |
46 | int i; | 50 | int i; |
47 | for_each_node_mask(i, nodes_parsed) { | 51 | for (i = 0; i < num_node_memblks; i++) { |
48 | struct bootnode *nd = &nodes[i]; | 52 | struct bootnode *nd = &node_memblk_range[i]; |
49 | if (nd->start == nd->end) | 53 | if (nd->start == nd->end) |
50 | continue; | 54 | continue; |
51 | if (nd->end > start && nd->start < end) | 55 | if (nd->end > start && nd->start < end) |
52 | return i; | 56 | return memblk_nodeid[i]; |
53 | if (nd->end == end && nd->start == start) | 57 | if (nd->end == end && nd->start == start) |
54 | return i; | 58 | return memblk_nodeid[i]; |
55 | } | 59 | } |
56 | return -1; | 60 | return -1; |
57 | } | 61 | } |
@@ -258,7 +262,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
258 | bad_srat(); | 262 | bad_srat(); |
259 | return; | 263 | return; |
260 | } | 264 | } |
261 | i = conflicting_nodes(start, end); | 265 | i = conflicting_memblks(start, end); |
262 | if (i == node) { | 266 | if (i == node) { |
263 | printk(KERN_WARNING | 267 | printk(KERN_WARNING |
264 | "SRAT: Warning: PXM %d (%lx-%lx) overlaps with itself (%Lx-%Lx)\n", | 268 | "SRAT: Warning: PXM %d (%lx-%lx) overlaps with itself (%Lx-%Lx)\n", |
@@ -283,10 +287,10 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
283 | nd->end = end; | 287 | nd->end = end; |
284 | } | 288 | } |
285 | 289 | ||
286 | printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, | 290 | printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm, |
287 | nd->start, nd->end); | 291 | start, end); |
288 | e820_register_active_regions(node, nd->start >> PAGE_SHIFT, | 292 | e820_register_active_regions(node, start >> PAGE_SHIFT, |
289 | nd->end >> PAGE_SHIFT); | 293 | end >> PAGE_SHIFT); |
290 | push_node_boundaries(node, nd->start >> PAGE_SHIFT, | 294 | push_node_boundaries(node, nd->start >> PAGE_SHIFT, |
291 | nd->end >> PAGE_SHIFT); | 295 | nd->end >> PAGE_SHIFT); |
292 | 296 | ||
@@ -298,6 +302,11 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
298 | if ((nd->start | nd->end) == 0) | 302 | if ((nd->start | nd->end) == 0) |
299 | node_clear(node, nodes_parsed); | 303 | node_clear(node, nodes_parsed); |
300 | } | 304 | } |
305 | |||
306 | node_memblk_range[num_node_memblks].start = start; | ||
307 | node_memblk_range[num_node_memblks].end = end; | ||
308 | memblk_nodeid[num_node_memblks] = node; | ||
309 | num_node_memblks++; | ||
301 | } | 310 | } |
302 | 311 | ||
303 | /* Sanity check to catch more bad SRATs (they are amazingly common). | 312 | /* Sanity check to catch more bad SRATs (they are amazingly common). |
@@ -368,7 +377,8 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
368 | return -1; | 377 | return -1; |
369 | } | 378 | } |
370 | 379 | ||
371 | memnode_shift = compute_hash_shift(nodes, MAX_NUMNODES); | 380 | memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks, |
381 | memblk_nodeid); | ||
372 | if (memnode_shift < 0) { | 382 | if (memnode_shift < 0) { |
373 | printk(KERN_ERR | 383 | printk(KERN_ERR |
374 | "SRAT: No NUMA node hash function found. Contact maintainer\n"); | 384 | "SRAT: No NUMA node hash function found. Contact maintainer\n"); |
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index 17a6b057856b..b7ad9f89d21f 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile | |||
@@ -37,7 +37,8 @@ $(obj)/%.so: OBJCOPYFLAGS := -S | |||
37 | $(obj)/%.so: $(obj)/%.so.dbg FORCE | 37 | $(obj)/%.so: $(obj)/%.so.dbg FORCE |
38 | $(call if_changed,objcopy) | 38 | $(call if_changed,objcopy) |
39 | 39 | ||
40 | CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64 | 40 | CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \ |
41 | $(filter -g%,$(KBUILD_CFLAGS)) | ||
41 | 42 | ||
42 | $(vobjs): KBUILD_CFLAGS += $(CFL) | 43 | $(vobjs): KBUILD_CFLAGS += $(CFL) |
43 | 44 | ||
diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/fbdev.c index 48fb38d7d2c0..4db42bff8c60 100644 --- a/arch/x86/video/fbdev.c +++ b/arch/x86/video/fbdev.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * arch/i386/video/fbdev.c - i386 Framebuffer | ||
3 | * | 2 | * |
4 | * Copyright (C) 2007 Antonino Daplas <adaplas@gmail.com> | 3 | * Copyright (C) 2007 Antonino Daplas <adaplas@gmail.com> |
5 | * | 4 | * |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 8ea709be3306..efd70a974591 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -314,4 +314,13 @@ config KEYBOARD_BFIN | |||
314 | To compile this driver as a module, choose M here: the | 314 | To compile this driver as a module, choose M here: the |
315 | module will be called bf54x-keys. | 315 | module will be called bf54x-keys. |
316 | 316 | ||
317 | config KEYBOARD_SH_KEYSC | ||
318 | tristate "SuperH KEYSC keypad support" | ||
319 | depends on SUPERH | ||
320 | help | ||
321 | Say Y here if you want to use a keypad attached to the KEYSC block | ||
322 | on SuperH processors such as sh7722 and sh7343. | ||
323 | |||
324 | To compile this driver as a module, choose M here: the | ||
325 | module will be called sh_keysc. | ||
317 | endif | 326 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index e741f4031012..0edc8f285d1c 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -26,3 +26,4 @@ obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o | |||
26 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | 26 | obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o |
27 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | 27 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o |
28 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 28 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
29 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | ||
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c new file mode 100644 index 000000000000..8486abc457ed --- /dev/null +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * SuperH KEYSC Keypad Driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Magnus Damm | ||
5 | * | ||
6 | * Based on gpio_keys.c, Copyright 2005 Phil Blundell | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/irq.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <asm/sh_keysc.h> | ||
23 | |||
24 | #define KYCR1_OFFS 0x00 | ||
25 | #define KYCR2_OFFS 0x04 | ||
26 | #define KYINDR_OFFS 0x08 | ||
27 | #define KYOUTDR_OFFS 0x0c | ||
28 | |||
29 | #define KYCR2_IRQ_LEVEL 0x10 | ||
30 | #define KYCR2_IRQ_DISABLED 0x00 | ||
31 | |||
32 | static const struct { | ||
33 | unsigned char kymd, keyout, keyin; | ||
34 | } sh_keysc_mode[] = { | ||
35 | [SH_KEYSC_MODE_1] = { 0, 6, 5 }, | ||
36 | [SH_KEYSC_MODE_2] = { 1, 5, 6 }, | ||
37 | [SH_KEYSC_MODE_3] = { 2, 4, 7 }, | ||
38 | }; | ||
39 | |||
40 | struct sh_keysc_priv { | ||
41 | void __iomem *iomem_base; | ||
42 | unsigned long last_keys; | ||
43 | struct input_dev *input; | ||
44 | struct sh_keysc_info pdata; | ||
45 | }; | ||
46 | |||
47 | static irqreturn_t sh_keysc_isr(int irq, void *dev_id) | ||
48 | { | ||
49 | struct platform_device *pdev = dev_id; | ||
50 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | ||
51 | struct sh_keysc_info *pdata = &priv->pdata; | ||
52 | unsigned long keys, keys1, keys0, mask; | ||
53 | unsigned char keyin_set, tmp; | ||
54 | int i, k; | ||
55 | |||
56 | dev_dbg(&pdev->dev, "isr!\n"); | ||
57 | |||
58 | keys1 = ~0; | ||
59 | keys0 = 0; | ||
60 | |||
61 | do { | ||
62 | keys = 0; | ||
63 | keyin_set = 0; | ||
64 | |||
65 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | ||
66 | |||
67 | for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { | ||
68 | iowrite16(0xfff ^ (3 << (i * 2)), | ||
69 | priv->iomem_base + KYOUTDR_OFFS); | ||
70 | udelay(pdata->delay); | ||
71 | tmp = ioread16(priv->iomem_base + KYINDR_OFFS); | ||
72 | keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i); | ||
73 | tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1; | ||
74 | keyin_set |= tmp; | ||
75 | } | ||
76 | |||
77 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | ||
78 | iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), | ||
79 | priv->iomem_base + KYCR2_OFFS); | ||
80 | |||
81 | keys ^= ~0; | ||
82 | keys &= (1 << (sh_keysc_mode[pdata->mode].keyin * | ||
83 | sh_keysc_mode[pdata->mode].keyout)) - 1; | ||
84 | keys1 &= keys; | ||
85 | keys0 |= keys; | ||
86 | |||
87 | dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); | ||
88 | |||
89 | } while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); | ||
90 | |||
91 | dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", | ||
92 | priv->last_keys, keys0, keys1); | ||
93 | |||
94 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | ||
95 | k = pdata->keycodes[i]; | ||
96 | if (!k) | ||
97 | continue; | ||
98 | |||
99 | mask = 1 << i; | ||
100 | |||
101 | if (!((priv->last_keys ^ keys0) & mask)) | ||
102 | continue; | ||
103 | |||
104 | if ((keys1 | keys0) & mask) { | ||
105 | input_event(priv->input, EV_KEY, k, 1); | ||
106 | priv->last_keys |= mask; | ||
107 | } | ||
108 | |||
109 | if (!(keys1 & mask)) { | ||
110 | input_event(priv->input, EV_KEY, k, 0); | ||
111 | priv->last_keys &= ~mask; | ||
112 | } | ||
113 | |||
114 | } | ||
115 | input_sync(priv->input); | ||
116 | |||
117 | return IRQ_HANDLED; | ||
118 | } | ||
119 | |||
120 | #define res_size(res) ((res)->end - (res)->start + 1) | ||
121 | |||
122 | static int __devinit sh_keysc_probe(struct platform_device *pdev) | ||
123 | { | ||
124 | struct sh_keysc_priv *priv; | ||
125 | struct sh_keysc_info *pdata; | ||
126 | struct resource *res; | ||
127 | struct input_dev *input; | ||
128 | int i, k; | ||
129 | int irq, error; | ||
130 | |||
131 | if (!pdev->dev.platform_data) { | ||
132 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
133 | error = -EINVAL; | ||
134 | goto err0; | ||
135 | } | ||
136 | |||
137 | error = -ENXIO; | ||
138 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
139 | if (res == NULL) { | ||
140 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
141 | goto err0; | ||
142 | } | ||
143 | |||
144 | irq = platform_get_irq(pdev, 0); | ||
145 | if (irq < 0) { | ||
146 | dev_err(&pdev->dev, "failed to get irq\n"); | ||
147 | goto err0; | ||
148 | } | ||
149 | |||
150 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
151 | if (priv == NULL) { | ||
152 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
153 | error = -ENOMEM; | ||
154 | goto err0; | ||
155 | } | ||
156 | |||
157 | platform_set_drvdata(pdev, priv); | ||
158 | memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); | ||
159 | pdata = &priv->pdata; | ||
160 | |||
161 | res = request_mem_region(res->start, res_size(res), pdev->name); | ||
162 | if (res == NULL) { | ||
163 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
164 | error = -EBUSY; | ||
165 | goto err1; | ||
166 | } | ||
167 | |||
168 | priv->iomem_base = ioremap_nocache(res->start, res_size(res)); | ||
169 | if (priv->iomem_base == NULL) { | ||
170 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
171 | error = -ENXIO; | ||
172 | goto err2; | ||
173 | } | ||
174 | |||
175 | priv->input = input_allocate_device(); | ||
176 | if (!priv->input) { | ||
177 | dev_err(&pdev->dev, "failed to allocate input device\n"); | ||
178 | error = -ENOMEM; | ||
179 | goto err3; | ||
180 | } | ||
181 | |||
182 | input = priv->input; | ||
183 | input->evbit[0] = BIT_MASK(EV_KEY); | ||
184 | |||
185 | input->name = pdev->name; | ||
186 | input->phys = "sh-keysc-keys/input0"; | ||
187 | input->dev.parent = &pdev->dev; | ||
188 | |||
189 | input->id.bustype = BUS_HOST; | ||
190 | input->id.vendor = 0x0001; | ||
191 | input->id.product = 0x0001; | ||
192 | input->id.version = 0x0100; | ||
193 | |||
194 | error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); | ||
195 | if (error) { | ||
196 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
197 | goto err4; | ||
198 | } | ||
199 | |||
200 | for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { | ||
201 | k = pdata->keycodes[i]; | ||
202 | if (k) | ||
203 | input_set_capability(input, EV_KEY, k); | ||
204 | } | ||
205 | |||
206 | error = input_register_device(input); | ||
207 | if (error) { | ||
208 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
209 | goto err5; | ||
210 | } | ||
211 | |||
212 | iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | | ||
213 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | ||
214 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | ||
215 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | ||
216 | return 0; | ||
217 | err5: | ||
218 | free_irq(irq, pdev); | ||
219 | err4: | ||
220 | input_free_device(input); | ||
221 | err3: | ||
222 | iounmap(priv->iomem_base); | ||
223 | err2: | ||
224 | release_mem_region(res->start, res_size(res)); | ||
225 | err1: | ||
226 | platform_set_drvdata(pdev, NULL); | ||
227 | kfree(priv); | ||
228 | err0: | ||
229 | return error; | ||
230 | } | ||
231 | |||
232 | static int __devexit sh_keysc_remove(struct platform_device *pdev) | ||
233 | { | ||
234 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | ||
235 | struct resource *res; | ||
236 | |||
237 | iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); | ||
238 | |||
239 | input_unregister_device(priv->input); | ||
240 | free_irq(platform_get_irq(pdev, 0), pdev); | ||
241 | iounmap(priv->iomem_base); | ||
242 | |||
243 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
244 | release_mem_region(res->start, res_size(res)); | ||
245 | |||
246 | platform_set_drvdata(pdev, NULL); | ||
247 | kfree(priv); | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | |||
252 | #define sh_keysc_suspend NULL | ||
253 | #define sh_keysc_resume NULL | ||
254 | |||
255 | struct platform_driver sh_keysc_device_driver = { | ||
256 | .probe = sh_keysc_probe, | ||
257 | .remove = __devexit_p(sh_keysc_remove), | ||
258 | .suspend = sh_keysc_suspend, | ||
259 | .resume = sh_keysc_resume, | ||
260 | .driver = { | ||
261 | .name = "sh_keysc", | ||
262 | } | ||
263 | }; | ||
264 | |||
265 | static int __init sh_keysc_init(void) | ||
266 | { | ||
267 | return platform_driver_register(&sh_keysc_device_driver); | ||
268 | } | ||
269 | |||
270 | static void __exit sh_keysc_exit(void) | ||
271 | { | ||
272 | platform_driver_unregister(&sh_keysc_device_driver); | ||
273 | } | ||
274 | |||
275 | module_init(sh_keysc_init); | ||
276 | module_exit(sh_keysc_exit); | ||
277 | |||
278 | MODULE_AUTHOR("Magnus Damm"); | ||
279 | MODULE_DESCRIPTION("SuperH KEYSC Keypad Driver"); | ||
280 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 9e9caa5d7f5f..c594b34c6767 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * SuperH On-Chip RTC Support | 2 | * SuperH On-Chip RTC Support |
3 | * | 3 | * |
4 | * Copyright (C) 2006, 2007 Paul Mundt | 4 | * Copyright (C) 2006, 2007, 2008 Paul Mundt |
5 | * Copyright (C) 2006 Jamie Lenehan | 5 | * Copyright (C) 2006 Jamie Lenehan |
6 | * Copyright (C) 2008 Angelo Castello | ||
6 | * | 7 | * |
7 | * Based on the old arch/sh/kernel/cpu/rtc.c by: | 8 | * Based on the old arch/sh/kernel/cpu/rtc.c by: |
8 | * | 9 | * |
@@ -26,7 +27,7 @@ | |||
26 | #include <asm/rtc.h> | 27 | #include <asm/rtc.h> |
27 | 28 | ||
28 | #define DRV_NAME "sh-rtc" | 29 | #define DRV_NAME "sh-rtc" |
29 | #define DRV_VERSION "0.1.6" | 30 | #define DRV_VERSION "0.2.0" |
30 | 31 | ||
31 | #define RTC_REG(r) ((r) * rtc_reg_size) | 32 | #define RTC_REG(r) ((r) * rtc_reg_size) |
32 | 33 | ||
@@ -63,6 +64,13 @@ | |||
63 | /* ALARM Bits - or with BCD encoded value */ | 64 | /* ALARM Bits - or with BCD encoded value */ |
64 | #define AR_ENB 0x80 /* Enable for alarm cmp */ | 65 | #define AR_ENB 0x80 /* Enable for alarm cmp */ |
65 | 66 | ||
67 | /* Period Bits */ | ||
68 | #define PF_HP 0x100 /* Enable Half Period to support 8,32,128Hz */ | ||
69 | #define PF_COUNT 0x200 /* Half periodic counter */ | ||
70 | #define PF_OXS 0x400 /* Periodic One x Second */ | ||
71 | #define PF_KOU 0x800 /* Kernel or User periodic request 1=kernel */ | ||
72 | #define PF_MASK 0xf00 | ||
73 | |||
66 | /* RCR1 Bits */ | 74 | /* RCR1 Bits */ |
67 | #define RCR1_CF 0x80 /* Carry Flag */ | 75 | #define RCR1_CF 0x80 /* Carry Flag */ |
68 | #define RCR1_CIE 0x10 /* Carry Interrupt Enable */ | 76 | #define RCR1_CIE 0x10 /* Carry Interrupt Enable */ |
@@ -84,33 +92,24 @@ struct sh_rtc { | |||
84 | unsigned int alarm_irq, periodic_irq, carry_irq; | 92 | unsigned int alarm_irq, periodic_irq, carry_irq; |
85 | struct rtc_device *rtc_dev; | 93 | struct rtc_device *rtc_dev; |
86 | spinlock_t lock; | 94 | spinlock_t lock; |
87 | int rearm_aie; | ||
88 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ | 95 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ |
96 | unsigned short periodic_freq; | ||
89 | }; | 97 | }; |
90 | 98 | ||
91 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | 99 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) |
92 | { | 100 | { |
93 | struct platform_device *pdev = to_platform_device(dev_id); | 101 | struct sh_rtc *rtc = dev_id; |
94 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 102 | unsigned int tmp; |
95 | unsigned int tmp, events = 0; | ||
96 | 103 | ||
97 | spin_lock(&rtc->lock); | 104 | spin_lock(&rtc->lock); |
98 | 105 | ||
99 | tmp = readb(rtc->regbase + RCR1); | 106 | tmp = readb(rtc->regbase + RCR1); |
100 | tmp &= ~RCR1_CF; | 107 | tmp &= ~RCR1_CF; |
101 | |||
102 | if (rtc->rearm_aie) { | ||
103 | if (tmp & RCR1_AF) | ||
104 | tmp &= ~RCR1_AF; /* try to clear AF again */ | ||
105 | else { | ||
106 | tmp |= RCR1_AIE; /* AF has cleared, rearm IRQ */ | ||
107 | rtc->rearm_aie = 0; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | writeb(tmp, rtc->regbase + RCR1); | 108 | writeb(tmp, rtc->regbase + RCR1); |
112 | 109 | ||
113 | rtc_update_irq(rtc->rtc_dev, 1, events); | 110 | /* Users have requested One x Second IRQ */ |
111 | if (rtc->periodic_freq & PF_OXS) | ||
112 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); | ||
114 | 113 | ||
115 | spin_unlock(&rtc->lock); | 114 | spin_unlock(&rtc->lock); |
116 | 115 | ||
@@ -119,47 +118,48 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | |||
119 | 118 | ||
120 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) | 119 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) |
121 | { | 120 | { |
122 | struct platform_device *pdev = to_platform_device(dev_id); | 121 | struct sh_rtc *rtc = dev_id; |
123 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 122 | unsigned int tmp; |
124 | unsigned int tmp, events = 0; | ||
125 | 123 | ||
126 | spin_lock(&rtc->lock); | 124 | spin_lock(&rtc->lock); |
127 | 125 | ||
128 | tmp = readb(rtc->regbase + RCR1); | 126 | tmp = readb(rtc->regbase + RCR1); |
129 | 127 | tmp &= ~(RCR1_AF | RCR1_AIE); | |
130 | /* | ||
131 | * If AF is set then the alarm has triggered. If we clear AF while | ||
132 | * the alarm time still matches the RTC time then AF will | ||
133 | * immediately be set again, and if AIE is enabled then the alarm | ||
134 | * interrupt will immediately be retrigger. So we clear AIE here | ||
135 | * and use rtc->rearm_aie so that the carry interrupt will keep | ||
136 | * trying to clear AF and once it stays cleared it'll re-enable | ||
137 | * AIE. | ||
138 | */ | ||
139 | if (tmp & RCR1_AF) { | ||
140 | events |= RTC_AF | RTC_IRQF; | ||
141 | |||
142 | tmp &= ~(RCR1_AF|RCR1_AIE); | ||
143 | |||
144 | writeb(tmp, rtc->regbase + RCR1); | 128 | writeb(tmp, rtc->regbase + RCR1); |
145 | 129 | ||
146 | rtc->rearm_aie = 1; | 130 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); |
147 | |||
148 | rtc_update_irq(rtc->rtc_dev, 1, events); | ||
149 | } | ||
150 | 131 | ||
151 | spin_unlock(&rtc->lock); | 132 | spin_unlock(&rtc->lock); |
133 | |||
152 | return IRQ_HANDLED; | 134 | return IRQ_HANDLED; |
153 | } | 135 | } |
154 | 136 | ||
155 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | 137 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) |
156 | { | 138 | { |
157 | struct platform_device *pdev = to_platform_device(dev_id); | 139 | struct sh_rtc *rtc = dev_id; |
158 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 140 | struct rtc_device *rtc_dev = rtc->rtc_dev; |
141 | unsigned int tmp; | ||
159 | 142 | ||
160 | spin_lock(&rtc->lock); | 143 | spin_lock(&rtc->lock); |
161 | 144 | ||
162 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); | 145 | tmp = readb(rtc->regbase + RCR2); |
146 | tmp &= ~RCR2_PEF; | ||
147 | writeb(tmp, rtc->regbase + RCR2); | ||
148 | |||
149 | /* Half period enabled than one skipped and the next notified */ | ||
150 | if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT)) | ||
151 | rtc->periodic_freq &= ~PF_COUNT; | ||
152 | else { | ||
153 | if (rtc->periodic_freq & PF_HP) | ||
154 | rtc->periodic_freq |= PF_COUNT; | ||
155 | if (rtc->periodic_freq & PF_KOU) { | ||
156 | spin_lock(&rtc_dev->irq_task_lock); | ||
157 | if (rtc_dev->irq_task) | ||
158 | rtc_dev->irq_task->func(rtc_dev->irq_task->private_data); | ||
159 | spin_unlock(&rtc_dev->irq_task_lock); | ||
160 | } else | ||
161 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); | ||
162 | } | ||
163 | 163 | ||
164 | spin_unlock(&rtc->lock); | 164 | spin_unlock(&rtc->lock); |
165 | 165 | ||
@@ -176,8 +176,8 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) | |||
176 | tmp = readb(rtc->regbase + RCR2); | 176 | tmp = readb(rtc->regbase + RCR2); |
177 | 177 | ||
178 | if (enable) { | 178 | if (enable) { |
179 | tmp &= ~RCR2_PESMASK; | 179 | tmp &= ~RCR2_PEF; /* Clear PES bit */ |
180 | tmp |= RCR2_PEF | (2 << 4); | 180 | tmp |= (rtc->periodic_freq & ~PF_HP); /* Set PES2-0 */ |
181 | } else | 181 | } else |
182 | tmp &= ~(RCR2_PESMASK | RCR2_PEF); | 182 | tmp &= ~(RCR2_PESMASK | RCR2_PEF); |
183 | 183 | ||
@@ -186,82 +186,81 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) | |||
186 | spin_unlock_irq(&rtc->lock); | 186 | spin_unlock_irq(&rtc->lock); |
187 | } | 187 | } |
188 | 188 | ||
189 | static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) | 189 | static inline int sh_rtc_setfreq(struct device *dev, unsigned int freq) |
190 | { | 190 | { |
191 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 191 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
192 | unsigned int tmp; | 192 | int tmp, ret = 0; |
193 | 193 | ||
194 | spin_lock_irq(&rtc->lock); | 194 | spin_lock_irq(&rtc->lock); |
195 | tmp = rtc->periodic_freq & PF_MASK; | ||
195 | 196 | ||
196 | tmp = readb(rtc->regbase + RCR1); | 197 | switch (freq) { |
197 | 198 | case 0: | |
198 | if (!enable) { | 199 | rtc->periodic_freq = 0x00; |
199 | tmp &= ~RCR1_AIE; | 200 | break; |
200 | rtc->rearm_aie = 0; | 201 | case 1: |
201 | } else if (rtc->rearm_aie == 0) | 202 | rtc->periodic_freq = 0x60; |
202 | tmp |= RCR1_AIE; | 203 | break; |
204 | case 2: | ||
205 | rtc->periodic_freq = 0x50; | ||
206 | break; | ||
207 | case 4: | ||
208 | rtc->periodic_freq = 0x40; | ||
209 | break; | ||
210 | case 8: | ||
211 | rtc->periodic_freq = 0x30 | PF_HP; | ||
212 | break; | ||
213 | case 16: | ||
214 | rtc->periodic_freq = 0x30; | ||
215 | break; | ||
216 | case 32: | ||
217 | rtc->periodic_freq = 0x20 | PF_HP; | ||
218 | break; | ||
219 | case 64: | ||
220 | rtc->periodic_freq = 0x20; | ||
221 | break; | ||
222 | case 128: | ||
223 | rtc->periodic_freq = 0x10 | PF_HP; | ||
224 | break; | ||
225 | case 256: | ||
226 | rtc->periodic_freq = 0x10; | ||
227 | break; | ||
228 | default: | ||
229 | ret = -ENOTSUPP; | ||
230 | } | ||
203 | 231 | ||
204 | writeb(tmp, rtc->regbase + RCR1); | 232 | if (ret == 0) { |
233 | rtc->periodic_freq |= tmp; | ||
234 | rtc->rtc_dev->irq_freq = freq; | ||
235 | } | ||
205 | 236 | ||
206 | spin_unlock_irq(&rtc->lock); | 237 | spin_unlock_irq(&rtc->lock); |
238 | return ret; | ||
207 | } | 239 | } |
208 | 240 | ||
209 | static int sh_rtc_open(struct device *dev) | 241 | static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) |
210 | { | 242 | { |
211 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 243 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
212 | unsigned int tmp; | 244 | unsigned int tmp; |
213 | int ret; | ||
214 | |||
215 | tmp = readb(rtc->regbase + RCR1); | ||
216 | tmp &= ~RCR1_CF; | ||
217 | tmp |= RCR1_CIE; | ||
218 | writeb(tmp, rtc->regbase + RCR1); | ||
219 | 245 | ||
220 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, | 246 | spin_lock_irq(&rtc->lock); |
221 | "sh-rtc period", dev); | ||
222 | if (unlikely(ret)) { | ||
223 | dev_err(dev, "request period IRQ failed with %d, IRQ %d\n", | ||
224 | ret, rtc->periodic_irq); | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, | ||
229 | "sh-rtc carry", dev); | ||
230 | if (unlikely(ret)) { | ||
231 | dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n", | ||
232 | ret, rtc->carry_irq); | ||
233 | free_irq(rtc->periodic_irq, dev); | ||
234 | goto err_bad_carry; | ||
235 | } | ||
236 | 247 | ||
237 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, | 248 | tmp = readb(rtc->regbase + RCR1); |
238 | "sh-rtc alarm", dev); | ||
239 | if (unlikely(ret)) { | ||
240 | dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n", | ||
241 | ret, rtc->alarm_irq); | ||
242 | goto err_bad_alarm; | ||
243 | } | ||
244 | 249 | ||
245 | return 0; | 250 | if (!enable) |
251 | tmp &= ~RCR1_AIE; | ||
252 | else | ||
253 | tmp |= RCR1_AIE; | ||
246 | 254 | ||
247 | err_bad_alarm: | 255 | writeb(tmp, rtc->regbase + RCR1); |
248 | free_irq(rtc->carry_irq, dev); | ||
249 | err_bad_carry: | ||
250 | free_irq(rtc->periodic_irq, dev); | ||
251 | 256 | ||
252 | return ret; | 257 | spin_unlock_irq(&rtc->lock); |
253 | } | 258 | } |
254 | 259 | ||
255 | static void sh_rtc_release(struct device *dev) | 260 | static void sh_rtc_release(struct device *dev) |
256 | { | 261 | { |
257 | struct sh_rtc *rtc = dev_get_drvdata(dev); | ||
258 | |||
259 | sh_rtc_setpie(dev, 0); | 262 | sh_rtc_setpie(dev, 0); |
260 | sh_rtc_setaie(dev, 0); | 263 | sh_rtc_setaie(dev, 0); |
261 | |||
262 | free_irq(rtc->periodic_irq, dev); | ||
263 | free_irq(rtc->carry_irq, dev); | ||
264 | free_irq(rtc->alarm_irq, dev); | ||
265 | } | 264 | } |
266 | 265 | ||
267 | static int sh_rtc_proc(struct device *dev, struct seq_file *seq) | 266 | static int sh_rtc_proc(struct device *dev, struct seq_file *seq) |
@@ -270,31 +269,44 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq) | |||
270 | unsigned int tmp; | 269 | unsigned int tmp; |
271 | 270 | ||
272 | tmp = readb(rtc->regbase + RCR1); | 271 | tmp = readb(rtc->regbase + RCR1); |
273 | seq_printf(seq, "carry_IRQ\t: %s\n", | 272 | seq_printf(seq, "carry_IRQ\t: %s\n", (tmp & RCR1_CIE) ? "yes" : "no"); |
274 | (tmp & RCR1_CIE) ? "yes" : "no"); | ||
275 | 273 | ||
276 | tmp = readb(rtc->regbase + RCR2); | 274 | tmp = readb(rtc->regbase + RCR2); |
277 | seq_printf(seq, "periodic_IRQ\t: %s\n", | 275 | seq_printf(seq, "periodic_IRQ\t: %s\n", |
278 | (tmp & RCR2_PEF) ? "yes" : "no"); | 276 | (tmp & RCR2_PESMASK) ? "yes" : "no"); |
279 | 277 | ||
280 | return 0; | 278 | return 0; |
281 | } | 279 | } |
282 | 280 | ||
283 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 281 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
284 | { | 282 | { |
285 | unsigned int ret = -ENOIOCTLCMD; | 283 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
284 | unsigned int ret = 0; | ||
286 | 285 | ||
287 | switch (cmd) { | 286 | switch (cmd) { |
288 | case RTC_PIE_OFF: | 287 | case RTC_PIE_OFF: |
289 | case RTC_PIE_ON: | 288 | case RTC_PIE_ON: |
290 | sh_rtc_setpie(dev, cmd == RTC_PIE_ON); | 289 | sh_rtc_setpie(dev, cmd == RTC_PIE_ON); |
291 | ret = 0; | ||
292 | break; | 290 | break; |
293 | case RTC_AIE_OFF: | 291 | case RTC_AIE_OFF: |
294 | case RTC_AIE_ON: | 292 | case RTC_AIE_ON: |
295 | sh_rtc_setaie(dev, cmd == RTC_AIE_ON); | 293 | sh_rtc_setaie(dev, cmd == RTC_AIE_ON); |
296 | ret = 0; | ||
297 | break; | 294 | break; |
295 | case RTC_UIE_OFF: | ||
296 | rtc->periodic_freq &= ~PF_OXS; | ||
297 | break; | ||
298 | case RTC_UIE_ON: | ||
299 | rtc->periodic_freq |= PF_OXS; | ||
300 | break; | ||
301 | case RTC_IRQP_READ: | ||
302 | ret = put_user(rtc->rtc_dev->irq_freq, | ||
303 | (unsigned long __user *)arg); | ||
304 | break; | ||
305 | case RTC_IRQP_SET: | ||
306 | ret = sh_rtc_setfreq(dev, arg); | ||
307 | break; | ||
308 | default: | ||
309 | ret = -ENOIOCTLCMD; | ||
298 | } | 310 | } |
299 | 311 | ||
300 | return ret; | 312 | return ret; |
@@ -421,7 +433,7 @@ static int sh_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
421 | { | 433 | { |
422 | struct platform_device *pdev = to_platform_device(dev); | 434 | struct platform_device *pdev = to_platform_device(dev); |
423 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 435 | struct sh_rtc *rtc = platform_get_drvdata(pdev); |
424 | struct rtc_time* tm = &wkalrm->time; | 436 | struct rtc_time *tm = &wkalrm->time; |
425 | 437 | ||
426 | spin_lock_irq(&rtc->lock); | 438 | spin_lock_irq(&rtc->lock); |
427 | 439 | ||
@@ -452,7 +464,7 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, | |||
452 | writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off); | 464 | writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off); |
453 | } | 465 | } |
454 | 466 | ||
455 | static int sh_rtc_check_alarm(struct rtc_time* tm) | 467 | static int sh_rtc_check_alarm(struct rtc_time *tm) |
456 | { | 468 | { |
457 | /* | 469 | /* |
458 | * The original rtc says anything > 0xc0 is "don't care" or "match | 470 | * The original rtc says anything > 0xc0 is "don't care" or "match |
@@ -503,11 +515,9 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
503 | 515 | ||
504 | /* disable alarm interrupt and clear the alarm flag */ | 516 | /* disable alarm interrupt and clear the alarm flag */ |
505 | rcr1 = readb(rtc->regbase + RCR1); | 517 | rcr1 = readb(rtc->regbase + RCR1); |
506 | rcr1 &= ~(RCR1_AF|RCR1_AIE); | 518 | rcr1 &= ~(RCR1_AF | RCR1_AIE); |
507 | writeb(rcr1, rtc->regbase + RCR1); | 519 | writeb(rcr1, rtc->regbase + RCR1); |
508 | 520 | ||
509 | rtc->rearm_aie = 0; | ||
510 | |||
511 | /* set alarm time */ | 521 | /* set alarm time */ |
512 | sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR); | 522 | sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR); |
513 | sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR); | 523 | sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR); |
@@ -529,14 +539,34 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
529 | return 0; | 539 | return 0; |
530 | } | 540 | } |
531 | 541 | ||
542 | static int sh_rtc_irq_set_state(struct device *dev, int enabled) | ||
543 | { | ||
544 | struct platform_device *pdev = to_platform_device(dev); | ||
545 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | ||
546 | |||
547 | if (enabled) { | ||
548 | rtc->periodic_freq |= PF_KOU; | ||
549 | return sh_rtc_ioctl(dev, RTC_PIE_ON, 0); | ||
550 | } else { | ||
551 | rtc->periodic_freq &= ~PF_KOU; | ||
552 | return sh_rtc_ioctl(dev, RTC_PIE_OFF, 0); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | static int sh_rtc_irq_set_freq(struct device *dev, int freq) | ||
557 | { | ||
558 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); | ||
559 | } | ||
560 | |||
532 | static struct rtc_class_ops sh_rtc_ops = { | 561 | static struct rtc_class_ops sh_rtc_ops = { |
533 | .open = sh_rtc_open, | ||
534 | .release = sh_rtc_release, | 562 | .release = sh_rtc_release, |
535 | .ioctl = sh_rtc_ioctl, | 563 | .ioctl = sh_rtc_ioctl, |
536 | .read_time = sh_rtc_read_time, | 564 | .read_time = sh_rtc_read_time, |
537 | .set_time = sh_rtc_set_time, | 565 | .set_time = sh_rtc_set_time, |
538 | .read_alarm = sh_rtc_read_alarm, | 566 | .read_alarm = sh_rtc_read_alarm, |
539 | .set_alarm = sh_rtc_set_alarm, | 567 | .set_alarm = sh_rtc_set_alarm, |
568 | .irq_set_state = sh_rtc_irq_set_state, | ||
569 | .irq_set_freq = sh_rtc_irq_set_freq, | ||
540 | .proc = sh_rtc_proc, | 570 | .proc = sh_rtc_proc, |
541 | }; | 571 | }; |
542 | 572 | ||
@@ -544,6 +574,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
544 | { | 574 | { |
545 | struct sh_rtc *rtc; | 575 | struct sh_rtc *rtc; |
546 | struct resource *res; | 576 | struct resource *res; |
577 | unsigned int tmp; | ||
547 | int ret = -ENOENT; | 578 | int ret = -ENOENT; |
548 | 579 | ||
549 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); | 580 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); |
@@ -552,6 +583,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
552 | 583 | ||
553 | spin_lock_init(&rtc->lock); | 584 | spin_lock_init(&rtc->lock); |
554 | 585 | ||
586 | /* get periodic/carry/alarm irqs */ | ||
555 | rtc->periodic_irq = platform_get_irq(pdev, 0); | 587 | rtc->periodic_irq = platform_get_irq(pdev, 0); |
556 | if (unlikely(rtc->periodic_irq < 0)) { | 588 | if (unlikely(rtc->periodic_irq < 0)) { |
557 | dev_err(&pdev->dev, "No IRQ for period\n"); | 589 | dev_err(&pdev->dev, "No IRQ for period\n"); |
@@ -608,8 +640,48 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
608 | rtc->capabilities |= pinfo->capabilities; | 640 | rtc->capabilities |= pinfo->capabilities; |
609 | } | 641 | } |
610 | 642 | ||
643 | rtc->rtc_dev->max_user_freq = 256; | ||
644 | rtc->rtc_dev->irq_freq = 1; | ||
645 | rtc->periodic_freq = 0x60; | ||
646 | |||
611 | platform_set_drvdata(pdev, rtc); | 647 | platform_set_drvdata(pdev, rtc); |
612 | 648 | ||
649 | /* register periodic/carry/alarm irqs */ | ||
650 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, | ||
651 | "sh-rtc period", rtc); | ||
652 | if (unlikely(ret)) { | ||
653 | dev_err(&pdev->dev, | ||
654 | "request period IRQ failed with %d, IRQ %d\n", ret, | ||
655 | rtc->periodic_irq); | ||
656 | goto err_badmap; | ||
657 | } | ||
658 | |||
659 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, | ||
660 | "sh-rtc carry", rtc); | ||
661 | if (unlikely(ret)) { | ||
662 | dev_err(&pdev->dev, | ||
663 | "request carry IRQ failed with %d, IRQ %d\n", ret, | ||
664 | rtc->carry_irq); | ||
665 | free_irq(rtc->periodic_irq, rtc); | ||
666 | goto err_badmap; | ||
667 | } | ||
668 | |||
669 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, | ||
670 | "sh-rtc alarm", rtc); | ||
671 | if (unlikely(ret)) { | ||
672 | dev_err(&pdev->dev, | ||
673 | "request alarm IRQ failed with %d, IRQ %d\n", ret, | ||
674 | rtc->alarm_irq); | ||
675 | free_irq(rtc->carry_irq, rtc); | ||
676 | free_irq(rtc->periodic_irq, rtc); | ||
677 | goto err_badmap; | ||
678 | } | ||
679 | |||
680 | tmp = readb(rtc->regbase + RCR1); | ||
681 | tmp &= ~RCR1_CF; | ||
682 | tmp |= RCR1_CIE; | ||
683 | writeb(tmp, rtc->regbase + RCR1); | ||
684 | |||
613 | return 0; | 685 | return 0; |
614 | 686 | ||
615 | err_badmap: | 687 | err_badmap: |
@@ -630,6 +702,10 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev) | |||
630 | sh_rtc_setpie(&pdev->dev, 0); | 702 | sh_rtc_setpie(&pdev->dev, 0); |
631 | sh_rtc_setaie(&pdev->dev, 0); | 703 | sh_rtc_setaie(&pdev->dev, 0); |
632 | 704 | ||
705 | free_irq(rtc->carry_irq, rtc); | ||
706 | free_irq(rtc->periodic_irq, rtc); | ||
707 | free_irq(rtc->alarm_irq, rtc); | ||
708 | |||
633 | release_resource(rtc->res); | 709 | release_resource(rtc->res); |
634 | 710 | ||
635 | platform_set_drvdata(pdev, NULL); | 711 | platform_set_drvdata(pdev, NULL); |
@@ -662,6 +738,8 @@ module_exit(sh_rtc_exit); | |||
662 | 738 | ||
663 | MODULE_DESCRIPTION("SuperH on-chip RTC driver"); | 739 | MODULE_DESCRIPTION("SuperH on-chip RTC driver"); |
664 | MODULE_VERSION(DRV_VERSION); | 740 | MODULE_VERSION(DRV_VERSION); |
665 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, Jamie Lenehan <lenehan@twibble.org>"); | 741 | MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, " |
742 | "Jamie Lenehan <lenehan@twibble.org>, " | ||
743 | "Angelo Castello <angelo.castello@st.com>"); | ||
666 | MODULE_LICENSE("GPL"); | 744 | MODULE_LICENSE("GPL"); |
667 | MODULE_ALIAS("platform:" DRV_NAME); | 745 | MODULE_ALIAS("platform:" DRV_NAME); |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index eff593080d4f..c2ea5d4df44a 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -333,7 +333,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | |||
333 | } | 333 | } |
334 | sci_out(port, SCFCR, fcr_val); | 334 | sci_out(port, SCFCR, fcr_val); |
335 | } | 335 | } |
336 | |||
337 | #elif defined(CONFIG_CPU_SH3) | 336 | #elif defined(CONFIG_CPU_SH3) |
338 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ | 337 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ |
339 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 338 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) |
@@ -384,6 +383,12 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | |||
384 | 383 | ||
385 | sci_out(port, SCFCR, fcr_val); | 384 | sci_out(port, SCFCR, fcr_val); |
386 | } | 385 | } |
386 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
387 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | ||
388 | { | ||
389 | /* Nothing to do here.. */ | ||
390 | sci_out(port, SCFCR, 0); | ||
391 | } | ||
387 | #else | 392 | #else |
388 | /* For SH7750 */ | 393 | /* For SH7750 */ |
389 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) | 394 | static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 01a9dd715f5d..fa8700a968fc 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -1,20 +1,5 @@ | |||
1 | /* $Id: sh-sci.h,v 1.4 2004/02/19 16:43:56 lethal Exp $ | ||
2 | * | ||
3 | * linux/drivers/serial/sh-sci.h | ||
4 | * | ||
5 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) | ||
6 | * Copyright (C) 1999, 2000 Niibe Yutaka | ||
7 | * Copyright (C) 2000 Greg Banks | ||
8 | * Copyright (C) 2002, 2003 Paul Mundt | ||
9 | * Modified to support multiple serial ports. Stuart Menefy (May 2000). | ||
10 | * Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003). | ||
11 | * Modified to support H8/300 Series Yoshinori Sato (Feb 2004). | ||
12 | * Removed SH7300 support (Jul 2007). | ||
13 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Aug 2007). | ||
14 | */ | ||
15 | #include <linux/serial_core.h> | 1 | #include <linux/serial_core.h> |
16 | #include <asm/io.h> | 2 | #include <asm/io.h> |
17 | |||
18 | #include <asm/gpio.h> | 3 | #include <asm/gpio.h> |
19 | 4 | ||
20 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) | 5 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) |
@@ -102,6 +87,15 @@ | |||
102 | # define SCSPTR0 SCPDR0 | 87 | # define SCSPTR0 SCPDR0 |
103 | # define SCIF_ORER 0x0001 /* overrun error bit */ | 88 | # define SCIF_ORER 0x0001 /* overrun error bit */ |
104 | # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 89 | # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
90 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
91 | # define SCSPTR0 0xa4050160 | ||
92 | # define SCSPTR1 0xa405013e | ||
93 | # define SCSPTR2 0xa4050160 | ||
94 | # define SCSPTR3 0xa405013e | ||
95 | # define SCSPTR4 0xa4050128 | ||
96 | # define SCSPTR5 0xa4050128 | ||
97 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
98 | # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | ||
105 | # define SCIF_ONLY | 99 | # define SCIF_ONLY |
106 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) | 100 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) |
107 | # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ | 101 | # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ |
@@ -395,6 +389,11 @@ | |||
395 | h8_sci_offset, h8_sci_size) \ | 389 | h8_sci_offset, h8_sci_size) \ |
396 | CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size) | 390 | CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size) |
397 | #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) | 391 | #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) |
392 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
393 | #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \ | ||
394 | CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) | ||
395 | #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \ | ||
396 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) | ||
398 | #else | 397 | #else |
399 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ | 398 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ |
400 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ | 399 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ |
@@ -419,6 +418,18 @@ SCIF_FNS(SCFDR, 0x1c, 16) | |||
419 | SCIF_FNS(SCxTDR, 0x20, 8) | 418 | SCIF_FNS(SCxTDR, 0x20, 8) |
420 | SCIF_FNS(SCxRDR, 0x24, 8) | 419 | SCIF_FNS(SCxRDR, 0x24, 8) |
421 | SCIF_FNS(SCLSR, 0x24, 16) | 420 | SCIF_FNS(SCLSR, 0x24, 16) |
421 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
422 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) | ||
423 | SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8) | ||
424 | SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16) | ||
425 | SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8) | ||
426 | SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16) | ||
427 | SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8) | ||
428 | SCIF_FNS(SCTDSR, 0x0c, 8) | ||
429 | SCIF_FNS(SCFER, 0x10, 16) | ||
430 | SCIF_FNS(SCFCR, 0x18, 16) | ||
431 | SCIF_FNS(SCFDR, 0x1c, 16) | ||
432 | SCIF_FNS(SCLSR, 0x24, 16) | ||
422 | #else | 433 | #else |
423 | /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ | 434 | /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ |
424 | /* name off sz off sz off sz off sz off sz*/ | 435 | /* name off sz off sz off sz off sz off sz*/ |
@@ -589,6 +600,23 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
589 | return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ | 600 | return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ |
590 | return 1; | 601 | return 1; |
591 | } | 602 | } |
603 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
604 | static inline int sci_rxd_in(struct uart_port *port) | ||
605 | { | ||
606 | if (port->mapbase == 0xffe00000) | ||
607 | return ctrl_inb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */ | ||
608 | if (port->mapbase == 0xffe10000) | ||
609 | return ctrl_inb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */ | ||
610 | if (port->mapbase == 0xffe20000) | ||
611 | return ctrl_inb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */ | ||
612 | if (port->mapbase == 0xa4e30000) | ||
613 | return ctrl_inb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */ | ||
614 | if (port->mapbase == 0xa4e40000) | ||
615 | return ctrl_inb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */ | ||
616 | if (port->mapbase == 0xa4e50000) | ||
617 | return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ | ||
618 | return 1; | ||
619 | } | ||
592 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | 620 | #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) |
593 | static inline int sci_rxd_in(struct uart_port *port) | 621 | static inline int sci_rxd_in(struct uart_port *port) |
594 | { | 622 | { |
@@ -727,6 +755,8 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
727 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 755 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
728 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 756 | defined(CONFIG_CPU_SUBTYPE_SH7721) |
729 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) | 757 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) |
758 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
759 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(16*bps)-1) | ||
730 | #elif defined(__H8300H__) || defined(__H8300S__) | 760 | #elif defined(__H8300H__) || defined(__H8300S__) |
731 | #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) | 761 | #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) |
732 | #elif defined(CONFIG_SUPERH64) | 762 | #elif defined(CONFIG_SUPERH64) |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index b8ea11fee5c6..de876fa793e1 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
15 | #include <linux/mount.h> | ||
15 | #include <linux/smp_lock.h> | 16 | #include <linux/smp_lock.h> |
16 | #include <asm/current.h> | 17 | #include <asm/current.h> |
17 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
@@ -23,6 +24,7 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
23 | struct ext2_inode_info *ei = EXT2_I(inode); | 24 | struct ext2_inode_info *ei = EXT2_I(inode); |
24 | unsigned int flags; | 25 | unsigned int flags; |
25 | unsigned short rsv_window_size; | 26 | unsigned short rsv_window_size; |
27 | int ret; | ||
26 | 28 | ||
27 | ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg); | 29 | ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg); |
28 | 30 | ||
@@ -34,14 +36,19 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
34 | case EXT2_IOC_SETFLAGS: { | 36 | case EXT2_IOC_SETFLAGS: { |
35 | unsigned int oldflags; | 37 | unsigned int oldflags; |
36 | 38 | ||
37 | if (IS_RDONLY(inode)) | 39 | ret = mnt_want_write(filp->f_path.mnt); |
38 | return -EROFS; | 40 | if (ret) |
41 | return ret; | ||
39 | 42 | ||
40 | if (!is_owner_or_cap(inode)) | 43 | if (!is_owner_or_cap(inode)) { |
41 | return -EACCES; | 44 | ret = -EACCES; |
45 | goto setflags_out; | ||
46 | } | ||
42 | 47 | ||
43 | if (get_user(flags, (int __user *) arg)) | 48 | if (get_user(flags, (int __user *) arg)) { |
44 | return -EFAULT; | 49 | ret = -EFAULT; |
50 | goto setflags_out; | ||
51 | } | ||
45 | 52 | ||
46 | if (!S_ISDIR(inode->i_mode)) | 53 | if (!S_ISDIR(inode->i_mode)) |
47 | flags &= ~EXT2_DIRSYNC_FL; | 54 | flags &= ~EXT2_DIRSYNC_FL; |
@@ -50,7 +57,8 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
50 | /* Is it quota file? Do not allow user to mess with it */ | 57 | /* Is it quota file? Do not allow user to mess with it */ |
51 | if (IS_NOQUOTA(inode)) { | 58 | if (IS_NOQUOTA(inode)) { |
52 | mutex_unlock(&inode->i_mutex); | 59 | mutex_unlock(&inode->i_mutex); |
53 | return -EPERM; | 60 | ret = -EPERM; |
61 | goto setflags_out; | ||
54 | } | 62 | } |
55 | oldflags = ei->i_flags; | 63 | oldflags = ei->i_flags; |
56 | 64 | ||
@@ -63,7 +71,8 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
63 | if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { | 71 | if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { |
64 | if (!capable(CAP_LINUX_IMMUTABLE)) { | 72 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
65 | mutex_unlock(&inode->i_mutex); | 73 | mutex_unlock(&inode->i_mutex); |
66 | return -EPERM; | 74 | ret = -EPERM; |
75 | goto setflags_out; | ||
67 | } | 76 | } |
68 | } | 77 | } |
69 | 78 | ||
@@ -75,20 +84,26 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
75 | ext2_set_inode_flags(inode); | 84 | ext2_set_inode_flags(inode); |
76 | inode->i_ctime = CURRENT_TIME_SEC; | 85 | inode->i_ctime = CURRENT_TIME_SEC; |
77 | mark_inode_dirty(inode); | 86 | mark_inode_dirty(inode); |
78 | return 0; | 87 | setflags_out: |
88 | mnt_drop_write(filp->f_path.mnt); | ||
89 | return ret; | ||
79 | } | 90 | } |
80 | case EXT2_IOC_GETVERSION: | 91 | case EXT2_IOC_GETVERSION: |
81 | return put_user(inode->i_generation, (int __user *) arg); | 92 | return put_user(inode->i_generation, (int __user *) arg); |
82 | case EXT2_IOC_SETVERSION: | 93 | case EXT2_IOC_SETVERSION: |
83 | if (!is_owner_or_cap(inode)) | 94 | if (!is_owner_or_cap(inode)) |
84 | return -EPERM; | 95 | return -EPERM; |
85 | if (IS_RDONLY(inode)) | 96 | ret = mnt_want_write(filp->f_path.mnt); |
86 | return -EROFS; | 97 | if (ret) |
87 | if (get_user(inode->i_generation, (int __user *) arg)) | 98 | return ret; |
88 | return -EFAULT; | 99 | if (get_user(inode->i_generation, (int __user *) arg)) { |
89 | inode->i_ctime = CURRENT_TIME_SEC; | 100 | ret = -EFAULT; |
90 | mark_inode_dirty(inode); | 101 | } else { |
91 | return 0; | 102 | inode->i_ctime = CURRENT_TIME_SEC; |
103 | mark_inode_dirty(inode); | ||
104 | } | ||
105 | mnt_drop_write(filp->f_path.mnt); | ||
106 | return ret; | ||
92 | case EXT2_IOC_GETRSVSZ: | 107 | case EXT2_IOC_GETRSVSZ: |
93 | if (test_opt(inode->i_sb, RESERVATION) | 108 | if (test_opt(inode->i_sb, RESERVATION) |
94 | && S_ISREG(inode->i_mode) | 109 | && S_ISREG(inode->i_mode) |
@@ -102,15 +117,16 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
102 | if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) | 117 | if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) |
103 | return -ENOTTY; | 118 | return -ENOTTY; |
104 | 119 | ||
105 | if (IS_RDONLY(inode)) | 120 | if (!is_owner_or_cap(inode)) |
106 | return -EROFS; | ||
107 | |||
108 | if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) | ||
109 | return -EACCES; | 121 | return -EACCES; |
110 | 122 | ||
111 | if (get_user(rsv_window_size, (int __user *)arg)) | 123 | if (get_user(rsv_window_size, (int __user *)arg)) |
112 | return -EFAULT; | 124 | return -EFAULT; |
113 | 125 | ||
126 | ret = mnt_want_write(filp->f_path.mnt); | ||
127 | if (ret) | ||
128 | return ret; | ||
129 | |||
114 | if (rsv_window_size > EXT2_MAX_RESERVE_BLOCKS) | 130 | if (rsv_window_size > EXT2_MAX_RESERVE_BLOCKS) |
115 | rsv_window_size = EXT2_MAX_RESERVE_BLOCKS; | 131 | rsv_window_size = EXT2_MAX_RESERVE_BLOCKS; |
116 | 132 | ||
@@ -131,6 +147,7 @@ long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
131 | rsv->rsv_goal_size = rsv_window_size; | 147 | rsv->rsv_goal_size = rsv_window_size; |
132 | } | 148 | } |
133 | mutex_unlock(&ei->truncate_mutex); | 149 | mutex_unlock(&ei->truncate_mutex); |
150 | mnt_drop_write(filp->f_path.mnt); | ||
134 | return 0; | 151 | return 0; |
135 | } | 152 | } |
136 | default: | 153 | default: |
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 023a070f55f1..0d0c70151642 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
13 | #include <linux/ext3_fs.h> | 13 | #include <linux/ext3_fs.h> |
14 | #include <linux/ext3_jbd.h> | 14 | #include <linux/ext3_jbd.h> |
15 | #include <linux/mount.h> | ||
15 | #include <linux/time.h> | 16 | #include <linux/time.h> |
16 | #include <linux/compat.h> | 17 | #include <linux/compat.h> |
17 | #include <linux/smp_lock.h> | 18 | #include <linux/smp_lock.h> |
@@ -38,14 +39,19 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
38 | unsigned int oldflags; | 39 | unsigned int oldflags; |
39 | unsigned int jflag; | 40 | unsigned int jflag; |
40 | 41 | ||
41 | if (IS_RDONLY(inode)) | 42 | err = mnt_want_write(filp->f_path.mnt); |
42 | return -EROFS; | 43 | if (err) |
44 | return err; | ||
43 | 45 | ||
44 | if (!is_owner_or_cap(inode)) | 46 | if (!is_owner_or_cap(inode)) { |
45 | return -EACCES; | 47 | err = -EACCES; |
48 | goto flags_out; | ||
49 | } | ||
46 | 50 | ||
47 | if (get_user(flags, (int __user *) arg)) | 51 | if (get_user(flags, (int __user *) arg)) { |
48 | return -EFAULT; | 52 | err = -EFAULT; |
53 | goto flags_out; | ||
54 | } | ||
49 | 55 | ||
50 | if (!S_ISDIR(inode->i_mode)) | 56 | if (!S_ISDIR(inode->i_mode)) |
51 | flags &= ~EXT3_DIRSYNC_FL; | 57 | flags &= ~EXT3_DIRSYNC_FL; |
@@ -54,7 +60,8 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
54 | /* Is it quota file? Do not allow user to mess with it */ | 60 | /* Is it quota file? Do not allow user to mess with it */ |
55 | if (IS_NOQUOTA(inode)) { | 61 | if (IS_NOQUOTA(inode)) { |
56 | mutex_unlock(&inode->i_mutex); | 62 | mutex_unlock(&inode->i_mutex); |
57 | return -EPERM; | 63 | err = -EPERM; |
64 | goto flags_out; | ||
58 | } | 65 | } |
59 | oldflags = ei->i_flags; | 66 | oldflags = ei->i_flags; |
60 | 67 | ||
@@ -70,7 +77,8 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
70 | if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { | 77 | if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { |
71 | if (!capable(CAP_LINUX_IMMUTABLE)) { | 78 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
72 | mutex_unlock(&inode->i_mutex); | 79 | mutex_unlock(&inode->i_mutex); |
73 | return -EPERM; | 80 | err = -EPERM; |
81 | goto flags_out; | ||
74 | } | 82 | } |
75 | } | 83 | } |
76 | 84 | ||
@@ -81,7 +89,8 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
81 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) { | 89 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) { |
82 | if (!capable(CAP_SYS_RESOURCE)) { | 90 | if (!capable(CAP_SYS_RESOURCE)) { |
83 | mutex_unlock(&inode->i_mutex); | 91 | mutex_unlock(&inode->i_mutex); |
84 | return -EPERM; | 92 | err = -EPERM; |
93 | goto flags_out; | ||
85 | } | 94 | } |
86 | } | 95 | } |
87 | 96 | ||
@@ -89,7 +98,8 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
89 | handle = ext3_journal_start(inode, 1); | 98 | handle = ext3_journal_start(inode, 1); |
90 | if (IS_ERR(handle)) { | 99 | if (IS_ERR(handle)) { |
91 | mutex_unlock(&inode->i_mutex); | 100 | mutex_unlock(&inode->i_mutex); |
92 | return PTR_ERR(handle); | 101 | err = PTR_ERR(handle); |
102 | goto flags_out; | ||
93 | } | 103 | } |
94 | if (IS_SYNC(inode)) | 104 | if (IS_SYNC(inode)) |
95 | handle->h_sync = 1; | 105 | handle->h_sync = 1; |
@@ -115,6 +125,8 @@ flags_err: | |||
115 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) | 125 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) |
116 | err = ext3_change_inode_journal_flag(inode, jflag); | 126 | err = ext3_change_inode_journal_flag(inode, jflag); |
117 | mutex_unlock(&inode->i_mutex); | 127 | mutex_unlock(&inode->i_mutex); |
128 | flags_out: | ||
129 | mnt_drop_write(filp->f_path.mnt); | ||
118 | return err; | 130 | return err; |
119 | } | 131 | } |
120 | case EXT3_IOC_GETVERSION: | 132 | case EXT3_IOC_GETVERSION: |
@@ -129,14 +141,18 @@ flags_err: | |||
129 | 141 | ||
130 | if (!is_owner_or_cap(inode)) | 142 | if (!is_owner_or_cap(inode)) |
131 | return -EPERM; | 143 | return -EPERM; |
132 | if (IS_RDONLY(inode)) | 144 | err = mnt_want_write(filp->f_path.mnt); |
133 | return -EROFS; | 145 | if (err) |
134 | if (get_user(generation, (int __user *) arg)) | 146 | return err; |
135 | return -EFAULT; | 147 | if (get_user(generation, (int __user *) arg)) { |
136 | 148 | err = -EFAULT; | |
149 | goto setversion_out; | ||
150 | } | ||
137 | handle = ext3_journal_start(inode, 1); | 151 | handle = ext3_journal_start(inode, 1); |
138 | if (IS_ERR(handle)) | 152 | if (IS_ERR(handle)) { |
139 | return PTR_ERR(handle); | 153 | err = PTR_ERR(handle); |
154 | goto setversion_out; | ||
155 | } | ||
140 | err = ext3_reserve_inode_write(handle, inode, &iloc); | 156 | err = ext3_reserve_inode_write(handle, inode, &iloc); |
141 | if (err == 0) { | 157 | if (err == 0) { |
142 | inode->i_ctime = CURRENT_TIME_SEC; | 158 | inode->i_ctime = CURRENT_TIME_SEC; |
@@ -144,6 +160,8 @@ flags_err: | |||
144 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); | 160 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); |
145 | } | 161 | } |
146 | ext3_journal_stop(handle); | 162 | ext3_journal_stop(handle); |
163 | setversion_out: | ||
164 | mnt_drop_write(filp->f_path.mnt); | ||
147 | return err; | 165 | return err; |
148 | } | 166 | } |
149 | #ifdef CONFIG_JBD_DEBUG | 167 | #ifdef CONFIG_JBD_DEBUG |
@@ -179,18 +197,24 @@ flags_err: | |||
179 | } | 197 | } |
180 | return -ENOTTY; | 198 | return -ENOTTY; |
181 | case EXT3_IOC_SETRSVSZ: { | 199 | case EXT3_IOC_SETRSVSZ: { |
200 | int err; | ||
182 | 201 | ||
183 | if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) | 202 | if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) |
184 | return -ENOTTY; | 203 | return -ENOTTY; |
185 | 204 | ||
186 | if (IS_RDONLY(inode)) | 205 | err = mnt_want_write(filp->f_path.mnt); |
187 | return -EROFS; | 206 | if (err) |
207 | return err; | ||
188 | 208 | ||
189 | if (!is_owner_or_cap(inode)) | 209 | if (!is_owner_or_cap(inode)) { |
190 | return -EACCES; | 210 | err = -EACCES; |
211 | goto setrsvsz_out; | ||
212 | } | ||
191 | 213 | ||
192 | if (get_user(rsv_window_size, (int __user *)arg)) | 214 | if (get_user(rsv_window_size, (int __user *)arg)) { |
193 | return -EFAULT; | 215 | err = -EFAULT; |
216 | goto setrsvsz_out; | ||
217 | } | ||
194 | 218 | ||
195 | if (rsv_window_size > EXT3_MAX_RESERVE_BLOCKS) | 219 | if (rsv_window_size > EXT3_MAX_RESERVE_BLOCKS) |
196 | rsv_window_size = EXT3_MAX_RESERVE_BLOCKS; | 220 | rsv_window_size = EXT3_MAX_RESERVE_BLOCKS; |
@@ -208,7 +232,9 @@ flags_err: | |||
208 | rsv->rsv_goal_size = rsv_window_size; | 232 | rsv->rsv_goal_size = rsv_window_size; |
209 | } | 233 | } |
210 | mutex_unlock(&ei->truncate_mutex); | 234 | mutex_unlock(&ei->truncate_mutex); |
211 | return 0; | 235 | setrsvsz_out: |
236 | mnt_drop_write(filp->f_path.mnt); | ||
237 | return err; | ||
212 | } | 238 | } |
213 | case EXT3_IOC_GROUP_EXTEND: { | 239 | case EXT3_IOC_GROUP_EXTEND: { |
214 | ext3_fsblk_t n_blocks_count; | 240 | ext3_fsblk_t n_blocks_count; |
@@ -218,17 +244,20 @@ flags_err: | |||
218 | if (!capable(CAP_SYS_RESOURCE)) | 244 | if (!capable(CAP_SYS_RESOURCE)) |
219 | return -EPERM; | 245 | return -EPERM; |
220 | 246 | ||
221 | if (IS_RDONLY(inode)) | 247 | err = mnt_want_write(filp->f_path.mnt); |
222 | return -EROFS; | 248 | if (err) |
223 | 249 | return err; | |
224 | if (get_user(n_blocks_count, (__u32 __user *)arg)) | ||
225 | return -EFAULT; | ||
226 | 250 | ||
251 | if (get_user(n_blocks_count, (__u32 __user *)arg)) { | ||
252 | err = -EFAULT; | ||
253 | goto group_extend_out; | ||
254 | } | ||
227 | err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count); | 255 | err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count); |
228 | journal_lock_updates(EXT3_SB(sb)->s_journal); | 256 | journal_lock_updates(EXT3_SB(sb)->s_journal); |
229 | journal_flush(EXT3_SB(sb)->s_journal); | 257 | journal_flush(EXT3_SB(sb)->s_journal); |
230 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | 258 | journal_unlock_updates(EXT3_SB(sb)->s_journal); |
231 | 259 | group_extend_out: | |
260 | mnt_drop_write(filp->f_path.mnt); | ||
232 | return err; | 261 | return err; |
233 | } | 262 | } |
234 | case EXT3_IOC_GROUP_ADD: { | 263 | case EXT3_IOC_GROUP_ADD: { |
@@ -239,18 +268,22 @@ flags_err: | |||
239 | if (!capable(CAP_SYS_RESOURCE)) | 268 | if (!capable(CAP_SYS_RESOURCE)) |
240 | return -EPERM; | 269 | return -EPERM; |
241 | 270 | ||
242 | if (IS_RDONLY(inode)) | 271 | err = mnt_want_write(filp->f_path.mnt); |
243 | return -EROFS; | 272 | if (err) |
273 | return err; | ||
244 | 274 | ||
245 | if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg, | 275 | if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg, |
246 | sizeof(input))) | 276 | sizeof(input))) { |
247 | return -EFAULT; | 277 | err = -EFAULT; |
278 | goto group_add_out; | ||
279 | } | ||
248 | 280 | ||
249 | err = ext3_group_add(sb, &input); | 281 | err = ext3_group_add(sb, &input); |
250 | journal_lock_updates(EXT3_SB(sb)->s_journal); | 282 | journal_lock_updates(EXT3_SB(sb)->s_journal); |
251 | journal_flush(EXT3_SB(sb)->s_journal); | 283 | journal_flush(EXT3_SB(sb)->s_journal); |
252 | journal_unlock_updates(EXT3_SB(sb)->s_journal); | 284 | journal_unlock_updates(EXT3_SB(sb)->s_journal); |
253 | 285 | group_add_out: | |
286 | mnt_drop_write(filp->f_path.mnt); | ||
254 | return err; | 287 | return err; |
255 | } | 288 | } |
256 | 289 | ||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 2ed7c37f897e..25b13ede8086 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/time.h> | 15 | #include <linux/time.h> |
16 | #include <linux/compat.h> | 16 | #include <linux/compat.h> |
17 | #include <linux/smp_lock.h> | 17 | #include <linux/smp_lock.h> |
18 | #include <linux/mount.h> | ||
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
19 | 20 | ||
20 | int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | 21 | int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, |
@@ -38,24 +39,25 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
38 | unsigned int oldflags; | 39 | unsigned int oldflags; |
39 | unsigned int jflag; | 40 | unsigned int jflag; |
40 | 41 | ||
41 | if (IS_RDONLY(inode)) | ||
42 | return -EROFS; | ||
43 | |||
44 | if (!is_owner_or_cap(inode)) | 42 | if (!is_owner_or_cap(inode)) |
45 | return -EACCES; | 43 | return -EACCES; |
46 | 44 | ||
47 | if (get_user(flags, (int __user *) arg)) | 45 | if (get_user(flags, (int __user *) arg)) |
48 | return -EFAULT; | 46 | return -EFAULT; |
49 | 47 | ||
48 | err = mnt_want_write(filp->f_path.mnt); | ||
49 | if (err) | ||
50 | return err; | ||
51 | |||
50 | if (!S_ISDIR(inode->i_mode)) | 52 | if (!S_ISDIR(inode->i_mode)) |
51 | flags &= ~EXT4_DIRSYNC_FL; | 53 | flags &= ~EXT4_DIRSYNC_FL; |
52 | 54 | ||
55 | err = -EPERM; | ||
53 | mutex_lock(&inode->i_mutex); | 56 | mutex_lock(&inode->i_mutex); |
54 | /* Is it quota file? Do not allow user to mess with it */ | 57 | /* Is it quota file? Do not allow user to mess with it */ |
55 | if (IS_NOQUOTA(inode)) { | 58 | if (IS_NOQUOTA(inode)) |
56 | mutex_unlock(&inode->i_mutex); | 59 | goto flags_out; |
57 | return -EPERM; | 60 | |
58 | } | ||
59 | oldflags = ei->i_flags; | 61 | oldflags = ei->i_flags; |
60 | 62 | ||
61 | /* The JOURNAL_DATA flag is modifiable only by root */ | 63 | /* The JOURNAL_DATA flag is modifiable only by root */ |
@@ -68,10 +70,8 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
68 | * This test looks nicer. Thanks to Pauline Middelink | 70 | * This test looks nicer. Thanks to Pauline Middelink |
69 | */ | 71 | */ |
70 | if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { | 72 | if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { |
71 | if (!capable(CAP_LINUX_IMMUTABLE)) { | 73 | if (!capable(CAP_LINUX_IMMUTABLE)) |
72 | mutex_unlock(&inode->i_mutex); | 74 | goto flags_out; |
73 | return -EPERM; | ||
74 | } | ||
75 | } | 75 | } |
76 | 76 | ||
77 | /* | 77 | /* |
@@ -79,17 +79,14 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
79 | * the relevant capability. | 79 | * the relevant capability. |
80 | */ | 80 | */ |
81 | if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { | 81 | if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) { |
82 | if (!capable(CAP_SYS_RESOURCE)) { | 82 | if (!capable(CAP_SYS_RESOURCE)) |
83 | mutex_unlock(&inode->i_mutex); | 83 | goto flags_out; |
84 | return -EPERM; | ||
85 | } | ||
86 | } | 84 | } |
87 | 85 | ||
88 | |||
89 | handle = ext4_journal_start(inode, 1); | 86 | handle = ext4_journal_start(inode, 1); |
90 | if (IS_ERR(handle)) { | 87 | if (IS_ERR(handle)) { |
91 | mutex_unlock(&inode->i_mutex); | 88 | err = PTR_ERR(handle); |
92 | return PTR_ERR(handle); | 89 | goto flags_out; |
93 | } | 90 | } |
94 | if (IS_SYNC(inode)) | 91 | if (IS_SYNC(inode)) |
95 | handle->h_sync = 1; | 92 | handle->h_sync = 1; |
@@ -107,14 +104,14 @@ int ext4_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
107 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 104 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
108 | flags_err: | 105 | flags_err: |
109 | ext4_journal_stop(handle); | 106 | ext4_journal_stop(handle); |
110 | if (err) { | 107 | if (err) |
111 | mutex_unlock(&inode->i_mutex); | 108 | goto flags_out; |
112 | return err; | ||
113 | } | ||
114 | 109 | ||
115 | if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) | 110 | if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) |
116 | err = ext4_change_inode_journal_flag(inode, jflag); | 111 | err = ext4_change_inode_journal_flag(inode, jflag); |
112 | flags_out: | ||
117 | mutex_unlock(&inode->i_mutex); | 113 | mutex_unlock(&inode->i_mutex); |
114 | mnt_drop_write(filp->f_path.mnt); | ||
118 | return err; | 115 | return err; |
119 | } | 116 | } |
120 | case EXT4_IOC_GETVERSION: | 117 | case EXT4_IOC_GETVERSION: |
@@ -129,14 +126,20 @@ flags_err: | |||
129 | 126 | ||
130 | if (!is_owner_or_cap(inode)) | 127 | if (!is_owner_or_cap(inode)) |
131 | return -EPERM; | 128 | return -EPERM; |
132 | if (IS_RDONLY(inode)) | 129 | |
133 | return -EROFS; | 130 | err = mnt_want_write(filp->f_path.mnt); |
134 | if (get_user(generation, (int __user *) arg)) | 131 | if (err) |
135 | return -EFAULT; | 132 | return err; |
133 | if (get_user(generation, (int __user *) arg)) { | ||
134 | err = -EFAULT; | ||
135 | goto setversion_out; | ||
136 | } | ||
136 | 137 | ||
137 | handle = ext4_journal_start(inode, 1); | 138 | handle = ext4_journal_start(inode, 1); |
138 | if (IS_ERR(handle)) | 139 | if (IS_ERR(handle)) { |
139 | return PTR_ERR(handle); | 140 | err = PTR_ERR(handle); |
141 | goto setversion_out; | ||
142 | } | ||
140 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 143 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
141 | if (err == 0) { | 144 | if (err == 0) { |
142 | inode->i_ctime = ext4_current_time(inode); | 145 | inode->i_ctime = ext4_current_time(inode); |
@@ -144,6 +147,8 @@ flags_err: | |||
144 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); | 147 | err = ext4_mark_iloc_dirty(handle, inode, &iloc); |
145 | } | 148 | } |
146 | ext4_journal_stop(handle); | 149 | ext4_journal_stop(handle); |
150 | setversion_out: | ||
151 | mnt_drop_write(filp->f_path.mnt); | ||
147 | return err; | 152 | return err; |
148 | } | 153 | } |
149 | #ifdef CONFIG_JBD2_DEBUG | 154 | #ifdef CONFIG_JBD2_DEBUG |
@@ -179,19 +184,21 @@ flags_err: | |||
179 | } | 184 | } |
180 | return -ENOTTY; | 185 | return -ENOTTY; |
181 | case EXT4_IOC_SETRSVSZ: { | 186 | case EXT4_IOC_SETRSVSZ: { |
187 | int err; | ||
182 | 188 | ||
183 | if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) | 189 | if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode)) |
184 | return -ENOTTY; | 190 | return -ENOTTY; |
185 | 191 | ||
186 | if (IS_RDONLY(inode)) | ||
187 | return -EROFS; | ||
188 | |||
189 | if (!is_owner_or_cap(inode)) | 192 | if (!is_owner_or_cap(inode)) |
190 | return -EACCES; | 193 | return -EACCES; |
191 | 194 | ||
192 | if (get_user(rsv_window_size, (int __user *)arg)) | 195 | if (get_user(rsv_window_size, (int __user *)arg)) |
193 | return -EFAULT; | 196 | return -EFAULT; |
194 | 197 | ||
198 | err = mnt_want_write(filp->f_path.mnt); | ||
199 | if (err) | ||
200 | return err; | ||
201 | |||
195 | if (rsv_window_size > EXT4_MAX_RESERVE_BLOCKS) | 202 | if (rsv_window_size > EXT4_MAX_RESERVE_BLOCKS) |
196 | rsv_window_size = EXT4_MAX_RESERVE_BLOCKS; | 203 | rsv_window_size = EXT4_MAX_RESERVE_BLOCKS; |
197 | 204 | ||
@@ -208,6 +215,7 @@ flags_err: | |||
208 | rsv->rsv_goal_size = rsv_window_size; | 215 | rsv->rsv_goal_size = rsv_window_size; |
209 | } | 216 | } |
210 | up_write(&ei->i_data_sem); | 217 | up_write(&ei->i_data_sem); |
218 | mnt_drop_write(filp->f_path.mnt); | ||
211 | return 0; | 219 | return 0; |
212 | } | 220 | } |
213 | case EXT4_IOC_GROUP_EXTEND: { | 221 | case EXT4_IOC_GROUP_EXTEND: { |
@@ -218,16 +226,18 @@ flags_err: | |||
218 | if (!capable(CAP_SYS_RESOURCE)) | 226 | if (!capable(CAP_SYS_RESOURCE)) |
219 | return -EPERM; | 227 | return -EPERM; |
220 | 228 | ||
221 | if (IS_RDONLY(inode)) | ||
222 | return -EROFS; | ||
223 | |||
224 | if (get_user(n_blocks_count, (__u32 __user *)arg)) | 229 | if (get_user(n_blocks_count, (__u32 __user *)arg)) |
225 | return -EFAULT; | 230 | return -EFAULT; |
226 | 231 | ||
232 | err = mnt_want_write(filp->f_path.mnt); | ||
233 | if (err) | ||
234 | return err; | ||
235 | |||
227 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); | 236 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); |
228 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 237 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
229 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 238 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
230 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 239 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
240 | mnt_drop_write(filp->f_path.mnt); | ||
231 | 241 | ||
232 | return err; | 242 | return err; |
233 | } | 243 | } |
@@ -239,17 +249,19 @@ flags_err: | |||
239 | if (!capable(CAP_SYS_RESOURCE)) | 249 | if (!capable(CAP_SYS_RESOURCE)) |
240 | return -EPERM; | 250 | return -EPERM; |
241 | 251 | ||
242 | if (IS_RDONLY(inode)) | ||
243 | return -EROFS; | ||
244 | |||
245 | if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg, | 252 | if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg, |
246 | sizeof(input))) | 253 | sizeof(input))) |
247 | return -EFAULT; | 254 | return -EFAULT; |
248 | 255 | ||
256 | err = mnt_want_write(filp->f_path.mnt); | ||
257 | if (err) | ||
258 | return err; | ||
259 | |||
249 | err = ext4_group_add(sb, &input); | 260 | err = ext4_group_add(sb, &input); |
250 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 261 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
251 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 262 | jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
252 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 263 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
264 | mnt_drop_write(filp->f_path.mnt); | ||
253 | 265 | ||
254 | return err; | 266 | return err; |
255 | } | 267 | } |
diff --git a/fs/fat/file.c b/fs/fat/file.c index c614175876e0..2a3bed967041 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/capability.h> | 9 | #include <linux/capability.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/mount.h> | ||
11 | #include <linux/time.h> | 12 | #include <linux/time.h> |
12 | #include <linux/msdos_fs.h> | 13 | #include <linux/msdos_fs.h> |
13 | #include <linux/smp_lock.h> | 14 | #include <linux/smp_lock.h> |
@@ -46,10 +47,9 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, | |||
46 | 47 | ||
47 | mutex_lock(&inode->i_mutex); | 48 | mutex_lock(&inode->i_mutex); |
48 | 49 | ||
49 | if (IS_RDONLY(inode)) { | 50 | err = mnt_want_write(filp->f_path.mnt); |
50 | err = -EROFS; | 51 | if (err) |
51 | goto up; | 52 | goto up_no_drop_write; |
52 | } | ||
53 | 53 | ||
54 | /* | 54 | /* |
55 | * ATTR_VOLUME and ATTR_DIR cannot be changed; this also | 55 | * ATTR_VOLUME and ATTR_DIR cannot be changed; this also |
@@ -105,7 +105,9 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, | |||
105 | 105 | ||
106 | MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED; | 106 | MSDOS_I(inode)->i_attrs = attr & ATTR_UNUSED; |
107 | mark_inode_dirty(inode); | 107 | mark_inode_dirty(inode); |
108 | up: | 108 | up: |
109 | mnt_drop_write(filp->f_path.mnt); | ||
110 | up_no_drop_write: | ||
109 | mutex_unlock(&inode->i_mutex); | 111 | mutex_unlock(&inode->i_mutex); |
110 | return err; | 112 | return err; |
111 | } | 113 | } |
diff --git a/fs/file_table.c b/fs/file_table.c index 986ff4ed0a7c..7a0a9b872251 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -42,6 +42,7 @@ static inline void file_free_rcu(struct rcu_head *head) | |||
42 | static inline void file_free(struct file *f) | 42 | static inline void file_free(struct file *f) |
43 | { | 43 | { |
44 | percpu_counter_dec(&nr_files); | 44 | percpu_counter_dec(&nr_files); |
45 | file_check_state(f); | ||
45 | call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); | 46 | call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); |
46 | } | 47 | } |
47 | 48 | ||
@@ -199,6 +200,18 @@ int init_file(struct file *file, struct vfsmount *mnt, struct dentry *dentry, | |||
199 | file->f_mapping = dentry->d_inode->i_mapping; | 200 | file->f_mapping = dentry->d_inode->i_mapping; |
200 | file->f_mode = mode; | 201 | file->f_mode = mode; |
201 | file->f_op = fop; | 202 | file->f_op = fop; |
203 | |||
204 | /* | ||
205 | * These mounts don't really matter in practice | ||
206 | * for r/o bind mounts. They aren't userspace- | ||
207 | * visible. We do this for consistency, and so | ||
208 | * that we can do debugging checks at __fput() | ||
209 | */ | ||
210 | if ((mode & FMODE_WRITE) && !special_file(dentry->d_inode->i_mode)) { | ||
211 | file_take_write(file); | ||
212 | error = mnt_want_write(mnt); | ||
213 | WARN_ON(error); | ||
214 | } | ||
202 | return error; | 215 | return error; |
203 | } | 216 | } |
204 | EXPORT_SYMBOL(init_file); | 217 | EXPORT_SYMBOL(init_file); |
@@ -211,6 +224,31 @@ void fput(struct file *file) | |||
211 | 224 | ||
212 | EXPORT_SYMBOL(fput); | 225 | EXPORT_SYMBOL(fput); |
213 | 226 | ||
227 | /** | ||
228 | * drop_file_write_access - give up ability to write to a file | ||
229 | * @file: the file to which we will stop writing | ||
230 | * | ||
231 | * This is a central place which will give up the ability | ||
232 | * to write to @file, along with access to write through | ||
233 | * its vfsmount. | ||
234 | */ | ||
235 | void drop_file_write_access(struct file *file) | ||
236 | { | ||
237 | struct vfsmount *mnt = file->f_path.mnt; | ||
238 | struct dentry *dentry = file->f_path.dentry; | ||
239 | struct inode *inode = dentry->d_inode; | ||
240 | |||
241 | put_write_access(inode); | ||
242 | |||
243 | if (special_file(inode->i_mode)) | ||
244 | return; | ||
245 | if (file_check_writeable(file) != 0) | ||
246 | return; | ||
247 | mnt_drop_write(mnt); | ||
248 | file_release_write(file); | ||
249 | } | ||
250 | EXPORT_SYMBOL_GPL(drop_file_write_access); | ||
251 | |||
214 | /* __fput is called from task context when aio completion releases the last | 252 | /* __fput is called from task context when aio completion releases the last |
215 | * last use of a struct file *. Do not use otherwise. | 253 | * last use of a struct file *. Do not use otherwise. |
216 | */ | 254 | */ |
@@ -236,10 +274,10 @@ void __fput(struct file *file) | |||
236 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) | 274 | if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) |
237 | cdev_put(inode->i_cdev); | 275 | cdev_put(inode->i_cdev); |
238 | fops_put(file->f_op); | 276 | fops_put(file->f_op); |
239 | if (file->f_mode & FMODE_WRITE) | ||
240 | put_write_access(inode); | ||
241 | put_pid(file->f_owner.pid); | 277 | put_pid(file->f_owner.pid); |
242 | file_kill(file); | 278 | file_kill(file); |
279 | if (file->f_mode & FMODE_WRITE) | ||
280 | drop_file_write_access(file); | ||
243 | file->f_path.dentry = NULL; | 281 | file->f_path.dentry = NULL; |
244 | file->f_path.mnt = NULL; | 282 | file->f_path.mnt = NULL; |
245 | file_free(file); | 283 | file_free(file); |
diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index b60c0affbec5..f457d2ca51ab 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/capability.h> | 15 | #include <linux/capability.h> |
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/mount.h> | ||
17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
18 | #include <linux/xattr.h> | 19 | #include <linux/xattr.h> |
19 | #include <asm/uaccess.h> | 20 | #include <asm/uaccess.h> |
@@ -35,25 +36,32 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
35 | flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */ | 36 | flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */ |
36 | return put_user(flags, (int __user *)arg); | 37 | return put_user(flags, (int __user *)arg); |
37 | case HFSPLUS_IOC_EXT2_SETFLAGS: { | 38 | case HFSPLUS_IOC_EXT2_SETFLAGS: { |
38 | if (IS_RDONLY(inode)) | 39 | int err = 0; |
39 | return -EROFS; | 40 | err = mnt_want_write(filp->f_path.mnt); |
40 | 41 | if (err) | |
41 | if (!is_owner_or_cap(inode)) | 42 | return err; |
42 | return -EACCES; | 43 | |
43 | 44 | if (!is_owner_or_cap(inode)) { | |
44 | if (get_user(flags, (int __user *)arg)) | 45 | err = -EACCES; |
45 | return -EFAULT; | 46 | goto setflags_out; |
46 | 47 | } | |
48 | if (get_user(flags, (int __user *)arg)) { | ||
49 | err = -EFAULT; | ||
50 | goto setflags_out; | ||
51 | } | ||
47 | if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || | 52 | if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || |
48 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { | 53 | HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { |
49 | if (!capable(CAP_LINUX_IMMUTABLE)) | 54 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
50 | return -EPERM; | 55 | err = -EPERM; |
56 | goto setflags_out; | ||
57 | } | ||
51 | } | 58 | } |
52 | 59 | ||
53 | /* don't silently ignore unsupported ext2 flags */ | 60 | /* don't silently ignore unsupported ext2 flags */ |
54 | if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) | 61 | if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { |
55 | return -EOPNOTSUPP; | 62 | err = -EOPNOTSUPP; |
56 | 63 | goto setflags_out; | |
64 | } | ||
57 | if (flags & FS_IMMUTABLE_FL) { /* EXT2_IMMUTABLE_FL */ | 65 | if (flags & FS_IMMUTABLE_FL) { /* EXT2_IMMUTABLE_FL */ |
58 | inode->i_flags |= S_IMMUTABLE; | 66 | inode->i_flags |= S_IMMUTABLE; |
59 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; | 67 | HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; |
@@ -75,7 +83,9 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
75 | 83 | ||
76 | inode->i_ctime = CURRENT_TIME_SEC; | 84 | inode->i_ctime = CURRENT_TIME_SEC; |
77 | mark_inode_dirty(inode); | 85 | mark_inode_dirty(inode); |
78 | return 0; | 86 | setflags_out: |
87 | mnt_drop_write(filp->f_path.mnt); | ||
88 | return err; | ||
79 | } | 89 | } |
80 | default: | 90 | default: |
81 | return -ENOTTY; | 91 | return -ENOTTY; |
diff --git a/fs/inode.c b/fs/inode.c index 53245ffcf93d..27ee1af50d02 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -1199,42 +1199,37 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry) | |||
1199 | struct inode *inode = dentry->d_inode; | 1199 | struct inode *inode = dentry->d_inode; |
1200 | struct timespec now; | 1200 | struct timespec now; |
1201 | 1201 | ||
1202 | if (inode->i_flags & S_NOATIME) | 1202 | if (mnt_want_write(mnt)) |
1203 | return; | 1203 | return; |
1204 | if (inode->i_flags & S_NOATIME) | ||
1205 | goto out; | ||
1204 | if (IS_NOATIME(inode)) | 1206 | if (IS_NOATIME(inode)) |
1205 | return; | 1207 | goto out; |
1206 | if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) | 1208 | if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) |
1207 | return; | 1209 | goto out; |
1208 | 1210 | ||
1209 | /* | 1211 | if (mnt->mnt_flags & MNT_NOATIME) |
1210 | * We may have a NULL vfsmount when coming from NFSD | 1212 | goto out; |
1211 | */ | 1213 | if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) |
1212 | if (mnt) { | 1214 | goto out; |
1213 | if (mnt->mnt_flags & MNT_NOATIME) | 1215 | if (mnt->mnt_flags & MNT_RELATIME) { |
1214 | return; | 1216 | /* |
1215 | if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) | 1217 | * With relative atime, only update atime if the previous |
1216 | return; | 1218 | * atime is earlier than either the ctime or mtime. |
1217 | 1219 | */ | |
1218 | if (mnt->mnt_flags & MNT_RELATIME) { | 1220 | if (timespec_compare(&inode->i_mtime, &inode->i_atime) < 0 && |
1219 | /* | 1221 | timespec_compare(&inode->i_ctime, &inode->i_atime) < 0) |
1220 | * With relative atime, only update atime if the | 1222 | goto out; |
1221 | * previous atime is earlier than either the ctime or | ||
1222 | * mtime. | ||
1223 | */ | ||
1224 | if (timespec_compare(&inode->i_mtime, | ||
1225 | &inode->i_atime) < 0 && | ||
1226 | timespec_compare(&inode->i_ctime, | ||
1227 | &inode->i_atime) < 0) | ||
1228 | return; | ||
1229 | } | ||
1230 | } | 1223 | } |
1231 | 1224 | ||
1232 | now = current_fs_time(inode->i_sb); | 1225 | now = current_fs_time(inode->i_sb); |
1233 | if (timespec_equal(&inode->i_atime, &now)) | 1226 | if (timespec_equal(&inode->i_atime, &now)) |
1234 | return; | 1227 | goto out; |
1235 | 1228 | ||
1236 | inode->i_atime = now; | 1229 | inode->i_atime = now; |
1237 | mark_inode_dirty_sync(inode); | 1230 | mark_inode_dirty_sync(inode); |
1231 | out: | ||
1232 | mnt_drop_write(mnt); | ||
1238 | } | 1233 | } |
1239 | EXPORT_SYMBOL(touch_atime); | 1234 | EXPORT_SYMBOL(touch_atime); |
1240 | 1235 | ||
@@ -1255,10 +1250,13 @@ void file_update_time(struct file *file) | |||
1255 | struct inode *inode = file->f_path.dentry->d_inode; | 1250 | struct inode *inode = file->f_path.dentry->d_inode; |
1256 | struct timespec now; | 1251 | struct timespec now; |
1257 | int sync_it = 0; | 1252 | int sync_it = 0; |
1253 | int err; | ||
1258 | 1254 | ||
1259 | if (IS_NOCMTIME(inode)) | 1255 | if (IS_NOCMTIME(inode)) |
1260 | return; | 1256 | return; |
1261 | if (IS_RDONLY(inode)) | 1257 | |
1258 | err = mnt_want_write(file->f_path.mnt); | ||
1259 | if (err) | ||
1262 | return; | 1260 | return; |
1263 | 1261 | ||
1264 | now = current_fs_time(inode->i_sb); | 1262 | now = current_fs_time(inode->i_sb); |
@@ -1279,6 +1277,7 @@ void file_update_time(struct file *file) | |||
1279 | 1277 | ||
1280 | if (sync_it) | 1278 | if (sync_it) |
1281 | mark_inode_dirty_sync(inode); | 1279 | mark_inode_dirty_sync(inode); |
1280 | mnt_drop_write(file->f_path.mnt); | ||
1282 | } | 1281 | } |
1283 | 1282 | ||
1284 | EXPORT_SYMBOL(file_update_time); | 1283 | EXPORT_SYMBOL(file_update_time); |
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index a1f8e375ad21..afe222bf300f 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/ctype.h> | 9 | #include <linux/ctype.h> |
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/mount.h> | ||
11 | #include <linux/time.h> | 12 | #include <linux/time.h> |
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include <asm/current.h> | 14 | #include <asm/current.h> |
@@ -65,23 +66,30 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
65 | return put_user(flags, (int __user *) arg); | 66 | return put_user(flags, (int __user *) arg); |
66 | case JFS_IOC_SETFLAGS: { | 67 | case JFS_IOC_SETFLAGS: { |
67 | unsigned int oldflags; | 68 | unsigned int oldflags; |
69 | int err; | ||
68 | 70 | ||
69 | if (IS_RDONLY(inode)) | 71 | err = mnt_want_write(filp->f_path.mnt); |
70 | return -EROFS; | 72 | if (err) |
73 | return err; | ||
71 | 74 | ||
72 | if (!is_owner_or_cap(inode)) | 75 | if (!is_owner_or_cap(inode)) { |
73 | return -EACCES; | 76 | err = -EACCES; |
74 | 77 | goto setflags_out; | |
75 | if (get_user(flags, (int __user *) arg)) | 78 | } |
76 | return -EFAULT; | 79 | if (get_user(flags, (int __user *) arg)) { |
80 | err = -EFAULT; | ||
81 | goto setflags_out; | ||
82 | } | ||
77 | 83 | ||
78 | flags = jfs_map_ext2(flags, 1); | 84 | flags = jfs_map_ext2(flags, 1); |
79 | if (!S_ISDIR(inode->i_mode)) | 85 | if (!S_ISDIR(inode->i_mode)) |
80 | flags &= ~JFS_DIRSYNC_FL; | 86 | flags &= ~JFS_DIRSYNC_FL; |
81 | 87 | ||
82 | /* Is it quota file? Do not allow user to mess with it */ | 88 | /* Is it quota file? Do not allow user to mess with it */ |
83 | if (IS_NOQUOTA(inode)) | 89 | if (IS_NOQUOTA(inode)) { |
84 | return -EPERM; | 90 | err = -EPERM; |
91 | goto setflags_out; | ||
92 | } | ||
85 | 93 | ||
86 | /* Lock against other parallel changes of flags */ | 94 | /* Lock against other parallel changes of flags */ |
87 | mutex_lock(&inode->i_mutex); | 95 | mutex_lock(&inode->i_mutex); |
@@ -98,7 +106,8 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
98 | (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) { | 106 | (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) { |
99 | if (!capable(CAP_LINUX_IMMUTABLE)) { | 107 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
100 | mutex_unlock(&inode->i_mutex); | 108 | mutex_unlock(&inode->i_mutex); |
101 | return -EPERM; | 109 | err = -EPERM; |
110 | goto setflags_out; | ||
102 | } | 111 | } |
103 | } | 112 | } |
104 | 113 | ||
@@ -110,7 +119,9 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
110 | mutex_unlock(&inode->i_mutex); | 119 | mutex_unlock(&inode->i_mutex); |
111 | inode->i_ctime = CURRENT_TIME_SEC; | 120 | inode->i_ctime = CURRENT_TIME_SEC; |
112 | mark_inode_dirty(inode); | 121 | mark_inode_dirty(inode); |
113 | return 0; | 122 | setflags_out: |
123 | mnt_drop_write(filp->f_path.mnt); | ||
124 | return err; | ||
114 | } | 125 | } |
115 | default: | 126 | default: |
116 | return -ENOTTY; | 127 | return -ENOTTY; |
diff --git a/fs/namei.c b/fs/namei.c index 8cf9bb9c2fc0..e179f71bfcb0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1623,8 +1623,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1623 | return -EACCES; | 1623 | return -EACCES; |
1624 | 1624 | ||
1625 | flag &= ~O_TRUNC; | 1625 | flag &= ~O_TRUNC; |
1626 | } else if (IS_RDONLY(inode) && (acc_mode & MAY_WRITE)) | 1626 | } |
1627 | return -EROFS; | ||
1628 | 1627 | ||
1629 | error = vfs_permission(nd, acc_mode); | 1628 | error = vfs_permission(nd, acc_mode); |
1630 | if (error) | 1629 | if (error) |
@@ -1677,7 +1676,12 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1677 | return 0; | 1676 | return 0; |
1678 | } | 1677 | } |
1679 | 1678 | ||
1680 | static int open_namei_create(struct nameidata *nd, struct path *path, | 1679 | /* |
1680 | * Be careful about ever adding any more callers of this | ||
1681 | * function. Its flags must be in the namei format, not | ||
1682 | * what get passed to sys_open(). | ||
1683 | */ | ||
1684 | static int __open_namei_create(struct nameidata *nd, struct path *path, | ||
1681 | int flag, int mode) | 1685 | int flag, int mode) |
1682 | { | 1686 | { |
1683 | int error; | 1687 | int error; |
@@ -1696,26 +1700,56 @@ static int open_namei_create(struct nameidata *nd, struct path *path, | |||
1696 | } | 1700 | } |
1697 | 1701 | ||
1698 | /* | 1702 | /* |
1699 | * open_namei() | 1703 | * Note that while the flag value (low two bits) for sys_open means: |
1704 | * 00 - read-only | ||
1705 | * 01 - write-only | ||
1706 | * 10 - read-write | ||
1707 | * 11 - special | ||
1708 | * it is changed into | ||
1709 | * 00 - no permissions needed | ||
1710 | * 01 - read-permission | ||
1711 | * 10 - write-permission | ||
1712 | * 11 - read-write | ||
1713 | * for the internal routines (ie open_namei()/follow_link() etc) | ||
1714 | * This is more logical, and also allows the 00 "no perm needed" | ||
1715 | * to be used for symlinks (where the permissions are checked | ||
1716 | * later). | ||
1700 | * | 1717 | * |
1701 | * namei for open - this is in fact almost the whole open-routine. | 1718 | */ |
1702 | * | 1719 | static inline int open_to_namei_flags(int flag) |
1703 | * Note that the low bits of "flag" aren't the same as in the open | 1720 | { |
1704 | * system call - they are 00 - no permissions needed | 1721 | if ((flag+1) & O_ACCMODE) |
1705 | * 01 - read permission needed | 1722 | flag++; |
1706 | * 10 - write permission needed | 1723 | return flag; |
1707 | * 11 - read/write permissions needed | 1724 | } |
1708 | * which is a lot more logical, and also allows the "no perm" needed | 1725 | |
1709 | * for symlinks (where the permissions are checked later). | 1726 | static int open_will_write_to_fs(int flag, struct inode *inode) |
1710 | * SMP-safe | 1727 | { |
1728 | /* | ||
1729 | * We'll never write to the fs underlying | ||
1730 | * a device file. | ||
1731 | */ | ||
1732 | if (special_file(inode->i_mode)) | ||
1733 | return 0; | ||
1734 | return (flag & O_TRUNC); | ||
1735 | } | ||
1736 | |||
1737 | /* | ||
1738 | * Note that the low bits of the passed in "open_flag" | ||
1739 | * are not the same as in the local variable "flag". See | ||
1740 | * open_to_namei_flags() for more details. | ||
1711 | */ | 1741 | */ |
1712 | int open_namei(int dfd, const char *pathname, int flag, | 1742 | struct file *do_filp_open(int dfd, const char *pathname, |
1713 | int mode, struct nameidata *nd) | 1743 | int open_flag, int mode) |
1714 | { | 1744 | { |
1745 | struct file *filp; | ||
1746 | struct nameidata nd; | ||
1715 | int acc_mode, error; | 1747 | int acc_mode, error; |
1716 | struct path path; | 1748 | struct path path; |
1717 | struct dentry *dir; | 1749 | struct dentry *dir; |
1718 | int count = 0; | 1750 | int count = 0; |
1751 | int will_write; | ||
1752 | int flag = open_to_namei_flags(open_flag); | ||
1719 | 1753 | ||
1720 | acc_mode = ACC_MODE(flag); | 1754 | acc_mode = ACC_MODE(flag); |
1721 | 1755 | ||
@@ -1733,18 +1767,19 @@ int open_namei(int dfd, const char *pathname, int flag, | |||
1733 | */ | 1767 | */ |
1734 | if (!(flag & O_CREAT)) { | 1768 | if (!(flag & O_CREAT)) { |
1735 | error = path_lookup_open(dfd, pathname, lookup_flags(flag), | 1769 | error = path_lookup_open(dfd, pathname, lookup_flags(flag), |
1736 | nd, flag); | 1770 | &nd, flag); |
1737 | if (error) | 1771 | if (error) |
1738 | return error; | 1772 | return ERR_PTR(error); |
1739 | goto ok; | 1773 | goto ok; |
1740 | } | 1774 | } |
1741 | 1775 | ||
1742 | /* | 1776 | /* |
1743 | * Create - we need to know the parent. | 1777 | * Create - we need to know the parent. |
1744 | */ | 1778 | */ |
1745 | error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode); | 1779 | error = path_lookup_create(dfd, pathname, LOOKUP_PARENT, |
1780 | &nd, flag, mode); | ||
1746 | if (error) | 1781 | if (error) |
1747 | return error; | 1782 | return ERR_PTR(error); |
1748 | 1783 | ||
1749 | /* | 1784 | /* |
1750 | * We have the parent and last component. First of all, check | 1785 | * We have the parent and last component. First of all, check |
@@ -1752,14 +1787,14 @@ int open_namei(int dfd, const char *pathname, int flag, | |||
1752 | * will not do. | 1787 | * will not do. |
1753 | */ | 1788 | */ |
1754 | error = -EISDIR; | 1789 | error = -EISDIR; |
1755 | if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len]) | 1790 | if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len]) |
1756 | goto exit; | 1791 | goto exit; |
1757 | 1792 | ||
1758 | dir = nd->path.dentry; | 1793 | dir = nd.path.dentry; |
1759 | nd->flags &= ~LOOKUP_PARENT; | 1794 | nd.flags &= ~LOOKUP_PARENT; |
1760 | mutex_lock(&dir->d_inode->i_mutex); | 1795 | mutex_lock(&dir->d_inode->i_mutex); |
1761 | path.dentry = lookup_hash(nd); | 1796 | path.dentry = lookup_hash(&nd); |
1762 | path.mnt = nd->path.mnt; | 1797 | path.mnt = nd.path.mnt; |
1763 | 1798 | ||
1764 | do_last: | 1799 | do_last: |
1765 | error = PTR_ERR(path.dentry); | 1800 | error = PTR_ERR(path.dentry); |
@@ -1768,18 +1803,31 @@ do_last: | |||
1768 | goto exit; | 1803 | goto exit; |
1769 | } | 1804 | } |
1770 | 1805 | ||
1771 | if (IS_ERR(nd->intent.open.file)) { | 1806 | if (IS_ERR(nd.intent.open.file)) { |
1772 | mutex_unlock(&dir->d_inode->i_mutex); | 1807 | error = PTR_ERR(nd.intent.open.file); |
1773 | error = PTR_ERR(nd->intent.open.file); | 1808 | goto exit_mutex_unlock; |
1774 | goto exit_dput; | ||
1775 | } | 1809 | } |
1776 | 1810 | ||
1777 | /* Negative dentry, just create the file */ | 1811 | /* Negative dentry, just create the file */ |
1778 | if (!path.dentry->d_inode) { | 1812 | if (!path.dentry->d_inode) { |
1779 | error = open_namei_create(nd, &path, flag, mode); | 1813 | /* |
1814 | * This write is needed to ensure that a | ||
1815 | * ro->rw transition does not occur between | ||
1816 | * the time when the file is created and when | ||
1817 | * a permanent write count is taken through | ||
1818 | * the 'struct file' in nameidata_to_filp(). | ||
1819 | */ | ||
1820 | error = mnt_want_write(nd.path.mnt); | ||
1780 | if (error) | 1821 | if (error) |
1822 | goto exit_mutex_unlock; | ||
1823 | error = __open_namei_create(&nd, &path, flag, mode); | ||
1824 | if (error) { | ||
1825 | mnt_drop_write(nd.path.mnt); | ||
1781 | goto exit; | 1826 | goto exit; |
1782 | return 0; | 1827 | } |
1828 | filp = nameidata_to_filp(&nd, open_flag); | ||
1829 | mnt_drop_write(nd.path.mnt); | ||
1830 | return filp; | ||
1783 | } | 1831 | } |
1784 | 1832 | ||
1785 | /* | 1833 | /* |
@@ -1804,23 +1852,52 @@ do_last: | |||
1804 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) | 1852 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) |
1805 | goto do_link; | 1853 | goto do_link; |
1806 | 1854 | ||
1807 | path_to_nameidata(&path, nd); | 1855 | path_to_nameidata(&path, &nd); |
1808 | error = -EISDIR; | 1856 | error = -EISDIR; |
1809 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) | 1857 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) |
1810 | goto exit; | 1858 | goto exit; |
1811 | ok: | 1859 | ok: |
1812 | error = may_open(nd, acc_mode, flag); | 1860 | /* |
1813 | if (error) | 1861 | * Consider: |
1862 | * 1. may_open() truncates a file | ||
1863 | * 2. a rw->ro mount transition occurs | ||
1864 | * 3. nameidata_to_filp() fails due to | ||
1865 | * the ro mount. | ||
1866 | * That would be inconsistent, and should | ||
1867 | * be avoided. Taking this mnt write here | ||
1868 | * ensures that (2) can not occur. | ||
1869 | */ | ||
1870 | will_write = open_will_write_to_fs(flag, nd.path.dentry->d_inode); | ||
1871 | if (will_write) { | ||
1872 | error = mnt_want_write(nd.path.mnt); | ||
1873 | if (error) | ||
1874 | goto exit; | ||
1875 | } | ||
1876 | error = may_open(&nd, acc_mode, flag); | ||
1877 | if (error) { | ||
1878 | if (will_write) | ||
1879 | mnt_drop_write(nd.path.mnt); | ||
1814 | goto exit; | 1880 | goto exit; |
1815 | return 0; | 1881 | } |
1882 | filp = nameidata_to_filp(&nd, open_flag); | ||
1883 | /* | ||
1884 | * It is now safe to drop the mnt write | ||
1885 | * because the filp has had a write taken | ||
1886 | * on its behalf. | ||
1887 | */ | ||
1888 | if (will_write) | ||
1889 | mnt_drop_write(nd.path.mnt); | ||
1890 | return filp; | ||
1816 | 1891 | ||
1892 | exit_mutex_unlock: | ||
1893 | mutex_unlock(&dir->d_inode->i_mutex); | ||
1817 | exit_dput: | 1894 | exit_dput: |
1818 | path_put_conditional(&path, nd); | 1895 | path_put_conditional(&path, &nd); |
1819 | exit: | 1896 | exit: |
1820 | if (!IS_ERR(nd->intent.open.file)) | 1897 | if (!IS_ERR(nd.intent.open.file)) |
1821 | release_open_intent(nd); | 1898 | release_open_intent(&nd); |
1822 | path_put(&nd->path); | 1899 | path_put(&nd.path); |
1823 | return error; | 1900 | return ERR_PTR(error); |
1824 | 1901 | ||
1825 | do_link: | 1902 | do_link: |
1826 | error = -ELOOP; | 1903 | error = -ELOOP; |
@@ -1836,43 +1913,60 @@ do_link: | |||
1836 | * stored in nd->last.name and we will have to putname() it when we | 1913 | * stored in nd->last.name and we will have to putname() it when we |
1837 | * are done. Procfs-like symlinks just set LAST_BIND. | 1914 | * are done. Procfs-like symlinks just set LAST_BIND. |
1838 | */ | 1915 | */ |
1839 | nd->flags |= LOOKUP_PARENT; | 1916 | nd.flags |= LOOKUP_PARENT; |
1840 | error = security_inode_follow_link(path.dentry, nd); | 1917 | error = security_inode_follow_link(path.dentry, &nd); |
1841 | if (error) | 1918 | if (error) |
1842 | goto exit_dput; | 1919 | goto exit_dput; |
1843 | error = __do_follow_link(&path, nd); | 1920 | error = __do_follow_link(&path, &nd); |
1844 | if (error) { | 1921 | if (error) { |
1845 | /* Does someone understand code flow here? Or it is only | 1922 | /* Does someone understand code flow here? Or it is only |
1846 | * me so stupid? Anathema to whoever designed this non-sense | 1923 | * me so stupid? Anathema to whoever designed this non-sense |
1847 | * with "intent.open". | 1924 | * with "intent.open". |
1848 | */ | 1925 | */ |
1849 | release_open_intent(nd); | 1926 | release_open_intent(&nd); |
1850 | return error; | 1927 | return ERR_PTR(error); |
1851 | } | 1928 | } |
1852 | nd->flags &= ~LOOKUP_PARENT; | 1929 | nd.flags &= ~LOOKUP_PARENT; |
1853 | if (nd->last_type == LAST_BIND) | 1930 | if (nd.last_type == LAST_BIND) |
1854 | goto ok; | 1931 | goto ok; |
1855 | error = -EISDIR; | 1932 | error = -EISDIR; |
1856 | if (nd->last_type != LAST_NORM) | 1933 | if (nd.last_type != LAST_NORM) |
1857 | goto exit; | 1934 | goto exit; |
1858 | if (nd->last.name[nd->last.len]) { | 1935 | if (nd.last.name[nd.last.len]) { |
1859 | __putname(nd->last.name); | 1936 | __putname(nd.last.name); |
1860 | goto exit; | 1937 | goto exit; |
1861 | } | 1938 | } |
1862 | error = -ELOOP; | 1939 | error = -ELOOP; |
1863 | if (count++==32) { | 1940 | if (count++==32) { |
1864 | __putname(nd->last.name); | 1941 | __putname(nd.last.name); |
1865 | goto exit; | 1942 | goto exit; |
1866 | } | 1943 | } |
1867 | dir = nd->path.dentry; | 1944 | dir = nd.path.dentry; |
1868 | mutex_lock(&dir->d_inode->i_mutex); | 1945 | mutex_lock(&dir->d_inode->i_mutex); |
1869 | path.dentry = lookup_hash(nd); | 1946 | path.dentry = lookup_hash(&nd); |
1870 | path.mnt = nd->path.mnt; | 1947 | path.mnt = nd.path.mnt; |
1871 | __putname(nd->last.name); | 1948 | __putname(nd.last.name); |
1872 | goto do_last; | 1949 | goto do_last; |
1873 | } | 1950 | } |
1874 | 1951 | ||
1875 | /** | 1952 | /** |
1953 | * filp_open - open file and return file pointer | ||
1954 | * | ||
1955 | * @filename: path to open | ||
1956 | * @flags: open flags as per the open(2) second argument | ||
1957 | * @mode: mode for the new file if O_CREAT is set, else ignored | ||
1958 | * | ||
1959 | * This is the helper to open a file from kernelspace if you really | ||
1960 | * have to. But in generally you should not do this, so please move | ||
1961 | * along, nothing to see here.. | ||
1962 | */ | ||
1963 | struct file *filp_open(const char *filename, int flags, int mode) | ||
1964 | { | ||
1965 | return do_filp_open(AT_FDCWD, filename, flags, mode); | ||
1966 | } | ||
1967 | EXPORT_SYMBOL(filp_open); | ||
1968 | |||
1969 | /** | ||
1876 | * lookup_create - lookup a dentry, creating it if it doesn't exist | 1970 | * lookup_create - lookup a dentry, creating it if it doesn't exist |
1877 | * @nd: nameidata info | 1971 | * @nd: nameidata info |
1878 | * @is_dir: directory flag | 1972 | * @is_dir: directory flag |
@@ -1945,6 +2039,23 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1945 | return error; | 2039 | return error; |
1946 | } | 2040 | } |
1947 | 2041 | ||
2042 | static int may_mknod(mode_t mode) | ||
2043 | { | ||
2044 | switch (mode & S_IFMT) { | ||
2045 | case S_IFREG: | ||
2046 | case S_IFCHR: | ||
2047 | case S_IFBLK: | ||
2048 | case S_IFIFO: | ||
2049 | case S_IFSOCK: | ||
2050 | case 0: /* zero mode translates to S_IFREG */ | ||
2051 | return 0; | ||
2052 | case S_IFDIR: | ||
2053 | return -EPERM; | ||
2054 | default: | ||
2055 | return -EINVAL; | ||
2056 | } | ||
2057 | } | ||
2058 | |||
1948 | asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | 2059 | asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, |
1949 | unsigned dev) | 2060 | unsigned dev) |
1950 | { | 2061 | { |
@@ -1963,12 +2074,19 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1963 | if (error) | 2074 | if (error) |
1964 | goto out; | 2075 | goto out; |
1965 | dentry = lookup_create(&nd, 0); | 2076 | dentry = lookup_create(&nd, 0); |
1966 | error = PTR_ERR(dentry); | 2077 | if (IS_ERR(dentry)) { |
1967 | 2078 | error = PTR_ERR(dentry); | |
2079 | goto out_unlock; | ||
2080 | } | ||
1968 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 2081 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
1969 | mode &= ~current->fs->umask; | 2082 | mode &= ~current->fs->umask; |
1970 | if (!IS_ERR(dentry)) { | 2083 | error = may_mknod(mode); |
1971 | switch (mode & S_IFMT) { | 2084 | if (error) |
2085 | goto out_dput; | ||
2086 | error = mnt_want_write(nd.path.mnt); | ||
2087 | if (error) | ||
2088 | goto out_dput; | ||
2089 | switch (mode & S_IFMT) { | ||
1972 | case 0: case S_IFREG: | 2090 | case 0: case S_IFREG: |
1973 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); | 2091 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); |
1974 | break; | 2092 | break; |
@@ -1979,14 +2097,11 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1979 | case S_IFIFO: case S_IFSOCK: | 2097 | case S_IFIFO: case S_IFSOCK: |
1980 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); | 2098 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); |
1981 | break; | 2099 | break; |
1982 | case S_IFDIR: | ||
1983 | error = -EPERM; | ||
1984 | break; | ||
1985 | default: | ||
1986 | error = -EINVAL; | ||
1987 | } | ||
1988 | dput(dentry); | ||
1989 | } | 2100 | } |
2101 | mnt_drop_write(nd.path.mnt); | ||
2102 | out_dput: | ||
2103 | dput(dentry); | ||
2104 | out_unlock: | ||
1990 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2105 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
1991 | path_put(&nd.path); | 2106 | path_put(&nd.path); |
1992 | out: | 2107 | out: |
@@ -2044,7 +2159,12 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) | |||
2044 | 2159 | ||
2045 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 2160 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
2046 | mode &= ~current->fs->umask; | 2161 | mode &= ~current->fs->umask; |
2162 | error = mnt_want_write(nd.path.mnt); | ||
2163 | if (error) | ||
2164 | goto out_dput; | ||
2047 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); | 2165 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); |
2166 | mnt_drop_write(nd.path.mnt); | ||
2167 | out_dput: | ||
2048 | dput(dentry); | 2168 | dput(dentry); |
2049 | out_unlock: | 2169 | out_unlock: |
2050 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2170 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2151,7 +2271,12 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2151 | error = PTR_ERR(dentry); | 2271 | error = PTR_ERR(dentry); |
2152 | if (IS_ERR(dentry)) | 2272 | if (IS_ERR(dentry)) |
2153 | goto exit2; | 2273 | goto exit2; |
2274 | error = mnt_want_write(nd.path.mnt); | ||
2275 | if (error) | ||
2276 | goto exit3; | ||
2154 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); | 2277 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); |
2278 | mnt_drop_write(nd.path.mnt); | ||
2279 | exit3: | ||
2155 | dput(dentry); | 2280 | dput(dentry); |
2156 | exit2: | 2281 | exit2: |
2157 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2282 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2232,7 +2357,11 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2232 | inode = dentry->d_inode; | 2357 | inode = dentry->d_inode; |
2233 | if (inode) | 2358 | if (inode) |
2234 | atomic_inc(&inode->i_count); | 2359 | atomic_inc(&inode->i_count); |
2360 | error = mnt_want_write(nd.path.mnt); | ||
2361 | if (error) | ||
2362 | goto exit2; | ||
2235 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); | 2363 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); |
2364 | mnt_drop_write(nd.path.mnt); | ||
2236 | exit2: | 2365 | exit2: |
2237 | dput(dentry); | 2366 | dput(dentry); |
2238 | } | 2367 | } |
@@ -2313,7 +2442,12 @@ asmlinkage long sys_symlinkat(const char __user *oldname, | |||
2313 | if (IS_ERR(dentry)) | 2442 | if (IS_ERR(dentry)) |
2314 | goto out_unlock; | 2443 | goto out_unlock; |
2315 | 2444 | ||
2445 | error = mnt_want_write(nd.path.mnt); | ||
2446 | if (error) | ||
2447 | goto out_dput; | ||
2316 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); | 2448 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); |
2449 | mnt_drop_write(nd.path.mnt); | ||
2450 | out_dput: | ||
2317 | dput(dentry); | 2451 | dput(dentry); |
2318 | out_unlock: | 2452 | out_unlock: |
2319 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2453 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2408,7 +2542,12 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | |||
2408 | error = PTR_ERR(new_dentry); | 2542 | error = PTR_ERR(new_dentry); |
2409 | if (IS_ERR(new_dentry)) | 2543 | if (IS_ERR(new_dentry)) |
2410 | goto out_unlock; | 2544 | goto out_unlock; |
2545 | error = mnt_want_write(nd.path.mnt); | ||
2546 | if (error) | ||
2547 | goto out_dput; | ||
2411 | error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); | 2548 | error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); |
2549 | mnt_drop_write(nd.path.mnt); | ||
2550 | out_dput: | ||
2412 | dput(new_dentry); | 2551 | dput(new_dentry); |
2413 | out_unlock: | 2552 | out_unlock: |
2414 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 2553 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
@@ -2634,8 +2773,12 @@ static int do_rename(int olddfd, const char *oldname, | |||
2634 | if (new_dentry == trap) | 2773 | if (new_dentry == trap) |
2635 | goto exit5; | 2774 | goto exit5; |
2636 | 2775 | ||
2776 | error = mnt_want_write(oldnd.path.mnt); | ||
2777 | if (error) | ||
2778 | goto exit5; | ||
2637 | error = vfs_rename(old_dir->d_inode, old_dentry, | 2779 | error = vfs_rename(old_dir->d_inode, old_dentry, |
2638 | new_dir->d_inode, new_dentry); | 2780 | new_dir->d_inode, new_dentry); |
2781 | mnt_drop_write(oldnd.path.mnt); | ||
2639 | exit5: | 2782 | exit5: |
2640 | dput(new_dentry); | 2783 | dput(new_dentry); |
2641 | exit4: | 2784 | exit4: |
diff --git a/fs/namespace.c b/fs/namespace.c index 94f026ec990a..678f7ce060f2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/quotaops.h> | 17 | #include <linux/quotaops.h> |
18 | #include <linux/acct.h> | 18 | #include <linux/acct.h> |
19 | #include <linux/capability.h> | 19 | #include <linux/capability.h> |
20 | #include <linux/cpumask.h> | ||
20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
21 | #include <linux/sysfs.h> | 22 | #include <linux/sysfs.h> |
22 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
@@ -55,6 +56,8 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) | |||
55 | return tmp & (HASH_SIZE - 1); | 56 | return tmp & (HASH_SIZE - 1); |
56 | } | 57 | } |
57 | 58 | ||
59 | #define MNT_WRITER_UNDERFLOW_LIMIT -(1<<16) | ||
60 | |||
58 | struct vfsmount *alloc_vfsmnt(const char *name) | 61 | struct vfsmount *alloc_vfsmnt(const char *name) |
59 | { | 62 | { |
60 | struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); | 63 | struct vfsmount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); |
@@ -68,6 +71,7 @@ struct vfsmount *alloc_vfsmnt(const char *name) | |||
68 | INIT_LIST_HEAD(&mnt->mnt_share); | 71 | INIT_LIST_HEAD(&mnt->mnt_share); |
69 | INIT_LIST_HEAD(&mnt->mnt_slave_list); | 72 | INIT_LIST_HEAD(&mnt->mnt_slave_list); |
70 | INIT_LIST_HEAD(&mnt->mnt_slave); | 73 | INIT_LIST_HEAD(&mnt->mnt_slave); |
74 | atomic_set(&mnt->__mnt_writers, 0); | ||
71 | if (name) { | 75 | if (name) { |
72 | int size = strlen(name) + 1; | 76 | int size = strlen(name) + 1; |
73 | char *newname = kmalloc(size, GFP_KERNEL); | 77 | char *newname = kmalloc(size, GFP_KERNEL); |
@@ -80,6 +84,263 @@ struct vfsmount *alloc_vfsmnt(const char *name) | |||
80 | return mnt; | 84 | return mnt; |
81 | } | 85 | } |
82 | 86 | ||
87 | /* | ||
88 | * Most r/o checks on a fs are for operations that take | ||
89 | * discrete amounts of time, like a write() or unlink(). | ||
90 | * We must keep track of when those operations start | ||
91 | * (for permission checks) and when they end, so that | ||
92 | * we can determine when writes are able to occur to | ||
93 | * a filesystem. | ||
94 | */ | ||
95 | /* | ||
96 | * __mnt_is_readonly: check whether a mount is read-only | ||
97 | * @mnt: the mount to check for its write status | ||
98 | * | ||
99 | * This shouldn't be used directly ouside of the VFS. | ||
100 | * It does not guarantee that the filesystem will stay | ||
101 | * r/w, just that it is right *now*. This can not and | ||
102 | * should not be used in place of IS_RDONLY(inode). | ||
103 | * mnt_want/drop_write() will _keep_ the filesystem | ||
104 | * r/w. | ||
105 | */ | ||
106 | int __mnt_is_readonly(struct vfsmount *mnt) | ||
107 | { | ||
108 | if (mnt->mnt_flags & MNT_READONLY) | ||
109 | return 1; | ||
110 | if (mnt->mnt_sb->s_flags & MS_RDONLY) | ||
111 | return 1; | ||
112 | return 0; | ||
113 | } | ||
114 | EXPORT_SYMBOL_GPL(__mnt_is_readonly); | ||
115 | |||
116 | struct mnt_writer { | ||
117 | /* | ||
118 | * If holding multiple instances of this lock, they | ||
119 | * must be ordered by cpu number. | ||
120 | */ | ||
121 | spinlock_t lock; | ||
122 | struct lock_class_key lock_class; /* compiles out with !lockdep */ | ||
123 | unsigned long count; | ||
124 | struct vfsmount *mnt; | ||
125 | } ____cacheline_aligned_in_smp; | ||
126 | static DEFINE_PER_CPU(struct mnt_writer, mnt_writers); | ||
127 | |||
128 | static int __init init_mnt_writers(void) | ||
129 | { | ||
130 | int cpu; | ||
131 | for_each_possible_cpu(cpu) { | ||
132 | struct mnt_writer *writer = &per_cpu(mnt_writers, cpu); | ||
133 | spin_lock_init(&writer->lock); | ||
134 | lockdep_set_class(&writer->lock, &writer->lock_class); | ||
135 | writer->count = 0; | ||
136 | } | ||
137 | return 0; | ||
138 | } | ||
139 | fs_initcall(init_mnt_writers); | ||
140 | |||
141 | static void unlock_mnt_writers(void) | ||
142 | { | ||
143 | int cpu; | ||
144 | struct mnt_writer *cpu_writer; | ||
145 | |||
146 | for_each_possible_cpu(cpu) { | ||
147 | cpu_writer = &per_cpu(mnt_writers, cpu); | ||
148 | spin_unlock(&cpu_writer->lock); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | static inline void __clear_mnt_count(struct mnt_writer *cpu_writer) | ||
153 | { | ||
154 | if (!cpu_writer->mnt) | ||
155 | return; | ||
156 | /* | ||
157 | * This is in case anyone ever leaves an invalid, | ||
158 | * old ->mnt and a count of 0. | ||
159 | */ | ||
160 | if (!cpu_writer->count) | ||
161 | return; | ||
162 | atomic_add(cpu_writer->count, &cpu_writer->mnt->__mnt_writers); | ||
163 | cpu_writer->count = 0; | ||
164 | } | ||
165 | /* | ||
166 | * must hold cpu_writer->lock | ||
167 | */ | ||
168 | static inline void use_cpu_writer_for_mount(struct mnt_writer *cpu_writer, | ||
169 | struct vfsmount *mnt) | ||
170 | { | ||
171 | if (cpu_writer->mnt == mnt) | ||
172 | return; | ||
173 | __clear_mnt_count(cpu_writer); | ||
174 | cpu_writer->mnt = mnt; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Most r/o checks on a fs are for operations that take | ||
179 | * discrete amounts of time, like a write() or unlink(). | ||
180 | * We must keep track of when those operations start | ||
181 | * (for permission checks) and when they end, so that | ||
182 | * we can determine when writes are able to occur to | ||
183 | * a filesystem. | ||
184 | */ | ||
185 | /** | ||
186 | * mnt_want_write - get write access to a mount | ||
187 | * @mnt: the mount on which to take a write | ||
188 | * | ||
189 | * This tells the low-level filesystem that a write is | ||
190 | * about to be performed to it, and makes sure that | ||
191 | * writes are allowed before returning success. When | ||
192 | * the write operation is finished, mnt_drop_write() | ||
193 | * must be called. This is effectively a refcount. | ||
194 | */ | ||
195 | int mnt_want_write(struct vfsmount *mnt) | ||
196 | { | ||
197 | int ret = 0; | ||
198 | struct mnt_writer *cpu_writer; | ||
199 | |||
200 | cpu_writer = &get_cpu_var(mnt_writers); | ||
201 | spin_lock(&cpu_writer->lock); | ||
202 | if (__mnt_is_readonly(mnt)) { | ||
203 | ret = -EROFS; | ||
204 | goto out; | ||
205 | } | ||
206 | use_cpu_writer_for_mount(cpu_writer, mnt); | ||
207 | cpu_writer->count++; | ||
208 | out: | ||
209 | spin_unlock(&cpu_writer->lock); | ||
210 | put_cpu_var(mnt_writers); | ||
211 | return ret; | ||
212 | } | ||
213 | EXPORT_SYMBOL_GPL(mnt_want_write); | ||
214 | |||
215 | static void lock_mnt_writers(void) | ||
216 | { | ||
217 | int cpu; | ||
218 | struct mnt_writer *cpu_writer; | ||
219 | |||
220 | for_each_possible_cpu(cpu) { | ||
221 | cpu_writer = &per_cpu(mnt_writers, cpu); | ||
222 | spin_lock(&cpu_writer->lock); | ||
223 | __clear_mnt_count(cpu_writer); | ||
224 | cpu_writer->mnt = NULL; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * These per-cpu write counts are not guaranteed to have | ||
230 | * matched increments and decrements on any given cpu. | ||
231 | * A file open()ed for write on one cpu and close()d on | ||
232 | * another cpu will imbalance this count. Make sure it | ||
233 | * does not get too far out of whack. | ||
234 | */ | ||
235 | static void handle_write_count_underflow(struct vfsmount *mnt) | ||
236 | { | ||
237 | if (atomic_read(&mnt->__mnt_writers) >= | ||
238 | MNT_WRITER_UNDERFLOW_LIMIT) | ||
239 | return; | ||
240 | /* | ||
241 | * It isn't necessary to hold all of the locks | ||
242 | * at the same time, but doing it this way makes | ||
243 | * us share a lot more code. | ||
244 | */ | ||
245 | lock_mnt_writers(); | ||
246 | /* | ||
247 | * vfsmount_lock is for mnt_flags. | ||
248 | */ | ||
249 | spin_lock(&vfsmount_lock); | ||
250 | /* | ||
251 | * If coalescing the per-cpu writer counts did not | ||
252 | * get us back to a positive writer count, we have | ||
253 | * a bug. | ||
254 | */ | ||
255 | if ((atomic_read(&mnt->__mnt_writers) < 0) && | ||
256 | !(mnt->mnt_flags & MNT_IMBALANCED_WRITE_COUNT)) { | ||
257 | printk(KERN_DEBUG "leak detected on mount(%p) writers " | ||
258 | "count: %d\n", | ||
259 | mnt, atomic_read(&mnt->__mnt_writers)); | ||
260 | WARN_ON(1); | ||
261 | /* use the flag to keep the dmesg spam down */ | ||
262 | mnt->mnt_flags |= MNT_IMBALANCED_WRITE_COUNT; | ||
263 | } | ||
264 | spin_unlock(&vfsmount_lock); | ||
265 | unlock_mnt_writers(); | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * mnt_drop_write - give up write access to a mount | ||
270 | * @mnt: the mount on which to give up write access | ||
271 | * | ||
272 | * Tells the low-level filesystem that we are done | ||
273 | * performing writes to it. Must be matched with | ||
274 | * mnt_want_write() call above. | ||
275 | */ | ||
276 | void mnt_drop_write(struct vfsmount *mnt) | ||
277 | { | ||
278 | int must_check_underflow = 0; | ||
279 | struct mnt_writer *cpu_writer; | ||
280 | |||
281 | cpu_writer = &get_cpu_var(mnt_writers); | ||
282 | spin_lock(&cpu_writer->lock); | ||
283 | |||
284 | use_cpu_writer_for_mount(cpu_writer, mnt); | ||
285 | if (cpu_writer->count > 0) { | ||
286 | cpu_writer->count--; | ||
287 | } else { | ||
288 | must_check_underflow = 1; | ||
289 | atomic_dec(&mnt->__mnt_writers); | ||
290 | } | ||
291 | |||
292 | spin_unlock(&cpu_writer->lock); | ||
293 | /* | ||
294 | * Logically, we could call this each time, | ||
295 | * but the __mnt_writers cacheline tends to | ||
296 | * be cold, and makes this expensive. | ||
297 | */ | ||
298 | if (must_check_underflow) | ||
299 | handle_write_count_underflow(mnt); | ||
300 | /* | ||
301 | * This could be done right after the spinlock | ||
302 | * is taken because the spinlock keeps us on | ||
303 | * the cpu, and disables preemption. However, | ||
304 | * putting it here bounds the amount that | ||
305 | * __mnt_writers can underflow. Without it, | ||
306 | * we could theoretically wrap __mnt_writers. | ||
307 | */ | ||
308 | put_cpu_var(mnt_writers); | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(mnt_drop_write); | ||
311 | |||
312 | static int mnt_make_readonly(struct vfsmount *mnt) | ||
313 | { | ||
314 | int ret = 0; | ||
315 | |||
316 | lock_mnt_writers(); | ||
317 | /* | ||
318 | * With all the locks held, this value is stable | ||
319 | */ | ||
320 | if (atomic_read(&mnt->__mnt_writers) > 0) { | ||
321 | ret = -EBUSY; | ||
322 | goto out; | ||
323 | } | ||
324 | /* | ||
325 | * nobody can do a successful mnt_want_write() with all | ||
326 | * of the counts in MNT_DENIED_WRITE and the locks held. | ||
327 | */ | ||
328 | spin_lock(&vfsmount_lock); | ||
329 | if (!ret) | ||
330 | mnt->mnt_flags |= MNT_READONLY; | ||
331 | spin_unlock(&vfsmount_lock); | ||
332 | out: | ||
333 | unlock_mnt_writers(); | ||
334 | return ret; | ||
335 | } | ||
336 | |||
337 | static void __mnt_unmake_readonly(struct vfsmount *mnt) | ||
338 | { | ||
339 | spin_lock(&vfsmount_lock); | ||
340 | mnt->mnt_flags &= ~MNT_READONLY; | ||
341 | spin_unlock(&vfsmount_lock); | ||
342 | } | ||
343 | |||
83 | int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) | 344 | int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) |
84 | { | 345 | { |
85 | mnt->mnt_sb = sb; | 346 | mnt->mnt_sb = sb; |
@@ -271,7 +532,36 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, | |||
271 | 532 | ||
272 | static inline void __mntput(struct vfsmount *mnt) | 533 | static inline void __mntput(struct vfsmount *mnt) |
273 | { | 534 | { |
535 | int cpu; | ||
274 | struct super_block *sb = mnt->mnt_sb; | 536 | struct super_block *sb = mnt->mnt_sb; |
537 | /* | ||
538 | * We don't have to hold all of the locks at the | ||
539 | * same time here because we know that we're the | ||
540 | * last reference to mnt and that no new writers | ||
541 | * can come in. | ||
542 | */ | ||
543 | for_each_possible_cpu(cpu) { | ||
544 | struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu); | ||
545 | if (cpu_writer->mnt != mnt) | ||
546 | continue; | ||
547 | spin_lock(&cpu_writer->lock); | ||
548 | atomic_add(cpu_writer->count, &mnt->__mnt_writers); | ||
549 | cpu_writer->count = 0; | ||
550 | /* | ||
551 | * Might as well do this so that no one | ||
552 | * ever sees the pointer and expects | ||
553 | * it to be valid. | ||
554 | */ | ||
555 | cpu_writer->mnt = NULL; | ||
556 | spin_unlock(&cpu_writer->lock); | ||
557 | } | ||
558 | /* | ||
559 | * This probably indicates that somebody messed | ||
560 | * up a mnt_want/drop_write() pair. If this | ||
561 | * happens, the filesystem was probably unable | ||
562 | * to make r/w->r/o transitions. | ||
563 | */ | ||
564 | WARN_ON(atomic_read(&mnt->__mnt_writers)); | ||
275 | dput(mnt->mnt_root); | 565 | dput(mnt->mnt_root); |
276 | free_vfsmnt(mnt); | 566 | free_vfsmnt(mnt); |
277 | deactivate_super(sb); | 567 | deactivate_super(sb); |
@@ -417,7 +707,7 @@ static int show_vfsmnt(struct seq_file *m, void *v) | |||
417 | seq_putc(m, '.'); | 707 | seq_putc(m, '.'); |
418 | mangle(m, mnt->mnt_sb->s_subtype); | 708 | mangle(m, mnt->mnt_sb->s_subtype); |
419 | } | 709 | } |
420 | seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); | 710 | seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); |
421 | for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { | 711 | for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { |
422 | if (mnt->mnt_sb->s_flags & fs_infop->flag) | 712 | if (mnt->mnt_sb->s_flags & fs_infop->flag) |
423 | seq_puts(m, fs_infop->str); | 713 | seq_puts(m, fs_infop->str); |
@@ -1019,6 +1309,23 @@ out: | |||
1019 | return err; | 1309 | return err; |
1020 | } | 1310 | } |
1021 | 1311 | ||
1312 | static int change_mount_flags(struct vfsmount *mnt, int ms_flags) | ||
1313 | { | ||
1314 | int error = 0; | ||
1315 | int readonly_request = 0; | ||
1316 | |||
1317 | if (ms_flags & MS_RDONLY) | ||
1318 | readonly_request = 1; | ||
1319 | if (readonly_request == __mnt_is_readonly(mnt)) | ||
1320 | return 0; | ||
1321 | |||
1322 | if (readonly_request) | ||
1323 | error = mnt_make_readonly(mnt); | ||
1324 | else | ||
1325 | __mnt_unmake_readonly(mnt); | ||
1326 | return error; | ||
1327 | } | ||
1328 | |||
1022 | /* | 1329 | /* |
1023 | * change filesystem flags. dir should be a physical root of filesystem. | 1330 | * change filesystem flags. dir should be a physical root of filesystem. |
1024 | * If you've mounted a non-root directory somewhere and want to do remount | 1331 | * If you've mounted a non-root directory somewhere and want to do remount |
@@ -1041,7 +1348,10 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags, | |||
1041 | return -EINVAL; | 1348 | return -EINVAL; |
1042 | 1349 | ||
1043 | down_write(&sb->s_umount); | 1350 | down_write(&sb->s_umount); |
1044 | err = do_remount_sb(sb, flags, data, 0); | 1351 | if (flags & MS_BIND) |
1352 | err = change_mount_flags(nd->path.mnt, flags); | ||
1353 | else | ||
1354 | err = do_remount_sb(sb, flags, data, 0); | ||
1045 | if (!err) | 1355 | if (!err) |
1046 | nd->path.mnt->mnt_flags = mnt_flags; | 1356 | nd->path.mnt->mnt_flags = mnt_flags; |
1047 | up_write(&sb->s_umount); | 1357 | up_write(&sb->s_umount); |
@@ -1425,6 +1735,8 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1425 | mnt_flags |= MNT_NODIRATIME; | 1735 | mnt_flags |= MNT_NODIRATIME; |
1426 | if (flags & MS_RELATIME) | 1736 | if (flags & MS_RELATIME) |
1427 | mnt_flags |= MNT_RELATIME; | 1737 | mnt_flags |= MNT_RELATIME; |
1738 | if (flags & MS_RDONLY) | ||
1739 | mnt_flags |= MNT_READONLY; | ||
1428 | 1740 | ||
1429 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | | 1741 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | |
1430 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); | 1742 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index c67b4bdcf719..ad8f167e54bc 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/ioctl.h> | 14 | #include <linux/ioctl.h> |
15 | #include <linux/time.h> | 15 | #include <linux/time.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/mount.h> | ||
17 | #include <linux/highuid.h> | 18 | #include <linux/highuid.h> |
18 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
19 | #include <linux/vmalloc.h> | 20 | #include <linux/vmalloc.h> |
@@ -261,7 +262,7 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg) | |||
261 | } | 262 | } |
262 | #endif /* CONFIG_NCPFS_NLS */ | 263 | #endif /* CONFIG_NCPFS_NLS */ |
263 | 264 | ||
264 | int ncp_ioctl(struct inode *inode, struct file *filp, | 265 | static int __ncp_ioctl(struct inode *inode, struct file *filp, |
265 | unsigned int cmd, unsigned long arg) | 266 | unsigned int cmd, unsigned long arg) |
266 | { | 267 | { |
267 | struct ncp_server *server = NCP_SERVER(inode); | 268 | struct ncp_server *server = NCP_SERVER(inode); |
@@ -822,6 +823,57 @@ outrel: | |||
822 | return -EINVAL; | 823 | return -EINVAL; |
823 | } | 824 | } |
824 | 825 | ||
826 | static int ncp_ioctl_need_write(unsigned int cmd) | ||
827 | { | ||
828 | switch (cmd) { | ||
829 | case NCP_IOC_GET_FS_INFO: | ||
830 | case NCP_IOC_GET_FS_INFO_V2: | ||
831 | case NCP_IOC_NCPREQUEST: | ||
832 | case NCP_IOC_SETDENTRYTTL: | ||
833 | case NCP_IOC_SIGN_INIT: | ||
834 | case NCP_IOC_LOCKUNLOCK: | ||
835 | case NCP_IOC_SET_SIGN_WANTED: | ||
836 | return 1; | ||
837 | case NCP_IOC_GETOBJECTNAME: | ||
838 | case NCP_IOC_SETOBJECTNAME: | ||
839 | case NCP_IOC_GETPRIVATEDATA: | ||
840 | case NCP_IOC_SETPRIVATEDATA: | ||
841 | case NCP_IOC_SETCHARSETS: | ||
842 | case NCP_IOC_GETCHARSETS: | ||
843 | case NCP_IOC_CONN_LOGGED_IN: | ||
844 | case NCP_IOC_GETDENTRYTTL: | ||
845 | case NCP_IOC_GETMOUNTUID2: | ||
846 | case NCP_IOC_SIGN_WANTED: | ||
847 | case NCP_IOC_GETROOT: | ||
848 | case NCP_IOC_SETROOT: | ||
849 | return 0; | ||
850 | default: | ||
851 | /* unkown IOCTL command, assume write */ | ||
852 | return 1; | ||
853 | } | ||
854 | } | ||
855 | |||
856 | int ncp_ioctl(struct inode *inode, struct file *filp, | ||
857 | unsigned int cmd, unsigned long arg) | ||
858 | { | ||
859 | int ret; | ||
860 | |||
861 | if (ncp_ioctl_need_write(cmd)) { | ||
862 | /* | ||
863 | * inside the ioctl(), any failures which | ||
864 | * are because of file_permission() are | ||
865 | * -EACCESS, so it seems consistent to keep | ||
866 | * that here. | ||
867 | */ | ||
868 | if (mnt_want_write(filp->f_path.mnt)) | ||
869 | return -EACCES; | ||
870 | } | ||
871 | ret = __ncp_ioctl(inode, filp, cmd, arg); | ||
872 | if (ncp_ioctl_need_write(cmd)) | ||
873 | mnt_drop_write(filp->f_path.mnt); | ||
874 | return ret; | ||
875 | } | ||
876 | |||
825 | #ifdef CONFIG_COMPAT | 877 | #ifdef CONFIG_COMPAT |
826 | long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 878 | long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
827 | { | 879 | { |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 6cea7479c5b4..d9e30ac2798d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -967,7 +967,8 @@ static int is_atomic_open(struct inode *dir, struct nameidata *nd) | |||
967 | if (nd->flags & LOOKUP_DIRECTORY) | 967 | if (nd->flags & LOOKUP_DIRECTORY) |
968 | return 0; | 968 | return 0; |
969 | /* Are we trying to write to a read only partition? */ | 969 | /* Are we trying to write to a read only partition? */ |
970 | if (IS_RDONLY(dir) && (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE))) | 970 | if (__mnt_is_readonly(nd->path.mnt) && |
971 | (nd->intent.open.flags & (O_CREAT|O_TRUNC|FMODE_WRITE))) | ||
971 | return 0; | 972 | return 0; |
972 | return 1; | 973 | return 1; |
973 | } | 974 | } |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index c593db047d8b..c309c881bd4e 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -658,14 +658,19 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
658 | return status; | 658 | return status; |
659 | } | 659 | } |
660 | } | 660 | } |
661 | status = mnt_want_write(cstate->current_fh.fh_export->ex_path.mnt); | ||
662 | if (status) | ||
663 | return status; | ||
661 | status = nfs_ok; | 664 | status = nfs_ok; |
662 | if (setattr->sa_acl != NULL) | 665 | if (setattr->sa_acl != NULL) |
663 | status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, | 666 | status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, |
664 | setattr->sa_acl); | 667 | setattr->sa_acl); |
665 | if (status) | 668 | if (status) |
666 | return status; | 669 | goto out; |
667 | status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, | 670 | status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, |
668 | 0, (time_t)0); | 671 | 0, (time_t)0); |
672 | out: | ||
673 | mnt_drop_write(cstate->current_fh.fh_export->ex_path.mnt); | ||
669 | return status; | 674 | return status; |
670 | } | 675 | } |
671 | 676 | ||
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 1ff90625860f..145b3c877a27 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/scatterlist.h> | 46 | #include <linux/scatterlist.h> |
47 | #include <linux/crypto.h> | 47 | #include <linux/crypto.h> |
48 | #include <linux/sched.h> | 48 | #include <linux/sched.h> |
49 | #include <linux/mount.h> | ||
49 | 50 | ||
50 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 51 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
51 | 52 | ||
@@ -154,7 +155,11 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
154 | dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); | 155 | dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); |
155 | goto out_put; | 156 | goto out_put; |
156 | } | 157 | } |
158 | status = mnt_want_write(rec_dir.path.mnt); | ||
159 | if (status) | ||
160 | goto out_put; | ||
157 | status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU); | 161 | status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU); |
162 | mnt_drop_write(rec_dir.path.mnt); | ||
158 | out_put: | 163 | out_put: |
159 | dput(dentry); | 164 | dput(dentry); |
160 | out_unlock: | 165 | out_unlock: |
@@ -313,12 +318,17 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp) | |||
313 | if (!rec_dir_init || !clp->cl_firststate) | 318 | if (!rec_dir_init || !clp->cl_firststate) |
314 | return; | 319 | return; |
315 | 320 | ||
321 | status = mnt_want_write(rec_dir.path.mnt); | ||
322 | if (status) | ||
323 | goto out; | ||
316 | clp->cl_firststate = 0; | 324 | clp->cl_firststate = 0; |
317 | nfs4_save_user(&uid, &gid); | 325 | nfs4_save_user(&uid, &gid); |
318 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); | 326 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); |
319 | nfs4_reset_user(uid, gid); | 327 | nfs4_reset_user(uid, gid); |
320 | if (status == 0) | 328 | if (status == 0) |
321 | nfsd4_sync_rec_dir(); | 329 | nfsd4_sync_rec_dir(); |
330 | mnt_drop_write(rec_dir.path.mnt); | ||
331 | out: | ||
322 | if (status) | 332 | if (status) |
323 | printk("NFSD: Failed to remove expired client state directory" | 333 | printk("NFSD: Failed to remove expired client state directory" |
324 | " %.*s\n", HEXDIR_LEN, clp->cl_recdir); | 334 | " %.*s\n", HEXDIR_LEN, clp->cl_recdir); |
@@ -347,13 +357,17 @@ nfsd4_recdir_purge_old(void) { | |||
347 | 357 | ||
348 | if (!rec_dir_init) | 358 | if (!rec_dir_init) |
349 | return; | 359 | return; |
360 | status = mnt_want_write(rec_dir.path.mnt); | ||
361 | if (status) | ||
362 | goto out; | ||
350 | status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old); | 363 | status = nfsd4_list_rec_dir(rec_dir.path.dentry, purge_old); |
351 | if (status == 0) | 364 | if (status == 0) |
352 | nfsd4_sync_rec_dir(); | 365 | nfsd4_sync_rec_dir(); |
366 | mnt_drop_write(rec_dir.path.mnt); | ||
367 | out: | ||
353 | if (status) | 368 | if (status) |
354 | printk("nfsd4: failed to purge old clients from recovery" | 369 | printk("nfsd4: failed to purge old clients from recovery" |
355 | " directory %s\n", rec_dir.path.dentry->d_name.name); | 370 | " directory %s\n", rec_dir.path.dentry->d_name.name); |
356 | return; | ||
357 | } | 371 | } |
358 | 372 | ||
359 | static int | 373 | static int |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index bcb97d8e8b8b..81a75f3081f4 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/sunrpc/svc.h> | 41 | #include <linux/sunrpc/svc.h> |
42 | #include <linux/nfsd/nfsd.h> | 42 | #include <linux/nfsd/nfsd.h> |
43 | #include <linux/nfsd/cache.h> | 43 | #include <linux/nfsd/cache.h> |
44 | #include <linux/file.h> | ||
44 | #include <linux/mount.h> | 45 | #include <linux/mount.h> |
45 | #include <linux/workqueue.h> | 46 | #include <linux/workqueue.h> |
46 | #include <linux/smp_lock.h> | 47 | #include <linux/smp_lock.h> |
@@ -1239,7 +1240,7 @@ static inline void | |||
1239 | nfs4_file_downgrade(struct file *filp, unsigned int share_access) | 1240 | nfs4_file_downgrade(struct file *filp, unsigned int share_access) |
1240 | { | 1241 | { |
1241 | if (share_access & NFS4_SHARE_ACCESS_WRITE) { | 1242 | if (share_access & NFS4_SHARE_ACCESS_WRITE) { |
1242 | put_write_access(filp->f_path.dentry->d_inode); | 1243 | drop_file_write_access(filp); |
1243 | filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; | 1244 | filp->f_mode = (filp->f_mode | FMODE_READ) & ~FMODE_WRITE; |
1244 | } | 1245 | } |
1245 | } | 1246 | } |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 46f59d5365a0..304bf5f643c9 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1255,23 +1255,35 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1255 | err = 0; | 1255 | err = 0; |
1256 | switch (type) { | 1256 | switch (type) { |
1257 | case S_IFREG: | 1257 | case S_IFREG: |
1258 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
1259 | if (host_err) | ||
1260 | goto out_nfserr; | ||
1258 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); | 1261 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); |
1259 | break; | 1262 | break; |
1260 | case S_IFDIR: | 1263 | case S_IFDIR: |
1264 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
1265 | if (host_err) | ||
1266 | goto out_nfserr; | ||
1261 | host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); | 1267 | host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); |
1262 | break; | 1268 | break; |
1263 | case S_IFCHR: | 1269 | case S_IFCHR: |
1264 | case S_IFBLK: | 1270 | case S_IFBLK: |
1265 | case S_IFIFO: | 1271 | case S_IFIFO: |
1266 | case S_IFSOCK: | 1272 | case S_IFSOCK: |
1273 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
1274 | if (host_err) | ||
1275 | goto out_nfserr; | ||
1267 | host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); | 1276 | host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); |
1268 | break; | 1277 | break; |
1269 | default: | 1278 | default: |
1270 | printk("nfsd: bad file type %o in nfsd_create\n", type); | 1279 | printk("nfsd: bad file type %o in nfsd_create\n", type); |
1271 | host_err = -EINVAL; | 1280 | host_err = -EINVAL; |
1281 | goto out_nfserr; | ||
1272 | } | 1282 | } |
1273 | if (host_err < 0) | 1283 | if (host_err < 0) { |
1284 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1274 | goto out_nfserr; | 1285 | goto out_nfserr; |
1286 | } | ||
1275 | 1287 | ||
1276 | if (EX_ISSYNC(fhp->fh_export)) { | 1288 | if (EX_ISSYNC(fhp->fh_export)) { |
1277 | err = nfserrno(nfsd_sync_dir(dentry)); | 1289 | err = nfserrno(nfsd_sync_dir(dentry)); |
@@ -1282,6 +1294,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1282 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); | 1294 | err2 = nfsd_create_setattr(rqstp, resfhp, iap); |
1283 | if (err2) | 1295 | if (err2) |
1284 | err = err2; | 1296 | err = err2; |
1297 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1285 | /* | 1298 | /* |
1286 | * Update the file handle to get the new inode info. | 1299 | * Update the file handle to get the new inode info. |
1287 | */ | 1300 | */ |
@@ -1359,6 +1372,9 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1359 | v_atime = verifier[1]&0x7fffffff; | 1372 | v_atime = verifier[1]&0x7fffffff; |
1360 | } | 1373 | } |
1361 | 1374 | ||
1375 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
1376 | if (host_err) | ||
1377 | goto out_nfserr; | ||
1362 | if (dchild->d_inode) { | 1378 | if (dchild->d_inode) { |
1363 | err = 0; | 1379 | err = 0; |
1364 | 1380 | ||
@@ -1390,12 +1406,15 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1390 | case NFS3_CREATE_GUARDED: | 1406 | case NFS3_CREATE_GUARDED: |
1391 | err = nfserr_exist; | 1407 | err = nfserr_exist; |
1392 | } | 1408 | } |
1409 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1393 | goto out; | 1410 | goto out; |
1394 | } | 1411 | } |
1395 | 1412 | ||
1396 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); | 1413 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); |
1397 | if (host_err < 0) | 1414 | if (host_err < 0) { |
1415 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1398 | goto out_nfserr; | 1416 | goto out_nfserr; |
1417 | } | ||
1399 | if (created) | 1418 | if (created) |
1400 | *created = 1; | 1419 | *created = 1; |
1401 | 1420 | ||
@@ -1420,6 +1439,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1420 | if (err2) | 1439 | if (err2) |
1421 | err = err2; | 1440 | err = err2; |
1422 | 1441 | ||
1442 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1423 | /* | 1443 | /* |
1424 | * Update the filehandle to get the new inode info. | 1444 | * Update the filehandle to get the new inode info. |
1425 | */ | 1445 | */ |
@@ -1522,6 +1542,10 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1522 | if (iap && (iap->ia_valid & ATTR_MODE)) | 1542 | if (iap && (iap->ia_valid & ATTR_MODE)) |
1523 | mode = iap->ia_mode & S_IALLUGO; | 1543 | mode = iap->ia_mode & S_IALLUGO; |
1524 | 1544 | ||
1545 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
1546 | if (host_err) | ||
1547 | goto out_nfserr; | ||
1548 | |||
1525 | if (unlikely(path[plen] != 0)) { | 1549 | if (unlikely(path[plen] != 0)) { |
1526 | char *path_alloced = kmalloc(plen+1, GFP_KERNEL); | 1550 | char *path_alloced = kmalloc(plen+1, GFP_KERNEL); |
1527 | if (path_alloced == NULL) | 1551 | if (path_alloced == NULL) |
@@ -1542,6 +1566,8 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1542 | err = nfserrno(host_err); | 1566 | err = nfserrno(host_err); |
1543 | fh_unlock(fhp); | 1567 | fh_unlock(fhp); |
1544 | 1568 | ||
1569 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1570 | |||
1545 | cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); | 1571 | cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); |
1546 | dput(dnew); | 1572 | dput(dnew); |
1547 | if (err==0) err = cerr; | 1573 | if (err==0) err = cerr; |
@@ -1592,6 +1618,11 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1592 | dold = tfhp->fh_dentry; | 1618 | dold = tfhp->fh_dentry; |
1593 | dest = dold->d_inode; | 1619 | dest = dold->d_inode; |
1594 | 1620 | ||
1621 | host_err = mnt_want_write(tfhp->fh_export->ex_path.mnt); | ||
1622 | if (host_err) { | ||
1623 | err = nfserrno(host_err); | ||
1624 | goto out_dput; | ||
1625 | } | ||
1595 | host_err = vfs_link(dold, dirp, dnew); | 1626 | host_err = vfs_link(dold, dirp, dnew); |
1596 | if (!host_err) { | 1627 | if (!host_err) { |
1597 | if (EX_ISSYNC(ffhp->fh_export)) { | 1628 | if (EX_ISSYNC(ffhp->fh_export)) { |
@@ -1605,7 +1636,8 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, | |||
1605 | else | 1636 | else |
1606 | err = nfserrno(host_err); | 1637 | err = nfserrno(host_err); |
1607 | } | 1638 | } |
1608 | 1639 | mnt_drop_write(tfhp->fh_export->ex_path.mnt); | |
1640 | out_dput: | ||
1609 | dput(dnew); | 1641 | dput(dnew); |
1610 | out_unlock: | 1642 | out_unlock: |
1611 | fh_unlock(ffhp); | 1643 | fh_unlock(ffhp); |
@@ -1678,13 +1710,20 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
1678 | if (ndentry == trap) | 1710 | if (ndentry == trap) |
1679 | goto out_dput_new; | 1711 | goto out_dput_new; |
1680 | 1712 | ||
1681 | #ifdef MSNFS | 1713 | if (svc_msnfs(ffhp) && |
1682 | if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && | ||
1683 | ((atomic_read(&odentry->d_count) > 1) | 1714 | ((atomic_read(&odentry->d_count) > 1) |
1684 | || (atomic_read(&ndentry->d_count) > 1))) { | 1715 | || (atomic_read(&ndentry->d_count) > 1))) { |
1685 | host_err = -EPERM; | 1716 | host_err = -EPERM; |
1686 | } else | 1717 | goto out_dput_new; |
1687 | #endif | 1718 | } |
1719 | |||
1720 | host_err = -EXDEV; | ||
1721 | if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt) | ||
1722 | goto out_dput_new; | ||
1723 | host_err = mnt_want_write(ffhp->fh_export->ex_path.mnt); | ||
1724 | if (host_err) | ||
1725 | goto out_dput_new; | ||
1726 | |||
1688 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); | 1727 | host_err = vfs_rename(fdir, odentry, tdir, ndentry); |
1689 | if (!host_err && EX_ISSYNC(tfhp->fh_export)) { | 1728 | if (!host_err && EX_ISSYNC(tfhp->fh_export)) { |
1690 | host_err = nfsd_sync_dir(tdentry); | 1729 | host_err = nfsd_sync_dir(tdentry); |
@@ -1692,6 +1731,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, | |||
1692 | host_err = nfsd_sync_dir(fdentry); | 1731 | host_err = nfsd_sync_dir(fdentry); |
1693 | } | 1732 | } |
1694 | 1733 | ||
1734 | mnt_drop_write(ffhp->fh_export->ex_path.mnt); | ||
1735 | |||
1695 | out_dput_new: | 1736 | out_dput_new: |
1696 | dput(ndentry); | 1737 | dput(ndentry); |
1697 | out_dput_old: | 1738 | out_dput_old: |
@@ -1750,6 +1791,10 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
1750 | if (!type) | 1791 | if (!type) |
1751 | type = rdentry->d_inode->i_mode & S_IFMT; | 1792 | type = rdentry->d_inode->i_mode & S_IFMT; |
1752 | 1793 | ||
1794 | host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
1795 | if (host_err) | ||
1796 | goto out_nfserr; | ||
1797 | |||
1753 | if (type != S_IFDIR) { /* It's UNLINK */ | 1798 | if (type != S_IFDIR) { /* It's UNLINK */ |
1754 | #ifdef MSNFS | 1799 | #ifdef MSNFS |
1755 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && | 1800 | if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && |
@@ -1765,10 +1810,12 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
1765 | dput(rdentry); | 1810 | dput(rdentry); |
1766 | 1811 | ||
1767 | if (host_err) | 1812 | if (host_err) |
1768 | goto out_nfserr; | 1813 | goto out_drop; |
1769 | if (EX_ISSYNC(fhp->fh_export)) | 1814 | if (EX_ISSYNC(fhp->fh_export)) |
1770 | host_err = nfsd_sync_dir(dentry); | 1815 | host_err = nfsd_sync_dir(dentry); |
1771 | 1816 | ||
1817 | out_drop: | ||
1818 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
1772 | out_nfserr: | 1819 | out_nfserr: |
1773 | err = nfserrno(host_err); | 1820 | err = nfserrno(host_err); |
1774 | out: | 1821 | out: |
@@ -1865,7 +1912,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
1865 | inode->i_mode, | 1912 | inode->i_mode, |
1866 | IS_IMMUTABLE(inode)? " immut" : "", | 1913 | IS_IMMUTABLE(inode)? " immut" : "", |
1867 | IS_APPEND(inode)? " append" : "", | 1914 | IS_APPEND(inode)? " append" : "", |
1868 | IS_RDONLY(inode)? " ro" : ""); | 1915 | __mnt_is_readonly(exp->ex_path.mnt)? " ro" : ""); |
1869 | dprintk(" owner %d/%d user %d/%d\n", | 1916 | dprintk(" owner %d/%d user %d/%d\n", |
1870 | inode->i_uid, inode->i_gid, current->fsuid, current->fsgid); | 1917 | inode->i_uid, inode->i_gid, current->fsuid, current->fsgid); |
1871 | #endif | 1918 | #endif |
@@ -1876,7 +1923,8 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
1876 | */ | 1923 | */ |
1877 | if (!(acc & MAY_LOCAL_ACCESS)) | 1924 | if (!(acc & MAY_LOCAL_ACCESS)) |
1878 | if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) { | 1925 | if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) { |
1879 | if (exp_rdonly(rqstp, exp) || IS_RDONLY(inode)) | 1926 | if (exp_rdonly(rqstp, exp) || |
1927 | __mnt_is_readonly(exp->ex_path.mnt)) | ||
1880 | return nfserr_rofs; | 1928 | return nfserr_rofs; |
1881 | if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode)) | 1929 | if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode)) |
1882 | return nfserr_perm; | 1930 | return nfserr_perm; |
@@ -2039,6 +2087,9 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) | |||
2039 | } else | 2087 | } else |
2040 | size = 0; | 2088 | size = 0; |
2041 | 2089 | ||
2090 | error = mnt_want_write(fhp->fh_export->ex_path.mnt); | ||
2091 | if (error) | ||
2092 | goto getout; | ||
2042 | if (size) | 2093 | if (size) |
2043 | error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); | 2094 | error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); |
2044 | else { | 2095 | else { |
@@ -2050,6 +2101,7 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) | |||
2050 | error = 0; | 2101 | error = 0; |
2051 | } | 2102 | } |
2052 | } | 2103 | } |
2104 | mnt_drop_write(fhp->fh_export->ex_path.mnt); | ||
2053 | 2105 | ||
2054 | getout: | 2106 | getout: |
2055 | kfree(value); | 2107 | kfree(value); |
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index b413166dd163..7b142f0ce995 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -60,10 +60,6 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
60 | goto bail; | 60 | goto bail; |
61 | } | 61 | } |
62 | 62 | ||
63 | status = -EROFS; | ||
64 | if (IS_RDONLY(inode)) | ||
65 | goto bail_unlock; | ||
66 | |||
67 | status = -EACCES; | 63 | status = -EACCES; |
68 | if (!is_owner_or_cap(inode)) | 64 | if (!is_owner_or_cap(inode)) |
69 | goto bail_unlock; | 65 | goto bail_unlock; |
@@ -134,8 +130,13 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
134 | if (get_user(flags, (int __user *) arg)) | 130 | if (get_user(flags, (int __user *) arg)) |
135 | return -EFAULT; | 131 | return -EFAULT; |
136 | 132 | ||
137 | return ocfs2_set_inode_attr(inode, flags, | 133 | status = mnt_want_write(filp->f_path.mnt); |
134 | if (status) | ||
135 | return status; | ||
136 | status = ocfs2_set_inode_attr(inode, flags, | ||
138 | OCFS2_FL_MODIFIABLE); | 137 | OCFS2_FL_MODIFIABLE); |
138 | mnt_drop_write(filp->f_path.mnt); | ||
139 | return status; | ||
139 | case OCFS2_IOC_RESVSP: | 140 | case OCFS2_IOC_RESVSP: |
140 | case OCFS2_IOC_RESVSP64: | 141 | case OCFS2_IOC_RESVSP64: |
141 | case OCFS2_IOC_UNRESVSP: | 142 | case OCFS2_IOC_UNRESVSP: |
@@ -244,21 +244,21 @@ static long do_sys_truncate(const char __user * path, loff_t length) | |||
244 | if (!S_ISREG(inode->i_mode)) | 244 | if (!S_ISREG(inode->i_mode)) |
245 | goto dput_and_out; | 245 | goto dput_and_out; |
246 | 246 | ||
247 | error = vfs_permission(&nd, MAY_WRITE); | 247 | error = mnt_want_write(nd.path.mnt); |
248 | if (error) | 248 | if (error) |
249 | goto dput_and_out; | 249 | goto dput_and_out; |
250 | 250 | ||
251 | error = -EROFS; | 251 | error = vfs_permission(&nd, MAY_WRITE); |
252 | if (IS_RDONLY(inode)) | 252 | if (error) |
253 | goto dput_and_out; | 253 | goto mnt_drop_write_and_out; |
254 | 254 | ||
255 | error = -EPERM; | 255 | error = -EPERM; |
256 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 256 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
257 | goto dput_and_out; | 257 | goto mnt_drop_write_and_out; |
258 | 258 | ||
259 | error = get_write_access(inode); | 259 | error = get_write_access(inode); |
260 | if (error) | 260 | if (error) |
261 | goto dput_and_out; | 261 | goto mnt_drop_write_and_out; |
262 | 262 | ||
263 | /* | 263 | /* |
264 | * Make sure that there are no leases. get_write_access() protects | 264 | * Make sure that there are no leases. get_write_access() protects |
@@ -276,6 +276,8 @@ static long do_sys_truncate(const char __user * path, loff_t length) | |||
276 | 276 | ||
277 | put_write_and_out: | 277 | put_write_and_out: |
278 | put_write_access(inode); | 278 | put_write_access(inode); |
279 | mnt_drop_write_and_out: | ||
280 | mnt_drop_write(nd.path.mnt); | ||
279 | dput_and_out: | 281 | dput_and_out: |
280 | path_put(&nd.path); | 282 | path_put(&nd.path); |
281 | out: | 283 | out: |
@@ -457,8 +459,17 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) | |||
457 | if(res || !(mode & S_IWOTH) || | 459 | if(res || !(mode & S_IWOTH) || |
458 | special_file(nd.path.dentry->d_inode->i_mode)) | 460 | special_file(nd.path.dentry->d_inode->i_mode)) |
459 | goto out_path_release; | 461 | goto out_path_release; |
460 | 462 | /* | |
461 | if(IS_RDONLY(nd.path.dentry->d_inode)) | 463 | * This is a rare case where using __mnt_is_readonly() |
464 | * is OK without a mnt_want/drop_write() pair. Since | ||
465 | * no actual write to the fs is performed here, we do | ||
466 | * not need to telegraph to that to anyone. | ||
467 | * | ||
468 | * By doing this, we accept that this access is | ||
469 | * inherently racy and know that the fs may change | ||
470 | * state before we even see this result. | ||
471 | */ | ||
472 | if (__mnt_is_readonly(nd.path.mnt)) | ||
462 | res = -EROFS; | 473 | res = -EROFS; |
463 | 474 | ||
464 | out_path_release: | 475 | out_path_release: |
@@ -567,12 +578,12 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
567 | 578 | ||
568 | audit_inode(NULL, dentry); | 579 | audit_inode(NULL, dentry); |
569 | 580 | ||
570 | err = -EROFS; | 581 | err = mnt_want_write(file->f_path.mnt); |
571 | if (IS_RDONLY(inode)) | 582 | if (err) |
572 | goto out_putf; | 583 | goto out_putf; |
573 | err = -EPERM; | 584 | err = -EPERM; |
574 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 585 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
575 | goto out_putf; | 586 | goto out_drop_write; |
576 | mutex_lock(&inode->i_mutex); | 587 | mutex_lock(&inode->i_mutex); |
577 | if (mode == (mode_t) -1) | 588 | if (mode == (mode_t) -1) |
578 | mode = inode->i_mode; | 589 | mode = inode->i_mode; |
@@ -581,6 +592,8 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
581 | err = notify_change(dentry, &newattrs); | 592 | err = notify_change(dentry, &newattrs); |
582 | mutex_unlock(&inode->i_mutex); | 593 | mutex_unlock(&inode->i_mutex); |
583 | 594 | ||
595 | out_drop_write: | ||
596 | mnt_drop_write(file->f_path.mnt); | ||
584 | out_putf: | 597 | out_putf: |
585 | fput(file); | 598 | fput(file); |
586 | out: | 599 | out: |
@@ -600,13 +613,13 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename, | |||
600 | goto out; | 613 | goto out; |
601 | inode = nd.path.dentry->d_inode; | 614 | inode = nd.path.dentry->d_inode; |
602 | 615 | ||
603 | error = -EROFS; | 616 | error = mnt_want_write(nd.path.mnt); |
604 | if (IS_RDONLY(inode)) | 617 | if (error) |
605 | goto dput_and_out; | 618 | goto dput_and_out; |
606 | 619 | ||
607 | error = -EPERM; | 620 | error = -EPERM; |
608 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 621 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
609 | goto dput_and_out; | 622 | goto out_drop_write; |
610 | 623 | ||
611 | mutex_lock(&inode->i_mutex); | 624 | mutex_lock(&inode->i_mutex); |
612 | if (mode == (mode_t) -1) | 625 | if (mode == (mode_t) -1) |
@@ -616,6 +629,8 @@ asmlinkage long sys_fchmodat(int dfd, const char __user *filename, | |||
616 | error = notify_change(nd.path.dentry, &newattrs); | 629 | error = notify_change(nd.path.dentry, &newattrs); |
617 | mutex_unlock(&inode->i_mutex); | 630 | mutex_unlock(&inode->i_mutex); |
618 | 631 | ||
632 | out_drop_write: | ||
633 | mnt_drop_write(nd.path.mnt); | ||
619 | dput_and_out: | 634 | dput_and_out: |
620 | path_put(&nd.path); | 635 | path_put(&nd.path); |
621 | out: | 636 | out: |
@@ -638,9 +653,6 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | |||
638 | printk(KERN_ERR "chown_common: NULL inode\n"); | 653 | printk(KERN_ERR "chown_common: NULL inode\n"); |
639 | goto out; | 654 | goto out; |
640 | } | 655 | } |
641 | error = -EROFS; | ||
642 | if (IS_RDONLY(inode)) | ||
643 | goto out; | ||
644 | error = -EPERM; | 656 | error = -EPERM; |
645 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 657 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
646 | goto out; | 658 | goto out; |
@@ -671,7 +683,12 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) | |||
671 | error = user_path_walk(filename, &nd); | 683 | error = user_path_walk(filename, &nd); |
672 | if (error) | 684 | if (error) |
673 | goto out; | 685 | goto out; |
686 | error = mnt_want_write(nd.path.mnt); | ||
687 | if (error) | ||
688 | goto out_release; | ||
674 | error = chown_common(nd.path.dentry, user, group); | 689 | error = chown_common(nd.path.dentry, user, group); |
690 | mnt_drop_write(nd.path.mnt); | ||
691 | out_release: | ||
675 | path_put(&nd.path); | 692 | path_put(&nd.path); |
676 | out: | 693 | out: |
677 | return error; | 694 | return error; |
@@ -691,7 +708,12 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, | |||
691 | error = __user_walk_fd(dfd, filename, follow, &nd); | 708 | error = __user_walk_fd(dfd, filename, follow, &nd); |
692 | if (error) | 709 | if (error) |
693 | goto out; | 710 | goto out; |
711 | error = mnt_want_write(nd.path.mnt); | ||
712 | if (error) | ||
713 | goto out_release; | ||
694 | error = chown_common(nd.path.dentry, user, group); | 714 | error = chown_common(nd.path.dentry, user, group); |
715 | mnt_drop_write(nd.path.mnt); | ||
716 | out_release: | ||
695 | path_put(&nd.path); | 717 | path_put(&nd.path); |
696 | out: | 718 | out: |
697 | return error; | 719 | return error; |
@@ -705,7 +727,12 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group | |||
705 | error = user_path_walk_link(filename, &nd); | 727 | error = user_path_walk_link(filename, &nd); |
706 | if (error) | 728 | if (error) |
707 | goto out; | 729 | goto out; |
730 | error = mnt_want_write(nd.path.mnt); | ||
731 | if (error) | ||
732 | goto out_release; | ||
708 | error = chown_common(nd.path.dentry, user, group); | 733 | error = chown_common(nd.path.dentry, user, group); |
734 | mnt_drop_write(nd.path.mnt); | ||
735 | out_release: | ||
709 | path_put(&nd.path); | 736 | path_put(&nd.path); |
710 | out: | 737 | out: |
711 | return error; | 738 | return error; |
@@ -722,14 +749,48 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) | |||
722 | if (!file) | 749 | if (!file) |
723 | goto out; | 750 | goto out; |
724 | 751 | ||
752 | error = mnt_want_write(file->f_path.mnt); | ||
753 | if (error) | ||
754 | goto out_fput; | ||
725 | dentry = file->f_path.dentry; | 755 | dentry = file->f_path.dentry; |
726 | audit_inode(NULL, dentry); | 756 | audit_inode(NULL, dentry); |
727 | error = chown_common(dentry, user, group); | 757 | error = chown_common(dentry, user, group); |
758 | mnt_drop_write(file->f_path.mnt); | ||
759 | out_fput: | ||
728 | fput(file); | 760 | fput(file); |
729 | out: | 761 | out: |
730 | return error; | 762 | return error; |
731 | } | 763 | } |
732 | 764 | ||
765 | /* | ||
766 | * You have to be very careful that these write | ||
767 | * counts get cleaned up in error cases and | ||
768 | * upon __fput(). This should probably never | ||
769 | * be called outside of __dentry_open(). | ||
770 | */ | ||
771 | static inline int __get_file_write_access(struct inode *inode, | ||
772 | struct vfsmount *mnt) | ||
773 | { | ||
774 | int error; | ||
775 | error = get_write_access(inode); | ||
776 | if (error) | ||
777 | return error; | ||
778 | /* | ||
779 | * Do not take mount writer counts on | ||
780 | * special files since no writes to | ||
781 | * the mount itself will occur. | ||
782 | */ | ||
783 | if (!special_file(inode->i_mode)) { | ||
784 | /* | ||
785 | * Balanced in __fput() | ||
786 | */ | ||
787 | error = mnt_want_write(mnt); | ||
788 | if (error) | ||
789 | put_write_access(inode); | ||
790 | } | ||
791 | return error; | ||
792 | } | ||
793 | |||
733 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | 794 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, |
734 | int flags, struct file *f, | 795 | int flags, struct file *f, |
735 | int (*open)(struct inode *, struct file *)) | 796 | int (*open)(struct inode *, struct file *)) |
@@ -742,9 +803,11 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
742 | FMODE_PREAD | FMODE_PWRITE; | 803 | FMODE_PREAD | FMODE_PWRITE; |
743 | inode = dentry->d_inode; | 804 | inode = dentry->d_inode; |
744 | if (f->f_mode & FMODE_WRITE) { | 805 | if (f->f_mode & FMODE_WRITE) { |
745 | error = get_write_access(inode); | 806 | error = __get_file_write_access(inode, mnt); |
746 | if (error) | 807 | if (error) |
747 | goto cleanup_file; | 808 | goto cleanup_file; |
809 | if (!special_file(inode->i_mode)) | ||
810 | file_take_write(f); | ||
748 | } | 811 | } |
749 | 812 | ||
750 | f->f_mapping = inode->i_mapping; | 813 | f->f_mapping = inode->i_mapping; |
@@ -784,8 +847,19 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
784 | 847 | ||
785 | cleanup_all: | 848 | cleanup_all: |
786 | fops_put(f->f_op); | 849 | fops_put(f->f_op); |
787 | if (f->f_mode & FMODE_WRITE) | 850 | if (f->f_mode & FMODE_WRITE) { |
788 | put_write_access(inode); | 851 | put_write_access(inode); |
852 | if (!special_file(inode->i_mode)) { | ||
853 | /* | ||
854 | * We don't consider this a real | ||
855 | * mnt_want/drop_write() pair | ||
856 | * because it all happenend right | ||
857 | * here, so just reset the state. | ||
858 | */ | ||
859 | file_reset_write(f); | ||
860 | mnt_drop_write(mnt); | ||
861 | } | ||
862 | } | ||
789 | file_kill(f); | 863 | file_kill(f); |
790 | f->f_path.dentry = NULL; | 864 | f->f_path.dentry = NULL; |
791 | f->f_path.mnt = NULL; | 865 | f->f_path.mnt = NULL; |
@@ -796,43 +870,6 @@ cleanup_file: | |||
796 | return ERR_PTR(error); | 870 | return ERR_PTR(error); |
797 | } | 871 | } |
798 | 872 | ||
799 | /* | ||
800 | * Note that while the flag value (low two bits) for sys_open means: | ||
801 | * 00 - read-only | ||
802 | * 01 - write-only | ||
803 | * 10 - read-write | ||
804 | * 11 - special | ||
805 | * it is changed into | ||
806 | * 00 - no permissions needed | ||
807 | * 01 - read-permission | ||
808 | * 10 - write-permission | ||
809 | * 11 - read-write | ||
810 | * for the internal routines (ie open_namei()/follow_link() etc). 00 is | ||
811 | * used by symlinks. | ||
812 | */ | ||
813 | static struct file *do_filp_open(int dfd, const char *filename, int flags, | ||
814 | int mode) | ||
815 | { | ||
816 | int namei_flags, error; | ||
817 | struct nameidata nd; | ||
818 | |||
819 | namei_flags = flags; | ||
820 | if ((namei_flags+1) & O_ACCMODE) | ||
821 | namei_flags++; | ||
822 | |||
823 | error = open_namei(dfd, filename, namei_flags, mode, &nd); | ||
824 | if (!error) | ||
825 | return nameidata_to_filp(&nd, flags); | ||
826 | |||
827 | return ERR_PTR(error); | ||
828 | } | ||
829 | |||
830 | struct file *filp_open(const char *filename, int flags, int mode) | ||
831 | { | ||
832 | return do_filp_open(AT_FDCWD, filename, flags, mode); | ||
833 | } | ||
834 | EXPORT_SYMBOL(filp_open); | ||
835 | |||
836 | /** | 873 | /** |
837 | * lookup_instantiate_filp - instantiates the open intent filp | 874 | * lookup_instantiate_filp - instantiates the open intent filp |
838 | * @nd: pointer to nameidata | 875 | * @nd: pointer to nameidata |
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index e0f0f098a523..74363a7aacbc 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/capability.h> | 5 | #include <linux/capability.h> |
6 | #include <linux/fs.h> | 6 | #include <linux/fs.h> |
7 | #include <linux/mount.h> | ||
7 | #include <linux/reiserfs_fs.h> | 8 | #include <linux/reiserfs_fs.h> |
8 | #include <linux/time.h> | 9 | #include <linux/time.h> |
9 | #include <asm/uaccess.h> | 10 | #include <asm/uaccess.h> |
@@ -25,6 +26,7 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
25 | unsigned long arg) | 26 | unsigned long arg) |
26 | { | 27 | { |
27 | unsigned int flags; | 28 | unsigned int flags; |
29 | int err = 0; | ||
28 | 30 | ||
29 | switch (cmd) { | 31 | switch (cmd) { |
30 | case REISERFS_IOC_UNPACK: | 32 | case REISERFS_IOC_UNPACK: |
@@ -48,50 +50,67 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
48 | if (!reiserfs_attrs(inode->i_sb)) | 50 | if (!reiserfs_attrs(inode->i_sb)) |
49 | return -ENOTTY; | 51 | return -ENOTTY; |
50 | 52 | ||
51 | if (IS_RDONLY(inode)) | 53 | err = mnt_want_write(filp->f_path.mnt); |
52 | return -EROFS; | 54 | if (err) |
55 | return err; | ||
53 | 56 | ||
54 | if (!is_owner_or_cap(inode)) | 57 | if (!is_owner_or_cap(inode)) { |
55 | return -EPERM; | 58 | err = -EPERM; |
56 | 59 | goto setflags_out; | |
57 | if (get_user(flags, (int __user *)arg)) | 60 | } |
58 | return -EFAULT; | 61 | if (get_user(flags, (int __user *)arg)) { |
59 | 62 | err = -EFAULT; | |
60 | /* Is it quota file? Do not allow user to mess with it. */ | 63 | goto setflags_out; |
61 | if (IS_NOQUOTA(inode)) | 64 | } |
62 | return -EPERM; | 65 | /* |
66 | * Is it quota file? Do not allow user to mess with it | ||
67 | */ | ||
68 | if (IS_NOQUOTA(inode)) { | ||
69 | err = -EPERM; | ||
70 | goto setflags_out; | ||
71 | } | ||
63 | if (((flags ^ REISERFS_I(inode)-> | 72 | if (((flags ^ REISERFS_I(inode)-> |
64 | i_attrs) & (REISERFS_IMMUTABLE_FL | | 73 | i_attrs) & (REISERFS_IMMUTABLE_FL | |
65 | REISERFS_APPEND_FL)) | 74 | REISERFS_APPEND_FL)) |
66 | && !capable(CAP_LINUX_IMMUTABLE)) | 75 | && !capable(CAP_LINUX_IMMUTABLE)) { |
67 | return -EPERM; | 76 | err = -EPERM; |
68 | 77 | goto setflags_out; | |
78 | } | ||
69 | if ((flags & REISERFS_NOTAIL_FL) && | 79 | if ((flags & REISERFS_NOTAIL_FL) && |
70 | S_ISREG(inode->i_mode)) { | 80 | S_ISREG(inode->i_mode)) { |
71 | int result; | 81 | int result; |
72 | 82 | ||
73 | result = reiserfs_unpack(inode, filp); | 83 | result = reiserfs_unpack(inode, filp); |
74 | if (result) | 84 | if (result) { |
75 | return result; | 85 | err = result; |
86 | goto setflags_out; | ||
87 | } | ||
76 | } | 88 | } |
77 | sd_attrs_to_i_attrs(flags, inode); | 89 | sd_attrs_to_i_attrs(flags, inode); |
78 | REISERFS_I(inode)->i_attrs = flags; | 90 | REISERFS_I(inode)->i_attrs = flags; |
79 | inode->i_ctime = CURRENT_TIME_SEC; | 91 | inode->i_ctime = CURRENT_TIME_SEC; |
80 | mark_inode_dirty(inode); | 92 | mark_inode_dirty(inode); |
81 | return 0; | 93 | setflags_out: |
94 | mnt_drop_write(filp->f_path.mnt); | ||
95 | return err; | ||
82 | } | 96 | } |
83 | case REISERFS_IOC_GETVERSION: | 97 | case REISERFS_IOC_GETVERSION: |
84 | return put_user(inode->i_generation, (int __user *)arg); | 98 | return put_user(inode->i_generation, (int __user *)arg); |
85 | case REISERFS_IOC_SETVERSION: | 99 | case REISERFS_IOC_SETVERSION: |
86 | if (!is_owner_or_cap(inode)) | 100 | if (!is_owner_or_cap(inode)) |
87 | return -EPERM; | 101 | return -EPERM; |
88 | if (IS_RDONLY(inode)) | 102 | err = mnt_want_write(filp->f_path.mnt); |
89 | return -EROFS; | 103 | if (err) |
90 | if (get_user(inode->i_generation, (int __user *)arg)) | 104 | return err; |
91 | return -EFAULT; | 105 | if (get_user(inode->i_generation, (int __user *)arg)) { |
106 | err = -EFAULT; | ||
107 | goto setversion_out; | ||
108 | } | ||
92 | inode->i_ctime = CURRENT_TIME_SEC; | 109 | inode->i_ctime = CURRENT_TIME_SEC; |
93 | mark_inode_dirty(inode); | 110 | mark_inode_dirty(inode); |
94 | return 0; | 111 | setversion_out: |
112 | mnt_drop_write(filp->f_path.mnt); | ||
113 | return err; | ||
95 | default: | 114 | default: |
96 | return -ENOTTY; | 115 | return -ENOTTY; |
97 | } | 116 | } |
diff --git a/fs/super.c b/fs/super.c index 09008dbd264e..1f8f05ede437 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
38 | #include <linux/kobject.h> | 38 | #include <linux/kobject.h> |
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | #include <linux/file.h> | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | 42 | ||
42 | 43 | ||
@@ -567,10 +568,29 @@ static void mark_files_ro(struct super_block *sb) | |||
567 | { | 568 | { |
568 | struct file *f; | 569 | struct file *f; |
569 | 570 | ||
571 | retry: | ||
570 | file_list_lock(); | 572 | file_list_lock(); |
571 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { | 573 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { |
572 | if (S_ISREG(f->f_path.dentry->d_inode->i_mode) && file_count(f)) | 574 | struct vfsmount *mnt; |
573 | f->f_mode &= ~FMODE_WRITE; | 575 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) |
576 | continue; | ||
577 | if (!file_count(f)) | ||
578 | continue; | ||
579 | if (!(f->f_mode & FMODE_WRITE)) | ||
580 | continue; | ||
581 | f->f_mode &= ~FMODE_WRITE; | ||
582 | if (file_check_writeable(f) != 0) | ||
583 | continue; | ||
584 | file_release_write(f); | ||
585 | mnt = mntget(f->f_path.mnt); | ||
586 | file_list_unlock(); | ||
587 | /* | ||
588 | * This can sleep, so we can't hold | ||
589 | * the file_list_lock() spinlock. | ||
590 | */ | ||
591 | mnt_drop_write(mnt); | ||
592 | mntput(mnt); | ||
593 | goto retry; | ||
574 | } | 594 | } |
575 | file_list_unlock(); | 595 | file_list_unlock(); |
576 | } | 596 | } |
diff --git a/fs/utimes.c b/fs/utimes.c index b18da9c0b97f..a2bef77dc9c9 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/file.h> | 2 | #include <linux/file.h> |
3 | #include <linux/fs.h> | 3 | #include <linux/fs.h> |
4 | #include <linux/linkage.h> | 4 | #include <linux/linkage.h> |
5 | #include <linux/mount.h> | ||
5 | #include <linux/namei.h> | 6 | #include <linux/namei.h> |
6 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
7 | #include <linux/stat.h> | 8 | #include <linux/stat.h> |
@@ -59,6 +60,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags | |||
59 | struct inode *inode; | 60 | struct inode *inode; |
60 | struct iattr newattrs; | 61 | struct iattr newattrs; |
61 | struct file *f = NULL; | 62 | struct file *f = NULL; |
63 | struct vfsmount *mnt; | ||
62 | 64 | ||
63 | error = -EINVAL; | 65 | error = -EINVAL; |
64 | if (times && (!nsec_valid(times[0].tv_nsec) || | 66 | if (times && (!nsec_valid(times[0].tv_nsec) || |
@@ -79,18 +81,20 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags | |||
79 | if (!f) | 81 | if (!f) |
80 | goto out; | 82 | goto out; |
81 | dentry = f->f_path.dentry; | 83 | dentry = f->f_path.dentry; |
84 | mnt = f->f_path.mnt; | ||
82 | } else { | 85 | } else { |
83 | error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); | 86 | error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); |
84 | if (error) | 87 | if (error) |
85 | goto out; | 88 | goto out; |
86 | 89 | ||
87 | dentry = nd.path.dentry; | 90 | dentry = nd.path.dentry; |
91 | mnt = nd.path.mnt; | ||
88 | } | 92 | } |
89 | 93 | ||
90 | inode = dentry->d_inode; | 94 | inode = dentry->d_inode; |
91 | 95 | ||
92 | error = -EROFS; | 96 | error = mnt_want_write(mnt); |
93 | if (IS_RDONLY(inode)) | 97 | if (error) |
94 | goto dput_and_out; | 98 | goto dput_and_out; |
95 | 99 | ||
96 | /* Don't worry, the checks are done in inode_change_ok() */ | 100 | /* Don't worry, the checks are done in inode_change_ok() */ |
@@ -98,7 +102,7 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags | |||
98 | if (times) { | 102 | if (times) { |
99 | error = -EPERM; | 103 | error = -EPERM; |
100 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 104 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
101 | goto dput_and_out; | 105 | goto mnt_drop_write_and_out; |
102 | 106 | ||
103 | if (times[0].tv_nsec == UTIME_OMIT) | 107 | if (times[0].tv_nsec == UTIME_OMIT) |
104 | newattrs.ia_valid &= ~ATTR_ATIME; | 108 | newattrs.ia_valid &= ~ATTR_ATIME; |
@@ -118,22 +122,24 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags | |||
118 | } else { | 122 | } else { |
119 | error = -EACCES; | 123 | error = -EACCES; |
120 | if (IS_IMMUTABLE(inode)) | 124 | if (IS_IMMUTABLE(inode)) |
121 | goto dput_and_out; | 125 | goto mnt_drop_write_and_out; |
122 | 126 | ||
123 | if (!is_owner_or_cap(inode)) { | 127 | if (!is_owner_or_cap(inode)) { |
124 | if (f) { | 128 | if (f) { |
125 | if (!(f->f_mode & FMODE_WRITE)) | 129 | if (!(f->f_mode & FMODE_WRITE)) |
126 | goto dput_and_out; | 130 | goto mnt_drop_write_and_out; |
127 | } else { | 131 | } else { |
128 | error = vfs_permission(&nd, MAY_WRITE); | 132 | error = vfs_permission(&nd, MAY_WRITE); |
129 | if (error) | 133 | if (error) |
130 | goto dput_and_out; | 134 | goto mnt_drop_write_and_out; |
131 | } | 135 | } |
132 | } | 136 | } |
133 | } | 137 | } |
134 | mutex_lock(&inode->i_mutex); | 138 | mutex_lock(&inode->i_mutex); |
135 | error = notify_change(dentry, &newattrs); | 139 | error = notify_change(dentry, &newattrs); |
136 | mutex_unlock(&inode->i_mutex); | 140 | mutex_unlock(&inode->i_mutex); |
141 | mnt_drop_write_and_out: | ||
142 | mnt_drop_write(mnt); | ||
137 | dput_and_out: | 143 | dput_and_out: |
138 | if (f) | 144 | if (f) |
139 | fput(f); | 145 | fput(f); |
diff --git a/fs/xattr.c b/fs/xattr.c index 3acab1615460..f7062da505d4 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/file.h> | 12 | #include <linux/file.h> |
13 | #include <linux/xattr.h> | 13 | #include <linux/xattr.h> |
14 | #include <linux/mount.h> | ||
14 | #include <linux/namei.h> | 15 | #include <linux/namei.h> |
15 | #include <linux/security.h> | 16 | #include <linux/security.h> |
16 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
@@ -32,8 +33,6 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
32 | * filesystem or on an immutable / append-only inode. | 33 | * filesystem or on an immutable / append-only inode. |
33 | */ | 34 | */ |
34 | if (mask & MAY_WRITE) { | 35 | if (mask & MAY_WRITE) { |
35 | if (IS_RDONLY(inode)) | ||
36 | return -EROFS; | ||
37 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 36 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
38 | return -EPERM; | 37 | return -EPERM; |
39 | } | 38 | } |
@@ -262,7 +261,11 @@ sys_setxattr(char __user *path, char __user *name, void __user *value, | |||
262 | error = user_path_walk(path, &nd); | 261 | error = user_path_walk(path, &nd); |
263 | if (error) | 262 | if (error) |
264 | return error; | 263 | return error; |
265 | error = setxattr(nd.path.dentry, name, value, size, flags); | 264 | error = mnt_want_write(nd.path.mnt); |
265 | if (!error) { | ||
266 | error = setxattr(nd.path.dentry, name, value, size, flags); | ||
267 | mnt_drop_write(nd.path.mnt); | ||
268 | } | ||
266 | path_put(&nd.path); | 269 | path_put(&nd.path); |
267 | return error; | 270 | return error; |
268 | } | 271 | } |
@@ -277,7 +280,11 @@ sys_lsetxattr(char __user *path, char __user *name, void __user *value, | |||
277 | error = user_path_walk_link(path, &nd); | 280 | error = user_path_walk_link(path, &nd); |
278 | if (error) | 281 | if (error) |
279 | return error; | 282 | return error; |
280 | error = setxattr(nd.path.dentry, name, value, size, flags); | 283 | error = mnt_want_write(nd.path.mnt); |
284 | if (!error) { | ||
285 | error = setxattr(nd.path.dentry, name, value, size, flags); | ||
286 | mnt_drop_write(nd.path.mnt); | ||
287 | } | ||
281 | path_put(&nd.path); | 288 | path_put(&nd.path); |
282 | return error; | 289 | return error; |
283 | } | 290 | } |
@@ -295,7 +302,12 @@ sys_fsetxattr(int fd, char __user *name, void __user *value, | |||
295 | return error; | 302 | return error; |
296 | dentry = f->f_path.dentry; | 303 | dentry = f->f_path.dentry; |
297 | audit_inode(NULL, dentry); | 304 | audit_inode(NULL, dentry); |
298 | error = setxattr(dentry, name, value, size, flags); | 305 | error = mnt_want_write(f->f_path.mnt); |
306 | if (!error) { | ||
307 | error = setxattr(dentry, name, value, size, flags); | ||
308 | mnt_drop_write(f->f_path.mnt); | ||
309 | } | ||
310 | out_fput: | ||
299 | fput(f); | 311 | fput(f); |
300 | return error; | 312 | return error; |
301 | } | 313 | } |
@@ -482,7 +494,11 @@ sys_removexattr(char __user *path, char __user *name) | |||
482 | error = user_path_walk(path, &nd); | 494 | error = user_path_walk(path, &nd); |
483 | if (error) | 495 | if (error) |
484 | return error; | 496 | return error; |
485 | error = removexattr(nd.path.dentry, name); | 497 | error = mnt_want_write(nd.path.mnt); |
498 | if (!error) { | ||
499 | error = removexattr(nd.path.dentry, name); | ||
500 | mnt_drop_write(nd.path.mnt); | ||
501 | } | ||
486 | path_put(&nd.path); | 502 | path_put(&nd.path); |
487 | return error; | 503 | return error; |
488 | } | 504 | } |
@@ -496,7 +512,11 @@ sys_lremovexattr(char __user *path, char __user *name) | |||
496 | error = user_path_walk_link(path, &nd); | 512 | error = user_path_walk_link(path, &nd); |
497 | if (error) | 513 | if (error) |
498 | return error; | 514 | return error; |
499 | error = removexattr(nd.path.dentry, name); | 515 | error = mnt_want_write(nd.path.mnt); |
516 | if (!error) { | ||
517 | error = removexattr(nd.path.dentry, name); | ||
518 | mnt_drop_write(nd.path.mnt); | ||
519 | } | ||
500 | path_put(&nd.path); | 520 | path_put(&nd.path); |
501 | return error; | 521 | return error; |
502 | } | 522 | } |
@@ -513,7 +533,11 @@ sys_fremovexattr(int fd, char __user *name) | |||
513 | return error; | 533 | return error; |
514 | dentry = f->f_path.dentry; | 534 | dentry = f->f_path.dentry; |
515 | audit_inode(NULL, dentry); | 535 | audit_inode(NULL, dentry); |
516 | error = removexattr(dentry, name); | 536 | error = mnt_want_write(f->f_path.mnt); |
537 | if (!error) { | ||
538 | error = removexattr(dentry, name); | ||
539 | mnt_drop_write(f->f_path.mnt); | ||
540 | } | ||
517 | fput(f); | 541 | fput(f); |
518 | return error; | 542 | return error; |
519 | } | 543 | } |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index bf7759793856..4ddb86b73c6b 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -535,8 +535,6 @@ xfs_attrmulti_attr_set( | |||
535 | char *kbuf; | 535 | char *kbuf; |
536 | int error = EFAULT; | 536 | int error = EFAULT; |
537 | 537 | ||
538 | if (IS_RDONLY(inode)) | ||
539 | return -EROFS; | ||
540 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 538 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
541 | return EPERM; | 539 | return EPERM; |
542 | if (len > XATTR_SIZE_MAX) | 540 | if (len > XATTR_SIZE_MAX) |
@@ -562,8 +560,6 @@ xfs_attrmulti_attr_remove( | |||
562 | char *name, | 560 | char *name, |
563 | __uint32_t flags) | 561 | __uint32_t flags) |
564 | { | 562 | { |
565 | if (IS_RDONLY(inode)) | ||
566 | return -EROFS; | ||
567 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 563 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
568 | return EPERM; | 564 | return EPERM; |
569 | return xfs_attr_remove(XFS_I(inode), name, flags); | 565 | return xfs_attr_remove(XFS_I(inode), name, flags); |
@@ -573,6 +569,7 @@ STATIC int | |||
573 | xfs_attrmulti_by_handle( | 569 | xfs_attrmulti_by_handle( |
574 | xfs_mount_t *mp, | 570 | xfs_mount_t *mp, |
575 | void __user *arg, | 571 | void __user *arg, |
572 | struct file *parfilp, | ||
576 | struct inode *parinode) | 573 | struct inode *parinode) |
577 | { | 574 | { |
578 | int error; | 575 | int error; |
@@ -626,13 +623,21 @@ xfs_attrmulti_by_handle( | |||
626 | &ops[i].am_length, ops[i].am_flags); | 623 | &ops[i].am_length, ops[i].am_flags); |
627 | break; | 624 | break; |
628 | case ATTR_OP_SET: | 625 | case ATTR_OP_SET: |
626 | ops[i].am_error = mnt_want_write(parfilp->f_path.mnt); | ||
627 | if (ops[i].am_error) | ||
628 | break; | ||
629 | ops[i].am_error = xfs_attrmulti_attr_set(inode, | 629 | ops[i].am_error = xfs_attrmulti_attr_set(inode, |
630 | attr_name, ops[i].am_attrvalue, | 630 | attr_name, ops[i].am_attrvalue, |
631 | ops[i].am_length, ops[i].am_flags); | 631 | ops[i].am_length, ops[i].am_flags); |
632 | mnt_drop_write(parfilp->f_path.mnt); | ||
632 | break; | 633 | break; |
633 | case ATTR_OP_REMOVE: | 634 | case ATTR_OP_REMOVE: |
635 | ops[i].am_error = mnt_want_write(parfilp->f_path.mnt); | ||
636 | if (ops[i].am_error) | ||
637 | break; | ||
634 | ops[i].am_error = xfs_attrmulti_attr_remove(inode, | 638 | ops[i].am_error = xfs_attrmulti_attr_remove(inode, |
635 | attr_name, ops[i].am_flags); | 639 | attr_name, ops[i].am_flags); |
640 | mnt_drop_write(parfilp->f_path.mnt); | ||
636 | break; | 641 | break; |
637 | default: | 642 | default: |
638 | ops[i].am_error = EINVAL; | 643 | ops[i].am_error = EINVAL; |
@@ -1133,7 +1138,7 @@ xfs_ioctl( | |||
1133 | return xfs_attrlist_by_handle(mp, arg, inode); | 1138 | return xfs_attrlist_by_handle(mp, arg, inode); |
1134 | 1139 | ||
1135 | case XFS_IOC_ATTRMULTI_BY_HANDLE: | 1140 | case XFS_IOC_ATTRMULTI_BY_HANDLE: |
1136 | return xfs_attrmulti_by_handle(mp, arg, inode); | 1141 | return xfs_attrmulti_by_handle(mp, arg, filp, inode); |
1137 | 1142 | ||
1138 | case XFS_IOC_SWAPEXT: { | 1143 | case XFS_IOC_SWAPEXT: { |
1139 | error = xfs_swapext((struct xfs_swapext __user *)arg); | 1144 | error = xfs_swapext((struct xfs_swapext __user *)arg); |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 0c958cf77758..a1237dad6430 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -155,13 +155,6 @@ xfs_ichgtime_fast( | |||
155 | */ | 155 | */ |
156 | ASSERT((flags & XFS_ICHGTIME_ACC) == 0); | 156 | ASSERT((flags & XFS_ICHGTIME_ACC) == 0); |
157 | 157 | ||
158 | /* | ||
159 | * We're not supposed to change timestamps in readonly-mounted | ||
160 | * filesystems. Throw it away if anyone asks us. | ||
161 | */ | ||
162 | if (unlikely(IS_RDONLY(inode))) | ||
163 | return; | ||
164 | |||
165 | if (flags & XFS_ICHGTIME_MOD) { | 158 | if (flags & XFS_ICHGTIME_MOD) { |
166 | tvp = &inode->i_mtime; | 159 | tvp = &inode->i_mtime; |
167 | ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; | 160 | ip->i_d.di_mtime.t_sec = (__int32_t)tvp->tv_sec; |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 21c0dbc74093..1ebd8004469c 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "xfs_vnodeops.h" | 51 | #include "xfs_vnodeops.h" |
52 | 52 | ||
53 | #include <linux/capability.h> | 53 | #include <linux/capability.h> |
54 | #include <linux/mount.h> | ||
54 | #include <linux/writeback.h> | 55 | #include <linux/writeback.h> |
55 | 56 | ||
56 | 57 | ||
@@ -670,10 +671,16 @@ start: | |||
670 | if (new_size > xip->i_size) | 671 | if (new_size > xip->i_size) |
671 | xip->i_new_size = new_size; | 672 | xip->i_new_size = new_size; |
672 | 673 | ||
673 | if (likely(!(ioflags & IO_INVIS))) { | 674 | /* |
675 | * We're not supposed to change timestamps in readonly-mounted | ||
676 | * filesystems. Throw it away if anyone asks us. | ||
677 | */ | ||
678 | if (likely(!(ioflags & IO_INVIS) && | ||
679 | !mnt_want_write(file->f_path.mnt))) { | ||
674 | file_update_time(file); | 680 | file_update_time(file); |
675 | xfs_ichgtime_fast(xip, inode, | 681 | xfs_ichgtime_fast(xip, inode, |
676 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 682 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
683 | mnt_drop_write(file->f_path.mnt); | ||
677 | } | 684 | } |
678 | 685 | ||
679 | /* | 686 | /* |
diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h index cfda7d5bf026..121b2ecddfc3 100644 --- a/include/asm-sh/bugs.h +++ b/include/asm-sh/bugs.h | |||
@@ -25,7 +25,7 @@ static void __init check_bugs(void) | |||
25 | case CPU_SH7619: | 25 | case CPU_SH7619: |
26 | *p++ = '2'; | 26 | *p++ = '2'; |
27 | break; | 27 | break; |
28 | case CPU_SH7203 ... CPU_SH7263: | 28 | case CPU_SH7203 ... CPU_MXG: |
29 | *p++ = '2'; | 29 | *p++ = '2'; |
30 | *p++ = 'a'; | 30 | *p++ = 'a'; |
31 | break; | 31 | break; |
diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h index ec028c649215..da46e67ae26d 100644 --- a/include/asm-sh/cpu-sh4/freq.h +++ b/include/asm-sh/cpu-sh4/freq.h | |||
@@ -10,14 +10,14 @@ | |||
10 | #ifndef __ASM_CPU_SH4_FREQ_H | 10 | #ifndef __ASM_CPU_SH4_FREQ_H |
11 | #define __ASM_CPU_SH4_FREQ_H | 11 | #define __ASM_CPU_SH4_FREQ_H |
12 | 12 | ||
13 | #if defined(CONFIG_CPU_SUBTYPE_SH7722) || defined(CONFIG_CPU_SUBTYPE_SH7366) | 13 | #if defined(CONFIG_CPU_SUBTYPE_SH7722) || \ |
14 | defined(CONFIG_CPU_SUBTYPE_SH7723) || \ | ||
15 | defined(CONFIG_CPU_SUBTYPE_SH7366) | ||
14 | #define FRQCR 0xa4150000 | 16 | #define FRQCR 0xa4150000 |
15 | #define VCLKCR 0xa4150004 | 17 | #define VCLKCR 0xa4150004 |
16 | #define SCLKACR 0xa4150008 | 18 | #define SCLKACR 0xa4150008 |
17 | #define SCLKBCR 0xa415000c | 19 | #define SCLKBCR 0xa415000c |
18 | #if defined(CONFIG_CPU_SUBTYPE_SH7722) | ||
19 | #define IrDACLKCR 0xa4150010 | 20 | #define IrDACLKCR 0xa4150010 |
20 | #endif | ||
21 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | 21 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
22 | defined(CONFIG_CPU_SUBTYPE_SH7780) | 22 | defined(CONFIG_CPU_SUBTYPE_SH7780) |
23 | #define FRQCR 0xffc80000 | 23 | #define FRQCR 0xffc80000 |
diff --git a/include/asm-sh/cpu-sh4/rtc.h b/include/asm-sh/cpu-sh4/rtc.h index f3d0f53275e4..25b1e6adfe8c 100644 --- a/include/asm-sh/cpu-sh4/rtc.h +++ b/include/asm-sh/cpu-sh4/rtc.h | |||
@@ -1,7 +1,12 @@ | |||
1 | #ifndef __ASM_SH_CPU_SH4_RTC_H | 1 | #ifndef __ASM_SH_CPU_SH4_RTC_H |
2 | #define __ASM_SH_CPU_SH4_RTC_H | 2 | #define __ASM_SH_CPU_SH4_RTC_H |
3 | 3 | ||
4 | #ifdef CONFIG_CPU_SUBTYPE_SH7723 | ||
5 | #define rtc_reg_size sizeof(u16) | ||
6 | #else | ||
4 | #define rtc_reg_size sizeof(u32) | 7 | #define rtc_reg_size sizeof(u32) |
8 | #endif | ||
9 | |||
5 | #define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */ | 10 | #define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */ |
6 | #define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR | 11 | #define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR |
7 | 12 | ||
diff --git a/include/asm-sh/migor.h b/include/asm-sh/migor.h new file mode 100644 index 000000000000..2329363afdc3 --- /dev/null +++ b/include/asm-sh/migor.h | |||
@@ -0,0 +1,58 @@ | |||
1 | #ifndef __ASM_SH_MIGOR_H | ||
2 | #define __ASM_SH_MIGOR_H | ||
3 | |||
4 | /* | ||
5 | * linux/include/asm-sh/migor.h | ||
6 | * | ||
7 | * Copyright (C) 2008 Renesas Solutions | ||
8 | * | ||
9 | * Portions Copyright (C) 2007 Nobuhiro Iwamatsu | ||
10 | * | ||
11 | * This file is subject to the terms and conditions of the GNU General Public | ||
12 | * License. See the file "COPYING" in the main directory of this archive | ||
13 | * for more details. | ||
14 | * | ||
15 | */ | ||
16 | #include <asm/addrspace.h> | ||
17 | |||
18 | /* GPIO */ | ||
19 | #define MSTPCR0 0xa4150030 | ||
20 | #define MSTPCR1 0xa4150034 | ||
21 | #define MSTPCR2 0xa4150038 | ||
22 | |||
23 | #define PORT_PACR 0xa4050100 | ||
24 | #define PORT_PDCR 0xa4050106 | ||
25 | #define PORT_PECR 0xa4050108 | ||
26 | #define PORT_PHCR 0xa405010e | ||
27 | #define PORT_PJCR 0xa4050110 | ||
28 | #define PORT_PKCR 0xa4050112 | ||
29 | #define PORT_PLCR 0xa4050114 | ||
30 | #define PORT_PMCR 0xa4050116 | ||
31 | #define PORT_PRCR 0xa405011c | ||
32 | #define PORT_PWCR 0xa4050146 | ||
33 | #define PORT_PXCR 0xa4050148 | ||
34 | #define PORT_PYCR 0xa405014a | ||
35 | #define PORT_PZCR 0xa405014c | ||
36 | #define PORT_PADR 0xa4050120 | ||
37 | #define PORT_PWDR 0xa4050166 | ||
38 | |||
39 | #define PORT_HIZCRA 0xa4050158 | ||
40 | #define PORT_HIZCRC 0xa405015c | ||
41 | |||
42 | #define PORT_MSELCRB 0xa4050182 | ||
43 | |||
44 | #define MSTPCR1 0xa4150034 | ||
45 | #define MSTPCR2 0xa4150038 | ||
46 | |||
47 | #define PORT_PSELA 0xa405014e | ||
48 | #define PORT_PSELB 0xa4050150 | ||
49 | #define PORT_PSELC 0xa4050152 | ||
50 | #define PORT_PSELD 0xa4050154 | ||
51 | |||
52 | #define PORT_HIZCRA 0xa4050158 | ||
53 | #define PORT_HIZCRB 0xa405015a | ||
54 | #define PORT_HIZCRC 0xa405015c | ||
55 | |||
56 | #define BSC_CS6ABCR 0xfec1001c | ||
57 | |||
58 | #endif /* __ASM_SH_MIGOR_H */ | ||
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index ec707b98e5b9..b7c7ce80f03e 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h | |||
@@ -16,7 +16,7 @@ enum cpu_type { | |||
16 | CPU_SH7619, | 16 | CPU_SH7619, |
17 | 17 | ||
18 | /* SH-2A types */ | 18 | /* SH-2A types */ |
19 | CPU_SH7203, CPU_SH7206, CPU_SH7263, | 19 | CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_MXG, |
20 | 20 | ||
21 | /* SH-3 types */ | 21 | /* SH-3 types */ |
22 | CPU_SH7705, CPU_SH7706, CPU_SH7707, | 22 | CPU_SH7705, CPU_SH7706, CPU_SH7707, |
@@ -29,7 +29,8 @@ enum cpu_type { | |||
29 | CPU_SH7760, CPU_SH4_202, CPU_SH4_501, | 29 | CPU_SH7760, CPU_SH4_202, CPU_SH4_501, |
30 | 30 | ||
31 | /* SH-4A types */ | 31 | /* SH-4A types */ |
32 | CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SHX3, | 32 | CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, |
33 | CPU_SH7723, CPU_SHX3, | ||
33 | 34 | ||
34 | /* SH4AL-DSP types */ | 35 | /* SH4AL-DSP types */ |
35 | CPU_SH7343, CPU_SH7722, CPU_SH7366, | 36 | CPU_SH7343, CPU_SH7722, CPU_SH7366, |
diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h index 1770460a4616..a33838f23a6d 100644 --- a/include/asm-sh/r7780rp.h +++ b/include/asm-sh/r7780rp.h | |||
@@ -55,11 +55,11 @@ | |||
55 | #define PA_SCSPTR1 (PA_BCR+0x0524) /* SCIF1 Serial Port control */ | 55 | #define PA_SCSPTR1 (PA_BCR+0x0524) /* SCIF1 Serial Port control */ |
56 | #define PA_SCLSR1 (PA_BCR+0x0528) /* SCIF1 Line Status control */ | 56 | #define PA_SCLSR1 (PA_BCR+0x0528) /* SCIF1 Line Status control */ |
57 | #define PA_SCRER1 (PA_BCR+0x052c) /* SCIF1 Serial Error control */ | 57 | #define PA_SCRER1 (PA_BCR+0x052c) /* SCIF1 Serial Error control */ |
58 | #define PA_ICCR (PA_BCR+0x0600) /* Serial control */ | 58 | #define PA_SMCR (PA_BCR+0x0600) /* 2-wire Serial control */ |
59 | #define PA_SAR (PA_BCR+0x0602) /* Serial Slave control */ | 59 | #define PA_SMSMADR (PA_BCR+0x0602) /* 2-wire Serial Slave control */ |
60 | #define PA_MDR (PA_BCR+0x0604) /* Serial Mode control */ | 60 | #define PA_SMMR (PA_BCR+0x0604) /* 2-wire Serial Mode control */ |
61 | #define PA_ADR1 (PA_BCR+0x0606) /* Serial Address1 control */ | 61 | #define PA_SMSADR1 (PA_BCR+0x0606) /* 2-wire Serial Address1 control */ |
62 | #define PA_DAR1 (PA_BCR+0x0646) /* Serial Data1 control */ | 62 | #define PA_SMTRDR1 (PA_BCR+0x0646) /* 2-wire Serial Data1 control */ |
63 | #define PA_VERREG (PA_BCR+0x0700) /* FPGA Version Register */ | 63 | #define PA_VERREG (PA_BCR+0x0700) /* FPGA Version Register */ |
64 | #define PA_POFF (PA_BCR+0x0800) /* System Power Off control */ | 64 | #define PA_POFF (PA_BCR+0x0800) /* System Power Off control */ |
65 | #define PA_PMR (PA_BCR+0x0900) /* */ | 65 | #define PA_PMR (PA_BCR+0x0900) /* */ |
@@ -107,11 +107,11 @@ | |||
107 | #define PA_SCFCR (PA_BCR+0x040c) /* SCIF FIFO control */ | 107 | #define PA_SCFCR (PA_BCR+0x040c) /* SCIF FIFO control */ |
108 | #define PA_SCFDR (PA_BCR+0x040e) /* SCIF FIFO data control */ | 108 | #define PA_SCFDR (PA_BCR+0x040e) /* SCIF FIFO data control */ |
109 | #define PA_SCLSR (PA_BCR+0x0412) /* SCIF Line Status control */ | 109 | #define PA_SCLSR (PA_BCR+0x0412) /* SCIF Line Status control */ |
110 | #define PA_ICCR (PA_BCR+0x0500) /* Serial control */ | 110 | #define PA_SMCR (PA_BCR+0x0500) /* 2-wire Serial control */ |
111 | #define PA_SAR (PA_BCR+0x0502) /* Serial Slave control */ | 111 | #define PA_SMSMADR (PA_BCR+0x0502) /* 2-wire Serial Slave control */ |
112 | #define PA_MDR (PA_BCR+0x0504) /* Serial Mode control */ | 112 | #define PA_SMMR (PA_BCR+0x0504) /* 2-wire Serial Mode control */ |
113 | #define PA_ADR1 (PA_BCR+0x0506) /* Serial Address1 control */ | 113 | #define PA_SMSADR1 (PA_BCR+0x0506) /* 2-wire Serial Address1 control */ |
114 | #define PA_DAR1 (PA_BCR+0x0546) /* Serial Data1 control */ | 114 | #define PA_SMTRDR1 (PA_BCR+0x0546) /* 2-wire Serial Data1 control */ |
115 | #define PA_VERREG (PA_BCR+0x0600) /* FPGA Version Register */ | 115 | #define PA_VERREG (PA_BCR+0x0600) /* FPGA Version Register */ |
116 | 116 | ||
117 | #define PA_AX88796L 0xa5800400 /* AX88796L Area */ | 117 | #define PA_AX88796L 0xa5800400 /* AX88796L Area */ |
@@ -190,6 +190,8 @@ | |||
190 | #define IRQ_TP (HL_FPGA_IRQ_BASE + 12) | 190 | #define IRQ_TP (HL_FPGA_IRQ_BASE + 12) |
191 | #define IRQ_RTC (HL_FPGA_IRQ_BASE + 13) | 191 | #define IRQ_RTC (HL_FPGA_IRQ_BASE + 13) |
192 | #define IRQ_TH_ALERT (HL_FPGA_IRQ_BASE + 14) | 192 | #define IRQ_TH_ALERT (HL_FPGA_IRQ_BASE + 14) |
193 | #define IRQ_SCIF0 (HL_FPGA_IRQ_BASE + 15) | ||
194 | #define IRQ_SCIF1 (HL_FPGA_IRQ_BASE + 16) | ||
193 | 195 | ||
194 | unsigned char *highlander_init_irq_r7780mp(void); | 196 | unsigned char *highlander_init_irq_r7780mp(void); |
195 | unsigned char *highlander_init_irq_r7780rp(void); | 197 | unsigned char *highlander_init_irq_r7780rp(void); |
diff --git a/include/asm-sh/se7721.h b/include/asm-sh/se7721.h new file mode 100644 index 000000000000..b957f6041193 --- /dev/null +++ b/include/asm-sh/se7721.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Renesas Solutions Corp. | ||
3 | * | ||
4 | * Hitachi UL SolutionEngine 7721 Support. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef __ASM_SH_SE7721_H | ||
13 | #define __ASM_SH_SE7721_H | ||
14 | #include <asm/addrspace.h> | ||
15 | |||
16 | /* Box specific addresses. */ | ||
17 | #define SE_AREA0_WIDTH 2 /* Area0: 32bit */ | ||
18 | #define PA_ROM 0xa0000000 /* EPROM */ | ||
19 | #define PA_ROM_SIZE 0x00200000 /* EPROM size 2M byte */ | ||
20 | #define PA_FROM 0xa1000000 /* Flash-ROM */ | ||
21 | #define PA_FROM_SIZE 0x01000000 /* Flash-ROM size 16M byte */ | ||
22 | #define PA_EXT1 0xa4000000 | ||
23 | #define PA_EXT1_SIZE 0x04000000 | ||
24 | #define PA_SDRAM 0xaC000000 /* SDRAM(Area3) 64MB */ | ||
25 | #define PA_SDRAM_SIZE 0x04000000 | ||
26 | |||
27 | #define PA_EXT4 0xb0000000 | ||
28 | #define PA_EXT4_SIZE 0x04000000 | ||
29 | |||
30 | #define PA_PERIPHERAL 0xB8000000 | ||
31 | |||
32 | #define PA_PCIC PA_PERIPHERAL | ||
33 | #define PA_MRSHPC (PA_PERIPHERAL + 0x003fffe0) | ||
34 | #define PA_MRSHPC_MW1 (PA_PERIPHERAL + 0x00400000) | ||
35 | #define PA_MRSHPC_MW2 (PA_PERIPHERAL + 0x00500000) | ||
36 | #define PA_MRSHPC_IO (PA_PERIPHERAL + 0x00600000) | ||
37 | #define MRSHPC_OPTION (PA_MRSHPC + 6) | ||
38 | #define MRSHPC_CSR (PA_MRSHPC + 8) | ||
39 | #define MRSHPC_ISR (PA_MRSHPC + 10) | ||
40 | #define MRSHPC_ICR (PA_MRSHPC + 12) | ||
41 | #define MRSHPC_CPWCR (PA_MRSHPC + 14) | ||
42 | #define MRSHPC_MW0CR1 (PA_MRSHPC + 16) | ||
43 | #define MRSHPC_MW1CR1 (PA_MRSHPC + 18) | ||
44 | #define MRSHPC_IOWCR1 (PA_MRSHPC + 20) | ||
45 | #define MRSHPC_MW0CR2 (PA_MRSHPC + 22) | ||
46 | #define MRSHPC_MW1CR2 (PA_MRSHPC + 24) | ||
47 | #define MRSHPC_IOWCR2 (PA_MRSHPC + 26) | ||
48 | #define MRSHPC_CDCR (PA_MRSHPC + 28) | ||
49 | #define MRSHPC_PCIC_INFO (PA_MRSHPC + 30) | ||
50 | |||
51 | #define PA_LED 0xB6800000 /* 8bit LED */ | ||
52 | #define PA_FPGA 0xB7000000 /* FPGA base address */ | ||
53 | |||
54 | #define MRSHPC_IRQ0 10 | ||
55 | |||
56 | #define FPGA_ILSR1 (PA_FPGA + 0x02) | ||
57 | #define FPGA_ILSR2 (PA_FPGA + 0x03) | ||
58 | #define FPGA_ILSR3 (PA_FPGA + 0x04) | ||
59 | #define FPGA_ILSR4 (PA_FPGA + 0x05) | ||
60 | #define FPGA_ILSR5 (PA_FPGA + 0x06) | ||
61 | #define FPGA_ILSR6 (PA_FPGA + 0x07) | ||
62 | #define FPGA_ILSR7 (PA_FPGA + 0x08) | ||
63 | #define FPGA_ILSR8 (PA_FPGA + 0x09) | ||
64 | |||
65 | void init_se7721_IRQ(void); | ||
66 | |||
67 | #define __IO_PREFIX se7721 | ||
68 | #include <asm/io_generic.h> | ||
69 | |||
70 | #endif /* __ASM_SH_SE7721_H */ | ||
diff --git a/include/asm-sh/se7722.h b/include/asm-sh/se7722.h index e0e89fcb8388..3690fe5857a4 100644 --- a/include/asm-sh/se7722.h +++ b/include/asm-sh/se7722.h | |||
@@ -77,6 +77,8 @@ | |||
77 | #define PORT_PSELA 0xA405014EUL | 77 | #define PORT_PSELA 0xA405014EUL |
78 | #define PORT_PYCR 0xA405014AUL | 78 | #define PORT_PYCR 0xA405014AUL |
79 | #define PORT_PZCR 0xA405014CUL | 79 | #define PORT_PZCR 0xA405014CUL |
80 | #define PORT_HIZCRA 0xA4050158UL | ||
81 | #define PORT_HIZCRC 0xA405015CUL | ||
80 | 82 | ||
81 | /* IRQ */ | 83 | /* IRQ */ |
82 | #define IRQ0_IRQ 32 | 84 | #define IRQ0_IRQ 32 |
diff --git a/include/asm-sh/sh_keysc.h b/include/asm-sh/sh_keysc.h new file mode 100644 index 000000000000..b5a4dd5a9729 --- /dev/null +++ b/include/asm-sh/sh_keysc.h | |||
@@ -0,0 +1,13 @@ | |||
1 | #ifndef __ASM_KEYSC_H__ | ||
2 | #define __ASM_KEYSC_H__ | ||
3 | |||
4 | #define SH_KEYSC_MAXKEYS 30 | ||
5 | |||
6 | struct sh_keysc_info { | ||
7 | enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode; | ||
8 | int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */ | ||
9 | int delay; | ||
10 | int keycodes[SH_KEYSC_MAXKEYS]; | ||
11 | }; | ||
12 | |||
13 | #endif /* __ASM_KEYSC_H__ */ | ||
diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 5145aa2a0ce9..e65b6b822cb3 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h | |||
@@ -146,6 +146,8 @@ extern unsigned int instruction_size(unsigned int insn); | |||
146 | 146 | ||
147 | extern unsigned long cached_to_uncached; | 147 | extern unsigned long cached_to_uncached; |
148 | 148 | ||
149 | extern struct dentry *sh_debugfs_root; | ||
150 | |||
149 | /* XXX | 151 | /* XXX |
150 | * disable hlt during certain critical i/o operations | 152 | * disable hlt during certain critical i/o operations |
151 | */ | 153 | */ |
diff --git a/include/asm-sh/uaccess_32.h b/include/asm-sh/uaccess_32.h index c0318b608893..1e41fda74bd3 100644 --- a/include/asm-sh/uaccess_32.h +++ b/include/asm-sh/uaccess_32.h | |||
@@ -55,13 +55,10 @@ static inline void set_fs(mm_segment_t s) | |||
55 | * If we don't have an MMU (or if its disabled) the only thing we really have | 55 | * If we don't have an MMU (or if its disabled) the only thing we really have |
56 | * to look out for is if the address resides somewhere outside of what | 56 | * to look out for is if the address resides somewhere outside of what |
57 | * available RAM we have. | 57 | * available RAM we have. |
58 | * | ||
59 | * TODO: This check could probably also stand to be restricted somewhat more.. | ||
60 | * though it still does the Right Thing(tm) for the time being. | ||
61 | */ | 58 | */ |
62 | static inline int __access_ok(unsigned long addr, unsigned long size) | 59 | static inline int __access_ok(unsigned long addr, unsigned long size) |
63 | { | 60 | { |
64 | return ((addr >= memory_start) && ((addr + size) < memory_end)); | 61 | return 1; |
65 | } | 62 | } |
66 | #else /* CONFIG_MMU */ | 63 | #else /* CONFIG_MMU */ |
67 | #define __addr_ok(addr) \ | 64 | #define __addr_ok(addr) \ |
diff --git a/include/asm-x86/boot.h b/include/asm-x86/boot.h index ed8affbf96cb..2faed7ecb092 100644 --- a/include/asm-x86/boot.h +++ b/include/asm-x86/boot.h | |||
@@ -17,4 +17,12 @@ | |||
17 | + (CONFIG_PHYSICAL_ALIGN - 1)) \ | 17 | + (CONFIG_PHYSICAL_ALIGN - 1)) \ |
18 | & ~(CONFIG_PHYSICAL_ALIGN - 1)) | 18 | & ~(CONFIG_PHYSICAL_ALIGN - 1)) |
19 | 19 | ||
20 | #ifdef CONFIG_X86_64 | ||
21 | #define BOOT_HEAP_SIZE 0x7000 | ||
22 | #define BOOT_STACK_SIZE 0x4000 | ||
23 | #else | ||
24 | #define BOOT_HEAP_SIZE 0x4000 | ||
25 | #define BOOT_STACK_SIZE 0x1000 | ||
26 | #endif | ||
27 | |||
20 | #endif /* _ASM_BOOT_H */ | 28 | #endif /* _ASM_BOOT_H */ |
diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index 58f790f4df52..a1a4dc7fe6ec 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h | |||
@@ -1,5 +1,237 @@ | |||
1 | #ifndef _ASM_DMA_MAPPING_H_ | ||
2 | #define _ASM_DMA_MAPPING_H_ | ||
3 | |||
4 | /* | ||
5 | * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for | ||
6 | * documentation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/scatterlist.h> | ||
10 | #include <asm/io.h> | ||
11 | #include <asm/swiotlb.h> | ||
12 | |||
13 | extern dma_addr_t bad_dma_address; | ||
14 | extern int iommu_merge; | ||
15 | extern struct device fallback_dev; | ||
16 | extern int panic_on_overflow; | ||
17 | extern int forbid_dac; | ||
18 | extern int force_iommu; | ||
19 | |||
20 | struct dma_mapping_ops { | ||
21 | int (*mapping_error)(dma_addr_t dma_addr); | ||
22 | void* (*alloc_coherent)(struct device *dev, size_t size, | ||
23 | dma_addr_t *dma_handle, gfp_t gfp); | ||
24 | void (*free_coherent)(struct device *dev, size_t size, | ||
25 | void *vaddr, dma_addr_t dma_handle); | ||
26 | dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr, | ||
27 | size_t size, int direction); | ||
28 | /* like map_single, but doesn't check the device mask */ | ||
29 | dma_addr_t (*map_simple)(struct device *hwdev, phys_addr_t ptr, | ||
30 | size_t size, int direction); | ||
31 | void (*unmap_single)(struct device *dev, dma_addr_t addr, | ||
32 | size_t size, int direction); | ||
33 | void (*sync_single_for_cpu)(struct device *hwdev, | ||
34 | dma_addr_t dma_handle, size_t size, | ||
35 | int direction); | ||
36 | void (*sync_single_for_device)(struct device *hwdev, | ||
37 | dma_addr_t dma_handle, size_t size, | ||
38 | int direction); | ||
39 | void (*sync_single_range_for_cpu)(struct device *hwdev, | ||
40 | dma_addr_t dma_handle, unsigned long offset, | ||
41 | size_t size, int direction); | ||
42 | void (*sync_single_range_for_device)(struct device *hwdev, | ||
43 | dma_addr_t dma_handle, unsigned long offset, | ||
44 | size_t size, int direction); | ||
45 | void (*sync_sg_for_cpu)(struct device *hwdev, | ||
46 | struct scatterlist *sg, int nelems, | ||
47 | int direction); | ||
48 | void (*sync_sg_for_device)(struct device *hwdev, | ||
49 | struct scatterlist *sg, int nelems, | ||
50 | int direction); | ||
51 | int (*map_sg)(struct device *hwdev, struct scatterlist *sg, | ||
52 | int nents, int direction); | ||
53 | void (*unmap_sg)(struct device *hwdev, | ||
54 | struct scatterlist *sg, int nents, | ||
55 | int direction); | ||
56 | int (*dma_supported)(struct device *hwdev, u64 mask); | ||
57 | int is_phys; | ||
58 | }; | ||
59 | |||
60 | extern const struct dma_mapping_ops *dma_ops; | ||
61 | |||
62 | static inline int dma_mapping_error(dma_addr_t dma_addr) | ||
63 | { | ||
64 | if (dma_ops->mapping_error) | ||
65 | return dma_ops->mapping_error(dma_addr); | ||
66 | |||
67 | return (dma_addr == bad_dma_address); | ||
68 | } | ||
69 | |||
70 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | ||
71 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | ||
72 | |||
73 | void *dma_alloc_coherent(struct device *dev, size_t size, | ||
74 | dma_addr_t *dma_handle, gfp_t flag); | ||
75 | |||
76 | void dma_free_coherent(struct device *dev, size_t size, | ||
77 | void *vaddr, dma_addr_t dma_handle); | ||
78 | |||
79 | |||
80 | extern int dma_supported(struct device *hwdev, u64 mask); | ||
81 | extern int dma_set_mask(struct device *dev, u64 mask); | ||
82 | |||
83 | static inline dma_addr_t | ||
84 | dma_map_single(struct device *hwdev, void *ptr, size_t size, | ||
85 | int direction) | ||
86 | { | ||
87 | BUG_ON(!valid_dma_direction(direction)); | ||
88 | return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction); | ||
89 | } | ||
90 | |||
91 | static inline void | ||
92 | dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, | ||
93 | int direction) | ||
94 | { | ||
95 | BUG_ON(!valid_dma_direction(direction)); | ||
96 | if (dma_ops->unmap_single) | ||
97 | dma_ops->unmap_single(dev, addr, size, direction); | ||
98 | } | ||
99 | |||
100 | static inline int | ||
101 | dma_map_sg(struct device *hwdev, struct scatterlist *sg, | ||
102 | int nents, int direction) | ||
103 | { | ||
104 | BUG_ON(!valid_dma_direction(direction)); | ||
105 | return dma_ops->map_sg(hwdev, sg, nents, direction); | ||
106 | } | ||
107 | |||
108 | static inline void | ||
109 | dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, | ||
110 | int direction) | ||
111 | { | ||
112 | BUG_ON(!valid_dma_direction(direction)); | ||
113 | if (dma_ops->unmap_sg) | ||
114 | dma_ops->unmap_sg(hwdev, sg, nents, direction); | ||
115 | } | ||
116 | |||
117 | static inline void | ||
118 | dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, | ||
119 | size_t size, int direction) | ||
120 | { | ||
121 | BUG_ON(!valid_dma_direction(direction)); | ||
122 | if (dma_ops->sync_single_for_cpu) | ||
123 | dma_ops->sync_single_for_cpu(hwdev, dma_handle, size, | ||
124 | direction); | ||
125 | flush_write_buffers(); | ||
126 | } | ||
127 | |||
128 | static inline void | ||
129 | dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, | ||
130 | size_t size, int direction) | ||
131 | { | ||
132 | BUG_ON(!valid_dma_direction(direction)); | ||
133 | if (dma_ops->sync_single_for_device) | ||
134 | dma_ops->sync_single_for_device(hwdev, dma_handle, size, | ||
135 | direction); | ||
136 | flush_write_buffers(); | ||
137 | } | ||
138 | |||
139 | static inline void | ||
140 | dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, | ||
141 | unsigned long offset, size_t size, int direction) | ||
142 | { | ||
143 | BUG_ON(!valid_dma_direction(direction)); | ||
144 | if (dma_ops->sync_single_range_for_cpu) | ||
145 | dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, | ||
146 | size, direction); | ||
147 | |||
148 | flush_write_buffers(); | ||
149 | } | ||
150 | |||
151 | static inline void | ||
152 | dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, | ||
153 | unsigned long offset, size_t size, | ||
154 | int direction) | ||
155 | { | ||
156 | BUG_ON(!valid_dma_direction(direction)); | ||
157 | if (dma_ops->sync_single_range_for_device) | ||
158 | dma_ops->sync_single_range_for_device(hwdev, dma_handle, | ||
159 | offset, size, direction); | ||
160 | |||
161 | flush_write_buffers(); | ||
162 | } | ||
163 | |||
164 | static inline void | ||
165 | dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, | ||
166 | int nelems, int direction) | ||
167 | { | ||
168 | BUG_ON(!valid_dma_direction(direction)); | ||
169 | if (dma_ops->sync_sg_for_cpu) | ||
170 | dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); | ||
171 | flush_write_buffers(); | ||
172 | } | ||
173 | |||
174 | static inline void | ||
175 | dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | ||
176 | int nelems, int direction) | ||
177 | { | ||
178 | BUG_ON(!valid_dma_direction(direction)); | ||
179 | if (dma_ops->sync_sg_for_device) | ||
180 | dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction); | ||
181 | |||
182 | flush_write_buffers(); | ||
183 | } | ||
184 | |||
185 | static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, | ||
186 | size_t offset, size_t size, | ||
187 | int direction) | ||
188 | { | ||
189 | BUG_ON(!valid_dma_direction(direction)); | ||
190 | return dma_ops->map_single(dev, page_to_phys(page)+offset, | ||
191 | size, direction); | ||
192 | } | ||
193 | |||
194 | static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, | ||
195 | size_t size, int direction) | ||
196 | { | ||
197 | dma_unmap_single(dev, addr, size, direction); | ||
198 | } | ||
199 | |||
200 | static inline void | ||
201 | dma_cache_sync(struct device *dev, void *vaddr, size_t size, | ||
202 | enum dma_data_direction dir) | ||
203 | { | ||
204 | flush_write_buffers(); | ||
205 | } | ||
206 | |||
207 | static inline int dma_get_cache_alignment(void) | ||
208 | { | ||
209 | /* no easy way to get cache size on all x86, so return the | ||
210 | * maximum possible, to be safe */ | ||
211 | return boot_cpu_data.x86_clflush_size; | ||
212 | } | ||
213 | |||
214 | #define dma_is_consistent(d, h) (1) | ||
215 | |||
1 | #ifdef CONFIG_X86_32 | 216 | #ifdef CONFIG_X86_32 |
2 | # include "dma-mapping_32.h" | 217 | # define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY |
3 | #else | 218 | struct dma_coherent_mem { |
4 | # include "dma-mapping_64.h" | 219 | void *virt_base; |
220 | u32 device_base; | ||
221 | int size; | ||
222 | int flags; | ||
223 | unsigned long *bitmap; | ||
224 | }; | ||
225 | |||
226 | extern int | ||
227 | dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
228 | dma_addr_t device_addr, size_t size, int flags); | ||
229 | |||
230 | extern void | ||
231 | dma_release_declared_memory(struct device *dev); | ||
232 | |||
233 | extern void * | ||
234 | dma_mark_declared_memory_occupied(struct device *dev, | ||
235 | dma_addr_t device_addr, size_t size); | ||
236 | #endif /* CONFIG_X86_32 */ | ||
5 | #endif | 237 | #endif |
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h deleted file mode 100644 index 55f01bd9e556..000000000000 --- a/include/asm-x86/dma-mapping_32.h +++ /dev/null | |||
@@ -1,187 +0,0 @@ | |||
1 | #ifndef _ASM_I386_DMA_MAPPING_H | ||
2 | #define _ASM_I386_DMA_MAPPING_H | ||
3 | |||
4 | #include <linux/mm.h> | ||
5 | #include <linux/scatterlist.h> | ||
6 | |||
7 | #include <asm/cache.h> | ||
8 | #include <asm/io.h> | ||
9 | #include <asm/bug.h> | ||
10 | |||
11 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | ||
12 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | ||
13 | |||
14 | void *dma_alloc_coherent(struct device *dev, size_t size, | ||
15 | dma_addr_t *dma_handle, gfp_t flag); | ||
16 | |||
17 | void dma_free_coherent(struct device *dev, size_t size, | ||
18 | void *vaddr, dma_addr_t dma_handle); | ||
19 | |||
20 | static inline dma_addr_t | ||
21 | dma_map_single(struct device *dev, void *ptr, size_t size, | ||
22 | enum dma_data_direction direction) | ||
23 | { | ||
24 | BUG_ON(!valid_dma_direction(direction)); | ||
25 | WARN_ON(size == 0); | ||
26 | flush_write_buffers(); | ||
27 | return virt_to_phys(ptr); | ||
28 | } | ||
29 | |||
30 | static inline void | ||
31 | dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
32 | enum dma_data_direction direction) | ||
33 | { | ||
34 | BUG_ON(!valid_dma_direction(direction)); | ||
35 | } | ||
36 | |||
37 | static inline int | ||
38 | dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, | ||
39 | enum dma_data_direction direction) | ||
40 | { | ||
41 | struct scatterlist *sg; | ||
42 | int i; | ||
43 | |||
44 | BUG_ON(!valid_dma_direction(direction)); | ||
45 | WARN_ON(nents == 0 || sglist[0].length == 0); | ||
46 | |||
47 | for_each_sg(sglist, sg, nents, i) { | ||
48 | BUG_ON(!sg_page(sg)); | ||
49 | |||
50 | sg->dma_address = sg_phys(sg); | ||
51 | } | ||
52 | |||
53 | flush_write_buffers(); | ||
54 | return nents; | ||
55 | } | ||
56 | |||
57 | static inline dma_addr_t | ||
58 | dma_map_page(struct device *dev, struct page *page, unsigned long offset, | ||
59 | size_t size, enum dma_data_direction direction) | ||
60 | { | ||
61 | BUG_ON(!valid_dma_direction(direction)); | ||
62 | return page_to_phys(page) + offset; | ||
63 | } | ||
64 | |||
65 | static inline void | ||
66 | dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, | ||
67 | enum dma_data_direction direction) | ||
68 | { | ||
69 | BUG_ON(!valid_dma_direction(direction)); | ||
70 | } | ||
71 | |||
72 | |||
73 | static inline void | ||
74 | dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | ||
75 | enum dma_data_direction direction) | ||
76 | { | ||
77 | BUG_ON(!valid_dma_direction(direction)); | ||
78 | } | ||
79 | |||
80 | static inline void | ||
81 | dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, | ||
82 | enum dma_data_direction direction) | ||
83 | { | ||
84 | } | ||
85 | |||
86 | static inline void | ||
87 | dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, | ||
88 | enum dma_data_direction direction) | ||
89 | { | ||
90 | flush_write_buffers(); | ||
91 | } | ||
92 | |||
93 | static inline void | ||
94 | dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, | ||
95 | unsigned long offset, size_t size, | ||
96 | enum dma_data_direction direction) | ||
97 | { | ||
98 | } | ||
99 | |||
100 | static inline void | ||
101 | dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, | ||
102 | unsigned long offset, size_t size, | ||
103 | enum dma_data_direction direction) | ||
104 | { | ||
105 | flush_write_buffers(); | ||
106 | } | ||
107 | |||
108 | static inline void | ||
109 | dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, | ||
110 | enum dma_data_direction direction) | ||
111 | { | ||
112 | } | ||
113 | |||
114 | static inline void | ||
115 | dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, | ||
116 | enum dma_data_direction direction) | ||
117 | { | ||
118 | flush_write_buffers(); | ||
119 | } | ||
120 | |||
121 | static inline int | ||
122 | dma_mapping_error(dma_addr_t dma_addr) | ||
123 | { | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | extern int forbid_dac; | ||
128 | |||
129 | static inline int | ||
130 | dma_supported(struct device *dev, u64 mask) | ||
131 | { | ||
132 | /* | ||
133 | * we fall back to GFP_DMA when the mask isn't all 1s, | ||
134 | * so we can't guarantee allocations that must be | ||
135 | * within a tighter range than GFP_DMA.. | ||
136 | */ | ||
137 | if(mask < 0x00ffffff) | ||
138 | return 0; | ||
139 | |||
140 | /* Work around chipset bugs */ | ||
141 | if (forbid_dac > 0 && mask > 0xffffffffULL) | ||
142 | return 0; | ||
143 | |||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | static inline int | ||
148 | dma_set_mask(struct device *dev, u64 mask) | ||
149 | { | ||
150 | if(!dev->dma_mask || !dma_supported(dev, mask)) | ||
151 | return -EIO; | ||
152 | |||
153 | *dev->dma_mask = mask; | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static inline int | ||
159 | dma_get_cache_alignment(void) | ||
160 | { | ||
161 | /* no easy way to get cache size on all x86, so return the | ||
162 | * maximum possible, to be safe */ | ||
163 | return (1 << INTERNODE_CACHE_SHIFT); | ||
164 | } | ||
165 | |||
166 | #define dma_is_consistent(d, h) (1) | ||
167 | |||
168 | static inline void | ||
169 | dma_cache_sync(struct device *dev, void *vaddr, size_t size, | ||
170 | enum dma_data_direction direction) | ||
171 | { | ||
172 | flush_write_buffers(); | ||
173 | } | ||
174 | |||
175 | #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY | ||
176 | extern int | ||
177 | dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, | ||
178 | dma_addr_t device_addr, size_t size, int flags); | ||
179 | |||
180 | extern void | ||
181 | dma_release_declared_memory(struct device *dev); | ||
182 | |||
183 | extern void * | ||
184 | dma_mark_declared_memory_occupied(struct device *dev, | ||
185 | dma_addr_t device_addr, size_t size); | ||
186 | |||
187 | #endif | ||
diff --git a/include/asm-x86/dma-mapping_64.h b/include/asm-x86/dma-mapping_64.h deleted file mode 100644 index ecd0f6125ba3..000000000000 --- a/include/asm-x86/dma-mapping_64.h +++ /dev/null | |||
@@ -1,202 +0,0 @@ | |||
1 | #ifndef _X8664_DMA_MAPPING_H | ||
2 | #define _X8664_DMA_MAPPING_H 1 | ||
3 | |||
4 | /* | ||
5 | * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for | ||
6 | * documentation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/scatterlist.h> | ||
10 | #include <asm/io.h> | ||
11 | #include <asm/swiotlb.h> | ||
12 | |||
13 | struct dma_mapping_ops { | ||
14 | int (*mapping_error)(dma_addr_t dma_addr); | ||
15 | void* (*alloc_coherent)(struct device *dev, size_t size, | ||
16 | dma_addr_t *dma_handle, gfp_t gfp); | ||
17 | void (*free_coherent)(struct device *dev, size_t size, | ||
18 | void *vaddr, dma_addr_t dma_handle); | ||
19 | dma_addr_t (*map_single)(struct device *hwdev, void *ptr, | ||
20 | size_t size, int direction); | ||
21 | /* like map_single, but doesn't check the device mask */ | ||
22 | dma_addr_t (*map_simple)(struct device *hwdev, char *ptr, | ||
23 | size_t size, int direction); | ||
24 | void (*unmap_single)(struct device *dev, dma_addr_t addr, | ||
25 | size_t size, int direction); | ||
26 | void (*sync_single_for_cpu)(struct device *hwdev, | ||
27 | dma_addr_t dma_handle, size_t size, | ||
28 | int direction); | ||
29 | void (*sync_single_for_device)(struct device *hwdev, | ||
30 | dma_addr_t dma_handle, size_t size, | ||
31 | int direction); | ||
32 | void (*sync_single_range_for_cpu)(struct device *hwdev, | ||
33 | dma_addr_t dma_handle, unsigned long offset, | ||
34 | size_t size, int direction); | ||
35 | void (*sync_single_range_for_device)(struct device *hwdev, | ||
36 | dma_addr_t dma_handle, unsigned long offset, | ||
37 | size_t size, int direction); | ||
38 | void (*sync_sg_for_cpu)(struct device *hwdev, | ||
39 | struct scatterlist *sg, int nelems, | ||
40 | int direction); | ||
41 | void (*sync_sg_for_device)(struct device *hwdev, | ||
42 | struct scatterlist *sg, int nelems, | ||
43 | int direction); | ||
44 | int (*map_sg)(struct device *hwdev, struct scatterlist *sg, | ||
45 | int nents, int direction); | ||
46 | void (*unmap_sg)(struct device *hwdev, | ||
47 | struct scatterlist *sg, int nents, | ||
48 | int direction); | ||
49 | int (*dma_supported)(struct device *hwdev, u64 mask); | ||
50 | int is_phys; | ||
51 | }; | ||
52 | |||
53 | extern dma_addr_t bad_dma_address; | ||
54 | extern const struct dma_mapping_ops* dma_ops; | ||
55 | extern int iommu_merge; | ||
56 | |||
57 | static inline int dma_mapping_error(dma_addr_t dma_addr) | ||
58 | { | ||
59 | if (dma_ops->mapping_error) | ||
60 | return dma_ops->mapping_error(dma_addr); | ||
61 | |||
62 | return (dma_addr == bad_dma_address); | ||
63 | } | ||
64 | |||
65 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | ||
66 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | ||
67 | |||
68 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | ||
69 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | ||
70 | |||
71 | extern void *dma_alloc_coherent(struct device *dev, size_t size, | ||
72 | dma_addr_t *dma_handle, gfp_t gfp); | ||
73 | extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr, | ||
74 | dma_addr_t dma_handle); | ||
75 | |||
76 | static inline dma_addr_t | ||
77 | dma_map_single(struct device *hwdev, void *ptr, size_t size, | ||
78 | int direction) | ||
79 | { | ||
80 | BUG_ON(!valid_dma_direction(direction)); | ||
81 | return dma_ops->map_single(hwdev, ptr, size, direction); | ||
82 | } | ||
83 | |||
84 | static inline void | ||
85 | dma_unmap_single(struct device *dev, dma_addr_t addr,size_t size, | ||
86 | int direction) | ||
87 | { | ||
88 | BUG_ON(!valid_dma_direction(direction)); | ||
89 | dma_ops->unmap_single(dev, addr, size, direction); | ||
90 | } | ||
91 | |||
92 | #define dma_map_page(dev,page,offset,size,dir) \ | ||
93 | dma_map_single((dev), page_address(page)+(offset), (size), (dir)) | ||
94 | |||
95 | #define dma_unmap_page dma_unmap_single | ||
96 | |||
97 | static inline void | ||
98 | dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, | ||
99 | size_t size, int direction) | ||
100 | { | ||
101 | BUG_ON(!valid_dma_direction(direction)); | ||
102 | if (dma_ops->sync_single_for_cpu) | ||
103 | dma_ops->sync_single_for_cpu(hwdev, dma_handle, size, | ||
104 | direction); | ||
105 | flush_write_buffers(); | ||
106 | } | ||
107 | |||
108 | static inline void | ||
109 | dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, | ||
110 | size_t size, int direction) | ||
111 | { | ||
112 | BUG_ON(!valid_dma_direction(direction)); | ||
113 | if (dma_ops->sync_single_for_device) | ||
114 | dma_ops->sync_single_for_device(hwdev, dma_handle, size, | ||
115 | direction); | ||
116 | flush_write_buffers(); | ||
117 | } | ||
118 | |||
119 | static inline void | ||
120 | dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, | ||
121 | unsigned long offset, size_t size, int direction) | ||
122 | { | ||
123 | BUG_ON(!valid_dma_direction(direction)); | ||
124 | if (dma_ops->sync_single_range_for_cpu) { | ||
125 | dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, size, direction); | ||
126 | } | ||
127 | |||
128 | flush_write_buffers(); | ||
129 | } | ||
130 | |||
131 | static inline void | ||
132 | dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, | ||
133 | unsigned long offset, size_t size, int direction) | ||
134 | { | ||
135 | BUG_ON(!valid_dma_direction(direction)); | ||
136 | if (dma_ops->sync_single_range_for_device) | ||
137 | dma_ops->sync_single_range_for_device(hwdev, dma_handle, | ||
138 | offset, size, direction); | ||
139 | |||
140 | flush_write_buffers(); | ||
141 | } | ||
142 | |||
143 | static inline void | ||
144 | dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, | ||
145 | int nelems, int direction) | ||
146 | { | ||
147 | BUG_ON(!valid_dma_direction(direction)); | ||
148 | if (dma_ops->sync_sg_for_cpu) | ||
149 | dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); | ||
150 | flush_write_buffers(); | ||
151 | } | ||
152 | |||
153 | static inline void | ||
154 | dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, | ||
155 | int nelems, int direction) | ||
156 | { | ||
157 | BUG_ON(!valid_dma_direction(direction)); | ||
158 | if (dma_ops->sync_sg_for_device) { | ||
159 | dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction); | ||
160 | } | ||
161 | |||
162 | flush_write_buffers(); | ||
163 | } | ||
164 | |||
165 | static inline int | ||
166 | dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) | ||
167 | { | ||
168 | BUG_ON(!valid_dma_direction(direction)); | ||
169 | return dma_ops->map_sg(hwdev, sg, nents, direction); | ||
170 | } | ||
171 | |||
172 | static inline void | ||
173 | dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, | ||
174 | int direction) | ||
175 | { | ||
176 | BUG_ON(!valid_dma_direction(direction)); | ||
177 | dma_ops->unmap_sg(hwdev, sg, nents, direction); | ||
178 | } | ||
179 | |||
180 | extern int dma_supported(struct device *hwdev, u64 mask); | ||
181 | |||
182 | /* same for gart, swiotlb, and nommu */ | ||
183 | static inline int dma_get_cache_alignment(void) | ||
184 | { | ||
185 | return boot_cpu_data.x86_clflush_size; | ||
186 | } | ||
187 | |||
188 | #define dma_is_consistent(d, h) 1 | ||
189 | |||
190 | extern int dma_set_mask(struct device *dev, u64 mask); | ||
191 | |||
192 | static inline void | ||
193 | dma_cache_sync(struct device *dev, void *vaddr, size_t size, | ||
194 | enum dma_data_direction dir) | ||
195 | { | ||
196 | flush_write_buffers(); | ||
197 | } | ||
198 | |||
199 | extern struct device fallback_dev; | ||
200 | extern int panic_on_overflow; | ||
201 | |||
202 | #endif /* _X8664_DMA_MAPPING_H */ | ||
diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h index 43b1a8bd4b34..a9f7c6ec32bf 100644 --- a/include/asm-x86/e820_32.h +++ b/include/asm-x86/e820_32.h | |||
@@ -24,7 +24,7 @@ extern void update_e820(void); | |||
24 | extern int e820_all_mapped(unsigned long start, unsigned long end, | 24 | extern int e820_all_mapped(unsigned long start, unsigned long end, |
25 | unsigned type); | 25 | unsigned type); |
26 | extern int e820_any_mapped(u64 start, u64 end, unsigned type); | 26 | extern int e820_any_mapped(u64 start, u64 end, unsigned type); |
27 | extern void find_max_pfn(void); | 27 | extern void propagate_e820_map(void); |
28 | extern void register_bootmem_low_pages(unsigned long max_low_pfn); | 28 | extern void register_bootmem_low_pages(unsigned long max_low_pfn); |
29 | extern void add_memory_region(unsigned long long start, | 29 | extern void add_memory_region(unsigned long long start, |
30 | unsigned long long size, int type); | 30 | unsigned long long size, int type); |
diff --git a/include/asm-x86/genapic_32.h b/include/asm-x86/genapic_32.h index f1b96932746b..b02ea6e17de8 100644 --- a/include/asm-x86/genapic_32.h +++ b/include/asm-x86/genapic_32.h | |||
@@ -117,6 +117,7 @@ extern struct genapic *genapic; | |||
117 | enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; | 117 | enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC}; |
118 | #define get_uv_system_type() UV_NONE | 118 | #define get_uv_system_type() UV_NONE |
119 | #define is_uv_system() 0 | 119 | #define is_uv_system() 0 |
120 | #define uv_wakeup_secondary(a, b) 1 | ||
120 | 121 | ||
121 | 122 | ||
122 | #endif | 123 | #endif |
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h index 54522b814f1c..da2adb45f6e3 100644 --- a/include/asm-x86/i387.h +++ b/include/asm-x86/i387.h | |||
@@ -21,8 +21,9 @@ | |||
21 | 21 | ||
22 | extern void fpu_init(void); | 22 | extern void fpu_init(void); |
23 | extern void mxcsr_feature_mask_init(void); | 23 | extern void mxcsr_feature_mask_init(void); |
24 | extern void init_fpu(struct task_struct *child); | 24 | extern int init_fpu(struct task_struct *child); |
25 | extern asmlinkage void math_state_restore(void); | 25 | extern asmlinkage void math_state_restore(void); |
26 | extern void init_thread_xstate(void); | ||
26 | 27 | ||
27 | extern user_regset_active_fn fpregs_active, xfpregs_active; | 28 | extern user_regset_active_fn fpregs_active, xfpregs_active; |
28 | extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; | 29 | extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get; |
@@ -117,24 +118,22 @@ static inline void __save_init_fpu(struct task_struct *tsk) | |||
117 | /* Using "fxsaveq %0" would be the ideal choice, but is only supported | 118 | /* Using "fxsaveq %0" would be the ideal choice, but is only supported |
118 | starting with gas 2.16. */ | 119 | starting with gas 2.16. */ |
119 | __asm__ __volatile__("fxsaveq %0" | 120 | __asm__ __volatile__("fxsaveq %0" |
120 | : "=m" (tsk->thread.i387.fxsave)); | 121 | : "=m" (tsk->thread.xstate->fxsave)); |
121 | #elif 0 | 122 | #elif 0 |
122 | /* Using, as a workaround, the properly prefixed form below isn't | 123 | /* Using, as a workaround, the properly prefixed form below isn't |
123 | accepted by any binutils version so far released, complaining that | 124 | accepted by any binutils version so far released, complaining that |
124 | the same type of prefix is used twice if an extended register is | 125 | the same type of prefix is used twice if an extended register is |
125 | needed for addressing (fix submitted to mainline 2005-11-21). */ | 126 | needed for addressing (fix submitted to mainline 2005-11-21). */ |
126 | __asm__ __volatile__("rex64/fxsave %0" | 127 | __asm__ __volatile__("rex64/fxsave %0" |
127 | : "=m" (tsk->thread.i387.fxsave)); | 128 | : "=m" (tsk->thread.xstate->fxsave)); |
128 | #else | 129 | #else |
129 | /* This, however, we can work around by forcing the compiler to select | 130 | /* This, however, we can work around by forcing the compiler to select |
130 | an addressing mode that doesn't require extended registers. */ | 131 | an addressing mode that doesn't require extended registers. */ |
131 | __asm__ __volatile__("rex64/fxsave %P2(%1)" | 132 | __asm__ __volatile__("rex64/fxsave (%1)" |
132 | : "=m" (tsk->thread.i387.fxsave) | 133 | : "=m" (tsk->thread.xstate->fxsave) |
133 | : "cdaSDb" (tsk), | 134 | : "cdaSDb" (&tsk->thread.xstate->fxsave)); |
134 | "i" (offsetof(__typeof__(*tsk), | ||
135 | thread.i387.fxsave))); | ||
136 | #endif | 135 | #endif |
137 | clear_fpu_state(&tsk->thread.i387.fxsave); | 136 | clear_fpu_state(&tsk->thread.xstate->fxsave); |
138 | task_thread_info(tsk)->status &= ~TS_USEDFPU; | 137 | task_thread_info(tsk)->status &= ~TS_USEDFPU; |
139 | } | 138 | } |
140 | 139 | ||
@@ -148,7 +147,7 @@ static inline int save_i387(struct _fpstate __user *buf) | |||
148 | int err = 0; | 147 | int err = 0; |
149 | 148 | ||
150 | BUILD_BUG_ON(sizeof(struct user_i387_struct) != | 149 | BUILD_BUG_ON(sizeof(struct user_i387_struct) != |
151 | sizeof(tsk->thread.i387.fxsave)); | 150 | sizeof(tsk->thread.xstate->fxsave)); |
152 | 151 | ||
153 | if ((unsigned long)buf % 16) | 152 | if ((unsigned long)buf % 16) |
154 | printk("save_i387: bad fpstate %p\n", buf); | 153 | printk("save_i387: bad fpstate %p\n", buf); |
@@ -164,7 +163,7 @@ static inline int save_i387(struct _fpstate __user *buf) | |||
164 | task_thread_info(tsk)->status &= ~TS_USEDFPU; | 163 | task_thread_info(tsk)->status &= ~TS_USEDFPU; |
165 | stts(); | 164 | stts(); |
166 | } else { | 165 | } else { |
167 | if (__copy_to_user(buf, &tsk->thread.i387.fxsave, | 166 | if (__copy_to_user(buf, &tsk->thread.xstate->fxsave, |
168 | sizeof(struct i387_fxsave_struct))) | 167 | sizeof(struct i387_fxsave_struct))) |
169 | return -1; | 168 | return -1; |
170 | } | 169 | } |
@@ -201,7 +200,7 @@ static inline void restore_fpu(struct task_struct *tsk) | |||
201 | "nop ; frstor %1", | 200 | "nop ; frstor %1", |
202 | "fxrstor %1", | 201 | "fxrstor %1", |
203 | X86_FEATURE_FXSR, | 202 | X86_FEATURE_FXSR, |
204 | "m" ((tsk)->thread.i387.fxsave)); | 203 | "m" (tsk->thread.xstate->fxsave)); |
205 | } | 204 | } |
206 | 205 | ||
207 | /* We need a safe address that is cheap to find and that is already | 206 | /* We need a safe address that is cheap to find and that is already |
@@ -225,8 +224,8 @@ static inline void __save_init_fpu(struct task_struct *tsk) | |||
225 | "fxsave %[fx]\n" | 224 | "fxsave %[fx]\n" |
226 | "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", | 225 | "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", |
227 | X86_FEATURE_FXSR, | 226 | X86_FEATURE_FXSR, |
228 | [fx] "m" (tsk->thread.i387.fxsave), | 227 | [fx] "m" (tsk->thread.xstate->fxsave), |
229 | [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); | 228 | [fsw] "m" (tsk->thread.xstate->fxsave.swd) : "memory"); |
230 | /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception | 229 | /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception |
231 | is pending. Clear the x87 state here by setting it to fixed | 230 | is pending. Clear the x87 state here by setting it to fixed |
232 | values. safe_address is a random variable that should be in L1 */ | 231 | values. safe_address is a random variable that should be in L1 */ |
@@ -327,25 +326,25 @@ static inline void clear_fpu(struct task_struct *tsk) | |||
327 | static inline unsigned short get_fpu_cwd(struct task_struct *tsk) | 326 | static inline unsigned short get_fpu_cwd(struct task_struct *tsk) |
328 | { | 327 | { |
329 | if (cpu_has_fxsr) { | 328 | if (cpu_has_fxsr) { |
330 | return tsk->thread.i387.fxsave.cwd; | 329 | return tsk->thread.xstate->fxsave.cwd; |
331 | } else { | 330 | } else { |
332 | return (unsigned short)tsk->thread.i387.fsave.cwd; | 331 | return (unsigned short)tsk->thread.xstate->fsave.cwd; |
333 | } | 332 | } |
334 | } | 333 | } |
335 | 334 | ||
336 | static inline unsigned short get_fpu_swd(struct task_struct *tsk) | 335 | static inline unsigned short get_fpu_swd(struct task_struct *tsk) |
337 | { | 336 | { |
338 | if (cpu_has_fxsr) { | 337 | if (cpu_has_fxsr) { |
339 | return tsk->thread.i387.fxsave.swd; | 338 | return tsk->thread.xstate->fxsave.swd; |
340 | } else { | 339 | } else { |
341 | return (unsigned short)tsk->thread.i387.fsave.swd; | 340 | return (unsigned short)tsk->thread.xstate->fsave.swd; |
342 | } | 341 | } |
343 | } | 342 | } |
344 | 343 | ||
345 | static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) | 344 | static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk) |
346 | { | 345 | { |
347 | if (cpu_has_xmm) { | 346 | if (cpu_has_xmm) { |
348 | return tsk->thread.i387.fxsave.mxcsr; | 347 | return tsk->thread.xstate->fxsave.mxcsr; |
349 | } else { | 348 | } else { |
350 | return MXCSR_DEFAULT; | 349 | return MXCSR_DEFAULT; |
351 | } | 350 | } |
diff --git a/include/asm-x86/numa_64.h b/include/asm-x86/numa_64.h index 32c22ae0709f..22e87c9f6a80 100644 --- a/include/asm-x86/numa_64.h +++ b/include/asm-x86/numa_64.h | |||
@@ -9,7 +9,8 @@ struct bootnode { | |||
9 | u64 end; | 9 | u64 end; |
10 | }; | 10 | }; |
11 | 11 | ||
12 | extern int compute_hash_shift(struct bootnode *nodes, int numnodes); | 12 | extern int compute_hash_shift(struct bootnode *nodes, int numblks, |
13 | int *nodeids); | ||
13 | 14 | ||
14 | #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT)) | 15 | #define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT)) |
15 | 16 | ||
diff --git a/include/asm-x86/pci_64.h b/include/asm-x86/pci_64.h index df867e5d80b1..f330234ffa5c 100644 --- a/include/asm-x86/pci_64.h +++ b/include/asm-x86/pci_64.h | |||
@@ -22,6 +22,7 @@ extern int (*pci_config_read)(int seg, int bus, int dev, int fn, | |||
22 | extern int (*pci_config_write)(int seg, int bus, int dev, int fn, | 22 | extern int (*pci_config_write)(int seg, int bus, int dev, int fn, |
23 | int reg, int len, u32 value); | 23 | int reg, int len, u32 value); |
24 | 24 | ||
25 | extern void dma32_reserve_bootmem(void); | ||
25 | extern void pci_iommu_alloc(void); | 26 | extern void pci_iommu_alloc(void); |
26 | 27 | ||
27 | /* The PCI address space does equal the physical memory | 28 | /* The PCI address space does equal the physical memory |
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 6e26c7c717a2..e6bf92ddeb21 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h | |||
@@ -354,7 +354,7 @@ struct i387_soft_struct { | |||
354 | u32 entry_eip; | 354 | u32 entry_eip; |
355 | }; | 355 | }; |
356 | 356 | ||
357 | union i387_union { | 357 | union thread_xstate { |
358 | struct i387_fsave_struct fsave; | 358 | struct i387_fsave_struct fsave; |
359 | struct i387_fxsave_struct fxsave; | 359 | struct i387_fxsave_struct fxsave; |
360 | struct i387_soft_struct soft; | 360 | struct i387_soft_struct soft; |
@@ -365,6 +365,9 @@ DECLARE_PER_CPU(struct orig_ist, orig_ist); | |||
365 | #endif | 365 | #endif |
366 | 366 | ||
367 | extern void print_cpu_info(struct cpuinfo_x86 *); | 367 | extern void print_cpu_info(struct cpuinfo_x86 *); |
368 | extern unsigned int xstate_size; | ||
369 | extern void free_thread_xstate(struct task_struct *); | ||
370 | extern struct kmem_cache *task_xstate_cachep; | ||
368 | extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); | 371 | extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); |
369 | extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); | 372 | extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); |
370 | extern unsigned short num_cache_leaves; | 373 | extern unsigned short num_cache_leaves; |
@@ -397,8 +400,8 @@ struct thread_struct { | |||
397 | unsigned long cr2; | 400 | unsigned long cr2; |
398 | unsigned long trap_no; | 401 | unsigned long trap_no; |
399 | unsigned long error_code; | 402 | unsigned long error_code; |
400 | /* Floating point info: */ | 403 | /* floating point and extended processor state */ |
401 | union i387_union i387 __attribute__((aligned(16)));; | 404 | union thread_xstate *xstate; |
402 | #ifdef CONFIG_X86_32 | 405 | #ifdef CONFIG_X86_32 |
403 | /* Virtual 86 mode info */ | 406 | /* Virtual 86 mode info */ |
404 | struct vm86_struct __user *vm86_info; | 407 | struct vm86_struct __user *vm86_info; |
@@ -918,4 +921,11 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, | |||
918 | 921 | ||
919 | #define KSTK_EIP(task) (task_pt_regs(task)->ip) | 922 | #define KSTK_EIP(task) (task_pt_regs(task)->ip) |
920 | 923 | ||
924 | /* Get/set a process' ability to use the timestamp counter instruction */ | ||
925 | #define GET_TSC_CTL(adr) get_tsc_mode((adr)) | ||
926 | #define SET_TSC_CTL(val) set_tsc_mode((val)) | ||
927 | |||
928 | extern int get_tsc_mode(unsigned long adr); | ||
929 | extern int set_tsc_mode(unsigned int val); | ||
930 | |||
921 | #endif | 931 | #endif |
diff --git a/include/asm-x86/scatterlist.h b/include/asm-x86/scatterlist.h index d13c197866d6..c0432061f81a 100644 --- a/include/asm-x86/scatterlist.h +++ b/include/asm-x86/scatterlist.h | |||
@@ -11,9 +11,7 @@ struct scatterlist { | |||
11 | unsigned int offset; | 11 | unsigned int offset; |
12 | unsigned int length; | 12 | unsigned int length; |
13 | dma_addr_t dma_address; | 13 | dma_addr_t dma_address; |
14 | #ifdef CONFIG_X86_64 | ||
15 | unsigned int dma_length; | 14 | unsigned int dma_length; |
16 | #endif | ||
17 | }; | 15 | }; |
18 | 16 | ||
19 | #define ARCH_HAS_SG_CHAIN | 17 | #define ARCH_HAS_SG_CHAIN |
diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h index d5fd12f2abdb..77244f17993f 100644 --- a/include/asm-x86/thread_info.h +++ b/include/asm-x86/thread_info.h | |||
@@ -1,5 +1,14 @@ | |||
1 | #ifndef _ASM_X86_THREAD_INFO_H | ||
1 | #ifdef CONFIG_X86_32 | 2 | #ifdef CONFIG_X86_32 |
2 | # include "thread_info_32.h" | 3 | # include "thread_info_32.h" |
3 | #else | 4 | #else |
4 | # include "thread_info_64.h" | 5 | # include "thread_info_64.h" |
5 | #endif | 6 | #endif |
7 | |||
8 | #ifndef __ASSEMBLY__ | ||
9 | extern void arch_task_cache_init(void); | ||
10 | extern void free_thread_info(struct thread_info *ti); | ||
11 | extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); | ||
12 | #define arch_task_cache_init arch_task_cache_init | ||
13 | #endif | ||
14 | #endif /* _ASM_X86_THREAD_INFO_H */ | ||
diff --git a/include/asm-x86/thread_info_32.h b/include/asm-x86/thread_info_32.h index 4e053fa561a9..531859962096 100644 --- a/include/asm-x86/thread_info_32.h +++ b/include/asm-x86/thread_info_32.h | |||
@@ -102,8 +102,6 @@ static inline struct thread_info *current_thread_info(void) | |||
102 | __get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE))) | 102 | __get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE))) |
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | #define free_thread_info(info) free_pages((unsigned long)(info), get_order(THREAD_SIZE)) | ||
106 | |||
107 | #else /* !__ASSEMBLY__ */ | 105 | #else /* !__ASSEMBLY__ */ |
108 | 106 | ||
109 | /* how to get the thread information struct from ASM */ | 107 | /* how to get the thread information struct from ASM */ |
diff --git a/include/asm-x86/thread_info_64.h b/include/asm-x86/thread_info_64.h index 1e5c6f6152cd..ed664e874dec 100644 --- a/include/asm-x86/thread_info_64.h +++ b/include/asm-x86/thread_info_64.h | |||
@@ -85,8 +85,6 @@ static inline struct thread_info *stack_thread_info(void) | |||
85 | #define alloc_thread_info(tsk) \ | 85 | #define alloc_thread_info(tsk) \ |
86 | ((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER)) | 86 | ((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER)) |
87 | 87 | ||
88 | #define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER) | ||
89 | |||
90 | #else /* !__ASSEMBLY__ */ | 88 | #else /* !__ASSEMBLY__ */ |
91 | 89 | ||
92 | /* how to get the thread information struct from ASM */ | 90 | /* how to get the thread information struct from ASM */ |
@@ -126,6 +124,7 @@ static inline struct thread_info *stack_thread_info(void) | |||
126 | #define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ | 124 | #define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */ |
127 | #define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */ | 125 | #define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */ |
128 | #define TIF_BTS_TRACE_TS 27 /* record scheduling event timestamps */ | 126 | #define TIF_BTS_TRACE_TS 27 /* record scheduling event timestamps */ |
127 | #define TIF_NOTSC 28 /* TSC is not accessible in userland */ | ||
129 | 128 | ||
130 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) | 129 | #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) |
131 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) | 130 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
@@ -147,6 +146,7 @@ static inline struct thread_info *stack_thread_info(void) | |||
147 | #define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR) | 146 | #define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR) |
148 | #define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR) | 147 | #define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR) |
149 | #define _TIF_BTS_TRACE_TS (1 << TIF_BTS_TRACE_TS) | 148 | #define _TIF_BTS_TRACE_TS (1 << TIF_BTS_TRACE_TS) |
149 | #define _TIF_NOTSC (1 << TIF_NOTSC) | ||
150 | 150 | ||
151 | /* work to do on interrupt/exception return */ | 151 | /* work to do on interrupt/exception return */ |
152 | #define _TIF_WORK_MASK \ | 152 | #define _TIF_WORK_MASK \ |
@@ -160,7 +160,7 @@ static inline struct thread_info *stack_thread_info(void) | |||
160 | 160 | ||
161 | /* flags to check in __switch_to() */ | 161 | /* flags to check in __switch_to() */ |
162 | #define _TIF_WORK_CTXSW \ | 162 | #define _TIF_WORK_CTXSW \ |
163 | (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_BTS_TRACE_TS) | 163 | (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_BTS_TRACE_TS|_TIF_NOTSC) |
164 | #define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW | 164 | #define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW |
165 | #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG) | 165 | #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG) |
166 | 166 | ||
diff --git a/include/asm-x86/tsc.h b/include/asm-x86/tsc.h index d2d8eb5b55f5..0434bd8349a7 100644 --- a/include/asm-x86/tsc.h +++ b/include/asm-x86/tsc.h | |||
@@ -18,6 +18,7 @@ extern unsigned int cpu_khz; | |||
18 | extern unsigned int tsc_khz; | 18 | extern unsigned int tsc_khz; |
19 | 19 | ||
20 | extern void disable_TSC(void); | 20 | extern void disable_TSC(void); |
21 | extern void enable_TSC(void); | ||
21 | 22 | ||
22 | static inline cycles_t get_cycles(void) | 23 | static inline cycles_t get_cycles(void) |
23 | { | 24 | { |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 14813b595802..a5f359a7ad0e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
19 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
20 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
21 | #include <linux/pfn.h> | ||
21 | 22 | ||
22 | #include <asm/page.h> | 23 | #include <asm/page.h> |
23 | #include <asm/system.h> | 24 | #include <asm/system.h> |
@@ -394,4 +395,10 @@ struct efi_generic_dev_path { | |||
394 | u16 length; | 395 | u16 length; |
395 | } __attribute ((packed)); | 396 | } __attribute ((packed)); |
396 | 397 | ||
398 | static inline void memrange_efi_to_native(u64 *addr, u64 *npages) | ||
399 | { | ||
400 | *npages = PFN_UP(*addr + (*npages<<EFI_PAGE_SHIFT)) - PFN_DOWN(*addr); | ||
401 | *addr &= PAGE_MASK; | ||
402 | } | ||
403 | |||
397 | #endif /* _LINUX_EFI_H */ | 404 | #endif /* _LINUX_EFI_H */ |
diff --git a/include/linux/file.h b/include/linux/file.h index 7239baac81a9..653477021e4c 100644 --- a/include/linux/file.h +++ b/include/linux/file.h | |||
@@ -61,6 +61,7 @@ extern struct kmem_cache *filp_cachep; | |||
61 | 61 | ||
62 | extern void __fput(struct file *); | 62 | extern void __fput(struct file *); |
63 | extern void fput(struct file *); | 63 | extern void fput(struct file *); |
64 | extern void drop_file_write_access(struct file *file); | ||
64 | 65 | ||
65 | struct file_operations; | 66 | struct file_operations; |
66 | struct vfsmount; | 67 | struct vfsmount; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index b84b848431f2..d1eeea669d2c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -776,6 +776,9 @@ static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index) | |||
776 | index < ra->start + ra->size); | 776 | index < ra->start + ra->size); |
777 | } | 777 | } |
778 | 778 | ||
779 | #define FILE_MNT_WRITE_TAKEN 1 | ||
780 | #define FILE_MNT_WRITE_RELEASED 2 | ||
781 | |||
779 | struct file { | 782 | struct file { |
780 | /* | 783 | /* |
781 | * fu_list becomes invalid after file_free is called and queued via | 784 | * fu_list becomes invalid after file_free is called and queued via |
@@ -810,6 +813,9 @@ struct file { | |||
810 | spinlock_t f_ep_lock; | 813 | spinlock_t f_ep_lock; |
811 | #endif /* #ifdef CONFIG_EPOLL */ | 814 | #endif /* #ifdef CONFIG_EPOLL */ |
812 | struct address_space *f_mapping; | 815 | struct address_space *f_mapping; |
816 | #ifdef CONFIG_DEBUG_WRITECOUNT | ||
817 | unsigned long f_mnt_write_state; | ||
818 | #endif | ||
813 | }; | 819 | }; |
814 | extern spinlock_t files_lock; | 820 | extern spinlock_t files_lock; |
815 | #define file_list_lock() spin_lock(&files_lock); | 821 | #define file_list_lock() spin_lock(&files_lock); |
@@ -818,6 +824,49 @@ extern spinlock_t files_lock; | |||
818 | #define get_file(x) atomic_inc(&(x)->f_count) | 824 | #define get_file(x) atomic_inc(&(x)->f_count) |
819 | #define file_count(x) atomic_read(&(x)->f_count) | 825 | #define file_count(x) atomic_read(&(x)->f_count) |
820 | 826 | ||
827 | #ifdef CONFIG_DEBUG_WRITECOUNT | ||
828 | static inline void file_take_write(struct file *f) | ||
829 | { | ||
830 | WARN_ON(f->f_mnt_write_state != 0); | ||
831 | f->f_mnt_write_state = FILE_MNT_WRITE_TAKEN; | ||
832 | } | ||
833 | static inline void file_release_write(struct file *f) | ||
834 | { | ||
835 | f->f_mnt_write_state |= FILE_MNT_WRITE_RELEASED; | ||
836 | } | ||
837 | static inline void file_reset_write(struct file *f) | ||
838 | { | ||
839 | f->f_mnt_write_state = 0; | ||
840 | } | ||
841 | static inline void file_check_state(struct file *f) | ||
842 | { | ||
843 | /* | ||
844 | * At this point, either both or neither of these bits | ||
845 | * should be set. | ||
846 | */ | ||
847 | WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN); | ||
848 | WARN_ON(f->f_mnt_write_state == FILE_MNT_WRITE_RELEASED); | ||
849 | } | ||
850 | static inline int file_check_writeable(struct file *f) | ||
851 | { | ||
852 | if (f->f_mnt_write_state == FILE_MNT_WRITE_TAKEN) | ||
853 | return 0; | ||
854 | printk(KERN_WARNING "writeable file with no " | ||
855 | "mnt_want_write()\n"); | ||
856 | WARN_ON(1); | ||
857 | return -EINVAL; | ||
858 | } | ||
859 | #else /* !CONFIG_DEBUG_WRITECOUNT */ | ||
860 | static inline void file_take_write(struct file *filp) {} | ||
861 | static inline void file_release_write(struct file *filp) {} | ||
862 | static inline void file_reset_write(struct file *filp) {} | ||
863 | static inline void file_check_state(struct file *filp) {} | ||
864 | static inline int file_check_writeable(struct file *filp) | ||
865 | { | ||
866 | return 0; | ||
867 | } | ||
868 | #endif /* CONFIG_DEBUG_WRITECOUNT */ | ||
869 | |||
821 | #define MAX_NON_LFS ((1UL<<31) - 1) | 870 | #define MAX_NON_LFS ((1UL<<31) - 1) |
822 | 871 | ||
823 | /* Page cache limit. The filesystems should put that into their s_maxbytes | 872 | /* Page cache limit. The filesystems should put that into their s_maxbytes |
@@ -1735,7 +1784,8 @@ extern struct file *create_read_pipe(struct file *f); | |||
1735 | extern struct file *create_write_pipe(void); | 1784 | extern struct file *create_write_pipe(void); |
1736 | extern void free_write_pipe(struct file *); | 1785 | extern void free_write_pipe(struct file *); |
1737 | 1786 | ||
1738 | extern int open_namei(int dfd, const char *, int, int, struct nameidata *); | 1787 | extern struct file *do_filp_open(int dfd, const char *pathname, |
1788 | int open_flag, int mode); | ||
1739 | extern int may_open(struct nameidata *, int, int); | 1789 | extern int may_open(struct nameidata *, int, int); |
1740 | 1790 | ||
1741 | extern int kernel_read(struct file *, unsigned long, char *, unsigned long); | 1791 | extern int kernel_read(struct file *, unsigned long, char *, unsigned long); |
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 412e025bc5c7..e600c4e9b8c5 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h | |||
@@ -84,10 +84,10 @@ | |||
84 | 84 | ||
85 | #define irqs_disabled() \ | 85 | #define irqs_disabled() \ |
86 | ({ \ | 86 | ({ \ |
87 | unsigned long flags; \ | 87 | unsigned long _flags; \ |
88 | \ | 88 | \ |
89 | raw_local_save_flags(flags); \ | 89 | raw_local_save_flags(_flags); \ |
90 | raw_irqs_disabled_flags(flags); \ | 90 | raw_irqs_disabled_flags(_flags); \ |
91 | }) | 91 | }) |
92 | 92 | ||
93 | #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) | 93 | #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) |
diff --git a/include/linux/list.h b/include/linux/list.h index 75ce2cb4ff6e..dac16f99c701 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -631,31 +631,14 @@ static inline void list_splice_init_rcu(struct list_head *list, | |||
631 | * as long as the traversal is guarded by rcu_read_lock(). | 631 | * as long as the traversal is guarded by rcu_read_lock(). |
632 | */ | 632 | */ |
633 | #define list_for_each_rcu(pos, head) \ | 633 | #define list_for_each_rcu(pos, head) \ |
634 | for (pos = (head)->next; \ | 634 | for (pos = rcu_dereference((head)->next); \ |
635 | prefetch(rcu_dereference(pos)->next), pos != (head); \ | 635 | prefetch(pos->next), pos != (head); \ |
636 | pos = pos->next) | 636 | pos = rcu_dereference(pos->next)) |
637 | 637 | ||
638 | #define __list_for_each_rcu(pos, head) \ | 638 | #define __list_for_each_rcu(pos, head) \ |
639 | for (pos = (head)->next; \ | 639 | for (pos = rcu_dereference((head)->next); \ |
640 | rcu_dereference(pos) != (head); \ | 640 | pos != (head); \ |
641 | pos = pos->next) | 641 | pos = rcu_dereference(pos->next)) |
642 | |||
643 | /** | ||
644 | * list_for_each_safe_rcu | ||
645 | * @pos: the &struct list_head to use as a loop cursor. | ||
646 | * @n: another &struct list_head to use as temporary storage | ||
647 | * @head: the head for your list. | ||
648 | * | ||
649 | * Iterate over an rcu-protected list, safe against removal of list entry. | ||
650 | * | ||
651 | * This list-traversal primitive may safely run concurrently with | ||
652 | * the _rcu list-mutation primitives such as list_add_rcu() | ||
653 | * as long as the traversal is guarded by rcu_read_lock(). | ||
654 | */ | ||
655 | #define list_for_each_safe_rcu(pos, n, head) \ | ||
656 | for (pos = (head)->next; \ | ||
657 | n = rcu_dereference(pos)->next, pos != (head); \ | ||
658 | pos = n) | ||
659 | 642 | ||
660 | /** | 643 | /** |
661 | * list_for_each_entry_rcu - iterate over rcu list of given type | 644 | * list_for_each_entry_rcu - iterate over rcu list of given type |
@@ -668,10 +651,9 @@ static inline void list_splice_init_rcu(struct list_head *list, | |||
668 | * as long as the traversal is guarded by rcu_read_lock(). | 651 | * as long as the traversal is guarded by rcu_read_lock(). |
669 | */ | 652 | */ |
670 | #define list_for_each_entry_rcu(pos, head, member) \ | 653 | #define list_for_each_entry_rcu(pos, head, member) \ |
671 | for (pos = list_entry((head)->next, typeof(*pos), member); \ | 654 | for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \ |
672 | prefetch(rcu_dereference(pos)->member.next), \ | 655 | prefetch(pos->member.next), &pos->member != (head); \ |
673 | &pos->member != (head); \ | 656 | pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member)) |
674 | pos = list_entry(pos->member.next, typeof(*pos), member)) | ||
675 | 657 | ||
676 | 658 | ||
677 | /** | 659 | /** |
@@ -686,9 +668,9 @@ static inline void list_splice_init_rcu(struct list_head *list, | |||
686 | * as long as the traversal is guarded by rcu_read_lock(). | 668 | * as long as the traversal is guarded by rcu_read_lock(). |
687 | */ | 669 | */ |
688 | #define list_for_each_continue_rcu(pos, head) \ | 670 | #define list_for_each_continue_rcu(pos, head) \ |
689 | for ((pos) = (pos)->next; \ | 671 | for ((pos) = rcu_dereference((pos)->next); \ |
690 | prefetch(rcu_dereference((pos))->next), (pos) != (head); \ | 672 | prefetch((pos)->next), (pos) != (head); \ |
691 | (pos) = (pos)->next) | 673 | (pos) = rcu_dereference((pos)->next)) |
692 | 674 | ||
693 | /* | 675 | /* |
694 | * Double linked lists with a single pointer list head. | 676 | * Double linked lists with a single pointer list head. |
@@ -986,10 +968,10 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev, | |||
986 | * as long as the traversal is guarded by rcu_read_lock(). | 968 | * as long as the traversal is guarded by rcu_read_lock(). |
987 | */ | 969 | */ |
988 | #define hlist_for_each_entry_rcu(tpos, pos, head, member) \ | 970 | #define hlist_for_each_entry_rcu(tpos, pos, head, member) \ |
989 | for (pos = (head)->first; \ | 971 | for (pos = rcu_dereference((head)->first); \ |
990 | rcu_dereference(pos) && ({ prefetch(pos->next); 1;}) && \ | 972 | pos && ({ prefetch(pos->next); 1;}) && \ |
991 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ | 973 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ |
992 | pos = pos->next) | 974 | pos = rcu_dereference(pos->next)) |
993 | 975 | ||
994 | #else | 976 | #else |
995 | #warning "don't include kernel headers in userspace" | 977 | #warning "don't include kernel headers in userspace" |
diff --git a/include/linux/mount.h b/include/linux/mount.h index 5ee2df217cdf..d6600e3f7e45 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/nodemask.h> | ||
17 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
18 | #include <asm/atomic.h> | 19 | #include <asm/atomic.h> |
19 | 20 | ||
@@ -28,8 +29,10 @@ struct mnt_namespace; | |||
28 | #define MNT_NOATIME 0x08 | 29 | #define MNT_NOATIME 0x08 |
29 | #define MNT_NODIRATIME 0x10 | 30 | #define MNT_NODIRATIME 0x10 |
30 | #define MNT_RELATIME 0x20 | 31 | #define MNT_RELATIME 0x20 |
32 | #define MNT_READONLY 0x40 /* does the user want this to be r/o? */ | ||
31 | 33 | ||
32 | #define MNT_SHRINKABLE 0x100 | 34 | #define MNT_SHRINKABLE 0x100 |
35 | #define MNT_IMBALANCED_WRITE_COUNT 0x200 /* just for debugging */ | ||
33 | 36 | ||
34 | #define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */ | 37 | #define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */ |
35 | #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */ | 38 | #define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */ |
@@ -62,6 +65,11 @@ struct vfsmount { | |||
62 | int mnt_expiry_mark; /* true if marked for expiry */ | 65 | int mnt_expiry_mark; /* true if marked for expiry */ |
63 | int mnt_pinned; | 66 | int mnt_pinned; |
64 | int mnt_ghosts; | 67 | int mnt_ghosts; |
68 | /* | ||
69 | * This value is not stable unless all of the mnt_writers[] spinlocks | ||
70 | * are held, and all mnt_writer[]s on this mount have 0 as their ->count | ||
71 | */ | ||
72 | atomic_t __mnt_writers; | ||
65 | }; | 73 | }; |
66 | 74 | ||
67 | static inline struct vfsmount *mntget(struct vfsmount *mnt) | 75 | static inline struct vfsmount *mntget(struct vfsmount *mnt) |
@@ -71,9 +79,12 @@ static inline struct vfsmount *mntget(struct vfsmount *mnt) | |||
71 | return mnt; | 79 | return mnt; |
72 | } | 80 | } |
73 | 81 | ||
82 | extern int mnt_want_write(struct vfsmount *mnt); | ||
83 | extern void mnt_drop_write(struct vfsmount *mnt); | ||
74 | extern void mntput_no_expire(struct vfsmount *mnt); | 84 | extern void mntput_no_expire(struct vfsmount *mnt); |
75 | extern void mnt_pin(struct vfsmount *mnt); | 85 | extern void mnt_pin(struct vfsmount *mnt); |
76 | extern void mnt_unpin(struct vfsmount *mnt); | 86 | extern void mnt_unpin(struct vfsmount *mnt); |
87 | extern int __mnt_is_readonly(struct vfsmount *mnt); | ||
77 | 88 | ||
78 | static inline void mntput(struct vfsmount *mnt) | 89 | static inline void mntput(struct vfsmount *mnt) |
79 | { | 90 | { |
diff --git a/include/linux/prctl.h b/include/linux/prctl.h index 3800639775ae..5c80b1939636 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h | |||
@@ -67,4 +67,10 @@ | |||
67 | #define PR_CAPBSET_READ 23 | 67 | #define PR_CAPBSET_READ 23 |
68 | #define PR_CAPBSET_DROP 24 | 68 | #define PR_CAPBSET_DROP 24 |
69 | 69 | ||
70 | /* Get/set the process' ability to use the timestamp counter instruction */ | ||
71 | #define PR_GET_TSC 25 | ||
72 | #define PR_SET_TSC 26 | ||
73 | # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */ | ||
74 | # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */ | ||
75 | |||
70 | #endif /* _LINUX_PRCTL_H */ | 76 | #endif /* _LINUX_PRCTL_H */ |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 60f7a27f7a9e..94fd3b08fb77 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -598,6 +598,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, | |||
598 | int oflag, mode_t mode, struct mq_attr __user *u_attr) | 598 | int oflag, mode_t mode, struct mq_attr __user *u_attr) |
599 | { | 599 | { |
600 | struct mq_attr attr; | 600 | struct mq_attr attr; |
601 | struct file *result; | ||
601 | int ret; | 602 | int ret; |
602 | 603 | ||
603 | if (u_attr) { | 604 | if (u_attr) { |
@@ -612,13 +613,24 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, | |||
612 | } | 613 | } |
613 | 614 | ||
614 | mode &= ~current->fs->umask; | 615 | mode &= ~current->fs->umask; |
616 | ret = mnt_want_write(mqueue_mnt); | ||
617 | if (ret) | ||
618 | goto out; | ||
615 | ret = vfs_create(dir->d_inode, dentry, mode, NULL); | 619 | ret = vfs_create(dir->d_inode, dentry, mode, NULL); |
616 | dentry->d_fsdata = NULL; | 620 | dentry->d_fsdata = NULL; |
617 | if (ret) | 621 | if (ret) |
618 | goto out; | 622 | goto out_drop_write; |
619 | 623 | ||
620 | return dentry_open(dentry, mqueue_mnt, oflag); | 624 | result = dentry_open(dentry, mqueue_mnt, oflag); |
621 | 625 | /* | |
626 | * dentry_open() took a persistent mnt_want_write(), | ||
627 | * so we can now drop this one. | ||
628 | */ | ||
629 | mnt_drop_write(mqueue_mnt); | ||
630 | return result; | ||
631 | |||
632 | out_drop_write: | ||
633 | mnt_drop_write(mqueue_mnt); | ||
622 | out: | 634 | out: |
623 | dput(dentry); | 635 | dput(dentry); |
624 | mntput(mqueue_mnt); | 636 | mntput(mqueue_mnt); |
@@ -742,8 +754,11 @@ asmlinkage long sys_mq_unlink(const char __user *u_name) | |||
742 | inode = dentry->d_inode; | 754 | inode = dentry->d_inode; |
743 | if (inode) | 755 | if (inode) |
744 | atomic_inc(&inode->i_count); | 756 | atomic_inc(&inode->i_count); |
745 | 757 | err = mnt_want_write(mqueue_mnt); | |
758 | if (err) | ||
759 | goto out_err; | ||
746 | err = vfs_unlink(dentry->d_parent->d_inode, dentry); | 760 | err = vfs_unlink(dentry->d_parent->d_inode, dentry); |
761 | mnt_drop_write(mqueue_mnt); | ||
747 | out_err: | 762 | out_err: |
748 | dput(dentry); | 763 | dput(dentry); |
749 | 764 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index 9c042f901570..89fe414645e9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -132,6 +132,14 @@ void __put_task_struct(struct task_struct *tsk) | |||
132 | free_task(tsk); | 132 | free_task(tsk); |
133 | } | 133 | } |
134 | 134 | ||
135 | /* | ||
136 | * macro override instead of weak attribute alias, to workaround | ||
137 | * gcc 4.1.0 and 4.1.1 bugs with weak attribute and empty functions. | ||
138 | */ | ||
139 | #ifndef arch_task_cache_init | ||
140 | #define arch_task_cache_init() | ||
141 | #endif | ||
142 | |||
135 | void __init fork_init(unsigned long mempages) | 143 | void __init fork_init(unsigned long mempages) |
136 | { | 144 | { |
137 | #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR | 145 | #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR |
@@ -144,6 +152,9 @@ void __init fork_init(unsigned long mempages) | |||
144 | ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL); | 152 | ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL); |
145 | #endif | 153 | #endif |
146 | 154 | ||
155 | /* do the arch specific task caches init */ | ||
156 | arch_task_cache_init(); | ||
157 | |||
147 | /* | 158 | /* |
148 | * The default maximum number of threads is set to a safe | 159 | * The default maximum number of threads is set to a safe |
149 | * value: the thread structures can take up at most half | 160 | * value: the thread structures can take up at most half |
@@ -163,6 +174,13 @@ void __init fork_init(unsigned long mempages) | |||
163 | init_task.signal->rlim[RLIMIT_NPROC]; | 174 | init_task.signal->rlim[RLIMIT_NPROC]; |
164 | } | 175 | } |
165 | 176 | ||
177 | int __attribute__((weak)) arch_dup_task_struct(struct task_struct *dst, | ||
178 | struct task_struct *src) | ||
179 | { | ||
180 | *dst = *src; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
166 | static struct task_struct *dup_task_struct(struct task_struct *orig) | 184 | static struct task_struct *dup_task_struct(struct task_struct *orig) |
167 | { | 185 | { |
168 | struct task_struct *tsk; | 186 | struct task_struct *tsk; |
@@ -181,15 +199,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
181 | return NULL; | 199 | return NULL; |
182 | } | 200 | } |
183 | 201 | ||
184 | *tsk = *orig; | 202 | err = arch_dup_task_struct(tsk, orig); |
203 | if (err) | ||
204 | goto out; | ||
205 | |||
185 | tsk->stack = ti; | 206 | tsk->stack = ti; |
186 | 207 | ||
187 | err = prop_local_init_single(&tsk->dirties); | 208 | err = prop_local_init_single(&tsk->dirties); |
188 | if (err) { | 209 | if (err) |
189 | free_thread_info(ti); | 210 | goto out; |
190 | free_task_struct(tsk); | ||
191 | return NULL; | ||
192 | } | ||
193 | 211 | ||
194 | setup_thread_stack(tsk, orig); | 212 | setup_thread_stack(tsk, orig); |
195 | 213 | ||
@@ -205,6 +223,11 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
205 | #endif | 223 | #endif |
206 | tsk->splice_pipe = NULL; | 224 | tsk->splice_pipe = NULL; |
207 | return tsk; | 225 | return tsk; |
226 | |||
227 | out: | ||
228 | free_thread_info(ti); | ||
229 | free_task_struct(tsk); | ||
230 | return NULL; | ||
208 | } | 231 | } |
209 | 232 | ||
210 | #ifdef CONFIG_MMU | 233 | #ifdef CONFIG_MMU |
diff --git a/kernel/sys.c b/kernel/sys.c index a626116af5db..6a0cc71ee88d 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -67,6 +67,12 @@ | |||
67 | #ifndef SET_ENDIAN | 67 | #ifndef SET_ENDIAN |
68 | # define SET_ENDIAN(a,b) (-EINVAL) | 68 | # define SET_ENDIAN(a,b) (-EINVAL) |
69 | #endif | 69 | #endif |
70 | #ifndef GET_TSC_CTL | ||
71 | # define GET_TSC_CTL(a) (-EINVAL) | ||
72 | #endif | ||
73 | #ifndef SET_TSC_CTL | ||
74 | # define SET_TSC_CTL(a) (-EINVAL) | ||
75 | #endif | ||
70 | 76 | ||
71 | /* | 77 | /* |
72 | * this is where the system-wide overflow UID and GID are defined, for | 78 | * this is where the system-wide overflow UID and GID are defined, for |
@@ -1737,7 +1743,12 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, | |||
1737 | #else | 1743 | #else |
1738 | return -EINVAL; | 1744 | return -EINVAL; |
1739 | #endif | 1745 | #endif |
1740 | 1746 | case PR_GET_TSC: | |
1747 | error = GET_TSC_CTL(arg2); | ||
1748 | break; | ||
1749 | case PR_SET_TSC: | ||
1750 | error = SET_TSC_CTL(arg2); | ||
1751 | break; | ||
1741 | default: | 1752 | default: |
1742 | error = -EINVAL; | 1753 | error = -EINVAL; |
1743 | break; | 1754 | break; |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index a3fa587c350c..2d6087c7cf98 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -178,6 +178,7 @@ static void change_clocksource(void) | |||
178 | if (clock == new) | 178 | if (clock == new) |
179 | return; | 179 | return; |
180 | 180 | ||
181 | new->cycle_last = 0; | ||
181 | now = clocksource_read(new); | 182 | now = clocksource_read(new); |
182 | nsec = __get_nsec_offset(); | 183 | nsec = __get_nsec_offset(); |
183 | timespec_add_ns(&xtime, nsec); | 184 | timespec_add_ns(&xtime, nsec); |
@@ -295,6 +296,7 @@ static int timekeeping_resume(struct sys_device *dev) | |||
295 | timespec_add_ns(&xtime, timekeeping_suspend_nsecs); | 296 | timespec_add_ns(&xtime, timekeeping_suspend_nsecs); |
296 | update_xtime_cache(0); | 297 | update_xtime_cache(0); |
297 | /* re-base the last cycle value */ | 298 | /* re-base the last cycle value */ |
299 | clock->cycle_last = 0; | ||
298 | clock->cycle_last = clocksource_read(clock); | 300 | clock->cycle_last = clocksource_read(clock); |
299 | clock->error = 0; | 301 | clock->error = 0; |
300 | timekeeping_suspended = 0; | 302 | timekeeping_suspended = 0; |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 95de3102bc87..623ef24c2381 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -427,6 +427,16 @@ config DEBUG_VM | |||
427 | 427 | ||
428 | If unsure, say N. | 428 | If unsure, say N. |
429 | 429 | ||
430 | config DEBUG_WRITECOUNT | ||
431 | bool "Debug filesystem writers count" | ||
432 | depends on DEBUG_KERNEL | ||
433 | help | ||
434 | Enable this to catch wrong use of the writers count in struct | ||
435 | vfsmount. This will increase the size of each file struct by | ||
436 | 32 bits. | ||
437 | |||
438 | If unsure, say N. | ||
439 | |||
430 | config DEBUG_LIST | 440 | config DEBUG_LIST |
431 | bool "Debug linked list manipulation" | 441 | bool "Debug linked list manipulation" |
432 | depends on DEBUG_KERNEL | 442 | depends on DEBUG_KERNEL |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 2851d0d15048..1454afcc06c4 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -819,7 +819,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
819 | */ | 819 | */ |
820 | mode = S_IFSOCK | | 820 | mode = S_IFSOCK | |
821 | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); | 821 | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); |
822 | err = mnt_want_write(nd.path.mnt); | ||
823 | if (err) | ||
824 | goto out_mknod_dput; | ||
822 | err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); | 825 | err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); |
826 | mnt_drop_write(nd.path.mnt); | ||
823 | if (err) | 827 | if (err) |
824 | goto out_mknod_dput; | 828 | goto out_mknod_dput; |
825 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); | 829 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |