diff options
165 files changed, 4758 insertions, 1291 deletions
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index 6e25c2659e0a..a2976a6de033 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <sys/types.h> | 21 | #include <sys/types.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <sys/socket.h> | 23 | #include <sys/socket.h> |
24 | #include <sys/wait.h> | ||
24 | #include <signal.h> | 25 | #include <signal.h> |
25 | 26 | ||
26 | #include <linux/genetlink.h> | 27 | #include <linux/genetlink.h> |
@@ -266,11 +267,13 @@ int main(int argc, char *argv[]) | |||
266 | int containerset = 0; | 267 | int containerset = 0; |
267 | char containerpath[1024]; | 268 | char containerpath[1024]; |
268 | int cfd = 0; | 269 | int cfd = 0; |
270 | int forking = 0; | ||
271 | sigset_t sigset; | ||
269 | 272 | ||
270 | struct msgtemplate msg; | 273 | struct msgtemplate msg; |
271 | 274 | ||
272 | while (1) { | 275 | while (!forking) { |
273 | c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:"); | 276 | c = getopt(argc, argv, "qdiw:r:m:t:p:vlC:c:"); |
274 | if (c < 0) | 277 | if (c < 0) |
275 | break; | 278 | break; |
276 | 279 | ||
@@ -319,6 +322,28 @@ int main(int argc, char *argv[]) | |||
319 | err(1, "Invalid pid\n"); | 322 | err(1, "Invalid pid\n"); |
320 | cmd_type = TASKSTATS_CMD_ATTR_PID; | 323 | cmd_type = TASKSTATS_CMD_ATTR_PID; |
321 | break; | 324 | break; |
325 | case 'c': | ||
326 | |||
327 | /* Block SIGCHLD for sigwait() later */ | ||
328 | if (sigemptyset(&sigset) == -1) | ||
329 | err(1, "Failed to empty sigset"); | ||
330 | if (sigaddset(&sigset, SIGCHLD)) | ||
331 | err(1, "Failed to set sigchld in sigset"); | ||
332 | sigprocmask(SIG_BLOCK, &sigset, NULL); | ||
333 | |||
334 | /* fork/exec a child */ | ||
335 | tid = fork(); | ||
336 | if (tid < 0) | ||
337 | err(1, "Fork failed\n"); | ||
338 | if (tid == 0) | ||
339 | if (execvp(argv[optind - 1], | ||
340 | &argv[optind - 1]) < 0) | ||
341 | exit(-1); | ||
342 | |||
343 | /* Set the command type and avoid further processing */ | ||
344 | cmd_type = TASKSTATS_CMD_ATTR_PID; | ||
345 | forking = 1; | ||
346 | break; | ||
322 | case 'v': | 347 | case 'v': |
323 | printf("debug on\n"); | 348 | printf("debug on\n"); |
324 | dbg = 1; | 349 | dbg = 1; |
@@ -370,6 +395,15 @@ int main(int argc, char *argv[]) | |||
370 | goto err; | 395 | goto err; |
371 | } | 396 | } |
372 | 397 | ||
398 | /* | ||
399 | * If we forked a child, wait for it to exit. Cannot use waitpid() | ||
400 | * as all the delicious data would be reaped as part of the wait | ||
401 | */ | ||
402 | if (tid && forking) { | ||
403 | int sig_received; | ||
404 | sigwait(&sigset, &sig_received); | ||
405 | } | ||
406 | |||
373 | if (tid) { | 407 | if (tid) { |
374 | rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, | 408 | rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, |
375 | cmd_type, &tid, sizeof(__u32)); | 409 | cmd_type, &tid, sizeof(__u32)); |
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index b34823ff1646..190018b0c649 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt | |||
@@ -18,7 +18,8 @@ CONTENTS: | |||
18 | 1.2 Why are cgroups needed ? | 18 | 1.2 Why are cgroups needed ? |
19 | 1.3 How are cgroups implemented ? | 19 | 1.3 How are cgroups implemented ? |
20 | 1.4 What does notify_on_release do ? | 20 | 1.4 What does notify_on_release do ? |
21 | 1.5 How do I use cgroups ? | 21 | 1.5 What does clone_children do ? |
22 | 1.6 How do I use cgroups ? | ||
22 | 2. Usage Examples and Syntax | 23 | 2. Usage Examples and Syntax |
23 | 2.1 Basic Usage | 24 | 2.1 Basic Usage |
24 | 2.2 Attaching processes | 25 | 2.2 Attaching processes |
@@ -293,7 +294,16 @@ notify_on_release in the root cgroup at system boot is disabled | |||
293 | value of their parents notify_on_release setting. The default value of | 294 | value of their parents notify_on_release setting. The default value of |
294 | a cgroup hierarchy's release_agent path is empty. | 295 | a cgroup hierarchy's release_agent path is empty. |
295 | 296 | ||
296 | 1.5 How do I use cgroups ? | 297 | 1.5 What does clone_children do ? |
298 | --------------------------------- | ||
299 | |||
300 | If the clone_children flag is enabled (1) in a cgroup, then all | ||
301 | cgroups created beneath will call the post_clone callbacks for each | ||
302 | subsystem of the newly created cgroup. Usually when this callback is | ||
303 | implemented for a subsystem, it copies the values of the parent | ||
304 | subsystem, this is the case for the cpuset. | ||
305 | |||
306 | 1.6 How do I use cgroups ? | ||
297 | -------------------------- | 307 | -------------------------- |
298 | 308 | ||
299 | To start a new job that is to be contained within a cgroup, using | 309 | To start a new job that is to be contained within a cgroup, using |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index d2af87ba96e1..f3da8c0a3af2 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -526,6 +526,23 @@ Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | |||
526 | 526 | ||
527 | ---------------------------- | 527 | ---------------------------- |
528 | 528 | ||
529 | What: namespace cgroup (ns_cgroup) | ||
530 | When: 2.6.38 | ||
531 | Why: The ns_cgroup leads to some problems: | ||
532 | * cgroup creation is out-of-control | ||
533 | * cgroup name can conflict when pids are looping | ||
534 | * it is not possible to have a single process handling | ||
535 | a lot of namespaces without falling in a exponential creation time | ||
536 | * we may want to create a namespace without creating a cgroup | ||
537 | |||
538 | The ns_cgroup is replaced by a compatibility flag 'clone_children', | ||
539 | where a newly created cgroup will copy the parent cgroup values. | ||
540 | The userspace has to manually create a cgroup and add a task to | ||
541 | the 'tasks' file. | ||
542 | Who: Daniel Lezcano <daniel.lezcano@free.fr> | ||
543 | |||
544 | ---------------------------- | ||
545 | |||
529 | What: iwlwifi disable_hw_scan module parameters | 546 | What: iwlwifi disable_hw_scan module parameters |
530 | When: 2.6.40 | 547 | When: 2.6.40 |
531 | Why: Hareware scan is the prefer method for iwlwifi devices for | 548 | Why: Hareware scan is the prefer method for iwlwifi devices for |
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index a563b74c7aef..e73df2722ff3 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -136,6 +136,7 @@ Table 1-1: Process specific entries in /proc | |||
136 | statm Process memory status information | 136 | statm Process memory status information |
137 | status Process status in human readable form | 137 | status Process status in human readable form |
138 | wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan | 138 | wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan |
139 | pagemap Page table | ||
139 | stack Report full stack trace, enable via CONFIG_STACKTRACE | 140 | stack Report full stack trace, enable via CONFIG_STACKTRACE |
140 | smaps a extension based on maps, showing the memory consumption of | 141 | smaps a extension based on maps, showing the memory consumption of |
141 | each mapping | 142 | each mapping |
@@ -370,6 +371,7 @@ Shared_Dirty: 0 kB | |||
370 | Private_Clean: 0 kB | 371 | Private_Clean: 0 kB |
371 | Private_Dirty: 0 kB | 372 | Private_Dirty: 0 kB |
372 | Referenced: 892 kB | 373 | Referenced: 892 kB |
374 | Anonymous: 0 kB | ||
373 | Swap: 0 kB | 375 | Swap: 0 kB |
374 | KernelPageSize: 4 kB | 376 | KernelPageSize: 4 kB |
375 | MMUPageSize: 4 kB | 377 | MMUPageSize: 4 kB |
@@ -378,9 +380,15 @@ The first of these lines shows the same information as is displayed for the | |||
378 | mapping in /proc/PID/maps. The remaining lines show the size of the mapping | 380 | mapping in /proc/PID/maps. The remaining lines show the size of the mapping |
379 | (size), the amount of the mapping that is currently resident in RAM (RSS), the | 381 | (size), the amount of the mapping that is currently resident in RAM (RSS), the |
380 | process' proportional share of this mapping (PSS), the number of clean and | 382 | process' proportional share of this mapping (PSS), the number of clean and |
381 | dirty shared pages in the mapping, and the number of clean and dirty private | 383 | dirty private pages in the mapping. Note that even a page which is part of a |
382 | pages in the mapping. The "Referenced" indicates the amount of memory | 384 | MAP_SHARED mapping, but has only a single pte mapped, i.e. is currently used |
383 | currently marked as referenced or accessed. | 385 | by only one process, is accounted as private and not as shared. "Referenced" |
386 | indicates the amount of memory currently marked as referenced or accessed. | ||
387 | "Anonymous" shows the amount of memory that does not belong to any file. Even | ||
388 | a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE | ||
389 | and a page is modified, the file page is replaced by a private anonymous copy. | ||
390 | "Swap" shows how much would-be-anonymous memory is also used, but out on | ||
391 | swap. | ||
384 | 392 | ||
385 | This file is only present if the CONFIG_MMU kernel configuration option is | 393 | This file is only present if the CONFIG_MMU kernel configuration option is |
386 | enabled. | 394 | enabled. |
@@ -397,6 +405,9 @@ To clear the bits for the file mapped pages associated with the process | |||
397 | > echo 3 > /proc/PID/clear_refs | 405 | > echo 3 > /proc/PID/clear_refs |
398 | Any other value written to /proc/PID/clear_refs will have no effect. | 406 | Any other value written to /proc/PID/clear_refs will have no effect. |
399 | 407 | ||
408 | The /proc/pid/pagemap gives the PFN, which can be used to find the pageflags | ||
409 | using /proc/kpageflags and number of times a page is mapped using | ||
410 | /proc/kpagecount. For detailed explanation, see Documentation/vm/pagemap.txt. | ||
400 | 411 | ||
401 | 1.2 Kernel data | 412 | 1.2 Kernel data |
402 | --------------- | 413 | --------------- |
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index b606c2c4dd37..30289fab86eb 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
@@ -80,8 +80,10 @@ dirty_background_bytes | |||
80 | Contains the amount of dirty memory at which the pdflush background writeback | 80 | Contains the amount of dirty memory at which the pdflush background writeback |
81 | daemon will start writeback. | 81 | daemon will start writeback. |
82 | 82 | ||
83 | If dirty_background_bytes is written, dirty_background_ratio becomes a function | 83 | Note: dirty_background_bytes is the counterpart of dirty_background_ratio. Only |
84 | of its value (dirty_background_bytes / the amount of dirtyable system memory). | 84 | one of them may be specified at a time. When one sysctl is written it is |
85 | immediately taken into account to evaluate the dirty memory limits and the | ||
86 | other appears as 0 when read. | ||
85 | 87 | ||
86 | ============================================================== | 88 | ============================================================== |
87 | 89 | ||
@@ -97,8 +99,10 @@ dirty_bytes | |||
97 | Contains the amount of dirty memory at which a process generating disk writes | 99 | Contains the amount of dirty memory at which a process generating disk writes |
98 | will itself start writeback. | 100 | will itself start writeback. |
99 | 101 | ||
100 | If dirty_bytes is written, dirty_ratio becomes a function of its value | 102 | Note: dirty_bytes is the counterpart of dirty_ratio. Only one of them may be |
101 | (dirty_bytes / the amount of dirtyable system memory). | 103 | specified at a time. When one sysctl is written it is immediately taken into |
104 | account to evaluate the dirty memory limits and the other appears as 0 when | ||
105 | read. | ||
102 | 106 | ||
103 | Note: the minimum value allowed for dirty_bytes is two pages (in bytes); any | 107 | Note: the minimum value allowed for dirty_bytes is two pages (in bytes); any |
104 | value lower than this limit will be ignored and the old configuration will be | 108 | value lower than this limit will be ignored and the old configuration will be |
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index d1dbd9acd1df..022c2748fa41 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c | |||
@@ -223,7 +223,7 @@ iommu_arena_free(struct pci_iommu_arena *arena, long ofs, long n) | |||
223 | */ | 223 | */ |
224 | static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask) | 224 | static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask) |
225 | { | 225 | { |
226 | dma64_addr_t dac_offset = alpha_mv.pci_dac_offset; | 226 | dma_addr_t dac_offset = alpha_mv.pci_dac_offset; |
227 | int ok = 1; | 227 | int ok = 1; |
228 | 228 | ||
229 | /* If this is not set, the machine doesn't support DAC at all. */ | 229 | /* If this is not set, the machine doesn't support DAC at all. */ |
@@ -756,7 +756,7 @@ static void alpha_pci_unmap_sg(struct device *dev, struct scatterlist *sg, | |||
756 | spin_lock_irqsave(&arena->lock, flags); | 756 | spin_lock_irqsave(&arena->lock, flags); |
757 | 757 | ||
758 | for (end = sg + nents; sg < end; ++sg) { | 758 | for (end = sg + nents; sg < end; ++sg) { |
759 | dma64_addr_t addr; | 759 | dma_addr_t addr; |
760 | size_t size; | 760 | size_t size; |
761 | long npages, ofs; | 761 | long npages, ofs; |
762 | dma_addr_t tend; | 762 | dma_addr_t tend; |
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index baa903602f6a..e2af5eb59bb4 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c | |||
@@ -269,7 +269,8 @@ void ptrace_disable(struct task_struct *child) | |||
269 | user_disable_single_step(child); | 269 | user_disable_single_step(child); |
270 | } | 270 | } |
271 | 271 | ||
272 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 272 | long arch_ptrace(struct task_struct *child, long request, |
273 | unsigned long addr, unsigned long data) | ||
273 | { | 274 | { |
274 | unsigned long tmp; | 275 | unsigned long tmp; |
275 | size_t copied; | 276 | size_t copied; |
@@ -292,7 +293,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
292 | case PTRACE_PEEKUSR: | 293 | case PTRACE_PEEKUSR: |
293 | force_successful_syscall_return(); | 294 | force_successful_syscall_return(); |
294 | ret = get_reg(child, addr); | 295 | ret = get_reg(child, addr); |
295 | DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret)); | 296 | DBG(DBG_MEM, ("peek $%lu->%#lx\n", addr, ret)); |
296 | break; | 297 | break; |
297 | 298 | ||
298 | /* When I and D space are separate, this will have to be fixed. */ | 299 | /* When I and D space are separate, this will have to be fixed. */ |
@@ -302,7 +303,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
302 | break; | 303 | break; |
303 | 304 | ||
304 | case PTRACE_POKEUSR: /* write the specified register */ | 305 | case PTRACE_POKEUSR: /* write the specified register */ |
305 | DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data)); | 306 | DBG(DBG_MEM, ("poke $%lu<-%#lx\n", addr, data)); |
306 | ret = put_reg(child, addr, data); | 307 | ret = put_reg(child, addr, data); |
307 | break; | 308 | break; |
308 | default: | 309 | default: |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index e0cb6370ed14..3e97483abcf0 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -1075,13 +1075,15 @@ out: | |||
1075 | } | 1075 | } |
1076 | #endif | 1076 | #endif |
1077 | 1077 | ||
1078 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 1078 | long arch_ptrace(struct task_struct *child, long request, |
1079 | unsigned long addr, unsigned long data) | ||
1079 | { | 1080 | { |
1080 | int ret; | 1081 | int ret; |
1082 | unsigned long __user *datap = (unsigned long __user *) data; | ||
1081 | 1083 | ||
1082 | switch (request) { | 1084 | switch (request) { |
1083 | case PTRACE_PEEKUSR: | 1085 | case PTRACE_PEEKUSR: |
1084 | ret = ptrace_read_user(child, addr, (unsigned long __user *)data); | 1086 | ret = ptrace_read_user(child, addr, datap); |
1085 | break; | 1087 | break; |
1086 | 1088 | ||
1087 | case PTRACE_POKEUSR: | 1089 | case PTRACE_POKEUSR: |
@@ -1089,34 +1091,34 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1089 | break; | 1091 | break; |
1090 | 1092 | ||
1091 | case PTRACE_GETREGS: | 1093 | case PTRACE_GETREGS: |
1092 | ret = ptrace_getregs(child, (void __user *)data); | 1094 | ret = ptrace_getregs(child, datap); |
1093 | break; | 1095 | break; |
1094 | 1096 | ||
1095 | case PTRACE_SETREGS: | 1097 | case PTRACE_SETREGS: |
1096 | ret = ptrace_setregs(child, (void __user *)data); | 1098 | ret = ptrace_setregs(child, datap); |
1097 | break; | 1099 | break; |
1098 | 1100 | ||
1099 | case PTRACE_GETFPREGS: | 1101 | case PTRACE_GETFPREGS: |
1100 | ret = ptrace_getfpregs(child, (void __user *)data); | 1102 | ret = ptrace_getfpregs(child, datap); |
1101 | break; | 1103 | break; |
1102 | 1104 | ||
1103 | case PTRACE_SETFPREGS: | 1105 | case PTRACE_SETFPREGS: |
1104 | ret = ptrace_setfpregs(child, (void __user *)data); | 1106 | ret = ptrace_setfpregs(child, datap); |
1105 | break; | 1107 | break; |
1106 | 1108 | ||
1107 | #ifdef CONFIG_IWMMXT | 1109 | #ifdef CONFIG_IWMMXT |
1108 | case PTRACE_GETWMMXREGS: | 1110 | case PTRACE_GETWMMXREGS: |
1109 | ret = ptrace_getwmmxregs(child, (void __user *)data); | 1111 | ret = ptrace_getwmmxregs(child, datap); |
1110 | break; | 1112 | break; |
1111 | 1113 | ||
1112 | case PTRACE_SETWMMXREGS: | 1114 | case PTRACE_SETWMMXREGS: |
1113 | ret = ptrace_setwmmxregs(child, (void __user *)data); | 1115 | ret = ptrace_setwmmxregs(child, datap); |
1114 | break; | 1116 | break; |
1115 | #endif | 1117 | #endif |
1116 | 1118 | ||
1117 | case PTRACE_GET_THREAD_AREA: | 1119 | case PTRACE_GET_THREAD_AREA: |
1118 | ret = put_user(task_thread_info(child)->tp_value, | 1120 | ret = put_user(task_thread_info(child)->tp_value, |
1119 | (unsigned long __user *) data); | 1121 | datap); |
1120 | break; | 1122 | break; |
1121 | 1123 | ||
1122 | case PTRACE_SET_SYSCALL: | 1124 | case PTRACE_SET_SYSCALL: |
@@ -1126,21 +1128,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1126 | 1128 | ||
1127 | #ifdef CONFIG_CRUNCH | 1129 | #ifdef CONFIG_CRUNCH |
1128 | case PTRACE_GETCRUNCHREGS: | 1130 | case PTRACE_GETCRUNCHREGS: |
1129 | ret = ptrace_getcrunchregs(child, (void __user *)data); | 1131 | ret = ptrace_getcrunchregs(child, datap); |
1130 | break; | 1132 | break; |
1131 | 1133 | ||
1132 | case PTRACE_SETCRUNCHREGS: | 1134 | case PTRACE_SETCRUNCHREGS: |
1133 | ret = ptrace_setcrunchregs(child, (void __user *)data); | 1135 | ret = ptrace_setcrunchregs(child, datap); |
1134 | break; | 1136 | break; |
1135 | #endif | 1137 | #endif |
1136 | 1138 | ||
1137 | #ifdef CONFIG_VFP | 1139 | #ifdef CONFIG_VFP |
1138 | case PTRACE_GETVFPREGS: | 1140 | case PTRACE_GETVFPREGS: |
1139 | ret = ptrace_getvfpregs(child, (void __user *)data); | 1141 | ret = ptrace_getvfpregs(child, datap); |
1140 | break; | 1142 | break; |
1141 | 1143 | ||
1142 | case PTRACE_SETVFPREGS: | 1144 | case PTRACE_SETVFPREGS: |
1143 | ret = ptrace_setvfpregs(child, (void __user *)data); | 1145 | ret = ptrace_setvfpregs(child, datap); |
1144 | break; | 1146 | break; |
1145 | #endif | 1147 | #endif |
1146 | 1148 | ||
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c index 2f420210d406..9057d6fd1d31 100644 --- a/arch/arm/mach-tegra/timer.c +++ b/arch/arm/mach-tegra/timer.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/cnt32_to_63.h> | 28 | #include <linux/cnt32_to_63.h> |
29 | 29 | ||
30 | #include <asm/mach/time.h> | 30 | #include <asm/mach/time.h> |
31 | #include <asm/mach/time.h> | ||
32 | #include <asm/localtimer.h> | 31 | #include <asm/localtimer.h> |
33 | 32 | ||
34 | #include <mach/iomap.h> | 33 | #include <mach/iomap.h> |
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index c00f119babbf..c435fd9e1da9 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c | |||
@@ -89,7 +89,7 @@ void __kunmap_atomic(void *kvaddr) | |||
89 | int idx, type; | 89 | int idx, type; |
90 | 90 | ||
91 | if (kvaddr >= (void *)FIXADDR_START) { | 91 | if (kvaddr >= (void *)FIXADDR_START) { |
92 | type = kmap_atomic_idx_pop(); | 92 | type = kmap_atomic_idx(); |
93 | idx = type + KM_TYPE_NR * smp_processor_id(); | 93 | idx = type + KM_TYPE_NR * smp_processor_id(); |
94 | 94 | ||
95 | if (cache_is_vivt()) | 95 | if (cache_is_vivt()) |
@@ -101,6 +101,7 @@ void __kunmap_atomic(void *kvaddr) | |||
101 | #else | 101 | #else |
102 | (void) idx; /* to kill a warning */ | 102 | (void) idx; /* to kill a warning */ |
103 | #endif | 103 | #endif |
104 | kmap_atomic_idx_pop(); | ||
104 | } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { | 105 | } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) { |
105 | /* this address was obtained through kmap_high_get() */ | 106 | /* this address was obtained through kmap_high_get() */ |
106 | kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)])); | 107 | kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)])); |
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h index 5fbde4b8dc12..93a812672d9a 100644 --- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h +++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/dmaengine.h> | 14 | #include <linux/dmaengine.h> |
15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/dmaengine.h> | ||
18 | 17 | ||
19 | /* dev types for memcpy */ | 18 | /* dev types for memcpy */ |
20 | #define STEDMA40_DEV_DST_MEMORY (-1) | 19 | #define STEDMA40_DEV_DST_MEMORY (-1) |
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c index 5e73c25f8f85..4aedcab7cd4b 100644 --- a/arch/avr32/kernel/ptrace.c +++ b/arch/avr32/kernel/ptrace.c | |||
@@ -146,9 +146,11 @@ static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs) | |||
146 | return ret; | 146 | return ret; |
147 | } | 147 | } |
148 | 148 | ||
149 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 149 | long arch_ptrace(struct task_struct *child, long request, |
150 | unsigned long addr, unsigned long data) | ||
150 | { | 151 | { |
151 | int ret; | 152 | int ret; |
153 | void __user *datap = (void __user *) data; | ||
152 | 154 | ||
153 | switch (request) { | 155 | switch (request) { |
154 | /* Read the word at location addr in the child process */ | 156 | /* Read the word at location addr in the child process */ |
@@ -158,8 +160,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
158 | break; | 160 | break; |
159 | 161 | ||
160 | case PTRACE_PEEKUSR: | 162 | case PTRACE_PEEKUSR: |
161 | ret = ptrace_read_user(child, addr, | 163 | ret = ptrace_read_user(child, addr, datap); |
162 | (unsigned long __user *)data); | ||
163 | break; | 164 | break; |
164 | 165 | ||
165 | /* Write the word in data at location addr */ | 166 | /* Write the word in data at location addr */ |
@@ -173,11 +174,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
173 | break; | 174 | break; |
174 | 175 | ||
175 | case PTRACE_GETREGS: | 176 | case PTRACE_GETREGS: |
176 | ret = ptrace_getregs(child, (void __user *)data); | 177 | ret = ptrace_getregs(child, datap); |
177 | break; | 178 | break; |
178 | 179 | ||
179 | case PTRACE_SETREGS: | 180 | case PTRACE_SETREGS: |
180 | ret = ptrace_setregs(child, (const void __user *)data); | 181 | ret = ptrace_setregs(child, datap); |
181 | break; | 182 | break; |
182 | 183 | ||
183 | default: | 184 | default: |
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index b35839354130..75089f80855d 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -38,12 +38,13 @@ | |||
38 | * Get contents of register REGNO in task TASK. | 38 | * Get contents of register REGNO in task TASK. |
39 | */ | 39 | */ |
40 | static inline long | 40 | static inline long |
41 | get_reg(struct task_struct *task, long regno, unsigned long __user *datap) | 41 | get_reg(struct task_struct *task, unsigned long regno, |
42 | unsigned long __user *datap) | ||
42 | { | 43 | { |
43 | long tmp; | 44 | long tmp; |
44 | struct pt_regs *regs = task_pt_regs(task); | 45 | struct pt_regs *regs = task_pt_regs(task); |
45 | 46 | ||
46 | if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0) | 47 | if (regno & 3 || regno > PT_LAST_PSEUDO) |
47 | return -EIO; | 48 | return -EIO; |
48 | 49 | ||
49 | switch (regno) { | 50 | switch (regno) { |
@@ -74,11 +75,11 @@ get_reg(struct task_struct *task, long regno, unsigned long __user *datap) | |||
74 | * Write contents of register REGNO in task TASK. | 75 | * Write contents of register REGNO in task TASK. |
75 | */ | 76 | */ |
76 | static inline int | 77 | static inline int |
77 | put_reg(struct task_struct *task, long regno, unsigned long data) | 78 | put_reg(struct task_struct *task, unsigned long regno, unsigned long data) |
78 | { | 79 | { |
79 | struct pt_regs *regs = task_pt_regs(task); | 80 | struct pt_regs *regs = task_pt_regs(task); |
80 | 81 | ||
81 | if (regno & 3 || regno > PT_LAST_PSEUDO || regno < 0) | 82 | if (regno & 3 || regno > PT_LAST_PSEUDO) |
82 | return -EIO; | 83 | return -EIO; |
83 | 84 | ||
84 | switch (regno) { | 85 | switch (regno) { |
@@ -240,7 +241,8 @@ void user_disable_single_step(struct task_struct *child) | |||
240 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | 241 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); |
241 | } | 242 | } |
242 | 243 | ||
243 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 244 | long arch_ptrace(struct task_struct *child, long request, |
245 | unsigned long addr, unsigned long data) | ||
244 | { | 246 | { |
245 | int ret; | 247 | int ret; |
246 | unsigned long __user *datap = (unsigned long __user *)data; | 248 | unsigned long __user *datap = (unsigned long __user *)data; |
@@ -368,14 +370,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
368 | return copy_regset_to_user(child, &user_bfin_native_view, | 370 | return copy_regset_to_user(child, &user_bfin_native_view, |
369 | REGSET_GENERAL, | 371 | REGSET_GENERAL, |
370 | 0, sizeof(struct pt_regs), | 372 | 0, sizeof(struct pt_regs), |
371 | (void __user *)data); | 373 | datap); |
372 | 374 | ||
373 | case PTRACE_SETREGS: | 375 | case PTRACE_SETREGS: |
374 | pr_debug("ptrace: PTRACE_SETREGS\n"); | 376 | pr_debug("ptrace: PTRACE_SETREGS\n"); |
375 | return copy_regset_from_user(child, &user_bfin_native_view, | 377 | return copy_regset_from_user(child, &user_bfin_native_view, |
376 | REGSET_GENERAL, | 378 | REGSET_GENERAL, |
377 | 0, sizeof(struct pt_regs), | 379 | 0, sizeof(struct pt_regs), |
378 | (const void __user *)data); | 380 | datap); |
379 | 381 | ||
380 | case_default: | 382 | case_default: |
381 | default: | 383 | default: |
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index e70c804e9377..320065f3cbe5 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c | |||
@@ -76,9 +76,11 @@ ptrace_disable(struct task_struct *child) | |||
76 | * (in user space) where the result of the ptrace call is written (instead of | 76 | * (in user space) where the result of the ptrace call is written (instead of |
77 | * being returned). | 77 | * being returned). |
78 | */ | 78 | */ |
79 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 79 | long arch_ptrace(struct task_struct *child, long request, |
80 | unsigned long addr, unsigned long data) | ||
80 | { | 81 | { |
81 | int ret; | 82 | int ret; |
83 | unsigned int regno = addr >> 2; | ||
82 | unsigned long __user *datap = (unsigned long __user *)data; | 84 | unsigned long __user *datap = (unsigned long __user *)data; |
83 | 85 | ||
84 | switch (request) { | 86 | switch (request) { |
@@ -93,10 +95,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
93 | unsigned long tmp; | 95 | unsigned long tmp; |
94 | 96 | ||
95 | ret = -EIO; | 97 | ret = -EIO; |
96 | if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) | 98 | if ((addr & 3) || regno > PT_MAX) |
97 | break; | 99 | break; |
98 | 100 | ||
99 | tmp = get_reg(child, addr >> 2); | 101 | tmp = get_reg(child, regno); |
100 | ret = put_user(tmp, datap); | 102 | ret = put_user(tmp, datap); |
101 | break; | 103 | break; |
102 | } | 104 | } |
@@ -110,19 +112,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
110 | /* Write the word at location address in the USER area. */ | 112 | /* Write the word at location address in the USER area. */ |
111 | case PTRACE_POKEUSR: | 113 | case PTRACE_POKEUSR: |
112 | ret = -EIO; | 114 | ret = -EIO; |
113 | if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) | 115 | if ((addr & 3) || regno > PT_MAX) |
114 | break; | 116 | break; |
115 | 117 | ||
116 | addr >>= 2; | 118 | if (regno == PT_DCCR) { |
117 | |||
118 | if (addr == PT_DCCR) { | ||
119 | /* don't allow the tracing process to change stuff like | 119 | /* don't allow the tracing process to change stuff like |
120 | * interrupt enable, kernel/user bit, dma enables etc. | 120 | * interrupt enable, kernel/user bit, dma enables etc. |
121 | */ | 121 | */ |
122 | data &= DCCR_MASK; | 122 | data &= DCCR_MASK; |
123 | data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; | 123 | data |= get_reg(child, PT_DCCR) & ~DCCR_MASK; |
124 | } | 124 | } |
125 | if (put_reg(child, addr, data)) | 125 | if (put_reg(child, regno, data)) |
126 | break; | 126 | break; |
127 | ret = 0; | 127 | ret = 0; |
128 | break; | 128 | break; |
@@ -141,7 +141,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | 143 | ||
144 | data += sizeof(long); | 144 | datap++; |
145 | } | 145 | } |
146 | 146 | ||
147 | break; | 147 | break; |
@@ -165,7 +165,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | put_reg(child, i, tmp); | 167 | put_reg(child, i, tmp); |
168 | data += sizeof(long); | 168 | datap++; |
169 | } | 169 | } |
170 | 170 | ||
171 | break; | 171 | break; |
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c index f4ebd1e7d0f5..511ece94a574 100644 --- a/arch/cris/arch-v32/kernel/ptrace.c +++ b/arch/cris/arch-v32/kernel/ptrace.c | |||
@@ -126,9 +126,11 @@ ptrace_disable(struct task_struct *child) | |||
126 | } | 126 | } |
127 | 127 | ||
128 | 128 | ||
129 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 129 | long arch_ptrace(struct task_struct *child, long request, |
130 | unsigned long addr, unsigned long data) | ||
130 | { | 131 | { |
131 | int ret; | 132 | int ret; |
133 | unsigned int regno = addr >> 2; | ||
132 | unsigned long __user *datap = (unsigned long __user *)data; | 134 | unsigned long __user *datap = (unsigned long __user *)data; |
133 | 135 | ||
134 | switch (request) { | 136 | switch (request) { |
@@ -163,10 +165,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
163 | unsigned long tmp; | 165 | unsigned long tmp; |
164 | 166 | ||
165 | ret = -EIO; | 167 | ret = -EIO; |
166 | if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) | 168 | if ((addr & 3) || regno > PT_MAX) |
167 | break; | 169 | break; |
168 | 170 | ||
169 | tmp = get_reg(child, addr >> 2); | 171 | tmp = get_reg(child, regno); |
170 | ret = put_user(tmp, datap); | 172 | ret = put_user(tmp, datap); |
171 | break; | 173 | break; |
172 | } | 174 | } |
@@ -180,19 +182,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
180 | /* Write the word at location address in the USER area. */ | 182 | /* Write the word at location address in the USER area. */ |
181 | case PTRACE_POKEUSR: | 183 | case PTRACE_POKEUSR: |
182 | ret = -EIO; | 184 | ret = -EIO; |
183 | if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) | 185 | if ((addr & 3) || regno > PT_MAX) |
184 | break; | 186 | break; |
185 | 187 | ||
186 | addr >>= 2; | 188 | if (regno == PT_CCS) { |
187 | |||
188 | if (addr == PT_CCS) { | ||
189 | /* don't allow the tracing process to change stuff like | 189 | /* don't allow the tracing process to change stuff like |
190 | * interrupt enable, kernel/user bit, dma enables etc. | 190 | * interrupt enable, kernel/user bit, dma enables etc. |
191 | */ | 191 | */ |
192 | data &= CCS_MASK; | 192 | data &= CCS_MASK; |
193 | data |= get_reg(child, PT_CCS) & ~CCS_MASK; | 193 | data |= get_reg(child, PT_CCS) & ~CCS_MASK; |
194 | } | 194 | } |
195 | if (put_reg(child, addr, data)) | 195 | if (put_reg(child, regno, data)) |
196 | break; | 196 | break; |
197 | ret = 0; | 197 | ret = 0; |
198 | break; | 198 | break; |
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c index fac028936a04..9d68f7fac730 100644 --- a/arch/frv/kernel/ptrace.c +++ b/arch/frv/kernel/ptrace.c | |||
@@ -254,23 +254,26 @@ void ptrace_disable(struct task_struct *child) | |||
254 | user_disable_single_step(child); | 254 | user_disable_single_step(child); |
255 | } | 255 | } |
256 | 256 | ||
257 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 257 | long arch_ptrace(struct task_struct *child, long request, |
258 | unsigned long addr, unsigned long data) | ||
258 | { | 259 | { |
259 | unsigned long tmp; | 260 | unsigned long tmp; |
260 | int ret; | 261 | int ret; |
262 | int regno = addr >> 2; | ||
263 | unsigned long __user *datap = (unsigned long __user *) data; | ||
261 | 264 | ||
262 | switch (request) { | 265 | switch (request) { |
263 | /* read the word at location addr in the USER area. */ | 266 | /* read the word at location addr in the USER area. */ |
264 | case PTRACE_PEEKUSR: { | 267 | case PTRACE_PEEKUSR: { |
265 | tmp = 0; | 268 | tmp = 0; |
266 | ret = -EIO; | 269 | ret = -EIO; |
267 | if ((addr & 3) || addr < 0) | 270 | if (addr & 3) |
268 | break; | 271 | break; |
269 | 272 | ||
270 | ret = 0; | 273 | ret = 0; |
271 | switch (addr >> 2) { | 274 | switch (regno) { |
272 | case 0 ... PT__END - 1: | 275 | case 0 ... PT__END - 1: |
273 | tmp = get_reg(child, addr >> 2); | 276 | tmp = get_reg(child, regno); |
274 | break; | 277 | break; |
275 | 278 | ||
276 | case PT__END + 0: | 279 | case PT__END + 0: |
@@ -299,23 +302,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
299 | } | 302 | } |
300 | 303 | ||
301 | if (ret == 0) | 304 | if (ret == 0) |
302 | ret = put_user(tmp, (unsigned long *) data); | 305 | ret = put_user(tmp, datap); |
303 | break; | 306 | break; |
304 | } | 307 | } |
305 | 308 | ||
306 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 309 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
307 | ret = -EIO; | 310 | ret = -EIO; |
308 | if ((addr & 3) || addr < 0) | 311 | if (addr & 3) |
309 | break; | 312 | break; |
310 | 313 | ||
311 | ret = 0; | 314 | switch (regno) { |
312 | switch (addr >> 2) { | ||
313 | case 0 ... PT__END - 1: | 315 | case 0 ... PT__END - 1: |
314 | ret = put_reg(child, addr >> 2, data); | 316 | ret = put_reg(child, regno, data); |
315 | break; | ||
316 | |||
317 | default: | ||
318 | ret = -EIO; | ||
319 | break; | 317 | break; |
320 | } | 318 | } |
321 | break; | 319 | break; |
@@ -324,25 +322,25 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
324 | return copy_regset_to_user(child, &user_frv_native_view, | 322 | return copy_regset_to_user(child, &user_frv_native_view, |
325 | REGSET_GENERAL, | 323 | REGSET_GENERAL, |
326 | 0, sizeof(child->thread.user->i), | 324 | 0, sizeof(child->thread.user->i), |
327 | (void __user *)data); | 325 | datap); |
328 | 326 | ||
329 | case PTRACE_SETREGS: /* Set all integer regs in the child. */ | 327 | case PTRACE_SETREGS: /* Set all integer regs in the child. */ |
330 | return copy_regset_from_user(child, &user_frv_native_view, | 328 | return copy_regset_from_user(child, &user_frv_native_view, |
331 | REGSET_GENERAL, | 329 | REGSET_GENERAL, |
332 | 0, sizeof(child->thread.user->i), | 330 | 0, sizeof(child->thread.user->i), |
333 | (const void __user *)data); | 331 | datap); |
334 | 332 | ||
335 | case PTRACE_GETFPREGS: /* Get the child FP/Media state. */ | 333 | case PTRACE_GETFPREGS: /* Get the child FP/Media state. */ |
336 | return copy_regset_to_user(child, &user_frv_native_view, | 334 | return copy_regset_to_user(child, &user_frv_native_view, |
337 | REGSET_FPMEDIA, | 335 | REGSET_FPMEDIA, |
338 | 0, sizeof(child->thread.user->f), | 336 | 0, sizeof(child->thread.user->f), |
339 | (void __user *)data); | 337 | datap); |
340 | 338 | ||
341 | case PTRACE_SETFPREGS: /* Set the child FP/Media state. */ | 339 | case PTRACE_SETFPREGS: /* Set the child FP/Media state. */ |
342 | return copy_regset_from_user(child, &user_frv_native_view, | 340 | return copy_regset_from_user(child, &user_frv_native_view, |
343 | REGSET_FPMEDIA, | 341 | REGSET_FPMEDIA, |
344 | 0, sizeof(child->thread.user->f), | 342 | 0, sizeof(child->thread.user->f), |
345 | (const void __user *)data); | 343 | datap); |
346 | 344 | ||
347 | default: | 345 | default: |
348 | ret = ptrace_request(child, request, addr, data); | 346 | ret = ptrace_request(child, request, addr, data); |
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c index 61088dcc1594..fd7fcd4c2e33 100644 --- a/arch/frv/mm/highmem.c +++ b/arch/frv/mm/highmem.c | |||
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(__kmap_atomic); | |||
68 | 68 | ||
69 | void __kunmap_atomic(void *kvaddr) | 69 | void __kunmap_atomic(void *kvaddr) |
70 | { | 70 | { |
71 | int type = kmap_atomic_idx_pop(); | 71 | int type = kmap_atomic_idx(); |
72 | switch (type) { | 72 | switch (type) { |
73 | case 0: __kunmap_atomic_primary(4, 6); break; | 73 | case 0: __kunmap_atomic_primary(4, 6); break; |
74 | case 1: __kunmap_atomic_primary(5, 7); break; | 74 | case 1: __kunmap_atomic_primary(5, 7); break; |
@@ -83,6 +83,7 @@ void __kunmap_atomic(void *kvaddr) | |||
83 | default: | 83 | default: |
84 | BUG(); | 84 | BUG(); |
85 | } | 85 | } |
86 | kmap_atomic_idx_pop(); | ||
86 | pagefault_enable(); | 87 | pagefault_enable(); |
87 | } | 88 | } |
88 | EXPORT_SYMBOL(__kunmap_atomic); | 89 | EXPORT_SYMBOL(__kunmap_atomic); |
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c index df114122ebdf..497fa89b5df4 100644 --- a/arch/h8300/kernel/ptrace.c +++ b/arch/h8300/kernel/ptrace.c | |||
@@ -50,27 +50,29 @@ void ptrace_disable(struct task_struct *child) | |||
50 | user_disable_single_step(child); | 50 | user_disable_single_step(child); |
51 | } | 51 | } |
52 | 52 | ||
53 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 53 | long arch_ptrace(struct task_struct *child, long request, |
54 | unsigned long addr, unsigned long data) | ||
54 | { | 55 | { |
55 | int ret; | 56 | int ret; |
57 | int regno = addr >> 2; | ||
58 | unsigned long __user *datap = (unsigned long __user *) data; | ||
56 | 59 | ||
57 | switch (request) { | 60 | switch (request) { |
58 | /* read the word at location addr in the USER area. */ | 61 | /* read the word at location addr in the USER area. */ |
59 | case PTRACE_PEEKUSR: { | 62 | case PTRACE_PEEKUSR: { |
60 | unsigned long tmp = 0; | 63 | unsigned long tmp = 0; |
61 | 64 | ||
62 | if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) { | 65 | if ((addr & 3) || addr >= sizeof(struct user)) { |
63 | ret = -EIO; | 66 | ret = -EIO; |
64 | break ; | 67 | break ; |
65 | } | 68 | } |
66 | 69 | ||
67 | ret = 0; /* Default return condition */ | 70 | ret = 0; /* Default return condition */ |
68 | addr = addr >> 2; /* temporary hack. */ | ||
69 | 71 | ||
70 | if (addr < H8300_REGS_NO) | 72 | if (regno < H8300_REGS_NO) |
71 | tmp = h8300_get_reg(child, addr); | 73 | tmp = h8300_get_reg(child, regno); |
72 | else { | 74 | else { |
73 | switch(addr) { | 75 | switch (regno) { |
74 | case 49: | 76 | case 49: |
75 | tmp = child->mm->start_code; | 77 | tmp = child->mm->start_code; |
76 | break ; | 78 | break ; |
@@ -88,24 +90,23 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
88 | } | 90 | } |
89 | } | 91 | } |
90 | if (!ret) | 92 | if (!ret) |
91 | ret = put_user(tmp,(unsigned long *) data); | 93 | ret = put_user(tmp, datap); |
92 | break ; | 94 | break ; |
93 | } | 95 | } |
94 | 96 | ||
95 | /* when I and D space are separate, this will have to be fixed. */ | 97 | /* when I and D space are separate, this will have to be fixed. */ |
96 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 98 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
97 | if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) { | 99 | if ((addr & 3) || addr >= sizeof(struct user)) { |
98 | ret = -EIO; | 100 | ret = -EIO; |
99 | break ; | 101 | break ; |
100 | } | 102 | } |
101 | addr = addr >> 2; /* temporary hack. */ | ||
102 | 103 | ||
103 | if (addr == PT_ORIG_ER0) { | 104 | if (regno == PT_ORIG_ER0) { |
104 | ret = -EIO; | 105 | ret = -EIO; |
105 | break ; | 106 | break ; |
106 | } | 107 | } |
107 | if (addr < H8300_REGS_NO) { | 108 | if (regno < H8300_REGS_NO) { |
108 | ret = h8300_put_reg(child, addr, data); | 109 | ret = h8300_put_reg(child, regno, data); |
109 | break ; | 110 | break ; |
110 | } | 111 | } |
111 | ret = -EIO; | 112 | ret = -EIO; |
@@ -116,11 +117,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
116 | unsigned long tmp; | 117 | unsigned long tmp; |
117 | for (i = 0; i < H8300_REGS_NO; i++) { | 118 | for (i = 0; i < H8300_REGS_NO; i++) { |
118 | tmp = h8300_get_reg(child, i); | 119 | tmp = h8300_get_reg(child, i); |
119 | if (put_user(tmp, (unsigned long *) data)) { | 120 | if (put_user(tmp, datap)) { |
120 | ret = -EFAULT; | 121 | ret = -EFAULT; |
121 | break; | 122 | break; |
122 | } | 123 | } |
123 | data += sizeof(long); | 124 | datap++; |
124 | } | 125 | } |
125 | ret = 0; | 126 | ret = 0; |
126 | break; | 127 | break; |
@@ -130,12 +131,12 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
130 | int i; | 131 | int i; |
131 | unsigned long tmp; | 132 | unsigned long tmp; |
132 | for (i = 0; i < H8300_REGS_NO; i++) { | 133 | for (i = 0; i < H8300_REGS_NO; i++) { |
133 | if (get_user(tmp, (unsigned long *) data)) { | 134 | if (get_user(tmp, datap)) { |
134 | ret = -EFAULT; | 135 | ret = -EFAULT; |
135 | break; | 136 | break; |
136 | } | 137 | } |
137 | h8300_put_reg(child, i, tmp); | 138 | h8300_put_reg(child, i, tmp); |
138 | data += sizeof(long); | 139 | datap++; |
139 | } | 140 | } |
140 | ret = 0; | 141 | ret = 0; |
141 | break; | 142 | break; |
diff --git a/arch/ia64/include/asm/cputime.h b/arch/ia64/include/asm/cputime.h index 7fa8a8594660..6073b187528a 100644 --- a/arch/ia64/include/asm/cputime.h +++ b/arch/ia64/include/asm/cputime.h | |||
@@ -56,10 +56,10 @@ typedef u64 cputime64_t; | |||
56 | #define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ)) | 56 | #define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ)) |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * Convert cputime <-> milliseconds | 59 | * Convert cputime <-> microseconds |
60 | */ | 60 | */ |
61 | #define cputime_to_msecs(__ct) ((__ct) / NSEC_PER_MSEC) | 61 | #define cputime_to_usecs(__ct) ((__ct) / NSEC_PER_USEC) |
62 | #define msecs_to_cputime(__msecs) ((__msecs) * NSEC_PER_MSEC) | 62 | #define usecs_to_cputime(__usecs) ((__usecs) * NSEC_PER_USEC) |
63 | 63 | ||
64 | /* | 64 | /* |
65 | * Convert cputime <-> seconds | 65 | * Convert cputime <-> seconds |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 7c7909f9bc93..8848f43d819e 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -1177,7 +1177,8 @@ ptrace_disable (struct task_struct *child) | |||
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | long | 1179 | long |
1180 | arch_ptrace (struct task_struct *child, long request, long addr, long data) | 1180 | arch_ptrace (struct task_struct *child, long request, |
1181 | unsigned long addr, unsigned long data) | ||
1181 | { | 1182 | { |
1182 | switch (request) { | 1183 | switch (request) { |
1183 | case PTRACE_PEEKTEXT: | 1184 | case PTRACE_PEEKTEXT: |
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index 0021ade4cba8..20743754f2b2 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -622,9 +622,11 @@ void ptrace_disable(struct task_struct *child) | |||
622 | } | 622 | } |
623 | 623 | ||
624 | long | 624 | long |
625 | arch_ptrace(struct task_struct *child, long request, long addr, long data) | 625 | arch_ptrace(struct task_struct *child, long request, |
626 | unsigned long addr, unsigned long data) | ||
626 | { | 627 | { |
627 | int ret; | 628 | int ret; |
629 | unsigned long __user *datap = (unsigned long __user *) data; | ||
628 | 630 | ||
629 | switch (request) { | 631 | switch (request) { |
630 | /* | 632 | /* |
@@ -639,8 +641,7 @@ arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
639 | * read the word at location addr in the USER area. | 641 | * read the word at location addr in the USER area. |
640 | */ | 642 | */ |
641 | case PTRACE_PEEKUSR: | 643 | case PTRACE_PEEKUSR: |
642 | ret = ptrace_read_user(child, addr, | 644 | ret = ptrace_read_user(child, addr, datap); |
643 | (unsigned long __user *)data); | ||
644 | break; | 645 | break; |
645 | 646 | ||
646 | /* | 647 | /* |
@@ -661,11 +662,11 @@ arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
661 | break; | 662 | break; |
662 | 663 | ||
663 | case PTRACE_GETREGS: | 664 | case PTRACE_GETREGS: |
664 | ret = ptrace_getregs(child, (void __user *)data); | 665 | ret = ptrace_getregs(child, datap); |
665 | break; | 666 | break; |
666 | 667 | ||
667 | case PTRACE_SETREGS: | 668 | case PTRACE_SETREGS: |
668 | ret = ptrace_setregs(child, (void __user *)data); | 669 | ret = ptrace_setregs(child, datap); |
669 | break; | 670 | break; |
670 | 671 | ||
671 | default: | 672 | default: |
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index 616e59752c29..0b252683cefb 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c | |||
@@ -156,55 +156,57 @@ void user_disable_single_step(struct task_struct *child) | |||
156 | singlestep_disable(child); | 156 | singlestep_disable(child); |
157 | } | 157 | } |
158 | 158 | ||
159 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 159 | long arch_ptrace(struct task_struct *child, long request, |
160 | unsigned long addr, unsigned long data) | ||
160 | { | 161 | { |
161 | unsigned long tmp; | 162 | unsigned long tmp; |
162 | int i, ret = 0; | 163 | int i, ret = 0; |
164 | int regno = addr >> 2; /* temporary hack. */ | ||
165 | unsigned long __user *datap = (unsigned long __user *) data; | ||
163 | 166 | ||
164 | switch (request) { | 167 | switch (request) { |
165 | /* read the word at location addr in the USER area. */ | 168 | /* read the word at location addr in the USER area. */ |
166 | case PTRACE_PEEKUSR: | 169 | case PTRACE_PEEKUSR: |
167 | if (addr & 3) | 170 | if (addr & 3) |
168 | goto out_eio; | 171 | goto out_eio; |
169 | addr >>= 2; /* temporary hack. */ | ||
170 | 172 | ||
171 | if (addr >= 0 && addr < 19) { | 173 | if (regno >= 0 && regno < 19) { |
172 | tmp = get_reg(child, addr); | 174 | tmp = get_reg(child, regno); |
173 | } else if (addr >= 21 && addr < 49) { | 175 | } else if (regno >= 21 && regno < 49) { |
174 | tmp = child->thread.fp[addr - 21]; | 176 | tmp = child->thread.fp[regno - 21]; |
175 | /* Convert internal fpu reg representation | 177 | /* Convert internal fpu reg representation |
176 | * into long double format | 178 | * into long double format |
177 | */ | 179 | */ |
178 | if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) | 180 | if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) |
179 | tmp = ((tmp & 0xffff0000) << 15) | | 181 | tmp = ((tmp & 0xffff0000) << 15) | |
180 | ((tmp & 0x0000ffff) << 16); | 182 | ((tmp & 0x0000ffff) << 16); |
181 | } else | 183 | } else |
182 | goto out_eio; | 184 | goto out_eio; |
183 | ret = put_user(tmp, (unsigned long *)data); | 185 | ret = put_user(tmp, datap); |
184 | break; | 186 | break; |
185 | 187 | ||
186 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 188 | case PTRACE_POKEUSR: |
189 | /* write the word at location addr in the USER area */ | ||
187 | if (addr & 3) | 190 | if (addr & 3) |
188 | goto out_eio; | 191 | goto out_eio; |
189 | addr >>= 2; /* temporary hack. */ | ||
190 | 192 | ||
191 | if (addr == PT_SR) { | 193 | if (regno == PT_SR) { |
192 | data &= SR_MASK; | 194 | data &= SR_MASK; |
193 | data |= get_reg(child, PT_SR) & ~SR_MASK; | 195 | data |= get_reg(child, PT_SR) & ~SR_MASK; |
194 | } | 196 | } |
195 | if (addr >= 0 && addr < 19) { | 197 | if (regno >= 0 && regno < 19) { |
196 | if (put_reg(child, addr, data)) | 198 | if (put_reg(child, regno, data)) |
197 | goto out_eio; | 199 | goto out_eio; |
198 | } else if (addr >= 21 && addr < 48) { | 200 | } else if (regno >= 21 && regno < 48) { |
199 | /* Convert long double format | 201 | /* Convert long double format |
200 | * into internal fpu reg representation | 202 | * into internal fpu reg representation |
201 | */ | 203 | */ |
202 | if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) { | 204 | if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) { |
203 | data = (unsigned long)data << 15; | 205 | data <<= 15; |
204 | data = (data & 0xffff0000) | | 206 | data = (data & 0xffff0000) | |
205 | ((data & 0x0000ffff) >> 1); | 207 | ((data & 0x0000ffff) >> 1); |
206 | } | 208 | } |
207 | child->thread.fp[addr - 21] = data; | 209 | child->thread.fp[regno - 21] = data; |
208 | } else | 210 | } else |
209 | goto out_eio; | 211 | goto out_eio; |
210 | break; | 212 | break; |
@@ -212,16 +214,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
212 | case PTRACE_GETREGS: /* Get all gp regs from the child. */ | 214 | case PTRACE_GETREGS: /* Get all gp regs from the child. */ |
213 | for (i = 0; i < 19; i++) { | 215 | for (i = 0; i < 19; i++) { |
214 | tmp = get_reg(child, i); | 216 | tmp = get_reg(child, i); |
215 | ret = put_user(tmp, (unsigned long *)data); | 217 | ret = put_user(tmp, datap); |
216 | if (ret) | 218 | if (ret) |
217 | break; | 219 | break; |
218 | data += sizeof(long); | 220 | datap++; |
219 | } | 221 | } |
220 | break; | 222 | break; |
221 | 223 | ||
222 | case PTRACE_SETREGS: /* Set all gp regs in the child. */ | 224 | case PTRACE_SETREGS: /* Set all gp regs in the child. */ |
223 | for (i = 0; i < 19; i++) { | 225 | for (i = 0; i < 19; i++) { |
224 | ret = get_user(tmp, (unsigned long *)data); | 226 | ret = get_user(tmp, datap); |
225 | if (ret) | 227 | if (ret) |
226 | break; | 228 | break; |
227 | if (i == PT_SR) { | 229 | if (i == PT_SR) { |
@@ -229,25 +231,24 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
229 | tmp |= get_reg(child, PT_SR) & ~SR_MASK; | 231 | tmp |= get_reg(child, PT_SR) & ~SR_MASK; |
230 | } | 232 | } |
231 | put_reg(child, i, tmp); | 233 | put_reg(child, i, tmp); |
232 | data += sizeof(long); | 234 | datap++; |
233 | } | 235 | } |
234 | break; | 236 | break; |
235 | 237 | ||
236 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ | 238 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ |
237 | if (copy_to_user((void *)data, &child->thread.fp, | 239 | if (copy_to_user(datap, &child->thread.fp, |
238 | sizeof(struct user_m68kfp_struct))) | 240 | sizeof(struct user_m68kfp_struct))) |
239 | ret = -EFAULT; | 241 | ret = -EFAULT; |
240 | break; | 242 | break; |
241 | 243 | ||
242 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ | 244 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ |
243 | if (copy_from_user(&child->thread.fp, (void *)data, | 245 | if (copy_from_user(&child->thread.fp, datap, |
244 | sizeof(struct user_m68kfp_struct))) | 246 | sizeof(struct user_m68kfp_struct))) |
245 | ret = -EFAULT; | 247 | ret = -EFAULT; |
246 | break; | 248 | break; |
247 | 249 | ||
248 | case PTRACE_GET_THREAD_AREA: | 250 | case PTRACE_GET_THREAD_AREA: |
249 | ret = put_user(task_thread_info(child)->tp_value, | 251 | ret = put_user(task_thread_info(child)->tp_value, datap); |
250 | (unsigned long __user *)data); | ||
251 | break; | 252 | break; |
252 | 253 | ||
253 | default: | 254 | default: |
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c index 6fe7c38cd556..6709fb707335 100644 --- a/arch/m68knommu/kernel/ptrace.c +++ b/arch/m68knommu/kernel/ptrace.c | |||
@@ -112,9 +112,12 @@ void ptrace_disable(struct task_struct *child) | |||
112 | user_disable_single_step(child); | 112 | user_disable_single_step(child); |
113 | } | 113 | } |
114 | 114 | ||
115 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 115 | long arch_ptrace(struct task_struct *child, long request, |
116 | unsigned long addr, unsigned long data) | ||
116 | { | 117 | { |
117 | int ret; | 118 | int ret; |
119 | int regno = addr >> 2; | ||
120 | unsigned long __user *datap = (unsigned long __user *) data; | ||
118 | 121 | ||
119 | switch (request) { | 122 | switch (request) { |
120 | /* read the word at location addr in the USER area. */ | 123 | /* read the word at location addr in the USER area. */ |
@@ -122,53 +125,48 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
122 | unsigned long tmp; | 125 | unsigned long tmp; |
123 | 126 | ||
124 | ret = -EIO; | 127 | ret = -EIO; |
125 | if ((addr & 3) || addr < 0 || | 128 | if ((addr & 3) || addr > sizeof(struct user) - 3) |
126 | addr > sizeof(struct user) - 3) | ||
127 | break; | 129 | break; |
128 | 130 | ||
129 | tmp = 0; /* Default return condition */ | 131 | tmp = 0; /* Default return condition */ |
130 | addr = addr >> 2; /* temporary hack. */ | ||
131 | ret = -EIO; | 132 | ret = -EIO; |
132 | if (addr < 19) { | 133 | if (regno < 19) { |
133 | tmp = get_reg(child, addr); | 134 | tmp = get_reg(child, regno); |
134 | if (addr == PT_SR) | 135 | if (regno == PT_SR) |
135 | tmp >>= 16; | 136 | tmp >>= 16; |
136 | } else if (addr >= 21 && addr < 49) { | 137 | } else if (regno >= 21 && regno < 49) { |
137 | tmp = child->thread.fp[addr - 21]; | 138 | tmp = child->thread.fp[regno - 21]; |
138 | } else if (addr == 49) { | 139 | } else if (regno == 49) { |
139 | tmp = child->mm->start_code; | 140 | tmp = child->mm->start_code; |
140 | } else if (addr == 50) { | 141 | } else if (regno == 50) { |
141 | tmp = child->mm->start_data; | 142 | tmp = child->mm->start_data; |
142 | } else if (addr == 51) { | 143 | } else if (regno == 51) { |
143 | tmp = child->mm->end_code; | 144 | tmp = child->mm->end_code; |
144 | } else | 145 | } else |
145 | break; | 146 | break; |
146 | ret = put_user(tmp,(unsigned long *) data); | 147 | ret = put_user(tmp, datap); |
147 | break; | 148 | break; |
148 | } | 149 | } |
149 | 150 | ||
150 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 151 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
151 | ret = -EIO; | 152 | ret = -EIO; |
152 | if ((addr & 3) || addr < 0 || | 153 | if ((addr & 3) || addr > sizeof(struct user) - 3) |
153 | addr > sizeof(struct user) - 3) | ||
154 | break; | 154 | break; |
155 | 155 | ||
156 | addr = addr >> 2; /* temporary hack. */ | 156 | if (regno == PT_SR) { |
157 | |||
158 | if (addr == PT_SR) { | ||
159 | data &= SR_MASK; | 157 | data &= SR_MASK; |
160 | data <<= 16; | 158 | data <<= 16; |
161 | data |= get_reg(child, PT_SR) & ~(SR_MASK << 16); | 159 | data |= get_reg(child, PT_SR) & ~(SR_MASK << 16); |
162 | } | 160 | } |
163 | if (addr < 19) { | 161 | if (regno < 19) { |
164 | if (put_reg(child, addr, data)) | 162 | if (put_reg(child, regno, data)) |
165 | break; | 163 | break; |
166 | ret = 0; | 164 | ret = 0; |
167 | break; | 165 | break; |
168 | } | 166 | } |
169 | if (addr >= 21 && addr < 48) | 167 | if (regno >= 21 && regno < 48) |
170 | { | 168 | { |
171 | child->thread.fp[addr - 21] = data; | 169 | child->thread.fp[regno - 21] = data; |
172 | ret = 0; | 170 | ret = 0; |
173 | } | 171 | } |
174 | break; | 172 | break; |
@@ -180,11 +178,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
180 | tmp = get_reg(child, i); | 178 | tmp = get_reg(child, i); |
181 | if (i == PT_SR) | 179 | if (i == PT_SR) |
182 | tmp >>= 16; | 180 | tmp >>= 16; |
183 | if (put_user(tmp, (unsigned long *) data)) { | 181 | if (put_user(tmp, datap)) { |
184 | ret = -EFAULT; | 182 | ret = -EFAULT; |
185 | break; | 183 | break; |
186 | } | 184 | } |
187 | data += sizeof(long); | 185 | datap++; |
188 | } | 186 | } |
189 | ret = 0; | 187 | ret = 0; |
190 | break; | 188 | break; |
@@ -194,7 +192,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
194 | int i; | 192 | int i; |
195 | unsigned long tmp; | 193 | unsigned long tmp; |
196 | for (i = 0; i < 19; i++) { | 194 | for (i = 0; i < 19; i++) { |
197 | if (get_user(tmp, (unsigned long *) data)) { | 195 | if (get_user(tmp, datap)) { |
198 | ret = -EFAULT; | 196 | ret = -EFAULT; |
199 | break; | 197 | break; |
200 | } | 198 | } |
@@ -204,7 +202,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
204 | tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16); | 202 | tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16); |
205 | } | 203 | } |
206 | put_reg(child, i, tmp); | 204 | put_reg(child, i, tmp); |
207 | data += sizeof(long); | 205 | datap++; |
208 | } | 206 | } |
209 | ret = 0; | 207 | ret = 0; |
210 | break; | 208 | break; |
@@ -213,7 +211,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
213 | #ifdef PTRACE_GETFPREGS | 211 | #ifdef PTRACE_GETFPREGS |
214 | case PTRACE_GETFPREGS: { /* Get the child FPU state. */ | 212 | case PTRACE_GETFPREGS: { /* Get the child FPU state. */ |
215 | ret = 0; | 213 | ret = 0; |
216 | if (copy_to_user((void *)data, &child->thread.fp, | 214 | if (copy_to_user(datap, &child->thread.fp, |
217 | sizeof(struct user_m68kfp_struct))) | 215 | sizeof(struct user_m68kfp_struct))) |
218 | ret = -EFAULT; | 216 | ret = -EFAULT; |
219 | break; | 217 | break; |
@@ -223,7 +221,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
223 | #ifdef PTRACE_SETFPREGS | 221 | #ifdef PTRACE_SETFPREGS |
224 | case PTRACE_SETFPREGS: { /* Set the child FPU state. */ | 222 | case PTRACE_SETFPREGS: { /* Set the child FPU state. */ |
225 | ret = 0; | 223 | ret = 0; |
226 | if (copy_from_user(&child->thread.fp, (void *)data, | 224 | if (copy_from_user(&child->thread.fp, datap, |
227 | sizeof(struct user_m68kfp_struct))) | 225 | sizeof(struct user_m68kfp_struct))) |
228 | ret = -EFAULT; | 226 | ret = -EFAULT; |
229 | break; | 227 | break; |
@@ -231,8 +229,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
231 | #endif | 229 | #endif |
232 | 230 | ||
233 | case PTRACE_GET_THREAD_AREA: | 231 | case PTRACE_GET_THREAD_AREA: |
234 | ret = put_user(task_thread_info(child)->tp_value, | 232 | ret = put_user(task_thread_info(child)->tp_value, datap); |
235 | (unsigned long __user *)data); | ||
236 | break; | 233 | break; |
237 | 234 | ||
238 | default: | 235 | default: |
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c index dc03ffc8174a..05ac8cc975d5 100644 --- a/arch/microblaze/kernel/ptrace.c +++ b/arch/microblaze/kernel/ptrace.c | |||
@@ -73,7 +73,8 @@ static microblaze_reg_t *reg_save_addr(unsigned reg_offs, | |||
73 | return (microblaze_reg_t *)((char *)regs + reg_offs); | 73 | return (microblaze_reg_t *)((char *)regs + reg_offs); |
74 | } | 74 | } |
75 | 75 | ||
76 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 76 | long arch_ptrace(struct task_struct *child, long request, |
77 | unsigned long addr, unsigned long data) | ||
77 | { | 78 | { |
78 | int rval; | 79 | int rval; |
79 | unsigned long val = 0; | 80 | unsigned long val = 0; |
@@ -99,7 +100,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
99 | } else { | 100 | } else { |
100 | rval = -EIO; | 101 | rval = -EIO; |
101 | } | 102 | } |
102 | } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) { | 103 | } else if (addr < PT_SIZE && (addr & 0x3) == 0) { |
103 | microblaze_reg_t *reg_addr = reg_save_addr(addr, child); | 104 | microblaze_reg_t *reg_addr = reg_save_addr(addr, child); |
104 | if (request == PTRACE_PEEKUSR) | 105 | if (request == PTRACE_PEEKUSR) |
105 | val = *reg_addr; | 106 | val = *reg_addr; |
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h index 5f4b9d4e4114..f1f508e4f971 100644 --- a/arch/mips/include/asm/pci/bridge.h +++ b/arch/mips/include/asm/pci/bridge.h | |||
@@ -839,7 +839,7 @@ struct bridge_controller { | |||
839 | nasid_t nasid; | 839 | nasid_t nasid; |
840 | unsigned int widget_id; | 840 | unsigned int widget_id; |
841 | unsigned int irq_cpu; | 841 | unsigned int irq_cpu; |
842 | dma64_addr_t baddr; | 842 | u64 baddr; |
843 | unsigned int pci_int[8]; | 843 | unsigned int pci_int[8]; |
844 | }; | 844 | }; |
845 | 845 | ||
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index c8777333e198..d21c388c0116 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -255,9 +255,13 @@ int ptrace_set_watch_regs(struct task_struct *child, | |||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 258 | long arch_ptrace(struct task_struct *child, long request, |
259 | unsigned long addr, unsigned long data) | ||
259 | { | 260 | { |
260 | int ret; | 261 | int ret; |
262 | void __user *addrp = (void __user *) addr; | ||
263 | void __user *datavp = (void __user *) data; | ||
264 | unsigned long __user *datalp = (void __user *) data; | ||
261 | 265 | ||
262 | switch (request) { | 266 | switch (request) { |
263 | /* when I and D space are separate, these will need to be fixed. */ | 267 | /* when I and D space are separate, these will need to be fixed. */ |
@@ -386,7 +390,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
386 | ret = -EIO; | 390 | ret = -EIO; |
387 | goto out; | 391 | goto out; |
388 | } | 392 | } |
389 | ret = put_user(tmp, (unsigned long __user *) data); | 393 | ret = put_user(tmp, datalp); |
390 | break; | 394 | break; |
391 | } | 395 | } |
392 | 396 | ||
@@ -478,34 +482,31 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
478 | } | 482 | } |
479 | 483 | ||
480 | case PTRACE_GETREGS: | 484 | case PTRACE_GETREGS: |
481 | ret = ptrace_getregs(child, (__s64 __user *) data); | 485 | ret = ptrace_getregs(child, datavp); |
482 | break; | 486 | break; |
483 | 487 | ||
484 | case PTRACE_SETREGS: | 488 | case PTRACE_SETREGS: |
485 | ret = ptrace_setregs(child, (__s64 __user *) data); | 489 | ret = ptrace_setregs(child, datavp); |
486 | break; | 490 | break; |
487 | 491 | ||
488 | case PTRACE_GETFPREGS: | 492 | case PTRACE_GETFPREGS: |
489 | ret = ptrace_getfpregs(child, (__u32 __user *) data); | 493 | ret = ptrace_getfpregs(child, datavp); |
490 | break; | 494 | break; |
491 | 495 | ||
492 | case PTRACE_SETFPREGS: | 496 | case PTRACE_SETFPREGS: |
493 | ret = ptrace_setfpregs(child, (__u32 __user *) data); | 497 | ret = ptrace_setfpregs(child, datavp); |
494 | break; | 498 | break; |
495 | 499 | ||
496 | case PTRACE_GET_THREAD_AREA: | 500 | case PTRACE_GET_THREAD_AREA: |
497 | ret = put_user(task_thread_info(child)->tp_value, | 501 | ret = put_user(task_thread_info(child)->tp_value, datalp); |
498 | (unsigned long __user *) data); | ||
499 | break; | 502 | break; |
500 | 503 | ||
501 | case PTRACE_GET_WATCH_REGS: | 504 | case PTRACE_GET_WATCH_REGS: |
502 | ret = ptrace_get_watch_regs(child, | 505 | ret = ptrace_get_watch_regs(child, addrp); |
503 | (struct pt_watch_regs __user *) addr); | ||
504 | break; | 506 | break; |
505 | 507 | ||
506 | case PTRACE_SET_WATCH_REGS: | 508 | case PTRACE_SET_WATCH_REGS: |
507 | ret = ptrace_set_watch_regs(child, | 509 | ret = ptrace_set_watch_regs(child, addrp); |
508 | (struct pt_watch_regs __user *) addr); | ||
509 | break; | 510 | break; |
510 | 511 | ||
511 | default: | 512 | default: |
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 1e69b1fb4b85..3634c7ea06ac 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c | |||
@@ -74,7 +74,7 @@ void __kunmap_atomic(void *kvaddr) | |||
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | 76 | ||
77 | type = kmap_atomic_idx_pop(); | 77 | type = kmap_atomic_idx(); |
78 | #ifdef CONFIG_DEBUG_HIGHMEM | 78 | #ifdef CONFIG_DEBUG_HIGHMEM |
79 | { | 79 | { |
80 | int idx = type + KM_TYPE_NR * smp_processor_id(); | 80 | int idx = type + KM_TYPE_NR * smp_processor_id(); |
@@ -89,6 +89,7 @@ void __kunmap_atomic(void *kvaddr) | |||
89 | local_flush_tlb_one(vaddr); | 89 | local_flush_tlb_one(vaddr); |
90 | } | 90 | } |
91 | #endif | 91 | #endif |
92 | kmap_atomic_idx_pop(); | ||
92 | pagefault_enable(); | 93 | pagefault_enable(); |
93 | } | 94 | } |
94 | EXPORT_SYMBOL(__kunmap_atomic); | 95 | EXPORT_SYMBOL(__kunmap_atomic); |
diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h index f577ba2268ca..e2155e686451 100644 --- a/arch/mn10300/include/asm/highmem.h +++ b/arch/mn10300/include/asm/highmem.h | |||
@@ -101,7 +101,7 @@ static inline void __kunmap_atomic(unsigned long vaddr) | |||
101 | return; | 101 | return; |
102 | } | 102 | } |
103 | 103 | ||
104 | type = kmap_atomic_idx_pop(); | 104 | type = kmap_atomic_idx(); |
105 | 105 | ||
106 | #if HIGHMEM_DEBUG | 106 | #if HIGHMEM_DEBUG |
107 | { | 107 | { |
@@ -119,6 +119,8 @@ static inline void __kunmap_atomic(unsigned long vaddr) | |||
119 | __flush_tlb_one(vaddr); | 119 | __flush_tlb_one(vaddr); |
120 | } | 120 | } |
121 | #endif | 121 | #endif |
122 | |||
123 | kmap_atomic_idx_pop(); | ||
122 | pagefault_enable(); | 124 | pagefault_enable(); |
123 | } | 125 | } |
124 | #endif /* __KERNEL__ */ | 126 | #endif /* __KERNEL__ */ |
diff --git a/arch/mn10300/kernel/ptrace.c b/arch/mn10300/kernel/ptrace.c index cf847dabc1bd..5c0b07e61006 100644 --- a/arch/mn10300/kernel/ptrace.c +++ b/arch/mn10300/kernel/ptrace.c | |||
@@ -295,31 +295,31 @@ void ptrace_disable(struct task_struct *child) | |||
295 | /* | 295 | /* |
296 | * handle the arch-specific side of process tracing | 296 | * handle the arch-specific side of process tracing |
297 | */ | 297 | */ |
298 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 298 | long arch_ptrace(struct task_struct *child, long request, |
299 | unsigned long addr, unsigned long data) | ||
299 | { | 300 | { |
300 | unsigned long tmp; | 301 | unsigned long tmp; |
301 | int ret; | 302 | int ret; |
303 | unsigned long __user *datap = (unsigned long __user *) data; | ||
302 | 304 | ||
303 | switch (request) { | 305 | switch (request) { |
304 | /* read the word at location addr in the USER area. */ | 306 | /* read the word at location addr in the USER area. */ |
305 | case PTRACE_PEEKUSR: | 307 | case PTRACE_PEEKUSR: |
306 | ret = -EIO; | 308 | ret = -EIO; |
307 | if ((addr & 3) || addr < 0 || | 309 | if ((addr & 3) || addr > sizeof(struct user) - 3) |
308 | addr > sizeof(struct user) - 3) | ||
309 | break; | 310 | break; |
310 | 311 | ||
311 | tmp = 0; /* Default return condition */ | 312 | tmp = 0; /* Default return condition */ |
312 | if (addr < NR_PTREGS << 2) | 313 | if (addr < NR_PTREGS << 2) |
313 | tmp = get_stack_long(child, | 314 | tmp = get_stack_long(child, |
314 | ptrace_regid_to_frame[addr]); | 315 | ptrace_regid_to_frame[addr]); |
315 | ret = put_user(tmp, (unsigned long *) data); | 316 | ret = put_user(tmp, datap); |
316 | break; | 317 | break; |
317 | 318 | ||
318 | /* write the word at location addr in the USER area */ | 319 | /* write the word at location addr in the USER area */ |
319 | case PTRACE_POKEUSR: | 320 | case PTRACE_POKEUSR: |
320 | ret = -EIO; | 321 | ret = -EIO; |
321 | if ((addr & 3) || addr < 0 || | 322 | if ((addr & 3) || addr > sizeof(struct user) - 3) |
322 | addr > sizeof(struct user) - 3) | ||
323 | break; | 323 | break; |
324 | 324 | ||
325 | ret = 0; | 325 | ret = 0; |
@@ -332,25 +332,25 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
332 | return copy_regset_to_user(child, &user_mn10300_native_view, | 332 | return copy_regset_to_user(child, &user_mn10300_native_view, |
333 | REGSET_GENERAL, | 333 | REGSET_GENERAL, |
334 | 0, NR_PTREGS * sizeof(long), | 334 | 0, NR_PTREGS * sizeof(long), |
335 | (void __user *)data); | 335 | datap); |
336 | 336 | ||
337 | case PTRACE_SETREGS: /* Set all integer regs in the child. */ | 337 | case PTRACE_SETREGS: /* Set all integer regs in the child. */ |
338 | return copy_regset_from_user(child, &user_mn10300_native_view, | 338 | return copy_regset_from_user(child, &user_mn10300_native_view, |
339 | REGSET_GENERAL, | 339 | REGSET_GENERAL, |
340 | 0, NR_PTREGS * sizeof(long), | 340 | 0, NR_PTREGS * sizeof(long), |
341 | (const void __user *)data); | 341 | datap); |
342 | 342 | ||
343 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ | 343 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ |
344 | return copy_regset_to_user(child, &user_mn10300_native_view, | 344 | return copy_regset_to_user(child, &user_mn10300_native_view, |
345 | REGSET_FPU, | 345 | REGSET_FPU, |
346 | 0, sizeof(struct fpu_state_struct), | 346 | 0, sizeof(struct fpu_state_struct), |
347 | (void __user *)data); | 347 | datap); |
348 | 348 | ||
349 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ | 349 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ |
350 | return copy_regset_from_user(child, &user_mn10300_native_view, | 350 | return copy_regset_from_user(child, &user_mn10300_native_view, |
351 | REGSET_FPU, | 351 | REGSET_FPU, |
352 | 0, sizeof(struct fpu_state_struct), | 352 | 0, sizeof(struct fpu_state_struct), |
353 | (const void __user *)data); | 353 | datap); |
354 | 354 | ||
355 | default: | 355 | default: |
356 | ret = ptrace_request(child, request, addr, data); | 356 | ret = ptrace_request(child, request, addr, data); |
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index c4f49e45129d..2905b1f52d30 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c | |||
@@ -110,7 +110,8 @@ void user_enable_block_step(struct task_struct *task) | |||
110 | pa_psw(task)->l = 0; | 110 | pa_psw(task)->l = 0; |
111 | } | 111 | } |
112 | 112 | ||
113 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 113 | long arch_ptrace(struct task_struct *child, long request, |
114 | unsigned long addr, unsigned long data) | ||
114 | { | 115 | { |
115 | unsigned long tmp; | 116 | unsigned long tmp; |
116 | long ret = -EIO; | 117 | long ret = -EIO; |
@@ -120,11 +121,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
120 | /* Read the word at location addr in the USER area. For ptraced | 121 | /* Read the word at location addr in the USER area. For ptraced |
121 | processes, the kernel saves all regs on a syscall. */ | 122 | processes, the kernel saves all regs on a syscall. */ |
122 | case PTRACE_PEEKUSR: | 123 | case PTRACE_PEEKUSR: |
123 | if ((addr & (sizeof(long)-1)) || | 124 | if ((addr & (sizeof(unsigned long)-1)) || |
124 | (unsigned long) addr >= sizeof(struct pt_regs)) | 125 | addr >= sizeof(struct pt_regs)) |
125 | break; | 126 | break; |
126 | tmp = *(unsigned long *) ((char *) task_regs(child) + addr); | 127 | tmp = *(unsigned long *) ((char *) task_regs(child) + addr); |
127 | ret = put_user(tmp, (unsigned long *) data); | 128 | ret = put_user(tmp, (unsigned long __user *) data); |
128 | break; | 129 | break; |
129 | 130 | ||
130 | /* Write the word at location addr in the USER area. This will need | 131 | /* Write the word at location addr in the USER area. This will need |
@@ -151,8 +152,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
151 | break; | 152 | break; |
152 | } | 153 | } |
153 | 154 | ||
154 | if ((addr & (sizeof(long)-1)) || | 155 | if ((addr & (sizeof(unsigned long)-1)) || |
155 | (unsigned long) addr >= sizeof(struct pt_regs)) | 156 | addr >= sizeof(struct pt_regs)) |
156 | break; | 157 | break; |
157 | if ((addr >= PT_GR1 && addr <= PT_GR31) || | 158 | if ((addr >= PT_GR1 && addr <= PT_GR31) || |
158 | addr == PT_IAOQ0 || addr == PT_IAOQ1 || | 159 | addr == PT_IAOQ0 || addr == PT_IAOQ1 || |
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index 8bdc6a9e5773..1cf20bdfbeca 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h | |||
@@ -124,23 +124,23 @@ static inline u64 cputime64_to_jiffies64(const cputime_t ct) | |||
124 | } | 124 | } |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Convert cputime <-> milliseconds | 127 | * Convert cputime <-> microseconds |
128 | */ | 128 | */ |
129 | extern u64 __cputime_msec_factor; | 129 | extern u64 __cputime_msec_factor; |
130 | 130 | ||
131 | static inline unsigned long cputime_to_msecs(const cputime_t ct) | 131 | static inline unsigned long cputime_to_usecs(const cputime_t ct) |
132 | { | 132 | { |
133 | return mulhdu(ct, __cputime_msec_factor); | 133 | return mulhdu(ct, __cputime_msec_factor) * USEC_PER_MSEC; |
134 | } | 134 | } |
135 | 135 | ||
136 | static inline cputime_t msecs_to_cputime(const unsigned long ms) | 136 | static inline cputime_t usecs_to_cputime(const unsigned long us) |
137 | { | 137 | { |
138 | cputime_t ct; | 138 | cputime_t ct; |
139 | unsigned long sec; | 139 | unsigned long sec; |
140 | 140 | ||
141 | /* have to be a little careful about overflow */ | 141 | /* have to be a little careful about overflow */ |
142 | ct = ms % 1000; | 142 | ct = us % 1000000; |
143 | sec = ms / 1000; | 143 | sec = us / 1000000; |
144 | if (ct) { | 144 | if (ct) { |
145 | ct *= tb_ticks_per_sec; | 145 | ct *= tb_ticks_per_sec; |
146 | do_div(ct, 1000); | 146 | do_div(ct, 1000); |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 286d9783d93f..a9b32967cff6 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -1406,37 +1406,42 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data) | |||
1406 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, | 1406 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, |
1407 | * we mark them as obsolete now, they will be removed in a future version | 1407 | * we mark them as obsolete now, they will be removed in a future version |
1408 | */ | 1408 | */ |
1409 | static long arch_ptrace_old(struct task_struct *child, long request, long addr, | 1409 | static long arch_ptrace_old(struct task_struct *child, long request, |
1410 | long data) | 1410 | unsigned long addr, unsigned long data) |
1411 | { | 1411 | { |
1412 | void __user *datavp = (void __user *) data; | ||
1413 | |||
1412 | switch (request) { | 1414 | switch (request) { |
1413 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ | 1415 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ |
1414 | return copy_regset_to_user(child, &user_ppc_native_view, | 1416 | return copy_regset_to_user(child, &user_ppc_native_view, |
1415 | REGSET_GPR, 0, 32 * sizeof(long), | 1417 | REGSET_GPR, 0, 32 * sizeof(long), |
1416 | (void __user *) data); | 1418 | datavp); |
1417 | 1419 | ||
1418 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ | 1420 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ |
1419 | return copy_regset_from_user(child, &user_ppc_native_view, | 1421 | return copy_regset_from_user(child, &user_ppc_native_view, |
1420 | REGSET_GPR, 0, 32 * sizeof(long), | 1422 | REGSET_GPR, 0, 32 * sizeof(long), |
1421 | (const void __user *) data); | 1423 | datavp); |
1422 | 1424 | ||
1423 | case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */ | 1425 | case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */ |
1424 | return copy_regset_to_user(child, &user_ppc_native_view, | 1426 | return copy_regset_to_user(child, &user_ppc_native_view, |
1425 | REGSET_FPR, 0, 32 * sizeof(double), | 1427 | REGSET_FPR, 0, 32 * sizeof(double), |
1426 | (void __user *) data); | 1428 | datavp); |
1427 | 1429 | ||
1428 | case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */ | 1430 | case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */ |
1429 | return copy_regset_from_user(child, &user_ppc_native_view, | 1431 | return copy_regset_from_user(child, &user_ppc_native_view, |
1430 | REGSET_FPR, 0, 32 * sizeof(double), | 1432 | REGSET_FPR, 0, 32 * sizeof(double), |
1431 | (const void __user *) data); | 1433 | datavp); |
1432 | } | 1434 | } |
1433 | 1435 | ||
1434 | return -EPERM; | 1436 | return -EPERM; |
1435 | } | 1437 | } |
1436 | 1438 | ||
1437 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 1439 | long arch_ptrace(struct task_struct *child, long request, |
1440 | unsigned long addr, unsigned long data) | ||
1438 | { | 1441 | { |
1439 | int ret = -EPERM; | 1442 | int ret = -EPERM; |
1443 | void __user *datavp = (void __user *) data; | ||
1444 | unsigned long __user *datalp = datavp; | ||
1440 | 1445 | ||
1441 | switch (request) { | 1446 | switch (request) { |
1442 | /* read the word at location addr in the USER area. */ | 1447 | /* read the word at location addr in the USER area. */ |
@@ -1446,11 +1451,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1446 | ret = -EIO; | 1451 | ret = -EIO; |
1447 | /* convert to index and check */ | 1452 | /* convert to index and check */ |
1448 | #ifdef CONFIG_PPC32 | 1453 | #ifdef CONFIG_PPC32 |
1449 | index = (unsigned long) addr >> 2; | 1454 | index = addr >> 2; |
1450 | if ((addr & 3) || (index > PT_FPSCR) | 1455 | if ((addr & 3) || (index > PT_FPSCR) |
1451 | || (child->thread.regs == NULL)) | 1456 | || (child->thread.regs == NULL)) |
1452 | #else | 1457 | #else |
1453 | index = (unsigned long) addr >> 3; | 1458 | index = addr >> 3; |
1454 | if ((addr & 7) || (index > PT_FPSCR)) | 1459 | if ((addr & 7) || (index > PT_FPSCR)) |
1455 | #endif | 1460 | #endif |
1456 | break; | 1461 | break; |
@@ -1463,7 +1468,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1463 | tmp = ((unsigned long *)child->thread.fpr) | 1468 | tmp = ((unsigned long *)child->thread.fpr) |
1464 | [TS_FPRWIDTH * (index - PT_FPR0)]; | 1469 | [TS_FPRWIDTH * (index - PT_FPR0)]; |
1465 | } | 1470 | } |
1466 | ret = put_user(tmp,(unsigned long __user *) data); | 1471 | ret = put_user(tmp, datalp); |
1467 | break; | 1472 | break; |
1468 | } | 1473 | } |
1469 | 1474 | ||
@@ -1474,11 +1479,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1474 | ret = -EIO; | 1479 | ret = -EIO; |
1475 | /* convert to index and check */ | 1480 | /* convert to index and check */ |
1476 | #ifdef CONFIG_PPC32 | 1481 | #ifdef CONFIG_PPC32 |
1477 | index = (unsigned long) addr >> 2; | 1482 | index = addr >> 2; |
1478 | if ((addr & 3) || (index > PT_FPSCR) | 1483 | if ((addr & 3) || (index > PT_FPSCR) |
1479 | || (child->thread.regs == NULL)) | 1484 | || (child->thread.regs == NULL)) |
1480 | #else | 1485 | #else |
1481 | index = (unsigned long) addr >> 3; | 1486 | index = addr >> 3; |
1482 | if ((addr & 7) || (index > PT_FPSCR)) | 1487 | if ((addr & 7) || (index > PT_FPSCR)) |
1483 | #endif | 1488 | #endif |
1484 | break; | 1489 | break; |
@@ -1525,11 +1530,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1525 | dbginfo.features = 0; | 1530 | dbginfo.features = 0; |
1526 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ | 1531 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ |
1527 | 1532 | ||
1528 | if (!access_ok(VERIFY_WRITE, data, | 1533 | if (!access_ok(VERIFY_WRITE, datavp, |
1529 | sizeof(struct ppc_debug_info))) | 1534 | sizeof(struct ppc_debug_info))) |
1530 | return -EFAULT; | 1535 | return -EFAULT; |
1531 | ret = __copy_to_user((struct ppc_debug_info __user *)data, | 1536 | ret = __copy_to_user(datavp, &dbginfo, |
1532 | &dbginfo, sizeof(struct ppc_debug_info)) ? | 1537 | sizeof(struct ppc_debug_info)) ? |
1533 | -EFAULT : 0; | 1538 | -EFAULT : 0; |
1534 | break; | 1539 | break; |
1535 | } | 1540 | } |
@@ -1537,11 +1542,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1537 | case PPC_PTRACE_SETHWDEBUG: { | 1542 | case PPC_PTRACE_SETHWDEBUG: { |
1538 | struct ppc_hw_breakpoint bp_info; | 1543 | struct ppc_hw_breakpoint bp_info; |
1539 | 1544 | ||
1540 | if (!access_ok(VERIFY_READ, data, | 1545 | if (!access_ok(VERIFY_READ, datavp, |
1541 | sizeof(struct ppc_hw_breakpoint))) | 1546 | sizeof(struct ppc_hw_breakpoint))) |
1542 | return -EFAULT; | 1547 | return -EFAULT; |
1543 | ret = __copy_from_user(&bp_info, | 1548 | ret = __copy_from_user(&bp_info, datavp, |
1544 | (struct ppc_hw_breakpoint __user *)data, | ||
1545 | sizeof(struct ppc_hw_breakpoint)) ? | 1549 | sizeof(struct ppc_hw_breakpoint)) ? |
1546 | -EFAULT : 0; | 1550 | -EFAULT : 0; |
1547 | if (!ret) | 1551 | if (!ret) |
@@ -1560,11 +1564,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1560 | if (addr > 0) | 1564 | if (addr > 0) |
1561 | break; | 1565 | break; |
1562 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 1566 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
1563 | ret = put_user(child->thread.dac1, | 1567 | ret = put_user(child->thread.dac1, datalp); |
1564 | (unsigned long __user *)data); | ||
1565 | #else | 1568 | #else |
1566 | ret = put_user(child->thread.dabr, | 1569 | ret = put_user(child->thread.dabr, datalp); |
1567 | (unsigned long __user *)data); | ||
1568 | #endif | 1570 | #endif |
1569 | break; | 1571 | break; |
1570 | } | 1572 | } |
@@ -1580,7 +1582,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1580 | return copy_regset_to_user(child, &user_ppc_native_view, | 1582 | return copy_regset_to_user(child, &user_ppc_native_view, |
1581 | REGSET_GPR, | 1583 | REGSET_GPR, |
1582 | 0, sizeof(struct pt_regs), | 1584 | 0, sizeof(struct pt_regs), |
1583 | (void __user *) data); | 1585 | datavp); |
1584 | 1586 | ||
1585 | #ifdef CONFIG_PPC64 | 1587 | #ifdef CONFIG_PPC64 |
1586 | case PTRACE_SETREGS64: | 1588 | case PTRACE_SETREGS64: |
@@ -1589,19 +1591,19 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1589 | return copy_regset_from_user(child, &user_ppc_native_view, | 1591 | return copy_regset_from_user(child, &user_ppc_native_view, |
1590 | REGSET_GPR, | 1592 | REGSET_GPR, |
1591 | 0, sizeof(struct pt_regs), | 1593 | 0, sizeof(struct pt_regs), |
1592 | (const void __user *) data); | 1594 | datavp); |
1593 | 1595 | ||
1594 | case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */ | 1596 | case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */ |
1595 | return copy_regset_to_user(child, &user_ppc_native_view, | 1597 | return copy_regset_to_user(child, &user_ppc_native_view, |
1596 | REGSET_FPR, | 1598 | REGSET_FPR, |
1597 | 0, sizeof(elf_fpregset_t), | 1599 | 0, sizeof(elf_fpregset_t), |
1598 | (void __user *) data); | 1600 | datavp); |
1599 | 1601 | ||
1600 | case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */ | 1602 | case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */ |
1601 | return copy_regset_from_user(child, &user_ppc_native_view, | 1603 | return copy_regset_from_user(child, &user_ppc_native_view, |
1602 | REGSET_FPR, | 1604 | REGSET_FPR, |
1603 | 0, sizeof(elf_fpregset_t), | 1605 | 0, sizeof(elf_fpregset_t), |
1604 | (const void __user *) data); | 1606 | datavp); |
1605 | 1607 | ||
1606 | #ifdef CONFIG_ALTIVEC | 1608 | #ifdef CONFIG_ALTIVEC |
1607 | case PTRACE_GETVRREGS: | 1609 | case PTRACE_GETVRREGS: |
@@ -1609,40 +1611,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1609 | REGSET_VMX, | 1611 | REGSET_VMX, |
1610 | 0, (33 * sizeof(vector128) + | 1612 | 0, (33 * sizeof(vector128) + |
1611 | sizeof(u32)), | 1613 | sizeof(u32)), |
1612 | (void __user *) data); | 1614 | datavp); |
1613 | 1615 | ||
1614 | case PTRACE_SETVRREGS: | 1616 | case PTRACE_SETVRREGS: |
1615 | return copy_regset_from_user(child, &user_ppc_native_view, | 1617 | return copy_regset_from_user(child, &user_ppc_native_view, |
1616 | REGSET_VMX, | 1618 | REGSET_VMX, |
1617 | 0, (33 * sizeof(vector128) + | 1619 | 0, (33 * sizeof(vector128) + |
1618 | sizeof(u32)), | 1620 | sizeof(u32)), |
1619 | (const void __user *) data); | 1621 | datavp); |
1620 | #endif | 1622 | #endif |
1621 | #ifdef CONFIG_VSX | 1623 | #ifdef CONFIG_VSX |
1622 | case PTRACE_GETVSRREGS: | 1624 | case PTRACE_GETVSRREGS: |
1623 | return copy_regset_to_user(child, &user_ppc_native_view, | 1625 | return copy_regset_to_user(child, &user_ppc_native_view, |
1624 | REGSET_VSX, | 1626 | REGSET_VSX, |
1625 | 0, 32 * sizeof(double), | 1627 | 0, 32 * sizeof(double), |
1626 | (void __user *) data); | 1628 | datavp); |
1627 | 1629 | ||
1628 | case PTRACE_SETVSRREGS: | 1630 | case PTRACE_SETVSRREGS: |
1629 | return copy_regset_from_user(child, &user_ppc_native_view, | 1631 | return copy_regset_from_user(child, &user_ppc_native_view, |
1630 | REGSET_VSX, | 1632 | REGSET_VSX, |
1631 | 0, 32 * sizeof(double), | 1633 | 0, 32 * sizeof(double), |
1632 | (const void __user *) data); | 1634 | datavp); |
1633 | #endif | 1635 | #endif |
1634 | #ifdef CONFIG_SPE | 1636 | #ifdef CONFIG_SPE |
1635 | case PTRACE_GETEVRREGS: | 1637 | case PTRACE_GETEVRREGS: |
1636 | /* Get the child spe register state. */ | 1638 | /* Get the child spe register state. */ |
1637 | return copy_regset_to_user(child, &user_ppc_native_view, | 1639 | return copy_regset_to_user(child, &user_ppc_native_view, |
1638 | REGSET_SPE, 0, 35 * sizeof(u32), | 1640 | REGSET_SPE, 0, 35 * sizeof(u32), |
1639 | (void __user *) data); | 1641 | datavp); |
1640 | 1642 | ||
1641 | case PTRACE_SETEVRREGS: | 1643 | case PTRACE_SETEVRREGS: |
1642 | /* Set the child spe register state. */ | 1644 | /* Set the child spe register state. */ |
1643 | return copy_regset_from_user(child, &user_ppc_native_view, | 1645 | return copy_regset_from_user(child, &user_ppc_native_view, |
1644 | REGSET_SPE, 0, 35 * sizeof(u32), | 1646 | REGSET_SPE, 0, 35 * sizeof(u32), |
1645 | (const void __user *) data); | 1647 | datavp); |
1646 | #endif | 1648 | #endif |
1647 | 1649 | ||
1648 | /* Old reverse args ptrace callss */ | 1650 | /* Old reverse args ptrace callss */ |
diff --git a/arch/powerpc/mm/highmem.c b/arch/powerpc/mm/highmem.c index b0848b462bbc..e7450bdbe83a 100644 --- a/arch/powerpc/mm/highmem.c +++ b/arch/powerpc/mm/highmem.c | |||
@@ -62,7 +62,7 @@ void __kunmap_atomic(void *kvaddr) | |||
62 | return; | 62 | return; |
63 | } | 63 | } |
64 | 64 | ||
65 | type = kmap_atomic_idx_pop(); | 65 | type = kmap_atomic_idx(); |
66 | 66 | ||
67 | #ifdef CONFIG_DEBUG_HIGHMEM | 67 | #ifdef CONFIG_DEBUG_HIGHMEM |
68 | { | 68 | { |
@@ -79,6 +79,8 @@ void __kunmap_atomic(void *kvaddr) | |||
79 | local_flush_tlb_page(NULL, vaddr); | 79 | local_flush_tlb_page(NULL, vaddr); |
80 | } | 80 | } |
81 | #endif | 81 | #endif |
82 | |||
83 | kmap_atomic_idx_pop(); | ||
82 | pagefault_enable(); | 84 | pagefault_enable(); |
83 | } | 85 | } |
84 | EXPORT_SYMBOL(__kunmap_atomic); | 86 | EXPORT_SYMBOL(__kunmap_atomic); |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 412763672d23..9725369d432a 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #define RIO_ATMU_REGS_OFFSET 0x10c00 | 50 | #define RIO_ATMU_REGS_OFFSET 0x10c00 |
51 | #define RIO_P_MSG_REGS_OFFSET 0x11000 | 51 | #define RIO_P_MSG_REGS_OFFSET 0x11000 |
52 | #define RIO_S_MSG_REGS_OFFSET 0x13000 | 52 | #define RIO_S_MSG_REGS_OFFSET 0x13000 |
53 | #define RIO_GCCSR 0x13c | ||
53 | #define RIO_ESCSR 0x158 | 54 | #define RIO_ESCSR 0x158 |
54 | #define RIO_CCSR 0x15c | 55 | #define RIO_CCSR 0x15c |
55 | #define RIO_LTLEDCSR 0x0608 | 56 | #define RIO_LTLEDCSR 0x0608 |
@@ -87,6 +88,9 @@ | |||
87 | #define RIO_IPWSR_PWD 0x00000008 | 88 | #define RIO_IPWSR_PWD 0x00000008 |
88 | #define RIO_IPWSR_PWB 0x00000004 | 89 | #define RIO_IPWSR_PWB 0x00000004 |
89 | 90 | ||
91 | #define RIO_EPWISR_PINT 0x80000000 | ||
92 | #define RIO_EPWISR_PW 0x00000001 | ||
93 | |||
90 | #define RIO_MSG_DESC_SIZE 32 | 94 | #define RIO_MSG_DESC_SIZE 32 |
91 | #define RIO_MSG_BUFFER_SIZE 4096 | 95 | #define RIO_MSG_BUFFER_SIZE 4096 |
92 | #define RIO_MIN_TX_RING_SIZE 2 | 96 | #define RIO_MIN_TX_RING_SIZE 2 |
@@ -1082,18 +1086,12 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) | |||
1082 | struct rio_priv *priv = port->priv; | 1086 | struct rio_priv *priv = port->priv; |
1083 | u32 epwisr, tmp; | 1087 | u32 epwisr, tmp; |
1084 | 1088 | ||
1085 | ipwmr = in_be32(&priv->msg_regs->pwmr); | ||
1086 | ipwsr = in_be32(&priv->msg_regs->pwsr); | ||
1087 | |||
1088 | epwisr = in_be32(priv->regs_win + RIO_EPWISR); | 1089 | epwisr = in_be32(priv->regs_win + RIO_EPWISR); |
1089 | if (epwisr & 0x80000000) { | 1090 | if (!(epwisr & RIO_EPWISR_PW)) |
1090 | tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); | 1091 | goto pw_done; |
1091 | pr_info("RIO_LTLEDCSR = 0x%x\n", tmp); | ||
1092 | out_be32(priv->regs_win + RIO_LTLEDCSR, 0); | ||
1093 | } | ||
1094 | 1092 | ||
1095 | if (!(epwisr & 0x00000001)) | 1093 | ipwmr = in_be32(&priv->msg_regs->pwmr); |
1096 | return IRQ_HANDLED; | 1094 | ipwsr = in_be32(&priv->msg_regs->pwsr); |
1097 | 1095 | ||
1098 | #ifdef DEBUG_PW | 1096 | #ifdef DEBUG_PW |
1099 | pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr); | 1097 | pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr); |
@@ -1109,20 +1107,6 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) | |||
1109 | pr_debug(" PWB"); | 1107 | pr_debug(" PWB"); |
1110 | pr_debug(" )\n"); | 1108 | pr_debug(" )\n"); |
1111 | #endif | 1109 | #endif |
1112 | out_be32(&priv->msg_regs->pwsr, | ||
1113 | ipwsr & (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); | ||
1114 | |||
1115 | if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) { | ||
1116 | priv->port_write_msg.err_count++; | ||
1117 | pr_info("RIO: Port-Write Transaction Err (%d)\n", | ||
1118 | priv->port_write_msg.err_count); | ||
1119 | } | ||
1120 | if (ipwsr & RIO_IPWSR_PWD) { | ||
1121 | priv->port_write_msg.discard_count++; | ||
1122 | pr_info("RIO: Port Discarded Port-Write Msg(s) (%d)\n", | ||
1123 | priv->port_write_msg.discard_count); | ||
1124 | } | ||
1125 | |||
1126 | /* Schedule deferred processing if PW was received */ | 1110 | /* Schedule deferred processing if PW was received */ |
1127 | if (ipwsr & RIO_IPWSR_QFI) { | 1111 | if (ipwsr & RIO_IPWSR_QFI) { |
1128 | /* Save PW message (if there is room in FIFO), | 1112 | /* Save PW message (if there is room in FIFO), |
@@ -1134,16 +1118,43 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) | |||
1134 | RIO_PW_MSG_SIZE); | 1118 | RIO_PW_MSG_SIZE); |
1135 | } else { | 1119 | } else { |
1136 | priv->port_write_msg.discard_count++; | 1120 | priv->port_write_msg.discard_count++; |
1137 | pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n", | 1121 | pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n", |
1138 | priv->port_write_msg.discard_count); | 1122 | priv->port_write_msg.discard_count); |
1139 | } | 1123 | } |
1124 | /* Clear interrupt and issue Clear Queue command. This allows | ||
1125 | * another port-write to be received. | ||
1126 | */ | ||
1127 | out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_QFI); | ||
1128 | out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ); | ||
1129 | |||
1140 | schedule_work(&priv->pw_work); | 1130 | schedule_work(&priv->pw_work); |
1141 | } | 1131 | } |
1142 | 1132 | ||
1143 | /* Issue Clear Queue command. This allows another | 1133 | if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) { |
1144 | * port-write to be received. | 1134 | priv->port_write_msg.err_count++; |
1145 | */ | 1135 | pr_debug("RIO: Port-Write Transaction Err (%d)\n", |
1146 | out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ); | 1136 | priv->port_write_msg.err_count); |
1137 | /* Clear Transaction Error: port-write controller should be | ||
1138 | * disabled when clearing this error | ||
1139 | */ | ||
1140 | out_be32(&priv->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE); | ||
1141 | out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_TE); | ||
1142 | out_be32(&priv->msg_regs->pwmr, ipwmr); | ||
1143 | } | ||
1144 | |||
1145 | if (ipwsr & RIO_IPWSR_PWD) { | ||
1146 | priv->port_write_msg.discard_count++; | ||
1147 | pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n", | ||
1148 | priv->port_write_msg.discard_count); | ||
1149 | out_be32(&priv->msg_regs->pwsr, RIO_IPWSR_PWD); | ||
1150 | } | ||
1151 | |||
1152 | pw_done: | ||
1153 | if (epwisr & RIO_EPWISR_PINT) { | ||
1154 | tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); | ||
1155 | pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp); | ||
1156 | out_be32(priv->regs_win + RIO_LTLEDCSR, 0); | ||
1157 | } | ||
1147 | 1158 | ||
1148 | return IRQ_HANDLED; | 1159 | return IRQ_HANDLED; |
1149 | } | 1160 | } |
@@ -1461,6 +1472,7 @@ int fsl_rio_setup(struct platform_device *dev) | |||
1461 | port->host_deviceid = fsl_rio_get_hdid(port->id); | 1472 | port->host_deviceid = fsl_rio_get_hdid(port->id); |
1462 | 1473 | ||
1463 | port->priv = priv; | 1474 | port->priv = priv; |
1475 | port->phys_efptr = 0x100; | ||
1464 | rio_register_mport(port); | 1476 | rio_register_mport(port); |
1465 | 1477 | ||
1466 | priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); | 1478 | priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); |
@@ -1508,6 +1520,12 @@ int fsl_rio_setup(struct platform_device *dev) | |||
1508 | dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", | 1520 | dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", |
1509 | port->sys_size ? 65536 : 256); | 1521 | port->sys_size ? 65536 : 256); |
1510 | 1522 | ||
1523 | if (port->host_deviceid >= 0) | ||
1524 | out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST | | ||
1525 | RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED); | ||
1526 | else | ||
1527 | out_be32(priv->regs_win + RIO_GCCSR, 0x00000000); | ||
1528 | |||
1511 | priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win | 1529 | priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win |
1512 | + RIO_ATMU_REGS_OFFSET); | 1530 | + RIO_ATMU_REGS_OFFSET); |
1513 | priv->maint_atmu_regs = priv->atmu_regs + 1; | 1531 | priv->maint_atmu_regs = priv->atmu_regs + 1; |
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 8b1a52a137c5..40e2ab0fa3f0 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h | |||
@@ -73,18 +73,18 @@ cputime64_to_jiffies64(cputime64_t cputime) | |||
73 | } | 73 | } |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Convert cputime to milliseconds and back. | 76 | * Convert cputime to microseconds and back. |
77 | */ | 77 | */ |
78 | static inline unsigned int | 78 | static inline unsigned int |
79 | cputime_to_msecs(const cputime_t cputime) | 79 | cputime_to_usecs(const cputime_t cputime) |
80 | { | 80 | { |
81 | return cputime_div(cputime, 4096000); | 81 | return cputime_div(cputime, 4096); |
82 | } | 82 | } |
83 | 83 | ||
84 | static inline cputime_t | 84 | static inline cputime_t |
85 | msecs_to_cputime(const unsigned int m) | 85 | usecs_to_cputime(const unsigned int m) |
86 | { | 86 | { |
87 | return (cputime_t) m * 4096000; | 87 | return (cputime_t) m * 4096; |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /* |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 83339d33c4b1..019bb714db49 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -343,7 +343,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) | |||
343 | return __poke_user(child, addr, data); | 343 | return __poke_user(child, addr, data); |
344 | } | 344 | } |
345 | 345 | ||
346 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 346 | long arch_ptrace(struct task_struct *child, long request, |
347 | unsigned long addr, unsigned long data) | ||
347 | { | 348 | { |
348 | ptrace_area parea; | 349 | ptrace_area parea; |
349 | int copied, ret; | 350 | int copied, ret; |
diff --git a/arch/score/kernel/ptrace.c b/arch/score/kernel/ptrace.c index 174c6422b096..55836188b217 100644 --- a/arch/score/kernel/ptrace.c +++ b/arch/score/kernel/ptrace.c | |||
@@ -325,7 +325,8 @@ void ptrace_disable(struct task_struct *child) | |||
325 | } | 325 | } |
326 | 326 | ||
327 | long | 327 | long |
328 | arch_ptrace(struct task_struct *child, long request, long addr, long data) | 328 | arch_ptrace(struct task_struct *child, long request, |
329 | unsigned long addr, unsigned long data) | ||
329 | { | 330 | { |
330 | int ret; | 331 | int ret; |
331 | unsigned long __user *datap = (void __user *)data; | 332 | unsigned long __user *datap = (void __user *)data; |
@@ -335,14 +336,14 @@ arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
335 | ret = copy_regset_to_user(child, &user_score_native_view, | 336 | ret = copy_regset_to_user(child, &user_score_native_view, |
336 | REGSET_GENERAL, | 337 | REGSET_GENERAL, |
337 | 0, sizeof(struct pt_regs), | 338 | 0, sizeof(struct pt_regs), |
338 | (void __user *)datap); | 339 | datap); |
339 | break; | 340 | break; |
340 | 341 | ||
341 | case PTRACE_SETREGS: | 342 | case PTRACE_SETREGS: |
342 | ret = copy_regset_from_user(child, &user_score_native_view, | 343 | ret = copy_regset_from_user(child, &user_score_native_view, |
343 | REGSET_GENERAL, | 344 | REGSET_GENERAL, |
344 | 0, sizeof(struct pt_regs), | 345 | 0, sizeof(struct pt_regs), |
345 | (const void __user *)datap); | 346 | datap); |
346 | break; | 347 | break; |
347 | 348 | ||
348 | default: | 349 | default: |
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 2cd42b58cb20..90a15d29feeb 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c | |||
@@ -365,9 +365,9 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) | |||
365 | return &user_sh_native_view; | 365 | return &user_sh_native_view; |
366 | } | 366 | } |
367 | 367 | ||
368 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 368 | long arch_ptrace(struct task_struct *child, long request, |
369 | unsigned long addr, unsigned long data) | ||
369 | { | 370 | { |
370 | struct user * dummy = NULL; | ||
371 | unsigned long __user *datap = (unsigned long __user *)data; | 371 | unsigned long __user *datap = (unsigned long __user *)data; |
372 | int ret; | 372 | int ret; |
373 | 373 | ||
@@ -383,17 +383,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
383 | 383 | ||
384 | if (addr < sizeof(struct pt_regs)) | 384 | if (addr < sizeof(struct pt_regs)) |
385 | tmp = get_stack_long(child, addr); | 385 | tmp = get_stack_long(child, addr); |
386 | else if (addr >= (long) &dummy->fpu && | 386 | else if (addr >= offsetof(struct user, fpu) && |
387 | addr < (long) &dummy->u_fpvalid) { | 387 | addr < offsetof(struct user, u_fpvalid)) { |
388 | if (!tsk_used_math(child)) { | 388 | if (!tsk_used_math(child)) { |
389 | if (addr == (long)&dummy->fpu.fpscr) | 389 | if (addr == offsetof(struct user, fpu.fpscr)) |
390 | tmp = FPSCR_INIT; | 390 | tmp = FPSCR_INIT; |
391 | else | 391 | else |
392 | tmp = 0; | 392 | tmp = 0; |
393 | } else | 393 | } else { |
394 | tmp = ((long *)child->thread.xstate) | 394 | unsigned long index; |
395 | [(addr - (long)&dummy->fpu) >> 2]; | 395 | index = addr - offsetof(struct user, fpu); |
396 | } else if (addr == (long) &dummy->u_fpvalid) | 396 | tmp = ((unsigned long *)child->thread.xstate) |
397 | [index >> 2]; | ||
398 | } | ||
399 | } else if (addr == offsetof(struct user, u_fpvalid)) | ||
397 | tmp = !!tsk_used_math(child); | 400 | tmp = !!tsk_used_math(child); |
398 | else if (addr == PT_TEXT_ADDR) | 401 | else if (addr == PT_TEXT_ADDR) |
399 | tmp = child->mm->start_code; | 402 | tmp = child->mm->start_code; |
@@ -417,13 +420,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
417 | 420 | ||
418 | if (addr < sizeof(struct pt_regs)) | 421 | if (addr < sizeof(struct pt_regs)) |
419 | ret = put_stack_long(child, addr, data); | 422 | ret = put_stack_long(child, addr, data); |
420 | else if (addr >= (long) &dummy->fpu && | 423 | else if (addr >= offsetof(struct user, fpu) && |
421 | addr < (long) &dummy->u_fpvalid) { | 424 | addr < offsetof(struct user, u_fpvalid)) { |
425 | unsigned long index; | ||
426 | index = addr - offsetof(struct user, fpu); | ||
422 | set_stopped_child_used_math(child); | 427 | set_stopped_child_used_math(child); |
423 | ((long *)child->thread.xstate) | 428 | ((unsigned long *)child->thread.xstate) |
424 | [(addr - (long)&dummy->fpu) >> 2] = data; | 429 | [index >> 2] = data; |
425 | ret = 0; | 430 | ret = 0; |
426 | } else if (addr == (long) &dummy->u_fpvalid) { | 431 | } else if (addr == offsetof(struct user, u_fpvalid)) { |
427 | conditional_stopped_child_used_math(data, child); | 432 | conditional_stopped_child_used_math(data, child); |
428 | ret = 0; | 433 | ret = 0; |
429 | } | 434 | } |
@@ -433,35 +438,35 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
433 | return copy_regset_to_user(child, &user_sh_native_view, | 438 | return copy_regset_to_user(child, &user_sh_native_view, |
434 | REGSET_GENERAL, | 439 | REGSET_GENERAL, |
435 | 0, sizeof(struct pt_regs), | 440 | 0, sizeof(struct pt_regs), |
436 | (void __user *)data); | 441 | datap); |
437 | case PTRACE_SETREGS: | 442 | case PTRACE_SETREGS: |
438 | return copy_regset_from_user(child, &user_sh_native_view, | 443 | return copy_regset_from_user(child, &user_sh_native_view, |
439 | REGSET_GENERAL, | 444 | REGSET_GENERAL, |
440 | 0, sizeof(struct pt_regs), | 445 | 0, sizeof(struct pt_regs), |
441 | (const void __user *)data); | 446 | datap); |
442 | #ifdef CONFIG_SH_FPU | 447 | #ifdef CONFIG_SH_FPU |
443 | case PTRACE_GETFPREGS: | 448 | case PTRACE_GETFPREGS: |
444 | return copy_regset_to_user(child, &user_sh_native_view, | 449 | return copy_regset_to_user(child, &user_sh_native_view, |
445 | REGSET_FPU, | 450 | REGSET_FPU, |
446 | 0, sizeof(struct user_fpu_struct), | 451 | 0, sizeof(struct user_fpu_struct), |
447 | (void __user *)data); | 452 | datap); |
448 | case PTRACE_SETFPREGS: | 453 | case PTRACE_SETFPREGS: |
449 | return copy_regset_from_user(child, &user_sh_native_view, | 454 | return copy_regset_from_user(child, &user_sh_native_view, |
450 | REGSET_FPU, | 455 | REGSET_FPU, |
451 | 0, sizeof(struct user_fpu_struct), | 456 | 0, sizeof(struct user_fpu_struct), |
452 | (const void __user *)data); | 457 | datap); |
453 | #endif | 458 | #endif |
454 | #ifdef CONFIG_SH_DSP | 459 | #ifdef CONFIG_SH_DSP |
455 | case PTRACE_GETDSPREGS: | 460 | case PTRACE_GETDSPREGS: |
456 | return copy_regset_to_user(child, &user_sh_native_view, | 461 | return copy_regset_to_user(child, &user_sh_native_view, |
457 | REGSET_DSP, | 462 | REGSET_DSP, |
458 | 0, sizeof(struct pt_dspregs), | 463 | 0, sizeof(struct pt_dspregs), |
459 | (void __user *)data); | 464 | datap); |
460 | case PTRACE_SETDSPREGS: | 465 | case PTRACE_SETDSPREGS: |
461 | return copy_regset_from_user(child, &user_sh_native_view, | 466 | return copy_regset_from_user(child, &user_sh_native_view, |
462 | REGSET_DSP, | 467 | REGSET_DSP, |
463 | 0, sizeof(struct pt_dspregs), | 468 | 0, sizeof(struct pt_dspregs), |
464 | (const void __user *)data); | 469 | datap); |
465 | #endif | 470 | #endif |
466 | default: | 471 | default: |
467 | ret = ptrace_request(child, request, addr, data); | 472 | ret = ptrace_request(child, request, addr, data); |
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c index e0fb065914aa..4436eacddb15 100644 --- a/arch/sh/kernel/ptrace_64.c +++ b/arch/sh/kernel/ptrace_64.c | |||
@@ -383,9 +383,11 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) | |||
383 | return &user_sh64_native_view; | 383 | return &user_sh64_native_view; |
384 | } | 384 | } |
385 | 385 | ||
386 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 386 | long arch_ptrace(struct task_struct *child, long request, |
387 | unsigned long addr, unsigned long data) | ||
387 | { | 388 | { |
388 | int ret; | 389 | int ret; |
390 | unsigned long __user *datap = (unsigned long __user *) data; | ||
389 | 391 | ||
390 | switch (request) { | 392 | switch (request) { |
391 | /* read the word at location addr in the USER area. */ | 393 | /* read the word at location addr in the USER area. */ |
@@ -400,13 +402,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
400 | tmp = get_stack_long(child, addr); | 402 | tmp = get_stack_long(child, addr); |
401 | else if ((addr >= offsetof(struct user, fpu)) && | 403 | else if ((addr >= offsetof(struct user, fpu)) && |
402 | (addr < offsetof(struct user, u_fpvalid))) { | 404 | (addr < offsetof(struct user, u_fpvalid))) { |
403 | tmp = get_fpu_long(child, addr - offsetof(struct user, fpu)); | 405 | unsigned long index; |
406 | index = addr - offsetof(struct user, fpu); | ||
407 | tmp = get_fpu_long(child, index); | ||
404 | } else if (addr == offsetof(struct user, u_fpvalid)) { | 408 | } else if (addr == offsetof(struct user, u_fpvalid)) { |
405 | tmp = !!tsk_used_math(child); | 409 | tmp = !!tsk_used_math(child); |
406 | } else { | 410 | } else { |
407 | break; | 411 | break; |
408 | } | 412 | } |
409 | ret = put_user(tmp, (unsigned long *)data); | 413 | ret = put_user(tmp, datap); |
410 | break; | 414 | break; |
411 | } | 415 | } |
412 | 416 | ||
@@ -437,7 +441,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
437 | } | 441 | } |
438 | else if ((addr >= offsetof(struct user, fpu)) && | 442 | else if ((addr >= offsetof(struct user, fpu)) && |
439 | (addr < offsetof(struct user, u_fpvalid))) { | 443 | (addr < offsetof(struct user, u_fpvalid))) { |
440 | ret = put_fpu_long(child, addr - offsetof(struct user, fpu), data); | 444 | unsigned long index; |
445 | index = addr - offsetof(struct user, fpu); | ||
446 | ret = put_fpu_long(child, index, data); | ||
441 | } | 447 | } |
442 | break; | 448 | break; |
443 | 449 | ||
@@ -445,23 +451,23 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
445 | return copy_regset_to_user(child, &user_sh64_native_view, | 451 | return copy_regset_to_user(child, &user_sh64_native_view, |
446 | REGSET_GENERAL, | 452 | REGSET_GENERAL, |
447 | 0, sizeof(struct pt_regs), | 453 | 0, sizeof(struct pt_regs), |
448 | (void __user *)data); | 454 | datap); |
449 | case PTRACE_SETREGS: | 455 | case PTRACE_SETREGS: |
450 | return copy_regset_from_user(child, &user_sh64_native_view, | 456 | return copy_regset_from_user(child, &user_sh64_native_view, |
451 | REGSET_GENERAL, | 457 | REGSET_GENERAL, |
452 | 0, sizeof(struct pt_regs), | 458 | 0, sizeof(struct pt_regs), |
453 | (const void __user *)data); | 459 | datap); |
454 | #ifdef CONFIG_SH_FPU | 460 | #ifdef CONFIG_SH_FPU |
455 | case PTRACE_GETFPREGS: | 461 | case PTRACE_GETFPREGS: |
456 | return copy_regset_to_user(child, &user_sh64_native_view, | 462 | return copy_regset_to_user(child, &user_sh64_native_view, |
457 | REGSET_FPU, | 463 | REGSET_FPU, |
458 | 0, sizeof(struct user_fpu_struct), | 464 | 0, sizeof(struct user_fpu_struct), |
459 | (void __user *)data); | 465 | datap); |
460 | case PTRACE_SETFPREGS: | 466 | case PTRACE_SETFPREGS: |
461 | return copy_regset_from_user(child, &user_sh64_native_view, | 467 | return copy_regset_from_user(child, &user_sh64_native_view, |
462 | REGSET_FPU, | 468 | REGSET_FPU, |
463 | 0, sizeof(struct user_fpu_struct), | 469 | 0, sizeof(struct user_fpu_struct), |
464 | (const void __user *)data); | 470 | datap); |
465 | #endif | 471 | #endif |
466 | default: | 472 | default: |
467 | ret = ptrace_request(child, request, addr, data); | 473 | ret = ptrace_request(child, request, addr, data); |
@@ -471,7 +477,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
471 | return ret; | 477 | return ret; |
472 | } | 478 | } |
473 | 479 | ||
474 | asmlinkage int sh64_ptrace(long request, long pid, long addr, long data) | 480 | asmlinkage int sh64_ptrace(long request, long pid, |
481 | unsigned long addr, unsigned long data) | ||
475 | { | 482 | { |
476 | #define WPC_DBRMODE 0x0d104008 | 483 | #define WPC_DBRMODE 0x0d104008 |
477 | static unsigned long first_call; | 484 | static unsigned long first_call; |
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h index 2889574608db..c2ced21c9dc1 100644 --- a/arch/sparc/include/asm/io_32.h +++ b/arch/sparc/include/asm/io_32.h | |||
@@ -208,6 +208,21 @@ _memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) | |||
208 | #define memset_io(d,c,sz) _memset_io(d,c,sz) | 208 | #define memset_io(d,c,sz) _memset_io(d,c,sz) |
209 | 209 | ||
210 | static inline void | 210 | static inline void |
211 | _sbus_memcpy_fromio(void *dst, const volatile void __iomem *src, | ||
212 | __kernel_size_t n) | ||
213 | { | ||
214 | char *d = dst; | ||
215 | |||
216 | while (n--) { | ||
217 | char tmp = sbus_readb(src); | ||
218 | *d++ = tmp; | ||
219 | src++; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | #define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz) | ||
224 | |||
225 | static inline void | ||
211 | _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) | 226 | _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) |
212 | { | 227 | { |
213 | char *d = dst; | 228 | char *d = dst; |
@@ -222,6 +237,22 @@ _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) | |||
222 | #define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) | 237 | #define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) |
223 | 238 | ||
224 | static inline void | 239 | static inline void |
240 | _sbus_memcpy_toio(volatile void __iomem *dst, const void *src, | ||
241 | __kernel_size_t n) | ||
242 | { | ||
243 | const char *s = src; | ||
244 | volatile void __iomem *d = dst; | ||
245 | |||
246 | while (n--) { | ||
247 | char tmp = *s++; | ||
248 | sbus_writeb(tmp, d); | ||
249 | d++; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | #define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz) | ||
254 | |||
255 | static inline void | ||
225 | _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) | 256 | _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) |
226 | { | 257 | { |
227 | const char *s = src; | 258 | const char *s = src; |
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index 9517d063c79c..9c8965415f0a 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h | |||
@@ -419,6 +419,21 @@ _memset_io(volatile void __iomem *dst, int c, __kernel_size_t n) | |||
419 | #define memset_io(d,c,sz) _memset_io(d,c,sz) | 419 | #define memset_io(d,c,sz) _memset_io(d,c,sz) |
420 | 420 | ||
421 | static inline void | 421 | static inline void |
422 | _sbus_memcpy_fromio(void *dst, const volatile void __iomem *src, | ||
423 | __kernel_size_t n) | ||
424 | { | ||
425 | char *d = dst; | ||
426 | |||
427 | while (n--) { | ||
428 | char tmp = sbus_readb(src); | ||
429 | *d++ = tmp; | ||
430 | src++; | ||
431 | } | ||
432 | } | ||
433 | |||
434 | #define sbus_memcpy_fromio(d, s, sz) _sbus_memcpy_fromio(d, s, sz) | ||
435 | |||
436 | static inline void | ||
422 | _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) | 437 | _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) |
423 | { | 438 | { |
424 | char *d = dst; | 439 | char *d = dst; |
@@ -433,6 +448,22 @@ _memcpy_fromio(void *dst, const volatile void __iomem *src, __kernel_size_t n) | |||
433 | #define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) | 448 | #define memcpy_fromio(d,s,sz) _memcpy_fromio(d,s,sz) |
434 | 449 | ||
435 | static inline void | 450 | static inline void |
451 | _sbus_memcpy_toio(volatile void __iomem *dst, const void *src, | ||
452 | __kernel_size_t n) | ||
453 | { | ||
454 | const char *s = src; | ||
455 | volatile void __iomem *d = dst; | ||
456 | |||
457 | while (n--) { | ||
458 | char tmp = *s++; | ||
459 | sbus_writeb(tmp, d); | ||
460 | d++; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | #define sbus_memcpy_toio(d, s, sz) _sbus_memcpy_toio(d, s, sz) | ||
465 | |||
466 | static inline void | ||
436 | _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) | 467 | _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n) |
437 | { | 468 | { |
438 | const char *s = src; | 469 | const char *s = src; |
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 5312782f0b5e..948b686ec089 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h | |||
@@ -38,7 +38,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) | |||
38 | * types on sparc64. However, it requires that the device | 38 | * types on sparc64. However, it requires that the device |
39 | * can drive enough of the 64 bits. | 39 | * can drive enough of the 64 bits. |
40 | */ | 40 | */ |
41 | #define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) | 41 | #define PCI64_REQUIRED_MASK (~(u64)0) |
42 | #define PCI64_ADDR_BASE 0xfffc000000000000UL | 42 | #define PCI64_ADDR_BASE 0xfffc000000000000UL |
43 | 43 | ||
44 | #ifdef CONFIG_PCI | 44 | #ifdef CONFIG_PCI |
diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index e608f397e11f..27b9e93d0121 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c | |||
@@ -323,18 +323,35 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) | |||
323 | return &user_sparc32_view; | 323 | return &user_sparc32_view; |
324 | } | 324 | } |
325 | 325 | ||
326 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 326 | struct fps { |
327 | unsigned long regs[32]; | ||
328 | unsigned long fsr; | ||
329 | unsigned long flags; | ||
330 | unsigned long extra; | ||
331 | unsigned long fpqd; | ||
332 | struct fq { | ||
333 | unsigned long *insnaddr; | ||
334 | unsigned long insn; | ||
335 | } fpq[16]; | ||
336 | }; | ||
337 | |||
338 | long arch_ptrace(struct task_struct *child, long request, | ||
339 | unsigned long addr, unsigned long data) | ||
327 | { | 340 | { |
328 | unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4]; | 341 | unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4]; |
342 | void __user *addr2p; | ||
329 | const struct user_regset_view *view; | 343 | const struct user_regset_view *view; |
344 | struct pt_regs __user *pregs; | ||
345 | struct fps __user *fps; | ||
330 | int ret; | 346 | int ret; |
331 | 347 | ||
332 | view = task_user_regset_view(current); | 348 | view = task_user_regset_view(current); |
349 | addr2p = (void __user *) addr2; | ||
350 | pregs = (struct pt_regs __user *) addr; | ||
351 | fps = (struct fps __user *) addr; | ||
333 | 352 | ||
334 | switch(request) { | 353 | switch(request) { |
335 | case PTRACE_GETREGS: { | 354 | case PTRACE_GETREGS: { |
336 | struct pt_regs __user *pregs = (struct pt_regs __user *) addr; | ||
337 | |||
338 | ret = copy_regset_to_user(child, view, REGSET_GENERAL, | 355 | ret = copy_regset_to_user(child, view, REGSET_GENERAL, |
339 | 32 * sizeof(u32), | 356 | 32 * sizeof(u32), |
340 | 4 * sizeof(u32), | 357 | 4 * sizeof(u32), |
@@ -348,8 +365,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
348 | } | 365 | } |
349 | 366 | ||
350 | case PTRACE_SETREGS: { | 367 | case PTRACE_SETREGS: { |
351 | struct pt_regs __user *pregs = (struct pt_regs __user *) addr; | ||
352 | |||
353 | ret = copy_regset_from_user(child, view, REGSET_GENERAL, | 368 | ret = copy_regset_from_user(child, view, REGSET_GENERAL, |
354 | 32 * sizeof(u32), | 369 | 32 * sizeof(u32), |
355 | 4 * sizeof(u32), | 370 | 4 * sizeof(u32), |
@@ -363,19 +378,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
363 | } | 378 | } |
364 | 379 | ||
365 | case PTRACE_GETFPREGS: { | 380 | case PTRACE_GETFPREGS: { |
366 | struct fps { | ||
367 | unsigned long regs[32]; | ||
368 | unsigned long fsr; | ||
369 | unsigned long flags; | ||
370 | unsigned long extra; | ||
371 | unsigned long fpqd; | ||
372 | struct fq { | ||
373 | unsigned long *insnaddr; | ||
374 | unsigned long insn; | ||
375 | } fpq[16]; | ||
376 | }; | ||
377 | struct fps __user *fps = (struct fps __user *) addr; | ||
378 | |||
379 | ret = copy_regset_to_user(child, view, REGSET_FP, | 381 | ret = copy_regset_to_user(child, view, REGSET_FP, |
380 | 0 * sizeof(u32), | 382 | 0 * sizeof(u32), |
381 | 32 * sizeof(u32), | 383 | 32 * sizeof(u32), |
@@ -397,19 +399,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
397 | } | 399 | } |
398 | 400 | ||
399 | case PTRACE_SETFPREGS: { | 401 | case PTRACE_SETFPREGS: { |
400 | struct fps { | ||
401 | unsigned long regs[32]; | ||
402 | unsigned long fsr; | ||
403 | unsigned long flags; | ||
404 | unsigned long extra; | ||
405 | unsigned long fpqd; | ||
406 | struct fq { | ||
407 | unsigned long *insnaddr; | ||
408 | unsigned long insn; | ||
409 | } fpq[16]; | ||
410 | }; | ||
411 | struct fps __user *fps = (struct fps __user *) addr; | ||
412 | |||
413 | ret = copy_regset_from_user(child, view, REGSET_FP, | 402 | ret = copy_regset_from_user(child, view, REGSET_FP, |
414 | 0 * sizeof(u32), | 403 | 0 * sizeof(u32), |
415 | 32 * sizeof(u32), | 404 | 32 * sizeof(u32), |
@@ -424,8 +413,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
424 | 413 | ||
425 | case PTRACE_READTEXT: | 414 | case PTRACE_READTEXT: |
426 | case PTRACE_READDATA: | 415 | case PTRACE_READDATA: |
427 | ret = ptrace_readdata(child, addr, | 416 | ret = ptrace_readdata(child, addr, addr2p, data); |
428 | (void __user *) addr2, data); | ||
429 | 417 | ||
430 | if (ret == data) | 418 | if (ret == data) |
431 | ret = 0; | 419 | ret = 0; |
@@ -435,8 +423,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
435 | 423 | ||
436 | case PTRACE_WRITETEXT: | 424 | case PTRACE_WRITETEXT: |
437 | case PTRACE_WRITEDATA: | 425 | case PTRACE_WRITEDATA: |
438 | ret = ptrace_writedata(child, (void __user *) addr2, | 426 | ret = ptrace_writedata(child, addr2p, addr, data); |
439 | addr, data); | ||
440 | 427 | ||
441 | if (ret == data) | 428 | if (ret == data) |
442 | ret = 0; | 429 | ret = 0; |
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index aa90da08bf61..9ccc812bc09e 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c | |||
@@ -969,16 +969,19 @@ struct fps { | |||
969 | unsigned long fsr; | 969 | unsigned long fsr; |
970 | }; | 970 | }; |
971 | 971 | ||
972 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 972 | long arch_ptrace(struct task_struct *child, long request, |
973 | unsigned long addr, unsigned long data) | ||
973 | { | 974 | { |
974 | const struct user_regset_view *view = task_user_regset_view(current); | 975 | const struct user_regset_view *view = task_user_regset_view(current); |
975 | unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; | 976 | unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4]; |
976 | struct pt_regs __user *pregs; | 977 | struct pt_regs __user *pregs; |
977 | struct fps __user *fps; | 978 | struct fps __user *fps; |
979 | void __user *addr2p; | ||
978 | int ret; | 980 | int ret; |
979 | 981 | ||
980 | pregs = (struct pt_regs __user *) (unsigned long) addr; | 982 | pregs = (struct pt_regs __user *) addr; |
981 | fps = (struct fps __user *) (unsigned long) addr; | 983 | fps = (struct fps __user *) addr; |
984 | addr2p = (void __user *) addr2; | ||
982 | 985 | ||
983 | switch (request) { | 986 | switch (request) { |
984 | case PTRACE_PEEKUSR: | 987 | case PTRACE_PEEKUSR: |
@@ -1029,8 +1032,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1029 | 1032 | ||
1030 | case PTRACE_READTEXT: | 1033 | case PTRACE_READTEXT: |
1031 | case PTRACE_READDATA: | 1034 | case PTRACE_READDATA: |
1032 | ret = ptrace_readdata(child, addr, | 1035 | ret = ptrace_readdata(child, addr, addr2p, data); |
1033 | (char __user *)addr2, data); | ||
1034 | if (ret == data) | 1036 | if (ret == data) |
1035 | ret = 0; | 1037 | ret = 0; |
1036 | else if (ret >= 0) | 1038 | else if (ret >= 0) |
@@ -1039,8 +1041,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1039 | 1041 | ||
1040 | case PTRACE_WRITETEXT: | 1042 | case PTRACE_WRITETEXT: |
1041 | case PTRACE_WRITEDATA: | 1043 | case PTRACE_WRITEDATA: |
1042 | ret = ptrace_writedata(child, (char __user *) addr2, | 1044 | ret = ptrace_writedata(child, addr2p, addr, data); |
1043 | addr, data); | ||
1044 | if (ret == data) | 1045 | if (ret == data) |
1045 | ret = 0; | 1046 | ret = 0; |
1046 | else if (ret >= 0) | 1047 | else if (ret >= 0) |
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c index 5e50c09b7dce..4730eac0747b 100644 --- a/arch/sparc/mm/highmem.c +++ b/arch/sparc/mm/highmem.c | |||
@@ -75,7 +75,7 @@ void __kunmap_atomic(void *kvaddr) | |||
75 | return; | 75 | return; |
76 | } | 76 | } |
77 | 77 | ||
78 | type = kmap_atomic_idx_pop(); | 78 | type = kmap_atomic_idx(); |
79 | 79 | ||
80 | #ifdef CONFIG_DEBUG_HIGHMEM | 80 | #ifdef CONFIG_DEBUG_HIGHMEM |
81 | { | 81 | { |
@@ -104,6 +104,8 @@ void __kunmap_atomic(void *kvaddr) | |||
104 | #endif | 104 | #endif |
105 | } | 105 | } |
106 | #endif | 106 | #endif |
107 | |||
108 | kmap_atomic_idx_pop(); | ||
107 | pagefault_enable(); | 109 | pagefault_enable(); |
108 | } | 110 | } |
109 | EXPORT_SYMBOL(__kunmap_atomic); | 111 | EXPORT_SYMBOL(__kunmap_atomic); |
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 89cfee07efa9..7e8c2844e093 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -58,6 +58,9 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING | |||
58 | config ARCH_PHYS_ADDR_T_64BIT | 58 | config ARCH_PHYS_ADDR_T_64BIT |
59 | def_bool y | 59 | def_bool y |
60 | 60 | ||
61 | config ARCH_DMA_ADDR_T_64BIT | ||
62 | def_bool y | ||
63 | |||
61 | config LOCKDEP_SUPPORT | 64 | config LOCKDEP_SUPPORT |
62 | def_bool y | 65 | def_bool y |
63 | 66 | ||
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 5b20c2874d51..9cd29884c09f 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c | |||
@@ -45,7 +45,8 @@ void ptrace_disable(struct task_struct *child) | |||
45 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 45 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
46 | } | 46 | } |
47 | 47 | ||
48 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 48 | long arch_ptrace(struct task_struct *child, long request, |
49 | unsigned long addr, unsigned long data) | ||
49 | { | 50 | { |
50 | unsigned long __user *datap = (long __user __force *)data; | 51 | unsigned long __user *datap = (long __user __force *)data; |
51 | unsigned long tmp; | 52 | unsigned long tmp; |
@@ -57,7 +58,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
57 | switch (request) { | 58 | switch (request) { |
58 | 59 | ||
59 | case PTRACE_PEEKUSR: /* Read register from pt_regs. */ | 60 | case PTRACE_PEEKUSR: /* Read register from pt_regs. */ |
60 | if (addr < 0 || addr >= PTREGS_SIZE) | 61 | if (addr >= PTREGS_SIZE) |
61 | break; | 62 | break; |
62 | childreg = (char *)task_pt_regs(child) + addr; | 63 | childreg = (char *)task_pt_regs(child) + addr; |
63 | #ifdef CONFIG_COMPAT | 64 | #ifdef CONFIG_COMPAT |
@@ -76,7 +77,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
76 | break; | 77 | break; |
77 | 78 | ||
78 | case PTRACE_POKEUSR: /* Write register in pt_regs. */ | 79 | case PTRACE_POKEUSR: /* Write register in pt_regs. */ |
79 | if (addr < 0 || addr >= PTREGS_SIZE) | 80 | if (addr >= PTREGS_SIZE) |
80 | break; | 81 | break; |
81 | childreg = (char *)task_pt_regs(child) + addr; | 82 | childreg = (char *)task_pt_regs(child) + addr; |
82 | #ifdef CONFIG_COMPAT | 83 | #ifdef CONFIG_COMPAT |
@@ -98,7 +99,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
98 | if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) | 99 | if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) |
99 | break; | 100 | break; |
100 | childregs = (long *)task_pt_regs(child); | 101 | childregs = (long *)task_pt_regs(child); |
101 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) { | 102 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); |
103 | ++i) { | ||
102 | ret = __put_user(childregs[i], &datap[i]); | 104 | ret = __put_user(childregs[i], &datap[i]); |
103 | if (ret != 0) | 105 | if (ret != 0) |
104 | break; | 106 | break; |
@@ -109,7 +111,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
109 | if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) | 111 | if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) |
110 | break; | 112 | break; |
111 | childregs = (long *)task_pt_regs(child); | 113 | childregs = (long *)task_pt_regs(child); |
112 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) { | 114 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); |
115 | ++i) { | ||
113 | ret = __get_user(childregs[i], &datap[i]); | 116 | ret = __get_user(childregs[i], &datap[i]); |
114 | if (ret != 0) | 117 | if (ret != 0) |
115 | break; | 118 | break; |
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index f3a50e74f9a4..ae51cad12da0 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <linux/timex.h> | 30 | #include <linux/timex.h> |
31 | #include <asm/setup.h> | 31 | #include <asm/setup.h> |
32 | #include <asm/sections.h> | 32 | #include <asm/sections.h> |
33 | #include <asm/sections.h> | ||
34 | #include <asm/cacheflush.h> | ||
35 | #include <asm/cacheflush.h> | 33 | #include <asm/cacheflush.h> |
36 | #include <asm/pgalloc.h> | 34 | #include <asm/pgalloc.h> |
37 | #include <asm/mmu_context.h> | 35 | #include <asm/mmu_context.h> |
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c index 8ef6595e162c..abb57331cf6e 100644 --- a/arch/tile/mm/highmem.c +++ b/arch/tile/mm/highmem.c | |||
@@ -241,7 +241,7 @@ void __kunmap_atomic(void *kvaddr) | |||
241 | pte_t pteval = *pte; | 241 | pte_t pteval = *pte; |
242 | int idx, type; | 242 | int idx, type; |
243 | 243 | ||
244 | type = kmap_atomic_idx_pop(); | 244 | type = kmap_atomic_idx(); |
245 | idx = type + KM_TYPE_NR*smp_processor_id(); | 245 | idx = type + KM_TYPE_NR*smp_processor_id(); |
246 | 246 | ||
247 | /* | 247 | /* |
@@ -252,6 +252,7 @@ void __kunmap_atomic(void *kvaddr) | |||
252 | BUG_ON(!pte_present(pteval) && !pte_migrating(pteval)); | 252 | BUG_ON(!pte_present(pteval) && !pte_migrating(pteval)); |
253 | kmap_atomic_unregister(pte_page(pteval), vaddr); | 253 | kmap_atomic_unregister(pte_page(pteval), vaddr); |
254 | kpte_clear_flush(pte, vaddr); | 254 | kpte_clear_flush(pte, vaddr); |
255 | kmap_atomic_idx_pop(); | ||
255 | } else { | 256 | } else { |
256 | /* Must be a lowmem page */ | 257 | /* Must be a lowmem page */ |
257 | BUG_ON(vaddr < PAGE_OFFSET); | 258 | BUG_ON(vaddr < PAGE_OFFSET); |
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index e0510496596c..a5e33f29bbeb 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -42,10 +42,12 @@ void ptrace_disable(struct task_struct *child) | |||
42 | extern int peek_user(struct task_struct * child, long addr, long data); | 42 | extern int peek_user(struct task_struct * child, long addr, long data); |
43 | extern int poke_user(struct task_struct * child, long addr, long data); | 43 | extern int poke_user(struct task_struct * child, long addr, long data); |
44 | 44 | ||
45 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 45 | long arch_ptrace(struct task_struct *child, long request, |
46 | unsigned long addr, unsigned long data) | ||
46 | { | 47 | { |
47 | int i, ret; | 48 | int i, ret; |
48 | unsigned long __user *p = (void __user *)(unsigned long)data; | 49 | unsigned long __user *p = (void __user *)data; |
50 | void __user *vp = p; | ||
49 | 51 | ||
50 | switch (request) { | 52 | switch (request) { |
51 | /* read word at location addr. */ | 53 | /* read word at location addr. */ |
@@ -107,24 +109,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
107 | #endif | 109 | #endif |
108 | #ifdef PTRACE_GETFPREGS | 110 | #ifdef PTRACE_GETFPREGS |
109 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ | 111 | case PTRACE_GETFPREGS: /* Get the child FPU state. */ |
110 | ret = get_fpregs((struct user_i387_struct __user *) data, | 112 | ret = get_fpregs(vp, child); |
111 | child); | ||
112 | break; | 113 | break; |
113 | #endif | 114 | #endif |
114 | #ifdef PTRACE_SETFPREGS | 115 | #ifdef PTRACE_SETFPREGS |
115 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ | 116 | case PTRACE_SETFPREGS: /* Set the child FPU state. */ |
116 | ret = set_fpregs((struct user_i387_struct __user *) data, | 117 | ret = set_fpregs(vp, child); |
117 | child); | ||
118 | break; | 118 | break; |
119 | #endif | 119 | #endif |
120 | case PTRACE_GET_THREAD_AREA: | 120 | case PTRACE_GET_THREAD_AREA: |
121 | ret = ptrace_get_thread_area(child, addr, | 121 | ret = ptrace_get_thread_area(child, addr, vp); |
122 | (struct user_desc __user *) data); | ||
123 | break; | 122 | break; |
124 | 123 | ||
125 | case PTRACE_SET_THREAD_AREA: | 124 | case PTRACE_SET_THREAD_AREA: |
126 | ret = ptrace_set_thread_area(child, addr, | 125 | ret = ptrace_set_thread_area(child, addr, datavp); |
127 | (struct user_desc __user *) data); | ||
128 | break; | 126 | break; |
129 | 127 | ||
130 | case PTRACE_FAULTINFO: { | 128 | case PTRACE_FAULTINFO: { |
@@ -134,7 +132,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
134 | * On i386, ptrace_faultinfo is smaller! | 132 | * On i386, ptrace_faultinfo is smaller! |
135 | */ | 133 | */ |
136 | ret = copy_to_user(p, &child->thread.arch.faultinfo, | 134 | ret = copy_to_user(p, &child->thread.arch.faultinfo, |
137 | sizeof(struct ptrace_faultinfo)); | 135 | sizeof(struct ptrace_faultinfo)) ? |
136 | -EIO : 0; | ||
138 | break; | 137 | break; |
139 | } | 138 | } |
140 | 139 | ||
@@ -158,7 +157,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
158 | #ifdef PTRACE_ARCH_PRCTL | 157 | #ifdef PTRACE_ARCH_PRCTL |
159 | case PTRACE_ARCH_PRCTL: | 158 | case PTRACE_ARCH_PRCTL: |
160 | /* XXX Calls ptrace on the host - needs some SMP thinking */ | 159 | /* XXX Calls ptrace on the host - needs some SMP thinking */ |
161 | ret = arch_prctl(child, data, (void *) addr); | 160 | ret = arch_prctl(child, data, (void __user *) addr); |
162 | break; | 161 | break; |
163 | #endif | 162 | #endif |
164 | default: | 163 | default: |
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index c9b176534d65..d23b2d3ea384 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c | |||
@@ -203,8 +203,8 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child) | |||
203 | (unsigned long *) &fpregs); | 203 | (unsigned long *) &fpregs); |
204 | } | 204 | } |
205 | 205 | ||
206 | long subarch_ptrace(struct task_struct *child, long request, long addr, | 206 | long subarch_ptrace(struct task_struct *child, long request, |
207 | long data) | 207 | unsigned long addr, unsigned long data) |
208 | { | 208 | { |
209 | return -EIO; | 209 | return -EIO; |
210 | } | 210 | } |
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index f3458d7d1c5a..f43613643cdb 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c | |||
@@ -175,19 +175,18 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child) | |||
175 | return restore_fp_registers(userspace_pid[cpu], fpregs); | 175 | return restore_fp_registers(userspace_pid[cpu], fpregs); |
176 | } | 176 | } |
177 | 177 | ||
178 | long subarch_ptrace(struct task_struct *child, long request, long addr, | 178 | long subarch_ptrace(struct task_struct *child, long request, |
179 | long data) | 179 | unsigned long addr, unsigned long data) |
180 | { | 180 | { |
181 | int ret = -EIO; | 181 | int ret = -EIO; |
182 | void __user *datap = (void __user *) data; | ||
182 | 183 | ||
183 | switch (request) { | 184 | switch (request) { |
184 | case PTRACE_GETFPXREGS: /* Get the child FPU state. */ | 185 | case PTRACE_GETFPXREGS: /* Get the child FPU state. */ |
185 | ret = get_fpregs((struct user_i387_struct __user *) data, | 186 | ret = get_fpregs(datap, child); |
186 | child); | ||
187 | break; | 187 | break; |
188 | case PTRACE_SETFPXREGS: /* Set the child FPU state. */ | 188 | case PTRACE_SETFPXREGS: /* Set the child FPU state. */ |
189 | ret = set_fpregs((struct user_i387_struct __user *) data, | 189 | ret = set_fpregs(datap, child); |
190 | child); | ||
191 | break; | 190 | break; |
192 | } | 191 | } |
193 | 192 | ||
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 70c4872cd8aa..45892dc4b72a 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -801,7 +801,8 @@ void ptrace_disable(struct task_struct *child) | |||
801 | static const struct user_regset_view user_x86_32_view; /* Initialized below. */ | 801 | static const struct user_regset_view user_x86_32_view; /* Initialized below. */ |
802 | #endif | 802 | #endif |
803 | 803 | ||
804 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 804 | long arch_ptrace(struct task_struct *child, long request, |
805 | unsigned long addr, unsigned long data) | ||
805 | { | 806 | { |
806 | int ret; | 807 | int ret; |
807 | unsigned long __user *datap = (unsigned long __user *)data; | 808 | unsigned long __user *datap = (unsigned long __user *)data; |
@@ -812,8 +813,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
812 | unsigned long tmp; | 813 | unsigned long tmp; |
813 | 814 | ||
814 | ret = -EIO; | 815 | ret = -EIO; |
815 | if ((addr & (sizeof(data) - 1)) || addr < 0 || | 816 | if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user)) |
816 | addr >= sizeof(struct user)) | ||
817 | break; | 817 | break; |
818 | 818 | ||
819 | tmp = 0; /* Default return condition */ | 819 | tmp = 0; /* Default return condition */ |
@@ -830,8 +830,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
830 | 830 | ||
831 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 831 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
832 | ret = -EIO; | 832 | ret = -EIO; |
833 | if ((addr & (sizeof(data) - 1)) || addr < 0 || | 833 | if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user)) |
834 | addr >= sizeof(struct user)) | ||
835 | break; | 834 | break; |
836 | 835 | ||
837 | if (addr < sizeof(struct user_regs_struct)) | 836 | if (addr < sizeof(struct user_regs_struct)) |
@@ -888,17 +887,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
888 | 887 | ||
889 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION | 888 | #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION |
890 | case PTRACE_GET_THREAD_AREA: | 889 | case PTRACE_GET_THREAD_AREA: |
891 | if (addr < 0) | 890 | if ((int) addr < 0) |
892 | return -EIO; | 891 | return -EIO; |
893 | ret = do_get_thread_area(child, addr, | 892 | ret = do_get_thread_area(child, addr, |
894 | (struct user_desc __user *) data); | 893 | (struct user_desc __user *)data); |
895 | break; | 894 | break; |
896 | 895 | ||
897 | case PTRACE_SET_THREAD_AREA: | 896 | case PTRACE_SET_THREAD_AREA: |
898 | if (addr < 0) | 897 | if ((int) addr < 0) |
899 | return -EIO; | 898 | return -EIO; |
900 | ret = do_set_thread_area(child, addr, | 899 | ret = do_set_thread_area(child, addr, |
901 | (struct user_desc __user *) data, 0); | 900 | (struct user_desc __user *)data, 0); |
902 | break; | 901 | break; |
903 | #endif | 902 | #endif |
904 | 903 | ||
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index d723e369003c..b49962662101 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
@@ -74,7 +74,7 @@ void __kunmap_atomic(void *kvaddr) | |||
74 | vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { | 74 | vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { |
75 | int idx, type; | 75 | int idx, type; |
76 | 76 | ||
77 | type = kmap_atomic_idx_pop(); | 77 | type = kmap_atomic_idx(); |
78 | idx = type + KM_TYPE_NR * smp_processor_id(); | 78 | idx = type + KM_TYPE_NR * smp_processor_id(); |
79 | 79 | ||
80 | #ifdef CONFIG_DEBUG_HIGHMEM | 80 | #ifdef CONFIG_DEBUG_HIGHMEM |
@@ -87,6 +87,7 @@ void __kunmap_atomic(void *kvaddr) | |||
87 | * attributes or becomes a protected page in a hypervisor. | 87 | * attributes or becomes a protected page in a hypervisor. |
88 | */ | 88 | */ |
89 | kpte_clear_flush(kmap_pte-idx, vaddr); | 89 | kpte_clear_flush(kmap_pte-idx, vaddr); |
90 | kmap_atomic_idx_pop(); | ||
90 | } | 91 | } |
91 | #ifdef CONFIG_DEBUG_HIGHMEM | 92 | #ifdef CONFIG_DEBUG_HIGHMEM |
92 | else { | 93 | else { |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 84346200e783..71a59296af80 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -51,7 +51,6 @@ | |||
51 | #include <asm/numa.h> | 51 | #include <asm/numa.h> |
52 | #include <asm/cacheflush.h> | 52 | #include <asm/cacheflush.h> |
53 | #include <asm/init.h> | 53 | #include <asm/init.h> |
54 | #include <linux/bootmem.h> | ||
55 | 54 | ||
56 | static int __init parse_direct_gbpages_off(char *arg) | 55 | static int __init parse_direct_gbpages_off(char *arg) |
57 | { | 56 | { |
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 75a3d7f24a2c..7b179b499fa3 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c | |||
@@ -98,7 +98,7 @@ iounmap_atomic(void __iomem *kvaddr) | |||
98 | vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { | 98 | vaddr <= __fix_to_virt(FIX_KMAP_BEGIN)) { |
99 | int idx, type; | 99 | int idx, type; |
100 | 100 | ||
101 | type = kmap_atomic_idx_pop(); | 101 | type = kmap_atomic_idx(); |
102 | idx = type + KM_TYPE_NR * smp_processor_id(); | 102 | idx = type + KM_TYPE_NR * smp_processor_id(); |
103 | 103 | ||
104 | #ifdef CONFIG_DEBUG_HIGHMEM | 104 | #ifdef CONFIG_DEBUG_HIGHMEM |
@@ -111,6 +111,7 @@ iounmap_atomic(void __iomem *kvaddr) | |||
111 | * attributes or becomes a protected page in a hypervisor. | 111 | * attributes or becomes a protected page in a hypervisor. |
112 | */ | 112 | */ |
113 | kpte_clear_flush(kmap_pte-idx, vaddr); | 113 | kpte_clear_flush(kmap_pte-idx, vaddr); |
114 | kmap_atomic_idx_pop(); | ||
114 | } | 115 | } |
115 | 116 | ||
116 | pagefault_enable(); | 117 | pagefault_enable(); |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 580da1aa4a4c..70ddeaeb1ef3 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include <asm/pgtable.h> | 59 | #include <asm/pgtable.h> |
60 | #include <asm/tlbflush.h> | 60 | #include <asm/tlbflush.h> |
61 | #include <asm/reboot.h> | 61 | #include <asm/reboot.h> |
62 | #include <asm/setup.h> | ||
63 | #include <asm/stackprotector.h> | 62 | #include <asm/stackprotector.h> |
64 | #include <asm/hypervisor.h> | 63 | #include <asm/hypervisor.h> |
65 | 64 | ||
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 9d4e1ceb3f09..c72c9473ef99 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c | |||
@@ -256,9 +256,11 @@ int ptrace_pokeusr(struct task_struct *child, long regno, long val) | |||
256 | return 0; | 256 | return 0; |
257 | } | 257 | } |
258 | 258 | ||
259 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 259 | long arch_ptrace(struct task_struct *child, long request, |
260 | unsigned long addr, unsigned long data) | ||
260 | { | 261 | { |
261 | int ret = -EPERM; | 262 | int ret = -EPERM; |
263 | void __user *datap = (void __user *) data; | ||
262 | 264 | ||
263 | switch (request) { | 265 | switch (request) { |
264 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | 266 | case PTRACE_PEEKTEXT: /* read word at location addr. */ |
@@ -267,7 +269,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
267 | break; | 269 | break; |
268 | 270 | ||
269 | case PTRACE_PEEKUSR: /* read register specified by addr. */ | 271 | case PTRACE_PEEKUSR: /* read register specified by addr. */ |
270 | ret = ptrace_peekusr(child, addr, (void __user *) data); | 272 | ret = ptrace_peekusr(child, addr, datap); |
271 | break; | 273 | break; |
272 | 274 | ||
273 | case PTRACE_POKETEXT: /* write the word at location addr. */ | 275 | case PTRACE_POKETEXT: /* write the word at location addr. */ |
@@ -280,19 +282,19 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
280 | break; | 282 | break; |
281 | 283 | ||
282 | case PTRACE_GETREGS: | 284 | case PTRACE_GETREGS: |
283 | ret = ptrace_getregs(child, (void __user *) data); | 285 | ret = ptrace_getregs(child, datap); |
284 | break; | 286 | break; |
285 | 287 | ||
286 | case PTRACE_SETREGS: | 288 | case PTRACE_SETREGS: |
287 | ret = ptrace_setregs(child, (void __user *) data); | 289 | ret = ptrace_setregs(child, datap); |
288 | break; | 290 | break; |
289 | 291 | ||
290 | case PTRACE_GETXTREGS: | 292 | case PTRACE_GETXTREGS: |
291 | ret = ptrace_getxregs(child, (void __user *) data); | 293 | ret = ptrace_getxregs(child, datap); |
292 | break; | 294 | break; |
293 | 295 | ||
294 | case PTRACE_SETXTREGS: | 296 | case PTRACE_SETXTREGS: |
295 | ret = ptrace_setxregs(child, (void __user *) data); | 297 | ret = ptrace_setxregs(child, datap); |
296 | break; | 298 | break; |
297 | 299 | ||
298 | default: | 300 | default: |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index e7ba774beda6..25373df1dcf8 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -566,6 +566,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_ | |||
566 | struct mailbox mailbox; | 566 | struct mailbox mailbox; |
567 | 567 | ||
568 | /* Got a packet for us */ | 568 | /* Got a packet for us */ |
569 | memset(&st_loc, 0, sizeof(st_loc)); | ||
569 | ret = do_ac_read(i, buf, &st_loc, &mailbox); | 570 | ret = do_ac_read(i, buf, &st_loc, &mailbox); |
570 | spin_unlock_irqrestore(&apbs[i].mutex, flags); | 571 | spin_unlock_irqrestore(&apbs[i].mutex, flags); |
571 | set_current_state(TASK_RUNNING); | 572 | set_current_state(TASK_RUNNING); |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 3afd62e856eb..e9cba13ee800 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -713,7 +713,6 @@ static int khvcd(void *unused) | |||
713 | struct hvc_struct *hp; | 713 | struct hvc_struct *hp; |
714 | 714 | ||
715 | set_freezable(); | 715 | set_freezable(); |
716 | __set_current_state(TASK_RUNNING); | ||
717 | do { | 716 | do { |
718 | poll_mask = 0; | 717 | poll_mask = 0; |
719 | hvc_kicked = 0; | 718 | hvc_kicked = 0; |
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile index bc397d92b499..7b78e0dfc5b0 100644 --- a/drivers/char/ip2/Makefile +++ b/drivers/char/ip2/Makefile | |||
@@ -4,5 +4,5 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_COMPUTONE) += ip2.o | 5 | obj-$(CONFIG_COMPUTONE) += ip2.o |
6 | 6 | ||
7 | ip2-objs := ip2main.o | 7 | ip2-y := ip2main.o |
8 | 8 | ||
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index eb8a1a8c188e..16a93648d54e 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the ipmi drivers. | 2 | # Makefile for the ipmi drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | ipmi_si-objs := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o | 5 | ipmi_si-y := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o |
6 | 6 | ||
7 | obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o | 7 | obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o |
8 | obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o | 8 | obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 1fc8876af1f5..2aa3977aae5e 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -916,7 +916,7 @@ static struct ipmi_smi_watcher smi_watcher = | |||
916 | .smi_gone = ipmi_smi_gone, | 916 | .smi_gone = ipmi_smi_gone, |
917 | }; | 917 | }; |
918 | 918 | ||
919 | static __init int init_ipmi_devintf(void) | 919 | static int __init init_ipmi_devintf(void) |
920 | { | 920 | { |
921 | int rv; | 921 | int rv; |
922 | 922 | ||
@@ -954,7 +954,7 @@ static __init int init_ipmi_devintf(void) | |||
954 | } | 954 | } |
955 | module_init(init_ipmi_devintf); | 955 | module_init(init_ipmi_devintf); |
956 | 956 | ||
957 | static __exit void cleanup_ipmi(void) | 957 | static void __exit cleanup_ipmi(void) |
958 | { | 958 | { |
959 | struct ipmi_reg_list *entry, *entry2; | 959 | struct ipmi_reg_list *entry, *entry2; |
960 | mutex_lock(®_list_mutex); | 960 | mutex_lock(®_list_mutex); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 4f3f8c9ec262..2fe72f8edf44 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -4442,13 +4442,13 @@ static int ipmi_init_msghandler(void) | |||
4442 | return 0; | 4442 | return 0; |
4443 | } | 4443 | } |
4444 | 4444 | ||
4445 | static __init int ipmi_init_msghandler_mod(void) | 4445 | static int __init ipmi_init_msghandler_mod(void) |
4446 | { | 4446 | { |
4447 | ipmi_init_msghandler(); | 4447 | ipmi_init_msghandler(); |
4448 | return 0; | 4448 | return 0; |
4449 | } | 4449 | } |
4450 | 4450 | ||
4451 | static __exit void cleanup_ipmi(void) | 4451 | static void __exit cleanup_ipmi(void) |
4452 | { | 4452 | { |
4453 | int count; | 4453 | int count; |
4454 | 4454 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index b293d57d30a7..035da9e64a17 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1846,7 +1846,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1846 | return rv; | 1846 | return rv; |
1847 | } | 1847 | } |
1848 | 1848 | ||
1849 | static __devinit void hardcode_find_bmc(void) | 1849 | static void __devinit hardcode_find_bmc(void) |
1850 | { | 1850 | { |
1851 | int i; | 1851 | int i; |
1852 | struct smi_info *info; | 1852 | struct smi_info *info; |
@@ -2029,7 +2029,7 @@ struct SPMITable { | |||
2029 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ | 2029 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ |
2030 | }; | 2030 | }; |
2031 | 2031 | ||
2032 | static __devinit int try_init_spmi(struct SPMITable *spmi) | 2032 | static int __devinit try_init_spmi(struct SPMITable *spmi) |
2033 | { | 2033 | { |
2034 | struct smi_info *info; | 2034 | struct smi_info *info; |
2035 | 2035 | ||
@@ -2112,7 +2112,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) | |||
2112 | return 0; | 2112 | return 0; |
2113 | } | 2113 | } |
2114 | 2114 | ||
2115 | static __devinit void spmi_find_bmc(void) | 2115 | static void __devinit spmi_find_bmc(void) |
2116 | { | 2116 | { |
2117 | acpi_status status; | 2117 | acpi_status status; |
2118 | struct SPMITable *spmi; | 2118 | struct SPMITable *spmi; |
@@ -2325,7 +2325,7 @@ static int __devinit decode_dmi(const struct dmi_header *dm, | |||
2325 | return 0; | 2325 | return 0; |
2326 | } | 2326 | } |
2327 | 2327 | ||
2328 | static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) | 2328 | static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data) |
2329 | { | 2329 | { |
2330 | struct smi_info *info; | 2330 | struct smi_info *info; |
2331 | 2331 | ||
@@ -3012,7 +3012,7 @@ static __devinitdata struct ipmi_default_vals | |||
3012 | { .port = 0 } | 3012 | { .port = 0 } |
3013 | }; | 3013 | }; |
3014 | 3014 | ||
3015 | static __devinit void default_find_bmc(void) | 3015 | static void __devinit default_find_bmc(void) |
3016 | { | 3016 | { |
3017 | struct smi_info *info; | 3017 | struct smi_info *info; |
3018 | int i; | 3018 | int i; |
@@ -3312,7 +3312,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
3312 | return rv; | 3312 | return rv; |
3313 | } | 3313 | } |
3314 | 3314 | ||
3315 | static __devinit int init_ipmi_si(void) | 3315 | static int __devinit init_ipmi_si(void) |
3316 | { | 3316 | { |
3317 | int i; | 3317 | int i; |
3318 | char *str; | 3318 | char *str; |
@@ -3525,7 +3525,7 @@ static void cleanup_one_si(struct smi_info *to_clean) | |||
3525 | kfree(to_clean); | 3525 | kfree(to_clean); |
3526 | } | 3526 | } |
3527 | 3527 | ||
3528 | static __exit void cleanup_ipmi_si(void) | 3528 | static void __exit cleanup_ipmi_si(void) |
3529 | { | 3529 | { |
3530 | struct smi_info *e, *tmp_e; | 3530 | struct smi_info *e, *tmp_e; |
3531 | 3531 | ||
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index c070b53984e4..e6d75627c6c8 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -176,9 +176,9 @@ static void mmtimer_setup_int_2(int cpu, u64 expires) | |||
176 | * in order to insure that the setup succeeds in a deterministic time frame. | 176 | * in order to insure that the setup succeeds in a deterministic time frame. |
177 | * It will check if the interrupt setup succeeded. | 177 | * It will check if the interrupt setup succeeded. |
178 | */ | 178 | */ |
179 | static int mmtimer_setup(int cpu, int comparator, unsigned long expires) | 179 | static int mmtimer_setup(int cpu, int comparator, unsigned long expires, |
180 | u64 *set_completion_time) | ||
180 | { | 181 | { |
181 | |||
182 | switch (comparator) { | 182 | switch (comparator) { |
183 | case 0: | 183 | case 0: |
184 | mmtimer_setup_int_0(cpu, expires); | 184 | mmtimer_setup_int_0(cpu, expires); |
@@ -191,7 +191,8 @@ static int mmtimer_setup(int cpu, int comparator, unsigned long expires) | |||
191 | break; | 191 | break; |
192 | } | 192 | } |
193 | /* We might've missed our expiration time */ | 193 | /* We might've missed our expiration time */ |
194 | if (rtc_time() <= expires) | 194 | *set_completion_time = rtc_time(); |
195 | if (*set_completion_time <= expires) | ||
195 | return 1; | 196 | return 1; |
196 | 197 | ||
197 | /* | 198 | /* |
@@ -227,6 +228,8 @@ static int mmtimer_disable_int(long nasid, int comparator) | |||
227 | #define TIMER_OFF 0xbadcabLL /* Timer is not setup */ | 228 | #define TIMER_OFF 0xbadcabLL /* Timer is not setup */ |
228 | #define TIMER_SET 0 /* Comparator is set for this timer */ | 229 | #define TIMER_SET 0 /* Comparator is set for this timer */ |
229 | 230 | ||
231 | #define MMTIMER_INTERVAL_RETRY_INCREMENT_DEFAULT 40 | ||
232 | |||
230 | /* There is one of these for each timer */ | 233 | /* There is one of these for each timer */ |
231 | struct mmtimer { | 234 | struct mmtimer { |
232 | struct rb_node list; | 235 | struct rb_node list; |
@@ -242,6 +245,11 @@ struct mmtimer_node { | |||
242 | }; | 245 | }; |
243 | static struct mmtimer_node *timers; | 246 | static struct mmtimer_node *timers; |
244 | 247 | ||
248 | static unsigned mmtimer_interval_retry_increment = | ||
249 | MMTIMER_INTERVAL_RETRY_INCREMENT_DEFAULT; | ||
250 | module_param(mmtimer_interval_retry_increment, uint, 0644); | ||
251 | MODULE_PARM_DESC(mmtimer_interval_retry_increment, | ||
252 | "RTC ticks to add to expiration on interval retry (default 40)"); | ||
245 | 253 | ||
246 | /* | 254 | /* |
247 | * Add a new mmtimer struct to the node's mmtimer list. | 255 | * Add a new mmtimer struct to the node's mmtimer list. |
@@ -289,7 +297,8 @@ static void mmtimer_set_next_timer(int nodeid) | |||
289 | struct mmtimer_node *n = &timers[nodeid]; | 297 | struct mmtimer_node *n = &timers[nodeid]; |
290 | struct mmtimer *x; | 298 | struct mmtimer *x; |
291 | struct k_itimer *t; | 299 | struct k_itimer *t; |
292 | int o; | 300 | u64 expires, exp, set_completion_time; |
301 | int i; | ||
293 | 302 | ||
294 | restart: | 303 | restart: |
295 | if (n->next == NULL) | 304 | if (n->next == NULL) |
@@ -300,7 +309,8 @@ restart: | |||
300 | if (!t->it.mmtimer.incr) { | 309 | if (!t->it.mmtimer.incr) { |
301 | /* Not an interval timer */ | 310 | /* Not an interval timer */ |
302 | if (!mmtimer_setup(x->cpu, COMPARATOR, | 311 | if (!mmtimer_setup(x->cpu, COMPARATOR, |
303 | t->it.mmtimer.expires)) { | 312 | t->it.mmtimer.expires, |
313 | &set_completion_time)) { | ||
304 | /* Late setup, fire now */ | 314 | /* Late setup, fire now */ |
305 | tasklet_schedule(&n->tasklet); | 315 | tasklet_schedule(&n->tasklet); |
306 | } | 316 | } |
@@ -308,14 +318,23 @@ restart: | |||
308 | } | 318 | } |
309 | 319 | ||
310 | /* Interval timer */ | 320 | /* Interval timer */ |
311 | o = 0; | 321 | i = 0; |
312 | while (!mmtimer_setup(x->cpu, COMPARATOR, t->it.mmtimer.expires)) { | 322 | expires = exp = t->it.mmtimer.expires; |
313 | unsigned long e, e1; | 323 | while (!mmtimer_setup(x->cpu, COMPARATOR, expires, |
314 | struct rb_node *next; | 324 | &set_completion_time)) { |
315 | t->it.mmtimer.expires += t->it.mmtimer.incr << o; | 325 | int to; |
316 | t->it_overrun += 1 << o; | 326 | |
317 | o++; | 327 | i++; |
318 | if (o > 20) { | 328 | expires = set_completion_time + |
329 | mmtimer_interval_retry_increment + (1 << i); | ||
330 | /* Calculate overruns as we go. */ | ||
331 | to = ((u64)(expires - exp) / t->it.mmtimer.incr); | ||
332 | if (to) { | ||
333 | t->it_overrun += to; | ||
334 | t->it.mmtimer.expires += t->it.mmtimer.incr * to; | ||
335 | exp = t->it.mmtimer.expires; | ||
336 | } | ||
337 | if (i > 20) { | ||
319 | printk(KERN_ALERT "mmtimer: cannot reschedule timer\n"); | 338 | printk(KERN_ALERT "mmtimer: cannot reschedule timer\n"); |
320 | t->it.mmtimer.clock = TIMER_OFF; | 339 | t->it.mmtimer.clock = TIMER_OFF; |
321 | n->next = rb_next(&x->list); | 340 | n->next = rb_next(&x->list); |
@@ -323,21 +342,6 @@ restart: | |||
323 | kfree(x); | 342 | kfree(x); |
324 | goto restart; | 343 | goto restart; |
325 | } | 344 | } |
326 | |||
327 | e = t->it.mmtimer.expires; | ||
328 | next = rb_next(&x->list); | ||
329 | |||
330 | if (next == NULL) | ||
331 | continue; | ||
332 | |||
333 | e1 = rb_entry(next, struct mmtimer, list)-> | ||
334 | timer->it.mmtimer.expires; | ||
335 | if (e > e1) { | ||
336 | n->next = next; | ||
337 | rb_erase(&x->list, &n->timer_head); | ||
338 | mmtimer_add_list(x); | ||
339 | goto restart; | ||
340 | } | ||
341 | } | 345 | } |
342 | } | 346 | } |
343 | 347 | ||
diff --git a/drivers/char/mwave/Makefile b/drivers/char/mwave/Makefile index 754c9e2058ed..26b4fce217b6 100644 --- a/drivers/char/mwave/Makefile +++ b/drivers/char/mwave/Makefile | |||
@@ -6,10 +6,10 @@ | |||
6 | 6 | ||
7 | obj-$(CONFIG_MWAVE) += mwave.o | 7 | obj-$(CONFIG_MWAVE) += mwave.o |
8 | 8 | ||
9 | mwave-objs := mwavedd.o smapi.o tp3780i.o 3780i.o | 9 | mwave-y := mwavedd.o smapi.o tp3780i.o 3780i.o |
10 | 10 | ||
11 | # To have the mwave driver disable other uarts if necessary | 11 | # To have the mwave driver disable other uarts if necessary |
12 | # EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES | 12 | # EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES |
13 | 13 | ||
14 | # To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: | 14 | # To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: |
15 | EXTRA_CFLAGS += -DMW_TRACE | 15 | ccflags-y := -DMW_TRACE |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 463df27494bd..dd9d75351cd6 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -303,6 +303,7 @@ static void mxser_enable_must_enchance_mode(unsigned long baseio) | |||
303 | outb(oldlcr, baseio + UART_LCR); | 303 | outb(oldlcr, baseio + UART_LCR); |
304 | } | 304 | } |
305 | 305 | ||
306 | #ifdef CONFIG_PCI | ||
306 | static void mxser_disable_must_enchance_mode(unsigned long baseio) | 307 | static void mxser_disable_must_enchance_mode(unsigned long baseio) |
307 | { | 308 | { |
308 | u8 oldlcr; | 309 | u8 oldlcr; |
@@ -317,6 +318,7 @@ static void mxser_disable_must_enchance_mode(unsigned long baseio) | |||
317 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | 318 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); |
318 | outb(oldlcr, baseio + UART_LCR); | 319 | outb(oldlcr, baseio + UART_LCR); |
319 | } | 320 | } |
321 | #endif | ||
320 | 322 | ||
321 | static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) | 323 | static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) |
322 | { | 324 | { |
@@ -388,6 +390,7 @@ static void mxser_set_must_enum_value(unsigned long baseio, u8 value) | |||
388 | outb(oldlcr, baseio + UART_LCR); | 390 | outb(oldlcr, baseio + UART_LCR); |
389 | } | 391 | } |
390 | 392 | ||
393 | #ifdef CONFIG_PCI | ||
391 | static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) | 394 | static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) |
392 | { | 395 | { |
393 | u8 oldlcr; | 396 | u8 oldlcr; |
@@ -404,6 +407,7 @@ static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) | |||
404 | *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); | 407 | *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); |
405 | outb(oldlcr, baseio + UART_LCR); | 408 | outb(oldlcr, baseio + UART_LCR); |
406 | } | 409 | } |
410 | #endif | ||
407 | 411 | ||
408 | static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) | 412 | static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) |
409 | { | 413 | { |
diff --git a/drivers/char/pcmcia/ipwireless/Makefile b/drivers/char/pcmcia/ipwireless/Makefile index b71eb593643d..db80873d7f20 100644 --- a/drivers/char/pcmcia/ipwireless/Makefile +++ b/drivers/char/pcmcia/ipwireless/Makefile | |||
@@ -6,5 +6,5 @@ | |||
6 | 6 | ||
7 | obj-$(CONFIG_IPWIRELESS) += ipwireless.o | 7 | obj-$(CONFIG_IPWIRELESS) += ipwireless.o |
8 | 8 | ||
9 | ipwireless-objs := hardware.o main.o network.o tty.o | 9 | ipwireless-y := hardware.o main.o network.o tty.o |
10 | 10 | ||
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 723152d978a9..f176dbaeb15a 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -613,6 +613,7 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
613 | 613 | ||
614 | case PPGETTIME: | 614 | case PPGETTIME: |
615 | to_jiffies = pp->pdev->timeout; | 615 | to_jiffies = pp->pdev->timeout; |
616 | memset(&par_timeout, 0, sizeof(par_timeout)); | ||
616 | par_timeout.tv_sec = to_jiffies / HZ; | 617 | par_timeout.tv_sec = to_jiffies / HZ; |
617 | par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ); | 618 | par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ); |
618 | if (copy_to_user (argp, &par_timeout, sizeof(struct timeval))) | 619 | if (copy_to_user (argp, &par_timeout, sizeof(struct timeval))) |
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index 74f00b5ffa36..73dcb0ee41fd 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/ramoops.h> | ||
28 | 30 | ||
29 | #define RAMOOPS_KERNMSG_HDR "====" | 31 | #define RAMOOPS_KERNMSG_HDR "====" |
30 | #define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) | 32 | #define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) |
@@ -91,11 +93,17 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
91 | cxt->count = (cxt->count + 1) % cxt->max_count; | 93 | cxt->count = (cxt->count + 1) % cxt->max_count; |
92 | } | 94 | } |
93 | 95 | ||
94 | static int __init ramoops_init(void) | 96 | static int __init ramoops_probe(struct platform_device *pdev) |
95 | { | 97 | { |
98 | struct ramoops_platform_data *pdata = pdev->dev.platform_data; | ||
96 | struct ramoops_context *cxt = &oops_cxt; | 99 | struct ramoops_context *cxt = &oops_cxt; |
97 | int err = -EINVAL; | 100 | int err = -EINVAL; |
98 | 101 | ||
102 | if (pdata) { | ||
103 | mem_size = pdata->mem_size; | ||
104 | mem_address = pdata->mem_address; | ||
105 | } | ||
106 | |||
99 | if (!mem_size) { | 107 | if (!mem_size) { |
100 | printk(KERN_ERR "ramoops: invalid size specification"); | 108 | printk(KERN_ERR "ramoops: invalid size specification"); |
101 | goto fail3; | 109 | goto fail3; |
@@ -142,7 +150,7 @@ fail3: | |||
142 | return err; | 150 | return err; |
143 | } | 151 | } |
144 | 152 | ||
145 | static void __exit ramoops_exit(void) | 153 | static int __exit ramoops_remove(struct platform_device *pdev) |
146 | { | 154 | { |
147 | struct ramoops_context *cxt = &oops_cxt; | 155 | struct ramoops_context *cxt = &oops_cxt; |
148 | 156 | ||
@@ -151,8 +159,26 @@ static void __exit ramoops_exit(void) | |||
151 | 159 | ||
152 | iounmap(cxt->virt_addr); | 160 | iounmap(cxt->virt_addr); |
153 | release_mem_region(cxt->phys_addr, cxt->size); | 161 | release_mem_region(cxt->phys_addr, cxt->size); |
162 | return 0; | ||
154 | } | 163 | } |
155 | 164 | ||
165 | static struct platform_driver ramoops_driver = { | ||
166 | .remove = __exit_p(ramoops_remove), | ||
167 | .driver = { | ||
168 | .name = "ramoops", | ||
169 | .owner = THIS_MODULE, | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | static int __init ramoops_init(void) | ||
174 | { | ||
175 | return platform_driver_probe(&ramoops_driver, ramoops_probe); | ||
176 | } | ||
177 | |||
178 | static void __exit ramoops_exit(void) | ||
179 | { | ||
180 | platform_driver_unregister(&ramoops_driver); | ||
181 | } | ||
156 | 182 | ||
157 | module_init(ramoops_init); | 183 | module_init(ramoops_init); |
158 | module_exit(ramoops_exit); | 184 | module_exit(ramoops_exit); |
diff --git a/drivers/char/rio/Makefile b/drivers/char/rio/Makefile index 2d1c5a7cba7d..1661875883fb 100644 --- a/drivers/char/rio/Makefile +++ b/drivers/char/rio/Makefile | |||
@@ -8,5 +8,5 @@ | |||
8 | 8 | ||
9 | obj-$(CONFIG_RIO) += rio.o | 9 | obj-$(CONFIG_RIO) += rio.o |
10 | 10 | ||
11 | rio-objs := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ | 11 | rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ |
12 | rioparam.o rioroute.o riotable.o riotty.o | 12 | rioparam.o rioroute.o riotable.o riotty.o |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 7c79d243acc9..86308830ac42 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -2345,7 +2345,7 @@ static int __init rp_init(void) | |||
2345 | ret = tty_register_driver(rocket_driver); | 2345 | ret = tty_register_driver(rocket_driver); |
2346 | if (ret < 0) { | 2346 | if (ret < 0) { |
2347 | printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); | 2347 | printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); |
2348 | goto err_tty; | 2348 | goto err_controller; |
2349 | } | 2349 | } |
2350 | 2350 | ||
2351 | #ifdef ROCKET_DEBUG_OPEN | 2351 | #ifdef ROCKET_DEBUG_OPEN |
@@ -2380,6 +2380,9 @@ static int __init rp_init(void) | |||
2380 | return 0; | 2380 | return 0; |
2381 | err_ttyu: | 2381 | err_ttyu: |
2382 | tty_unregister_driver(rocket_driver); | 2382 | tty_unregister_driver(rocket_driver); |
2383 | err_controller: | ||
2384 | if (controller) | ||
2385 | release_region(controller, 4); | ||
2383 | err_tty: | 2386 | err_tty: |
2384 | put_tty_driver(rocket_driver); | 2387 | put_tty_driver(rocket_driver); |
2385 | err: | 2388 | err: |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 1746d91205f7..d01fffeac951 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -301,6 +301,8 @@ struct slgt_info { | |||
301 | unsigned int rx_pio; | 301 | unsigned int rx_pio; |
302 | unsigned int if_mode; | 302 | unsigned int if_mode; |
303 | unsigned int base_clock; | 303 | unsigned int base_clock; |
304 | unsigned int xsync; | ||
305 | unsigned int xctrl; | ||
304 | 306 | ||
305 | /* device status */ | 307 | /* device status */ |
306 | 308 | ||
@@ -405,6 +407,8 @@ static MGSL_PARAMS default_params = { | |||
405 | #define TDCSR 0x94 /* tx DMA control/status */ | 407 | #define TDCSR 0x94 /* tx DMA control/status */ |
406 | #define RDDAR 0x98 /* rx DMA descriptor address */ | 408 | #define RDDAR 0x98 /* rx DMA descriptor address */ |
407 | #define TDDAR 0x9c /* tx DMA descriptor address */ | 409 | #define TDDAR 0x9c /* tx DMA descriptor address */ |
410 | #define XSR 0x40 /* extended sync pattern */ | ||
411 | #define XCR 0x44 /* extended control */ | ||
408 | 412 | ||
409 | #define RXIDLE BIT14 | 413 | #define RXIDLE BIT14 |
410 | #define RXBREAK BIT14 | 414 | #define RXBREAK BIT14 |
@@ -517,6 +521,10 @@ static int set_interface(struct slgt_info *info, int if_mode); | |||
517 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 521 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
518 | static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 522 | static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
519 | static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 523 | static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
524 | static int get_xsync(struct slgt_info *info, int __user *if_mode); | ||
525 | static int set_xsync(struct slgt_info *info, int if_mode); | ||
526 | static int get_xctrl(struct slgt_info *info, int __user *if_mode); | ||
527 | static int set_xctrl(struct slgt_info *info, int if_mode); | ||
520 | 528 | ||
521 | /* | 529 | /* |
522 | * driver functions | 530 | * driver functions |
@@ -1056,6 +1064,14 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1056 | return get_gpio(info, argp); | 1064 | return get_gpio(info, argp); |
1057 | case MGSL_IOCWAITGPIO: | 1065 | case MGSL_IOCWAITGPIO: |
1058 | return wait_gpio(info, argp); | 1066 | return wait_gpio(info, argp); |
1067 | case MGSL_IOCGXSYNC: | ||
1068 | return get_xsync(info, argp); | ||
1069 | case MGSL_IOCSXSYNC: | ||
1070 | return set_xsync(info, (int)arg); | ||
1071 | case MGSL_IOCGXCTRL: | ||
1072 | return get_xctrl(info, argp); | ||
1073 | case MGSL_IOCSXCTRL: | ||
1074 | return set_xctrl(info, (int)arg); | ||
1059 | } | 1075 | } |
1060 | mutex_lock(&info->port.mutex); | 1076 | mutex_lock(&info->port.mutex); |
1061 | switch (cmd) { | 1077 | switch (cmd) { |
@@ -1132,6 +1148,7 @@ static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *us | |||
1132 | struct MGSL_PARAMS32 tmp_params; | 1148 | struct MGSL_PARAMS32 tmp_params; |
1133 | 1149 | ||
1134 | DBGINFO(("%s get_params32\n", info->device_name)); | 1150 | DBGINFO(("%s get_params32\n", info->device_name)); |
1151 | memset(&tmp_params, 0, sizeof(tmp_params)); | ||
1135 | tmp_params.mode = (compat_ulong_t)info->params.mode; | 1152 | tmp_params.mode = (compat_ulong_t)info->params.mode; |
1136 | tmp_params.loopback = info->params.loopback; | 1153 | tmp_params.loopback = info->params.loopback; |
1137 | tmp_params.flags = info->params.flags; | 1154 | tmp_params.flags = info->params.flags; |
@@ -1212,12 +1229,16 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, | |||
1212 | case MGSL_IOCSGPIO: | 1229 | case MGSL_IOCSGPIO: |
1213 | case MGSL_IOCGGPIO: | 1230 | case MGSL_IOCGGPIO: |
1214 | case MGSL_IOCWAITGPIO: | 1231 | case MGSL_IOCWAITGPIO: |
1232 | case MGSL_IOCGXSYNC: | ||
1233 | case MGSL_IOCGXCTRL: | ||
1215 | case MGSL_IOCSTXIDLE: | 1234 | case MGSL_IOCSTXIDLE: |
1216 | case MGSL_IOCTXENABLE: | 1235 | case MGSL_IOCTXENABLE: |
1217 | case MGSL_IOCRXENABLE: | 1236 | case MGSL_IOCRXENABLE: |
1218 | case MGSL_IOCTXABORT: | 1237 | case MGSL_IOCTXABORT: |
1219 | case TIOCMIWAIT: | 1238 | case TIOCMIWAIT: |
1220 | case MGSL_IOCSIF: | 1239 | case MGSL_IOCSIF: |
1240 | case MGSL_IOCSXSYNC: | ||
1241 | case MGSL_IOCSXCTRL: | ||
1221 | rc = ioctl(tty, file, cmd, arg); | 1242 | rc = ioctl(tty, file, cmd, arg); |
1222 | break; | 1243 | break; |
1223 | } | 1244 | } |
@@ -1617,6 +1638,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1617 | if (cmd != SIOCWANDEV) | 1638 | if (cmd != SIOCWANDEV) |
1618 | return hdlc_ioctl(dev, ifr, cmd); | 1639 | return hdlc_ioctl(dev, ifr, cmd); |
1619 | 1640 | ||
1641 | memset(&new_line, 0, sizeof(new_line)); | ||
1642 | |||
1620 | switch(ifr->ifr_settings.type) { | 1643 | switch(ifr->ifr_settings.type) { |
1621 | case IF_GET_IFACE: /* return current sync_serial_settings */ | 1644 | case IF_GET_IFACE: /* return current sync_serial_settings */ |
1622 | 1645 | ||
@@ -1958,6 +1981,7 @@ static void bh_handler(struct work_struct *work) | |||
1958 | case MGSL_MODE_RAW: | 1981 | case MGSL_MODE_RAW: |
1959 | case MGSL_MODE_MONOSYNC: | 1982 | case MGSL_MODE_MONOSYNC: |
1960 | case MGSL_MODE_BISYNC: | 1983 | case MGSL_MODE_BISYNC: |
1984 | case MGSL_MODE_XSYNC: | ||
1961 | while(rx_get_buf(info)); | 1985 | while(rx_get_buf(info)); |
1962 | break; | 1986 | break; |
1963 | } | 1987 | } |
@@ -2357,26 +2381,27 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id) | |||
2357 | 2381 | ||
2358 | DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); | 2382 | DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); |
2359 | 2383 | ||
2360 | spin_lock(&info->lock); | ||
2361 | |||
2362 | while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { | 2384 | while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { |
2363 | DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); | 2385 | DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); |
2364 | info->irq_occurred = true; | 2386 | info->irq_occurred = true; |
2365 | for(i=0; i < info->port_count ; i++) { | 2387 | for(i=0; i < info->port_count ; i++) { |
2366 | if (info->port_array[i] == NULL) | 2388 | if (info->port_array[i] == NULL) |
2367 | continue; | 2389 | continue; |
2390 | spin_lock(&info->port_array[i]->lock); | ||
2368 | if (gsr & (BIT8 << i)) | 2391 | if (gsr & (BIT8 << i)) |
2369 | isr_serial(info->port_array[i]); | 2392 | isr_serial(info->port_array[i]); |
2370 | if (gsr & (BIT16 << (i*2))) | 2393 | if (gsr & (BIT16 << (i*2))) |
2371 | isr_rdma(info->port_array[i]); | 2394 | isr_rdma(info->port_array[i]); |
2372 | if (gsr & (BIT17 << (i*2))) | 2395 | if (gsr & (BIT17 << (i*2))) |
2373 | isr_tdma(info->port_array[i]); | 2396 | isr_tdma(info->port_array[i]); |
2397 | spin_unlock(&info->port_array[i]->lock); | ||
2374 | } | 2398 | } |
2375 | } | 2399 | } |
2376 | 2400 | ||
2377 | if (info->gpio_present) { | 2401 | if (info->gpio_present) { |
2378 | unsigned int state; | 2402 | unsigned int state; |
2379 | unsigned int changed; | 2403 | unsigned int changed; |
2404 | spin_lock(&info->lock); | ||
2380 | while ((changed = rd_reg32(info, IOSR)) != 0) { | 2405 | while ((changed = rd_reg32(info, IOSR)) != 0) { |
2381 | DBGISR(("%s iosr=%08x\n", info->device_name, changed)); | 2406 | DBGISR(("%s iosr=%08x\n", info->device_name, changed)); |
2382 | /* read latched state of GPIO signals */ | 2407 | /* read latched state of GPIO signals */ |
@@ -2388,22 +2413,24 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id) | |||
2388 | isr_gpio(info->port_array[i], changed, state); | 2413 | isr_gpio(info->port_array[i], changed, state); |
2389 | } | 2414 | } |
2390 | } | 2415 | } |
2416 | spin_unlock(&info->lock); | ||
2391 | } | 2417 | } |
2392 | 2418 | ||
2393 | for(i=0; i < info->port_count ; i++) { | 2419 | for(i=0; i < info->port_count ; i++) { |
2394 | struct slgt_info *port = info->port_array[i]; | 2420 | struct slgt_info *port = info->port_array[i]; |
2395 | 2421 | if (port == NULL) | |
2396 | if (port && (port->port.count || port->netcount) && | 2422 | continue; |
2423 | spin_lock(&port->lock); | ||
2424 | if ((port->port.count || port->netcount) && | ||
2397 | port->pending_bh && !port->bh_running && | 2425 | port->pending_bh && !port->bh_running && |
2398 | !port->bh_requested) { | 2426 | !port->bh_requested) { |
2399 | DBGISR(("%s bh queued\n", port->device_name)); | 2427 | DBGISR(("%s bh queued\n", port->device_name)); |
2400 | schedule_work(&port->task); | 2428 | schedule_work(&port->task); |
2401 | port->bh_requested = true; | 2429 | port->bh_requested = true; |
2402 | } | 2430 | } |
2431 | spin_unlock(&port->lock); | ||
2403 | } | 2432 | } |
2404 | 2433 | ||
2405 | spin_unlock(&info->lock); | ||
2406 | |||
2407 | DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); | 2434 | DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); |
2408 | return IRQ_HANDLED; | 2435 | return IRQ_HANDLED; |
2409 | } | 2436 | } |
@@ -2883,6 +2910,69 @@ static int set_interface(struct slgt_info *info, int if_mode) | |||
2883 | return 0; | 2910 | return 0; |
2884 | } | 2911 | } |
2885 | 2912 | ||
2913 | static int get_xsync(struct slgt_info *info, int __user *xsync) | ||
2914 | { | ||
2915 | DBGINFO(("%s get_xsync=%x\n", info->device_name, info->xsync)); | ||
2916 | if (put_user(info->xsync, xsync)) | ||
2917 | return -EFAULT; | ||
2918 | return 0; | ||
2919 | } | ||
2920 | |||
2921 | /* | ||
2922 | * set extended sync pattern (1 to 4 bytes) for extended sync mode | ||
2923 | * | ||
2924 | * sync pattern is contained in least significant bytes of value | ||
2925 | * most significant byte of sync pattern is oldest (1st sent/detected) | ||
2926 | */ | ||
2927 | static int set_xsync(struct slgt_info *info, int xsync) | ||
2928 | { | ||
2929 | unsigned long flags; | ||
2930 | |||
2931 | DBGINFO(("%s set_xsync=%x)\n", info->device_name, xsync)); | ||
2932 | spin_lock_irqsave(&info->lock, flags); | ||
2933 | info->xsync = xsync; | ||
2934 | wr_reg32(info, XSR, xsync); | ||
2935 | spin_unlock_irqrestore(&info->lock, flags); | ||
2936 | return 0; | ||
2937 | } | ||
2938 | |||
2939 | static int get_xctrl(struct slgt_info *info, int __user *xctrl) | ||
2940 | { | ||
2941 | DBGINFO(("%s get_xctrl=%x\n", info->device_name, info->xctrl)); | ||
2942 | if (put_user(info->xctrl, xctrl)) | ||
2943 | return -EFAULT; | ||
2944 | return 0; | ||
2945 | } | ||
2946 | |||
2947 | /* | ||
2948 | * set extended control options | ||
2949 | * | ||
2950 | * xctrl[31:19] reserved, must be zero | ||
2951 | * xctrl[18:17] extended sync pattern length in bytes | ||
2952 | * 00 = 1 byte in xsr[7:0] | ||
2953 | * 01 = 2 bytes in xsr[15:0] | ||
2954 | * 10 = 3 bytes in xsr[23:0] | ||
2955 | * 11 = 4 bytes in xsr[31:0] | ||
2956 | * xctrl[16] 1 = enable terminal count, 0=disabled | ||
2957 | * xctrl[15:0] receive terminal count for fixed length packets | ||
2958 | * value is count minus one (0 = 1 byte packet) | ||
2959 | * when terminal count is reached, receiver | ||
2960 | * automatically returns to hunt mode and receive | ||
2961 | * FIFO contents are flushed to DMA buffers with | ||
2962 | * end of frame (EOF) status | ||
2963 | */ | ||
2964 | static int set_xctrl(struct slgt_info *info, int xctrl) | ||
2965 | { | ||
2966 | unsigned long flags; | ||
2967 | |||
2968 | DBGINFO(("%s set_xctrl=%x)\n", info->device_name, xctrl)); | ||
2969 | spin_lock_irqsave(&info->lock, flags); | ||
2970 | info->xctrl = xctrl; | ||
2971 | wr_reg32(info, XCR, xctrl); | ||
2972 | spin_unlock_irqrestore(&info->lock, flags); | ||
2973 | return 0; | ||
2974 | } | ||
2975 | |||
2886 | /* | 2976 | /* |
2887 | * set general purpose IO pin state and direction | 2977 | * set general purpose IO pin state and direction |
2888 | * | 2978 | * |
@@ -2906,7 +2996,7 @@ static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
2906 | info->device_name, gpio.state, gpio.smask, | 2996 | info->device_name, gpio.state, gpio.smask, |
2907 | gpio.dir, gpio.dmask)); | 2997 | gpio.dir, gpio.dmask)); |
2908 | 2998 | ||
2909 | spin_lock_irqsave(&info->lock,flags); | 2999 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
2910 | if (gpio.dmask) { | 3000 | if (gpio.dmask) { |
2911 | data = rd_reg32(info, IODR); | 3001 | data = rd_reg32(info, IODR); |
2912 | data |= gpio.dmask & gpio.dir; | 3002 | data |= gpio.dmask & gpio.dir; |
@@ -2919,7 +3009,7 @@ static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
2919 | data &= ~(gpio.smask & ~gpio.state); | 3009 | data &= ~(gpio.smask & ~gpio.state); |
2920 | wr_reg32(info, IOVR, data); | 3010 | wr_reg32(info, IOVR, data); |
2921 | } | 3011 | } |
2922 | spin_unlock_irqrestore(&info->lock,flags); | 3012 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
2923 | 3013 | ||
2924 | return 0; | 3014 | return 0; |
2925 | } | 3015 | } |
@@ -3020,7 +3110,7 @@ static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
3020 | return -EINVAL; | 3110 | return -EINVAL; |
3021 | init_cond_wait(&wait, gpio.smask); | 3111 | init_cond_wait(&wait, gpio.smask); |
3022 | 3112 | ||
3023 | spin_lock_irqsave(&info->lock, flags); | 3113 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
3024 | /* enable interrupts for watched pins */ | 3114 | /* enable interrupts for watched pins */ |
3025 | wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); | 3115 | wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); |
3026 | /* get current pin states */ | 3116 | /* get current pin states */ |
@@ -3032,20 +3122,20 @@ static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
3032 | } else { | 3122 | } else { |
3033 | /* wait for target state */ | 3123 | /* wait for target state */ |
3034 | add_cond_wait(&info->gpio_wait_q, &wait); | 3124 | add_cond_wait(&info->gpio_wait_q, &wait); |
3035 | spin_unlock_irqrestore(&info->lock, flags); | 3125 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
3036 | schedule(); | 3126 | schedule(); |
3037 | if (signal_pending(current)) | 3127 | if (signal_pending(current)) |
3038 | rc = -ERESTARTSYS; | 3128 | rc = -ERESTARTSYS; |
3039 | else | 3129 | else |
3040 | gpio.state = wait.data; | 3130 | gpio.state = wait.data; |
3041 | spin_lock_irqsave(&info->lock, flags); | 3131 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
3042 | remove_cond_wait(&info->gpio_wait_q, &wait); | 3132 | remove_cond_wait(&info->gpio_wait_q, &wait); |
3043 | } | 3133 | } |
3044 | 3134 | ||
3045 | /* disable all GPIO interrupts if no waiting processes */ | 3135 | /* disable all GPIO interrupts if no waiting processes */ |
3046 | if (info->gpio_wait_q == NULL) | 3136 | if (info->gpio_wait_q == NULL) |
3047 | wr_reg32(info, IOER, 0); | 3137 | wr_reg32(info, IOER, 0); |
3048 | spin_unlock_irqrestore(&info->lock,flags); | 3138 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
3049 | 3139 | ||
3050 | if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) | 3140 | if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) |
3051 | rc = -EFAULT; | 3141 | rc = -EFAULT; |
@@ -3578,7 +3668,6 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3578 | 3668 | ||
3579 | /* copy resource information from first port to others */ | 3669 | /* copy resource information from first port to others */ |
3580 | for (i = 1; i < port_count; ++i) { | 3670 | for (i = 1; i < port_count; ++i) { |
3581 | port_array[i]->lock = port_array[0]->lock; | ||
3582 | port_array[i]->irq_level = port_array[0]->irq_level; | 3671 | port_array[i]->irq_level = port_array[0]->irq_level; |
3583 | port_array[i]->reg_addr = port_array[0]->reg_addr; | 3672 | port_array[i]->reg_addr = port_array[0]->reg_addr; |
3584 | alloc_dma_bufs(port_array[i]); | 3673 | alloc_dma_bufs(port_array[i]); |
@@ -3763,7 +3852,9 @@ module_exit(slgt_exit); | |||
3763 | #define CALC_REGADDR() \ | 3852 | #define CALC_REGADDR() \ |
3764 | unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ | 3853 | unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ |
3765 | if (addr >= 0x80) \ | 3854 | if (addr >= 0x80) \ |
3766 | reg_addr += (info->port_num) * 32; | 3855 | reg_addr += (info->port_num) * 32; \ |
3856 | else if (addr >= 0x40) \ | ||
3857 | reg_addr += (info->port_num) * 16; | ||
3767 | 3858 | ||
3768 | static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) | 3859 | static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) |
3769 | { | 3860 | { |
@@ -4182,7 +4273,13 @@ static void sync_mode(struct slgt_info *info) | |||
4182 | 4273 | ||
4183 | /* TCR (tx control) | 4274 | /* TCR (tx control) |
4184 | * | 4275 | * |
4185 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync | 4276 | * 15..13 mode |
4277 | * 000=HDLC/SDLC | ||
4278 | * 001=raw bit synchronous | ||
4279 | * 010=asynchronous/isochronous | ||
4280 | * 011=monosync byte synchronous | ||
4281 | * 100=bisync byte synchronous | ||
4282 | * 101=xsync byte synchronous | ||
4186 | * 12..10 encoding | 4283 | * 12..10 encoding |
4187 | * 09 CRC enable | 4284 | * 09 CRC enable |
4188 | * 08 CRC32 | 4285 | * 08 CRC32 |
@@ -4197,6 +4294,9 @@ static void sync_mode(struct slgt_info *info) | |||
4197 | val = BIT2; | 4294 | val = BIT2; |
4198 | 4295 | ||
4199 | switch(info->params.mode) { | 4296 | switch(info->params.mode) { |
4297 | case MGSL_MODE_XSYNC: | ||
4298 | val |= BIT15 + BIT13; | ||
4299 | break; | ||
4200 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; | 4300 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4201 | case MGSL_MODE_BISYNC: val |= BIT15; break; | 4301 | case MGSL_MODE_BISYNC: val |= BIT15; break; |
4202 | case MGSL_MODE_RAW: val |= BIT13; break; | 4302 | case MGSL_MODE_RAW: val |= BIT13; break; |
@@ -4251,7 +4351,13 @@ static void sync_mode(struct slgt_info *info) | |||
4251 | 4351 | ||
4252 | /* RCR (rx control) | 4352 | /* RCR (rx control) |
4253 | * | 4353 | * |
4254 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync | 4354 | * 15..13 mode |
4355 | * 000=HDLC/SDLC | ||
4356 | * 001=raw bit synchronous | ||
4357 | * 010=asynchronous/isochronous | ||
4358 | * 011=monosync byte synchronous | ||
4359 | * 100=bisync byte synchronous | ||
4360 | * 101=xsync byte synchronous | ||
4255 | * 12..10 encoding | 4361 | * 12..10 encoding |
4256 | * 09 CRC enable | 4362 | * 09 CRC enable |
4257 | * 08 CRC32 | 4363 | * 08 CRC32 |
@@ -4263,6 +4369,9 @@ static void sync_mode(struct slgt_info *info) | |||
4263 | val = 0; | 4369 | val = 0; |
4264 | 4370 | ||
4265 | switch(info->params.mode) { | 4371 | switch(info->params.mode) { |
4372 | case MGSL_MODE_XSYNC: | ||
4373 | val |= BIT15 + BIT13; | ||
4374 | break; | ||
4266 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; | 4375 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4267 | case MGSL_MODE_BISYNC: val |= BIT15; break; | 4376 | case MGSL_MODE_BISYNC: val |= BIT15; break; |
4268 | case MGSL_MODE_RAW: val |= BIT13; break; | 4377 | case MGSL_MODE_RAW: val |= BIT13; break; |
@@ -4679,6 +4788,7 @@ static bool rx_get_buf(struct slgt_info *info) | |||
4679 | switch(info->params.mode) { | 4788 | switch(info->params.mode) { |
4680 | case MGSL_MODE_MONOSYNC: | 4789 | case MGSL_MODE_MONOSYNC: |
4681 | case MGSL_MODE_BISYNC: | 4790 | case MGSL_MODE_BISYNC: |
4791 | case MGSL_MODE_XSYNC: | ||
4682 | /* ignore residue in byte synchronous modes */ | 4792 | /* ignore residue in byte synchronous modes */ |
4683 | if (desc_residue(info->rbufs[i])) | 4793 | if (desc_residue(info->rbufs[i])) |
4684 | count--; | 4794 | count--; |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 38df8c19e74c..6b68a0fb4611 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -503,6 +503,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
503 | struct kbd_struct * kbd; | 503 | struct kbd_struct * kbd; |
504 | unsigned int console; | 504 | unsigned int console; |
505 | unsigned char ucval; | 505 | unsigned char ucval; |
506 | unsigned int uival; | ||
506 | void __user *up = (void __user *)arg; | 507 | void __user *up = (void __user *)arg; |
507 | int i, perm; | 508 | int i, perm; |
508 | int ret = 0; | 509 | int ret = 0; |
@@ -657,7 +658,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
657 | break; | 658 | break; |
658 | 659 | ||
659 | case KDGETMODE: | 660 | case KDGETMODE: |
660 | ucval = vc->vc_mode; | 661 | uival = vc->vc_mode; |
661 | goto setint; | 662 | goto setint; |
662 | 663 | ||
663 | case KDMAPDISP: | 664 | case KDMAPDISP: |
@@ -695,7 +696,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
695 | break; | 696 | break; |
696 | 697 | ||
697 | case KDGKBMODE: | 698 | case KDGKBMODE: |
698 | ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : | 699 | uival = ((kbd->kbdmode == VC_RAW) ? K_RAW : |
699 | (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : | 700 | (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : |
700 | (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : | 701 | (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : |
701 | K_XLATE); | 702 | K_XLATE); |
@@ -717,9 +718,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
717 | break; | 718 | break; |
718 | 719 | ||
719 | case KDGKBMETA: | 720 | case KDGKBMETA: |
720 | ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); | 721 | uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); |
721 | setint: | 722 | setint: |
722 | ret = put_user(ucval, (int __user *)arg); | 723 | ret = put_user(uival, (int __user *)arg); |
723 | break; | 724 | break; |
724 | 725 | ||
725 | case KDGETKEYCODE: | 726 | case KDGETKEYCODE: |
@@ -949,7 +950,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
949 | for (i = 0; i < MAX_NR_CONSOLES; ++i) | 950 | for (i = 0; i < MAX_NR_CONSOLES; ++i) |
950 | if (! VT_IS_IN_USE(i)) | 951 | if (! VT_IS_IN_USE(i)) |
951 | break; | 952 | break; |
952 | ucval = i < MAX_NR_CONSOLES ? (i+1) : -1; | 953 | uival = i < MAX_NR_CONSOLES ? (i+1) : -1; |
953 | goto setint; | 954 | goto setint; |
954 | 955 | ||
955 | /* | 956 | /* |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index b3d22d659990..e28e41668177 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/string.h> | 2 | #include <linux/string.h> |
3 | #include <linux/init.h> | 3 | #include <linux/init.h> |
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/ctype.h> | ||
5 | #include <linux/dmi.h> | 6 | #include <linux/dmi.h> |
6 | #include <linux/efi.h> | 7 | #include <linux/efi.h> |
7 | #include <linux/bootmem.h> | 8 | #include <linux/bootmem.h> |
@@ -361,6 +362,33 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy) | |||
361 | } | 362 | } |
362 | } | 363 | } |
363 | 364 | ||
365 | static void __init print_filtered(const char *info) | ||
366 | { | ||
367 | const char *p; | ||
368 | |||
369 | if (!info) | ||
370 | return; | ||
371 | |||
372 | for (p = info; *p; p++) | ||
373 | if (isprint(*p)) | ||
374 | printk(KERN_CONT "%c", *p); | ||
375 | else | ||
376 | printk(KERN_CONT "\\x%02x", *p & 0xff); | ||
377 | } | ||
378 | |||
379 | static void __init dmi_dump_ids(void) | ||
380 | { | ||
381 | printk(KERN_DEBUG "DMI: "); | ||
382 | print_filtered(dmi_get_system_info(DMI_BOARD_NAME)); | ||
383 | printk(KERN_CONT "/"); | ||
384 | print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME)); | ||
385 | printk(KERN_CONT ", BIOS "); | ||
386 | print_filtered(dmi_get_system_info(DMI_BIOS_VERSION)); | ||
387 | printk(KERN_CONT " "); | ||
388 | print_filtered(dmi_get_system_info(DMI_BIOS_DATE)); | ||
389 | printk(KERN_CONT "\n"); | ||
390 | } | ||
391 | |||
364 | static int __init dmi_present(const char __iomem *p) | 392 | static int __init dmi_present(const char __iomem *p) |
365 | { | 393 | { |
366 | u8 buf[15]; | 394 | u8 buf[15]; |
@@ -381,8 +409,10 @@ static int __init dmi_present(const char __iomem *p) | |||
381 | buf[14] >> 4, buf[14] & 0xF); | 409 | buf[14] >> 4, buf[14] & 0xF); |
382 | else | 410 | else |
383 | printk(KERN_INFO "DMI present.\n"); | 411 | printk(KERN_INFO "DMI present.\n"); |
384 | if (dmi_walk_early(dmi_decode) == 0) | 412 | if (dmi_walk_early(dmi_decode) == 0) { |
413 | dmi_dump_ids(); | ||
385 | return 0; | 414 | return 0; |
415 | } | ||
386 | } | 416 | } |
387 | return 1; | 417 | return 1; |
388 | } | 418 | } |
diff --git a/drivers/gpio/74x164.c b/drivers/gpio/74x164.c new file mode 100644 index 000000000000..d91ff4c282e9 --- /dev/null +++ b/drivers/gpio/74x164.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/spi/spi.h> | ||
15 | #include <linux/spi/74x164.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/slab.h> | ||
18 | |||
19 | #define GEN_74X164_GPIO_COUNT 8 | ||
20 | |||
21 | |||
22 | struct gen_74x164_chip { | ||
23 | struct spi_device *spi; | ||
24 | struct gpio_chip gpio_chip; | ||
25 | struct mutex lock; | ||
26 | u8 port_config; | ||
27 | }; | ||
28 | |||
29 | static void gen_74x164_set_value(struct gpio_chip *, unsigned, int); | ||
30 | |||
31 | static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc) | ||
32 | { | ||
33 | return container_of(gc, struct gen_74x164_chip, gpio_chip); | ||
34 | } | ||
35 | |||
36 | static int __gen_74x164_write_config(struct gen_74x164_chip *chip) | ||
37 | { | ||
38 | return spi_write(chip->spi, | ||
39 | &chip->port_config, sizeof(chip->port_config)); | ||
40 | } | ||
41 | |||
42 | static int gen_74x164_direction_output(struct gpio_chip *gc, | ||
43 | unsigned offset, int val) | ||
44 | { | ||
45 | gen_74x164_set_value(gc, offset, val); | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) | ||
50 | { | ||
51 | struct gen_74x164_chip *chip = gpio_to_chip(gc); | ||
52 | int ret; | ||
53 | |||
54 | mutex_lock(&chip->lock); | ||
55 | ret = (chip->port_config >> offset) & 0x1; | ||
56 | mutex_unlock(&chip->lock); | ||
57 | |||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | static void gen_74x164_set_value(struct gpio_chip *gc, | ||
62 | unsigned offset, int val) | ||
63 | { | ||
64 | struct gen_74x164_chip *chip = gpio_to_chip(gc); | ||
65 | |||
66 | mutex_lock(&chip->lock); | ||
67 | if (val) | ||
68 | chip->port_config |= (1 << offset); | ||
69 | else | ||
70 | chip->port_config &= ~(1 << offset); | ||
71 | |||
72 | __gen_74x164_write_config(chip); | ||
73 | mutex_unlock(&chip->lock); | ||
74 | } | ||
75 | |||
76 | static int __devinit gen_74x164_probe(struct spi_device *spi) | ||
77 | { | ||
78 | struct gen_74x164_chip *chip; | ||
79 | struct gen_74x164_chip_platform_data *pdata; | ||
80 | int ret; | ||
81 | |||
82 | pdata = spi->dev.platform_data; | ||
83 | if (!pdata || !pdata->base) { | ||
84 | dev_dbg(&spi->dev, "incorrect or missing platform data\n"); | ||
85 | return -EINVAL; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * bits_per_word cannot be configured in platform data | ||
90 | */ | ||
91 | spi->bits_per_word = 8; | ||
92 | |||
93 | ret = spi_setup(spi); | ||
94 | if (ret < 0) | ||
95 | return ret; | ||
96 | |||
97 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
98 | if (!chip) | ||
99 | return -ENOMEM; | ||
100 | |||
101 | mutex_init(&chip->lock); | ||
102 | |||
103 | dev_set_drvdata(&spi->dev, chip); | ||
104 | |||
105 | chip->spi = spi; | ||
106 | |||
107 | chip->gpio_chip.label = GEN_74X164_DRIVER_NAME, | ||
108 | chip->gpio_chip.direction_output = gen_74x164_direction_output; | ||
109 | chip->gpio_chip.get = gen_74x164_get_value; | ||
110 | chip->gpio_chip.set = gen_74x164_set_value; | ||
111 | chip->gpio_chip.base = pdata->base; | ||
112 | chip->gpio_chip.ngpio = GEN_74X164_GPIO_COUNT; | ||
113 | chip->gpio_chip.can_sleep = 1; | ||
114 | chip->gpio_chip.dev = &spi->dev; | ||
115 | chip->gpio_chip.owner = THIS_MODULE; | ||
116 | |||
117 | ret = __gen_74x164_write_config(chip); | ||
118 | if (ret) { | ||
119 | dev_err(&spi->dev, "Failed writing: %d\n", ret); | ||
120 | goto exit_destroy; | ||
121 | } | ||
122 | |||
123 | ret = gpiochip_add(&chip->gpio_chip); | ||
124 | if (ret) | ||
125 | goto exit_destroy; | ||
126 | |||
127 | return ret; | ||
128 | |||
129 | exit_destroy: | ||
130 | dev_set_drvdata(&spi->dev, NULL); | ||
131 | mutex_destroy(&chip->lock); | ||
132 | kfree(chip); | ||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | static int gen_74x164_remove(struct spi_device *spi) | ||
137 | { | ||
138 | struct gen_74x164_chip *chip; | ||
139 | int ret; | ||
140 | |||
141 | chip = dev_get_drvdata(&spi->dev); | ||
142 | if (chip == NULL) | ||
143 | return -ENODEV; | ||
144 | |||
145 | dev_set_drvdata(&spi->dev, NULL); | ||
146 | |||
147 | ret = gpiochip_remove(&chip->gpio_chip); | ||
148 | if (!ret) { | ||
149 | mutex_destroy(&chip->lock); | ||
150 | kfree(chip); | ||
151 | } else | ||
152 | dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n", | ||
153 | ret); | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | static struct spi_driver gen_74x164_driver = { | ||
159 | .driver = { | ||
160 | .name = GEN_74X164_DRIVER_NAME, | ||
161 | .owner = THIS_MODULE, | ||
162 | }, | ||
163 | .probe = gen_74x164_probe, | ||
164 | .remove = __devexit_p(gen_74x164_remove), | ||
165 | }; | ||
166 | |||
167 | static int __init gen_74x164_init(void) | ||
168 | { | ||
169 | return spi_register_driver(&gen_74x164_driver); | ||
170 | } | ||
171 | subsys_initcall(gen_74x164_init); | ||
172 | |||
173 | static void __exit gen_74x164_exit(void) | ||
174 | { | ||
175 | spi_unregister_driver(&gen_74x164_driver); | ||
176 | } | ||
177 | module_exit(gen_74x164_exit); | ||
178 | |||
179 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | ||
180 | MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); | ||
181 | MODULE_DESCRIPTION("GPIO expander driver for 74X164 8-bits shift register"); | ||
182 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa2054544..dd9b4ba8d32d 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -70,6 +70,11 @@ config GPIO_MAX730X | |||
70 | 70 | ||
71 | comment "Memory mapped GPIO expanders:" | 71 | comment "Memory mapped GPIO expanders:" |
72 | 72 | ||
73 | config GPIO_BASIC_MMIO | ||
74 | tristate "Basic memory-mapped GPIO controllers support" | ||
75 | help | ||
76 | Say yes here to support basic memory-mapped GPIO controllers. | ||
77 | |||
73 | config GPIO_IT8761E | 78 | config GPIO_IT8761E |
74 | tristate "IT8761E GPIO support" | 79 | tristate "IT8761E GPIO support" |
75 | depends on GPIOLIB | 80 | depends on GPIOLIB |
@@ -267,6 +272,13 @@ config GPIO_ADP5588 | |||
267 | To compile this driver as a module, choose M here: the module will be | 272 | To compile this driver as a module, choose M here: the module will be |
268 | called adp5588-gpio. | 273 | called adp5588-gpio. |
269 | 274 | ||
275 | config GPIO_ADP5588_IRQ | ||
276 | bool "Interrupt controller support for ADP5588" | ||
277 | depends on GPIO_ADP5588=y | ||
278 | help | ||
279 | Say yes here to enable the adp5588 to be used as an interrupt | ||
280 | controller. It requires the driver to be built in the kernel. | ||
281 | |||
270 | comment "PCI GPIO expanders:" | 282 | comment "PCI GPIO expanders:" |
271 | 283 | ||
272 | config GPIO_CS5535 | 284 | config GPIO_CS5535 |
@@ -301,6 +313,14 @@ config GPIO_LANGWELL | |||
301 | help | 313 | help |
302 | Say Y here to support Intel Langwell/Penwell GPIO. | 314 | Say Y here to support Intel Langwell/Penwell GPIO. |
303 | 315 | ||
316 | config GPIO_PCH | ||
317 | tristate "PCH GPIO of Intel Topcliff" | ||
318 | depends on PCI | ||
319 | help | ||
320 | This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff | ||
321 | which is an IOH(Input/Output Hub) for x86 embedded processor. | ||
322 | This driver can access PCH GPIO device. | ||
323 | |||
304 | config GPIO_TIMBERDALE | 324 | config GPIO_TIMBERDALE |
305 | bool "Support for timberdale GPIO IP" | 325 | bool "Support for timberdale GPIO IP" |
306 | depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM | 326 | depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM |
@@ -339,6 +359,14 @@ config GPIO_MC33880 | |||
339 | SPI driver for Freescale MC33880 high-side/low-side switch. | 359 | SPI driver for Freescale MC33880 high-side/low-side switch. |
340 | This provides GPIO interface supporting inputs and outputs. | 360 | This provides GPIO interface supporting inputs and outputs. |
341 | 361 | ||
362 | config GPIO_74X164 | ||
363 | tristate "74x164 serial-in/parallel-out 8-bits shift register" | ||
364 | depends on SPI_MASTER | ||
365 | help | ||
366 | Platform driver for 74x164 compatible serial-in/parallel-out | ||
367 | 8-outputs shift registers. This driver can be used to provide access | ||
368 | to more gpio outputs. | ||
369 | |||
342 | comment "AC97 GPIO expanders:" | 370 | comment "AC97 GPIO expanders:" |
343 | 371 | ||
344 | config GPIO_UCB1400 | 372 | config GPIO_UCB1400 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d93720..da2ecde5abdd 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_GPIOLIB) += gpiolib.o | |||
10 | 10 | ||
11 | obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o | 11 | obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o |
12 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o | 12 | obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o |
13 | obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o | ||
13 | obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o | 14 | obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o |
14 | obj-$(CONFIG_GPIO_MAX730X) += max730x.o | 15 | obj-$(CONFIG_GPIO_MAX730X) += max730x.o |
15 | obj-$(CONFIG_GPIO_MAX7300) += max7300.o | 16 | obj-$(CONFIG_GPIO_MAX7300) += max7300.o |
@@ -17,8 +18,10 @@ obj-$(CONFIG_GPIO_MAX7301) += max7301.o | |||
17 | obj-$(CONFIG_GPIO_MAX732X) += max732x.o | 18 | obj-$(CONFIG_GPIO_MAX732X) += max732x.o |
18 | obj-$(CONFIG_GPIO_MC33880) += mc33880.o | 19 | obj-$(CONFIG_GPIO_MC33880) += mc33880.o |
19 | obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o | 20 | obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o |
21 | obj-$(CONFIG_GPIO_74X164) += 74x164.o | ||
20 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o | 22 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o |
21 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o | 23 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o |
24 | obj-$(CONFIG_GPIO_PCH) += pch_gpio.o | ||
22 | obj-$(CONFIG_GPIO_PL061) += pl061.o | 25 | obj-$(CONFIG_GPIO_PL061) += pl061.o |
23 | obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o | 26 | obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o |
24 | obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o | 27 | obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o |
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c index 2e8e9e24f887..0871f78af593 100644 --- a/drivers/gpio/adp5588-gpio.c +++ b/drivers/gpio/adp5588-gpio.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * GPIO Chip driver for Analog Devices | 2 | * GPIO Chip driver for Analog Devices |
3 | * ADP5588 I/O Expander and QWERTY Keypad Controller | 3 | * ADP5588/ADP5587 I/O Expander and QWERTY Keypad Controller |
4 | * | 4 | * |
5 | * Copyright 2009 Analog Devices Inc. | 5 | * Copyright 2009-2010 Analog Devices Inc. |
6 | * | 6 | * |
7 | * Licensed under the GPL-2 or later. | 7 | * Licensed under the GPL-2 or later. |
8 | */ | 8 | */ |
@@ -13,21 +13,34 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/irq.h> | ||
16 | 18 | ||
17 | #include <linux/i2c/adp5588.h> | 19 | #include <linux/i2c/adp5588.h> |
18 | 20 | ||
19 | #define DRV_NAME "adp5588-gpio" | 21 | #define DRV_NAME "adp5588-gpio" |
20 | #define MAXGPIO 18 | 22 | |
21 | #define ADP_BANK(offs) ((offs) >> 3) | 23 | /* |
22 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | 24 | * Early pre 4.0 Silicon required to delay readout by at least 25ms, |
25 | * since the Event Counter Register updated 25ms after the interrupt | ||
26 | * asserted. | ||
27 | */ | ||
28 | #define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4) | ||
23 | 29 | ||
24 | struct adp5588_gpio { | 30 | struct adp5588_gpio { |
25 | struct i2c_client *client; | 31 | struct i2c_client *client; |
26 | struct gpio_chip gpio_chip; | 32 | struct gpio_chip gpio_chip; |
27 | struct mutex lock; /* protect cached dir, dat_out */ | 33 | struct mutex lock; /* protect cached dir, dat_out */ |
34 | /* protect serialized access to the interrupt controller bus */ | ||
35 | struct mutex irq_lock; | ||
28 | unsigned gpio_start; | 36 | unsigned gpio_start; |
37 | unsigned irq_base; | ||
29 | uint8_t dat_out[3]; | 38 | uint8_t dat_out[3]; |
30 | uint8_t dir[3]; | 39 | uint8_t dir[3]; |
40 | uint8_t int_lvl[3]; | ||
41 | uint8_t int_en[3]; | ||
42 | uint8_t irq_mask[3]; | ||
43 | uint8_t irq_stat[3]; | ||
31 | }; | 44 | }; |
32 | 45 | ||
33 | static int adp5588_gpio_read(struct i2c_client *client, u8 reg) | 46 | static int adp5588_gpio_read(struct i2c_client *client, u8 reg) |
@@ -55,8 +68,8 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off) | |||
55 | struct adp5588_gpio *dev = | 68 | struct adp5588_gpio *dev = |
56 | container_of(chip, struct adp5588_gpio, gpio_chip); | 69 | container_of(chip, struct adp5588_gpio, gpio_chip); |
57 | 70 | ||
58 | return !!(adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + ADP_BANK(off)) | 71 | return !!(adp5588_gpio_read(dev->client, |
59 | & ADP_BIT(off)); | 72 | GPIO_DAT_STAT1 + ADP5588_BANK(off)) & ADP5588_BIT(off)); |
60 | } | 73 | } |
61 | 74 | ||
62 | static void adp5588_gpio_set_value(struct gpio_chip *chip, | 75 | static void adp5588_gpio_set_value(struct gpio_chip *chip, |
@@ -66,8 +79,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip, | |||
66 | struct adp5588_gpio *dev = | 79 | struct adp5588_gpio *dev = |
67 | container_of(chip, struct adp5588_gpio, gpio_chip); | 80 | container_of(chip, struct adp5588_gpio, gpio_chip); |
68 | 81 | ||
69 | bank = ADP_BANK(off); | 82 | bank = ADP5588_BANK(off); |
70 | bit = ADP_BIT(off); | 83 | bit = ADP5588_BIT(off); |
71 | 84 | ||
72 | mutex_lock(&dev->lock); | 85 | mutex_lock(&dev->lock); |
73 | if (val) | 86 | if (val) |
@@ -87,10 +100,10 @@ static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off) | |||
87 | struct adp5588_gpio *dev = | 100 | struct adp5588_gpio *dev = |
88 | container_of(chip, struct adp5588_gpio, gpio_chip); | 101 | container_of(chip, struct adp5588_gpio, gpio_chip); |
89 | 102 | ||
90 | bank = ADP_BANK(off); | 103 | bank = ADP5588_BANK(off); |
91 | 104 | ||
92 | mutex_lock(&dev->lock); | 105 | mutex_lock(&dev->lock); |
93 | dev->dir[bank] &= ~ADP_BIT(off); | 106 | dev->dir[bank] &= ~ADP5588_BIT(off); |
94 | ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]); | 107 | ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]); |
95 | mutex_unlock(&dev->lock); | 108 | mutex_unlock(&dev->lock); |
96 | 109 | ||
@@ -105,8 +118,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, | |||
105 | struct adp5588_gpio *dev = | 118 | struct adp5588_gpio *dev = |
106 | container_of(chip, struct adp5588_gpio, gpio_chip); | 119 | container_of(chip, struct adp5588_gpio, gpio_chip); |
107 | 120 | ||
108 | bank = ADP_BANK(off); | 121 | bank = ADP5588_BANK(off); |
109 | bit = ADP_BIT(off); | 122 | bit = ADP5588_BIT(off); |
110 | 123 | ||
111 | mutex_lock(&dev->lock); | 124 | mutex_lock(&dev->lock); |
112 | dev->dir[bank] |= bit; | 125 | dev->dir[bank] |= bit; |
@@ -125,6 +138,213 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip, | |||
125 | return ret; | 138 | return ret; |
126 | } | 139 | } |
127 | 140 | ||
141 | #ifdef CONFIG_GPIO_ADP5588_IRQ | ||
142 | static int adp5588_gpio_to_irq(struct gpio_chip *chip, unsigned off) | ||
143 | { | ||
144 | struct adp5588_gpio *dev = | ||
145 | container_of(chip, struct adp5588_gpio, gpio_chip); | ||
146 | return dev->irq_base + off; | ||
147 | } | ||
148 | |||
149 | static void adp5588_irq_bus_lock(unsigned int irq) | ||
150 | { | ||
151 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | ||
152 | mutex_lock(&dev->irq_lock); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * genirq core code can issue chip->mask/unmask from atomic context. | ||
157 | * This doesn't work for slow busses where an access needs to sleep. | ||
158 | * bus_sync_unlock() is therefore called outside the atomic context, | ||
159 | * syncs the current irq mask state with the slow external controller | ||
160 | * and unlocks the bus. | ||
161 | */ | ||
162 | |||
163 | static void adp5588_irq_bus_sync_unlock(unsigned int irq) | ||
164 | { | ||
165 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | ||
166 | int i; | ||
167 | |||
168 | for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) | ||
169 | if (dev->int_en[i] ^ dev->irq_mask[i]) { | ||
170 | dev->int_en[i] = dev->irq_mask[i]; | ||
171 | adp5588_gpio_write(dev->client, GPIO_INT_EN1 + i, | ||
172 | dev->int_en[i]); | ||
173 | } | ||
174 | |||
175 | mutex_unlock(&dev->irq_lock); | ||
176 | } | ||
177 | |||
178 | static void adp5588_irq_mask(unsigned int irq) | ||
179 | { | ||
180 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | ||
181 | unsigned gpio = irq - dev->irq_base; | ||
182 | |||
183 | dev->irq_mask[ADP5588_BANK(gpio)] &= ~ADP5588_BIT(gpio); | ||
184 | } | ||
185 | |||
186 | static void adp5588_irq_unmask(unsigned int irq) | ||
187 | { | ||
188 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | ||
189 | unsigned gpio = irq - dev->irq_base; | ||
190 | |||
191 | dev->irq_mask[ADP5588_BANK(gpio)] |= ADP5588_BIT(gpio); | ||
192 | } | ||
193 | |||
194 | static int adp5588_irq_set_type(unsigned int irq, unsigned int type) | ||
195 | { | ||
196 | struct adp5588_gpio *dev = get_irq_chip_data(irq); | ||
197 | uint16_t gpio = irq - dev->irq_base; | ||
198 | unsigned bank, bit; | ||
199 | |||
200 | if ((type & IRQ_TYPE_EDGE_BOTH)) { | ||
201 | dev_err(&dev->client->dev, "irq %d: unsupported type %d\n", | ||
202 | irq, type); | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | |||
206 | bank = ADP5588_BANK(gpio); | ||
207 | bit = ADP5588_BIT(gpio); | ||
208 | |||
209 | if (type & IRQ_TYPE_LEVEL_HIGH) | ||
210 | dev->int_lvl[bank] |= bit; | ||
211 | else if (type & IRQ_TYPE_LEVEL_LOW) | ||
212 | dev->int_lvl[bank] &= ~bit; | ||
213 | else | ||
214 | return -EINVAL; | ||
215 | |||
216 | adp5588_gpio_direction_input(&dev->gpio_chip, gpio); | ||
217 | adp5588_gpio_write(dev->client, GPIO_INT_LVL1 + bank, | ||
218 | dev->int_lvl[bank]); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static struct irq_chip adp5588_irq_chip = { | ||
224 | .name = "adp5588", | ||
225 | .mask = adp5588_irq_mask, | ||
226 | .unmask = adp5588_irq_unmask, | ||
227 | .bus_lock = adp5588_irq_bus_lock, | ||
228 | .bus_sync_unlock = adp5588_irq_bus_sync_unlock, | ||
229 | .set_type = adp5588_irq_set_type, | ||
230 | }; | ||
231 | |||
232 | static int adp5588_gpio_read_intstat(struct i2c_client *client, u8 *buf) | ||
233 | { | ||
234 | int ret = i2c_smbus_read_i2c_block_data(client, GPIO_INT_STAT1, 3, buf); | ||
235 | |||
236 | if (ret < 0) | ||
237 | dev_err(&client->dev, "Read INT_STAT Error\n"); | ||
238 | |||
239 | return ret; | ||
240 | } | ||
241 | |||
242 | static irqreturn_t adp5588_irq_handler(int irq, void *devid) | ||
243 | { | ||
244 | struct adp5588_gpio *dev = devid; | ||
245 | unsigned status, bank, bit, pending; | ||
246 | int ret; | ||
247 | status = adp5588_gpio_read(dev->client, INT_STAT); | ||
248 | |||
249 | if (status & ADP5588_GPI_INT) { | ||
250 | ret = adp5588_gpio_read_intstat(dev->client, dev->irq_stat); | ||
251 | if (ret < 0) | ||
252 | memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat)); | ||
253 | |||
254 | for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); | ||
255 | bank++, bit = 0) { | ||
256 | pending = dev->irq_stat[bank] & dev->irq_mask[bank]; | ||
257 | |||
258 | while (pending) { | ||
259 | if (pending & (1 << bit)) { | ||
260 | handle_nested_irq(dev->irq_base + | ||
261 | (bank << 3) + bit); | ||
262 | pending &= ~(1 << bit); | ||
263 | |||
264 | } | ||
265 | bit++; | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | |||
270 | adp5588_gpio_write(dev->client, INT_STAT, status); /* Status is W1C */ | ||
271 | |||
272 | return IRQ_HANDLED; | ||
273 | } | ||
274 | |||
275 | static int adp5588_irq_setup(struct adp5588_gpio *dev) | ||
276 | { | ||
277 | struct i2c_client *client = dev->client; | ||
278 | struct adp5588_gpio_platform_data *pdata = client->dev.platform_data; | ||
279 | unsigned gpio; | ||
280 | int ret; | ||
281 | |||
282 | adp5588_gpio_write(client, CFG, ADP5588_AUTO_INC); | ||
283 | adp5588_gpio_write(client, INT_STAT, -1); /* status is W1C */ | ||
284 | adp5588_gpio_read_intstat(client, dev->irq_stat); /* read to clear */ | ||
285 | |||
286 | dev->irq_base = pdata->irq_base; | ||
287 | mutex_init(&dev->irq_lock); | ||
288 | |||
289 | for (gpio = 0; gpio < dev->gpio_chip.ngpio; gpio++) { | ||
290 | int irq = gpio + dev->irq_base; | ||
291 | set_irq_chip_data(irq, dev); | ||
292 | set_irq_chip_and_handler(irq, &adp5588_irq_chip, | ||
293 | handle_level_irq); | ||
294 | set_irq_nested_thread(irq, 1); | ||
295 | #ifdef CONFIG_ARM | ||
296 | /* | ||
297 | * ARM needs us to explicitly flag the IRQ as VALID, | ||
298 | * once we do so, it will also set the noprobe. | ||
299 | */ | ||
300 | set_irq_flags(irq, IRQF_VALID); | ||
301 | #else | ||
302 | set_irq_noprobe(irq); | ||
303 | #endif | ||
304 | } | ||
305 | |||
306 | ret = request_threaded_irq(client->irq, | ||
307 | NULL, | ||
308 | adp5588_irq_handler, | ||
309 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
310 | dev_name(&client->dev), dev); | ||
311 | if (ret) { | ||
312 | dev_err(&client->dev, "failed to request irq %d\n", | ||
313 | client->irq); | ||
314 | goto out; | ||
315 | } | ||
316 | |||
317 | dev->gpio_chip.to_irq = adp5588_gpio_to_irq; | ||
318 | adp5588_gpio_write(client, CFG, | ||
319 | ADP5588_AUTO_INC | ADP5588_INT_CFG | ADP5588_GPI_INT); | ||
320 | |||
321 | return 0; | ||
322 | |||
323 | out: | ||
324 | dev->irq_base = 0; | ||
325 | return ret; | ||
326 | } | ||
327 | |||
328 | static void adp5588_irq_teardown(struct adp5588_gpio *dev) | ||
329 | { | ||
330 | if (dev->irq_base) | ||
331 | free_irq(dev->client->irq, dev); | ||
332 | } | ||
333 | |||
334 | #else | ||
335 | static int adp5588_irq_setup(struct adp5588_gpio *dev) | ||
336 | { | ||
337 | struct i2c_client *client = dev->client; | ||
338 | dev_warn(&client->dev, "interrupt support not compiled in\n"); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static void adp5588_irq_teardown(struct adp5588_gpio *dev) | ||
344 | { | ||
345 | } | ||
346 | #endif /* CONFIG_GPIO_ADP5588_IRQ */ | ||
347 | |||
128 | static int __devinit adp5588_gpio_probe(struct i2c_client *client, | 348 | static int __devinit adp5588_gpio_probe(struct i2c_client *client, |
129 | const struct i2c_device_id *id) | 349 | const struct i2c_device_id *id) |
130 | { | 350 | { |
@@ -160,37 +380,46 @@ static int __devinit adp5588_gpio_probe(struct i2c_client *client, | |||
160 | gc->can_sleep = 1; | 380 | gc->can_sleep = 1; |
161 | 381 | ||
162 | gc->base = pdata->gpio_start; | 382 | gc->base = pdata->gpio_start; |
163 | gc->ngpio = MAXGPIO; | 383 | gc->ngpio = ADP5588_MAXGPIO; |
164 | gc->label = client->name; | 384 | gc->label = client->name; |
165 | gc->owner = THIS_MODULE; | 385 | gc->owner = THIS_MODULE; |
166 | 386 | ||
167 | mutex_init(&dev->lock); | 387 | mutex_init(&dev->lock); |
168 | 388 | ||
169 | |||
170 | ret = adp5588_gpio_read(dev->client, DEV_ID); | 389 | ret = adp5588_gpio_read(dev->client, DEV_ID); |
171 | if (ret < 0) | 390 | if (ret < 0) |
172 | goto err; | 391 | goto err; |
173 | 392 | ||
174 | revid = ret & ADP5588_DEVICE_ID_MASK; | 393 | revid = ret & ADP5588_DEVICE_ID_MASK; |
175 | 394 | ||
176 | for (i = 0, ret = 0; i <= ADP_BANK(MAXGPIO); i++) { | 395 | for (i = 0, ret = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) { |
177 | dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i); | 396 | dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i); |
178 | dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i); | 397 | dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i); |
179 | ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0); | 398 | ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0); |
180 | ret |= adp5588_gpio_write(client, GPIO_PULL1 + i, | 399 | ret |= adp5588_gpio_write(client, GPIO_PULL1 + i, |
181 | (pdata->pullup_dis_mask >> (8 * i)) & 0xFF); | 400 | (pdata->pullup_dis_mask >> (8 * i)) & 0xFF); |
182 | 401 | ret |= adp5588_gpio_write(client, GPIO_INT_EN1 + i, 0); | |
183 | if (ret) | 402 | if (ret) |
184 | goto err; | 403 | goto err; |
185 | } | 404 | } |
186 | 405 | ||
406 | if (pdata->irq_base) { | ||
407 | if (WA_DELAYED_READOUT_REVID(revid)) { | ||
408 | dev_warn(&client->dev, "GPIO int not supported\n"); | ||
409 | } else { | ||
410 | ret = adp5588_irq_setup(dev); | ||
411 | if (ret) | ||
412 | goto err; | ||
413 | } | ||
414 | } | ||
415 | |||
187 | ret = gpiochip_add(&dev->gpio_chip); | 416 | ret = gpiochip_add(&dev->gpio_chip); |
188 | if (ret) | 417 | if (ret) |
189 | goto err; | 418 | goto err_irq; |
190 | 419 | ||
191 | dev_info(&client->dev, "gpios %d..%d on a %s Rev. %d\n", | 420 | dev_info(&client->dev, "gpios %d..%d (IRQ Base %d) on a %s Rev. %d\n", |
192 | gc->base, gc->base + gc->ngpio - 1, | 421 | gc->base, gc->base + gc->ngpio - 1, |
193 | client->name, revid); | 422 | pdata->irq_base, client->name, revid); |
194 | 423 | ||
195 | if (pdata->setup) { | 424 | if (pdata->setup) { |
196 | ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context); | 425 | ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context); |
@@ -199,8 +428,11 @@ static int __devinit adp5588_gpio_probe(struct i2c_client *client, | |||
199 | } | 428 | } |
200 | 429 | ||
201 | i2c_set_clientdata(client, dev); | 430 | i2c_set_clientdata(client, dev); |
431 | |||
202 | return 0; | 432 | return 0; |
203 | 433 | ||
434 | err_irq: | ||
435 | adp5588_irq_teardown(dev); | ||
204 | err: | 436 | err: |
205 | kfree(dev); | 437 | kfree(dev); |
206 | return ret; | 438 | return ret; |
@@ -222,6 +454,9 @@ static int __devexit adp5588_gpio_remove(struct i2c_client *client) | |||
222 | } | 454 | } |
223 | } | 455 | } |
224 | 456 | ||
457 | if (dev->irq_base) | ||
458 | free_irq(dev->client->irq, dev); | ||
459 | |||
225 | ret = gpiochip_remove(&dev->gpio_chip); | 460 | ret = gpiochip_remove(&dev->gpio_chip); |
226 | if (ret) { | 461 | if (ret) { |
227 | dev_err(&client->dev, "gpiochip_remove failed %d\n", ret); | 462 | dev_err(&client->dev, "gpiochip_remove failed %d\n", ret); |
diff --git a/drivers/gpio/basic_mmio_gpio.c b/drivers/gpio/basic_mmio_gpio.c new file mode 100644 index 000000000000..3addea65894e --- /dev/null +++ b/drivers/gpio/basic_mmio_gpio.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* | ||
2 | * Driver for basic memory-mapped GPIO controllers. | ||
3 | * | ||
4 | * Copyright 2008 MontaVista Software, Inc. | ||
5 | * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | * ....``.```~~~~````.`.`.`.`.```````'',,,.........`````......`....... | ||
13 | * ...`` ```````.. | ||
14 | * ..The simplest form of a GPIO controller that the driver supports is`` | ||
15 | * `.just a single "data" register, where GPIO state can be read and/or ` | ||
16 | * `,..written. ,,..``~~~~ .....``.`.`.~~.```.`.........``````.``````` | ||
17 | * ````````` | ||
18 | ___ | ||
19 | _/~~|___/~| . ```~~~~~~ ___/___\___ ,~.`.`.`.`````.~~...,,,,... | ||
20 | __________|~$@~~~ %~ /o*o*o*o*o*o\ .. Implementing such a GPIO . | ||
21 | o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` | ||
22 | `....trivial..'~`.```.``` | ||
23 | * ``````` | ||
24 | * .```````~~~~`..`.``.``. | ||
25 | * . The driver supports `... ,..```.`~~~```````````````....````.``,, | ||
26 | * . big-endian notation, just`. .. A bit more sophisticated controllers , | ||
27 | * . register the device with -be`. .with a pair of set/clear-bit registers , | ||
28 | * `.. suffix. ```~~`````....`.` . affecting the data register and the .` | ||
29 | * ``.`.``...``` ```.. output pins are also supported.` | ||
30 | * ^^ `````.`````````.,``~``~``~~`````` | ||
31 | * . ^^ | ||
32 | * ,..`.`.`...````````````......`.`.`.`.`.`..`.`.`.. | ||
33 | * .. The expectation is that in at least some cases . ,-~~~-, | ||
34 | * .this will be used with roll-your-own ASIC/FPGA .` \ / | ||
35 | * .logic in Verilog or VHDL. ~~~`````````..`````~~` \ / | ||
36 | * ..````````......``````````` \o_ | ||
37 | * | | ||
38 | * ^^ / \ | ||
39 | * | ||
40 | * ...`````~~`.....``.`..........``````.`.``.```........``. | ||
41 | * ` 8, 16, 32 and 64 bits registers are supported, and``. | ||
42 | * . the number of GPIOs is determined by the width of ~ | ||
43 | * .. the registers. ,............```.`.`..`.`.~~~.`.`.`~ | ||
44 | * `.......````.``` | ||
45 | */ | ||
46 | |||
47 | #include <linux/init.h> | ||
48 | #include <linux/bug.h> | ||
49 | #include <linux/kernel.h> | ||
50 | #include <linux/module.h> | ||
51 | #include <linux/spinlock.h> | ||
52 | #include <linux/compiler.h> | ||
53 | #include <linux/types.h> | ||
54 | #include <linux/errno.h> | ||
55 | #include <linux/log2.h> | ||
56 | #include <linux/ioport.h> | ||
57 | #include <linux/io.h> | ||
58 | #include <linux/gpio.h> | ||
59 | #include <linux/slab.h> | ||
60 | #include <linux/platform_device.h> | ||
61 | #include <linux/mod_devicetable.h> | ||
62 | #include <linux/basic_mmio_gpio.h> | ||
63 | |||
64 | struct bgpio_chip { | ||
65 | struct gpio_chip gc; | ||
66 | void __iomem *reg_dat; | ||
67 | void __iomem *reg_set; | ||
68 | void __iomem *reg_clr; | ||
69 | |||
70 | /* Number of bits (GPIOs): <register width> * 8. */ | ||
71 | int bits; | ||
72 | |||
73 | /* | ||
74 | * Some GPIO controllers work with the big-endian bits notation, | ||
75 | * e.g. in a 8-bits register, GPIO7 is the least significant bit. | ||
76 | */ | ||
77 | int big_endian_bits; | ||
78 | |||
79 | /* | ||
80 | * Used to lock bgpio_chip->data. Also, this is needed to keep | ||
81 | * shadowed and real data registers writes together. | ||
82 | */ | ||
83 | spinlock_t lock; | ||
84 | |||
85 | /* Shadowed data register to clear/set bits safely. */ | ||
86 | unsigned long data; | ||
87 | }; | ||
88 | |||
89 | static struct bgpio_chip *to_bgpio_chip(struct gpio_chip *gc) | ||
90 | { | ||
91 | return container_of(gc, struct bgpio_chip, gc); | ||
92 | } | ||
93 | |||
94 | static unsigned long bgpio_in(struct bgpio_chip *bgc) | ||
95 | { | ||
96 | switch (bgc->bits) { | ||
97 | case 8: | ||
98 | return __raw_readb(bgc->reg_dat); | ||
99 | case 16: | ||
100 | return __raw_readw(bgc->reg_dat); | ||
101 | case 32: | ||
102 | return __raw_readl(bgc->reg_dat); | ||
103 | #if BITS_PER_LONG >= 64 | ||
104 | case 64: | ||
105 | return __raw_readq(bgc->reg_dat); | ||
106 | #endif | ||
107 | } | ||
108 | return -EINVAL; | ||
109 | } | ||
110 | |||
111 | static void bgpio_out(struct bgpio_chip *bgc, void __iomem *reg, | ||
112 | unsigned long data) | ||
113 | { | ||
114 | switch (bgc->bits) { | ||
115 | case 8: | ||
116 | __raw_writeb(data, reg); | ||
117 | return; | ||
118 | case 16: | ||
119 | __raw_writew(data, reg); | ||
120 | return; | ||
121 | case 32: | ||
122 | __raw_writel(data, reg); | ||
123 | return; | ||
124 | #if BITS_PER_LONG >= 64 | ||
125 | case 64: | ||
126 | __raw_writeq(data, reg); | ||
127 | return; | ||
128 | #endif | ||
129 | } | ||
130 | } | ||
131 | |||
132 | static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin) | ||
133 | { | ||
134 | if (bgc->big_endian_bits) | ||
135 | return 1 << (bgc->bits - 1 - pin); | ||
136 | else | ||
137 | return 1 << pin; | ||
138 | } | ||
139 | |||
140 | static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
141 | { | ||
142 | struct bgpio_chip *bgc = to_bgpio_chip(gc); | ||
143 | |||
144 | return bgpio_in(bgc) & bgpio_pin2mask(bgc, gpio); | ||
145 | } | ||
146 | |||
147 | static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
148 | { | ||
149 | struct bgpio_chip *bgc = to_bgpio_chip(gc); | ||
150 | unsigned long mask = bgpio_pin2mask(bgc, gpio); | ||
151 | unsigned long flags; | ||
152 | |||
153 | if (bgc->reg_set) { | ||
154 | if (val) | ||
155 | bgpio_out(bgc, bgc->reg_set, mask); | ||
156 | else | ||
157 | bgpio_out(bgc, bgc->reg_clr, mask); | ||
158 | return; | ||
159 | } | ||
160 | |||
161 | spin_lock_irqsave(&bgc->lock, flags); | ||
162 | |||
163 | if (val) | ||
164 | bgc->data |= mask; | ||
165 | else | ||
166 | bgc->data &= ~mask; | ||
167 | |||
168 | bgpio_out(bgc, bgc->reg_dat, bgc->data); | ||
169 | |||
170 | spin_unlock_irqrestore(&bgc->lock, flags); | ||
171 | } | ||
172 | |||
173 | static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
174 | { | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
179 | { | ||
180 | bgpio_set(gc, gpio, val); | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int __devinit bgpio_probe(struct platform_device *pdev) | ||
185 | { | ||
186 | const struct platform_device_id *platid = platform_get_device_id(pdev); | ||
187 | struct device *dev = &pdev->dev; | ||
188 | struct bgpio_pdata *pdata = dev_get_platdata(dev); | ||
189 | struct bgpio_chip *bgc; | ||
190 | struct resource *res_dat; | ||
191 | struct resource *res_set; | ||
192 | struct resource *res_clr; | ||
193 | resource_size_t dat_sz; | ||
194 | int bits; | ||
195 | int ret; | ||
196 | |||
197 | res_dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); | ||
198 | if (!res_dat) | ||
199 | return -EINVAL; | ||
200 | |||
201 | dat_sz = resource_size(res_dat); | ||
202 | if (!is_power_of_2(dat_sz)) | ||
203 | return -EINVAL; | ||
204 | |||
205 | bits = dat_sz * 8; | ||
206 | if (bits > BITS_PER_LONG) | ||
207 | return -EINVAL; | ||
208 | |||
209 | bgc = devm_kzalloc(dev, sizeof(*bgc), GFP_KERNEL); | ||
210 | if (!bgc) | ||
211 | return -ENOMEM; | ||
212 | |||
213 | bgc->reg_dat = devm_ioremap(dev, res_dat->start, dat_sz); | ||
214 | if (!bgc->reg_dat) | ||
215 | return -ENOMEM; | ||
216 | |||
217 | res_set = platform_get_resource_byname(pdev, IORESOURCE_MEM, "set"); | ||
218 | res_clr = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clr"); | ||
219 | if (res_set && res_clr) { | ||
220 | if (resource_size(res_set) != resource_size(res_clr) || | ||
221 | resource_size(res_set) != dat_sz) | ||
222 | return -EINVAL; | ||
223 | |||
224 | bgc->reg_set = devm_ioremap(dev, res_set->start, dat_sz); | ||
225 | bgc->reg_clr = devm_ioremap(dev, res_clr->start, dat_sz); | ||
226 | if (!bgc->reg_set || !bgc->reg_clr) | ||
227 | return -ENOMEM; | ||
228 | } else if (res_set || res_clr) { | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | |||
232 | spin_lock_init(&bgc->lock); | ||
233 | |||
234 | bgc->bits = bits; | ||
235 | bgc->big_endian_bits = !strcmp(platid->name, "basic-mmio-gpio-be"); | ||
236 | bgc->data = bgpio_in(bgc); | ||
237 | |||
238 | bgc->gc.ngpio = bits; | ||
239 | bgc->gc.direction_input = bgpio_dir_in; | ||
240 | bgc->gc.direction_output = bgpio_dir_out; | ||
241 | bgc->gc.get = bgpio_get; | ||
242 | bgc->gc.set = bgpio_set; | ||
243 | bgc->gc.dev = dev; | ||
244 | bgc->gc.label = dev_name(dev); | ||
245 | |||
246 | if (pdata) | ||
247 | bgc->gc.base = pdata->base; | ||
248 | else | ||
249 | bgc->gc.base = -1; | ||
250 | |||
251 | dev_set_drvdata(dev, bgc); | ||
252 | |||
253 | ret = gpiochip_add(&bgc->gc); | ||
254 | if (ret) | ||
255 | dev_err(dev, "gpiochip_add() failed: %d\n", ret); | ||
256 | |||
257 | return ret; | ||
258 | } | ||
259 | |||
260 | static int __devexit bgpio_remove(struct platform_device *pdev) | ||
261 | { | ||
262 | struct bgpio_chip *bgc = dev_get_drvdata(&pdev->dev); | ||
263 | |||
264 | return gpiochip_remove(&bgc->gc); | ||
265 | } | ||
266 | |||
267 | static const struct platform_device_id bgpio_id_table[] = { | ||
268 | { "basic-mmio-gpio", }, | ||
269 | { "basic-mmio-gpio-be", }, | ||
270 | {}, | ||
271 | }; | ||
272 | MODULE_DEVICE_TABLE(platform, bgpio_id_table); | ||
273 | |||
274 | static struct platform_driver bgpio_driver = { | ||
275 | .driver = { | ||
276 | .name = "basic-mmio-gpio", | ||
277 | }, | ||
278 | .id_table = bgpio_id_table, | ||
279 | .probe = bgpio_probe, | ||
280 | .remove = __devexit_p(bgpio_remove), | ||
281 | }; | ||
282 | |||
283 | static int __init bgpio_init(void) | ||
284 | { | ||
285 | return platform_driver_register(&bgpio_driver); | ||
286 | } | ||
287 | module_init(bgpio_init); | ||
288 | |||
289 | static void __exit bgpio_exit(void) | ||
290 | { | ||
291 | platform_driver_unregister(&bgpio_driver); | ||
292 | } | ||
293 | module_exit(bgpio_exit); | ||
294 | |||
295 | MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers"); | ||
296 | MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); | ||
297 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index 8383a8d7f994..64db9dc3a275 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c | |||
@@ -18,10 +18,12 @@ | |||
18 | /* Supports: | 18 | /* Supports: |
19 | * Moorestown platform Langwell chip. | 19 | * Moorestown platform Langwell chip. |
20 | * Medfield platform Penwell chip. | 20 | * Medfield platform Penwell chip. |
21 | * Whitney point. | ||
21 | */ | 22 | */ |
22 | 23 | ||
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/platform_device.h> | ||
25 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
26 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
27 | #include <linux/stddef.h> | 29 | #include <linux/stddef.h> |
@@ -158,15 +160,15 @@ static int lnw_irq_type(unsigned irq, unsigned type) | |||
158 | spin_unlock_irqrestore(&lnw->lock, flags); | 160 | spin_unlock_irqrestore(&lnw->lock, flags); |
159 | 161 | ||
160 | return 0; | 162 | return 0; |
161 | }; | 163 | } |
162 | 164 | ||
163 | static void lnw_irq_unmask(unsigned irq) | 165 | static void lnw_irq_unmask(unsigned irq) |
164 | { | 166 | { |
165 | }; | 167 | } |
166 | 168 | ||
167 | static void lnw_irq_mask(unsigned irq) | 169 | static void lnw_irq_mask(unsigned irq) |
168 | { | 170 | { |
169 | }; | 171 | } |
170 | 172 | ||
171 | static struct irq_chip lnw_irqchip = { | 173 | static struct irq_chip lnw_irqchip = { |
172 | .name = "LNW-GPIO", | 174 | .name = "LNW-GPIO", |
@@ -300,9 +302,88 @@ static struct pci_driver lnw_gpio_driver = { | |||
300 | .probe = lnw_gpio_probe, | 302 | .probe = lnw_gpio_probe, |
301 | }; | 303 | }; |
302 | 304 | ||
305 | |||
306 | static int __devinit wp_gpio_probe(struct platform_device *pdev) | ||
307 | { | ||
308 | struct lnw_gpio *lnw; | ||
309 | struct gpio_chip *gc; | ||
310 | struct resource *rc; | ||
311 | int retval = 0; | ||
312 | |||
313 | rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
314 | if (!rc) | ||
315 | return -EINVAL; | ||
316 | |||
317 | lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL); | ||
318 | if (!lnw) { | ||
319 | dev_err(&pdev->dev, | ||
320 | "can't allocate whitneypoint_gpio chip data\n"); | ||
321 | return -ENOMEM; | ||
322 | } | ||
323 | lnw->reg_base = ioremap_nocache(rc->start, resource_size(rc)); | ||
324 | if (lnw->reg_base == NULL) { | ||
325 | retval = -EINVAL; | ||
326 | goto err_kmalloc; | ||
327 | } | ||
328 | spin_lock_init(&lnw->lock); | ||
329 | gc = &lnw->chip; | ||
330 | gc->label = dev_name(&pdev->dev); | ||
331 | gc->owner = THIS_MODULE; | ||
332 | gc->direction_input = lnw_gpio_direction_input; | ||
333 | gc->direction_output = lnw_gpio_direction_output; | ||
334 | gc->get = lnw_gpio_get; | ||
335 | gc->set = lnw_gpio_set; | ||
336 | gc->to_irq = NULL; | ||
337 | gc->base = 0; | ||
338 | gc->ngpio = 64; | ||
339 | gc->can_sleep = 0; | ||
340 | retval = gpiochip_add(gc); | ||
341 | if (retval) { | ||
342 | dev_err(&pdev->dev, "whitneypoint gpiochip_add error %d\n", | ||
343 | retval); | ||
344 | goto err_ioremap; | ||
345 | } | ||
346 | platform_set_drvdata(pdev, lnw); | ||
347 | return 0; | ||
348 | err_ioremap: | ||
349 | iounmap(lnw->reg_base); | ||
350 | err_kmalloc: | ||
351 | kfree(lnw); | ||
352 | return retval; | ||
353 | } | ||
354 | |||
355 | static int __devexit wp_gpio_remove(struct platform_device *pdev) | ||
356 | { | ||
357 | struct lnw_gpio *lnw = platform_get_drvdata(pdev); | ||
358 | int err; | ||
359 | err = gpiochip_remove(&lnw->chip); | ||
360 | if (err) | ||
361 | dev_err(&pdev->dev, "failed to remove gpio_chip.\n"); | ||
362 | iounmap(lnw->reg_base); | ||
363 | kfree(lnw); | ||
364 | platform_set_drvdata(pdev, NULL); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static struct platform_driver wp_gpio_driver = { | ||
369 | .probe = wp_gpio_probe, | ||
370 | .remove = __devexit_p(wp_gpio_remove), | ||
371 | .driver = { | ||
372 | .name = "wp_gpio", | ||
373 | .owner = THIS_MODULE, | ||
374 | }, | ||
375 | }; | ||
376 | |||
303 | static int __init lnw_gpio_init(void) | 377 | static int __init lnw_gpio_init(void) |
304 | { | 378 | { |
305 | return pci_register_driver(&lnw_gpio_driver); | 379 | int ret; |
380 | ret = pci_register_driver(&lnw_gpio_driver); | ||
381 | if (ret < 0) | ||
382 | return ret; | ||
383 | ret = platform_driver_register(&wp_gpio_driver); | ||
384 | if (ret < 0) | ||
385 | pci_unregister_driver(&lnw_gpio_driver); | ||
386 | return ret; | ||
306 | } | 387 | } |
307 | 388 | ||
308 | device_initcall(lnw_gpio_init); | 389 | device_initcall(lnw_gpio_init); |
diff --git a/drivers/gpio/pch_gpio.c b/drivers/gpio/pch_gpio.c new file mode 100644 index 000000000000..0eba0a75c804 --- /dev/null +++ b/drivers/gpio/pch_gpio.c | |||
@@ -0,0 +1,312 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; version 2 of the License. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
16 | */ | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/gpio.h> | ||
20 | |||
21 | #define PCH_GPIO_ALL_PINS 0xfff /* Mask for GPIO pins 0 to 11 */ | ||
22 | #define GPIO_NUM_PINS 12 /* Specifies number of GPIO PINS GPIO0-GPIO11 */ | ||
23 | |||
24 | struct pch_regs { | ||
25 | u32 ien; | ||
26 | u32 istatus; | ||
27 | u32 idisp; | ||
28 | u32 iclr; | ||
29 | u32 imask; | ||
30 | u32 imaskclr; | ||
31 | u32 po; | ||
32 | u32 pi; | ||
33 | u32 pm; | ||
34 | u32 im0; | ||
35 | u32 im1; | ||
36 | u32 reserved[4]; | ||
37 | u32 reset; | ||
38 | }; | ||
39 | |||
40 | /** | ||
41 | * struct pch_gpio_reg_data - The register store data. | ||
42 | * @po_reg: To store contents of PO register. | ||
43 | * @pm_reg: To store contents of PM register. | ||
44 | */ | ||
45 | struct pch_gpio_reg_data { | ||
46 | u32 po_reg; | ||
47 | u32 pm_reg; | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * struct pch_gpio - GPIO private data structure. | ||
52 | * @base: PCI base address of Memory mapped I/O register. | ||
53 | * @reg: Memory mapped PCH GPIO register list. | ||
54 | * @dev: Pointer to device structure. | ||
55 | * @gpio: Data for GPIO infrastructure. | ||
56 | * @pch_gpio_reg: Memory mapped Register data is saved here | ||
57 | * when suspend. | ||
58 | */ | ||
59 | struct pch_gpio { | ||
60 | void __iomem *base; | ||
61 | struct pch_regs __iomem *reg; | ||
62 | struct device *dev; | ||
63 | struct gpio_chip gpio; | ||
64 | struct pch_gpio_reg_data pch_gpio_reg; | ||
65 | struct mutex lock; | ||
66 | }; | ||
67 | |||
68 | static void pch_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) | ||
69 | { | ||
70 | u32 reg_val; | ||
71 | struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); | ||
72 | |||
73 | mutex_lock(&chip->lock); | ||
74 | reg_val = ioread32(&chip->reg->po); | ||
75 | if (val) | ||
76 | reg_val |= (1 << nr); | ||
77 | else | ||
78 | reg_val &= ~(1 << nr); | ||
79 | |||
80 | iowrite32(reg_val, &chip->reg->po); | ||
81 | mutex_unlock(&chip->lock); | ||
82 | } | ||
83 | |||
84 | static int pch_gpio_get(struct gpio_chip *gpio, unsigned nr) | ||
85 | { | ||
86 | struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); | ||
87 | |||
88 | return ioread32(&chip->reg->pi) & (1 << nr); | ||
89 | } | ||
90 | |||
91 | static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | ||
92 | int val) | ||
93 | { | ||
94 | struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); | ||
95 | u32 pm; | ||
96 | u32 reg_val; | ||
97 | |||
98 | mutex_lock(&chip->lock); | ||
99 | pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS; | ||
100 | pm |= (1 << nr); | ||
101 | iowrite32(pm, &chip->reg->pm); | ||
102 | |||
103 | reg_val = ioread32(&chip->reg->po); | ||
104 | if (val) | ||
105 | reg_val |= (1 << nr); | ||
106 | else | ||
107 | reg_val &= ~(1 << nr); | ||
108 | |||
109 | mutex_unlock(&chip->lock); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int pch_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | ||
115 | { | ||
116 | struct pch_gpio *chip = container_of(gpio, struct pch_gpio, gpio); | ||
117 | u32 pm; | ||
118 | |||
119 | mutex_lock(&chip->lock); | ||
120 | pm = ioread32(&chip->reg->pm) & PCH_GPIO_ALL_PINS; /*bits 0-11*/ | ||
121 | pm &= ~(1 << nr); | ||
122 | iowrite32(pm, &chip->reg->pm); | ||
123 | mutex_unlock(&chip->lock); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Save register configuration and disable interrupts. | ||
130 | */ | ||
131 | static void pch_gpio_save_reg_conf(struct pch_gpio *chip) | ||
132 | { | ||
133 | chip->pch_gpio_reg.po_reg = ioread32(&chip->reg->po); | ||
134 | chip->pch_gpio_reg.pm_reg = ioread32(&chip->reg->pm); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * This function restores the register configuration of the GPIO device. | ||
139 | */ | ||
140 | static void pch_gpio_restore_reg_conf(struct pch_gpio *chip) | ||
141 | { | ||
142 | /* to store contents of PO register */ | ||
143 | iowrite32(chip->pch_gpio_reg.po_reg, &chip->reg->po); | ||
144 | /* to store contents of PM register */ | ||
145 | iowrite32(chip->pch_gpio_reg.pm_reg, &chip->reg->pm); | ||
146 | } | ||
147 | |||
148 | static void pch_gpio_setup(struct pch_gpio *chip) | ||
149 | { | ||
150 | struct gpio_chip *gpio = &chip->gpio; | ||
151 | |||
152 | gpio->label = dev_name(chip->dev); | ||
153 | gpio->owner = THIS_MODULE; | ||
154 | gpio->direction_input = pch_gpio_direction_input; | ||
155 | gpio->get = pch_gpio_get; | ||
156 | gpio->direction_output = pch_gpio_direction_output; | ||
157 | gpio->set = pch_gpio_set; | ||
158 | gpio->dbg_show = NULL; | ||
159 | gpio->base = -1; | ||
160 | gpio->ngpio = GPIO_NUM_PINS; | ||
161 | gpio->can_sleep = 0; | ||
162 | } | ||
163 | |||
164 | static int __devinit pch_gpio_probe(struct pci_dev *pdev, | ||
165 | const struct pci_device_id *id) | ||
166 | { | ||
167 | s32 ret; | ||
168 | struct pch_gpio *chip; | ||
169 | |||
170 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
171 | if (chip == NULL) | ||
172 | return -ENOMEM; | ||
173 | |||
174 | chip->dev = &pdev->dev; | ||
175 | ret = pci_enable_device(pdev); | ||
176 | if (ret) { | ||
177 | dev_err(&pdev->dev, "%s : pci_enable_device FAILED", __func__); | ||
178 | goto err_pci_enable; | ||
179 | } | ||
180 | |||
181 | ret = pci_request_regions(pdev, KBUILD_MODNAME); | ||
182 | if (ret) { | ||
183 | dev_err(&pdev->dev, "pci_request_regions FAILED-%d", ret); | ||
184 | goto err_request_regions; | ||
185 | } | ||
186 | |||
187 | chip->base = pci_iomap(pdev, 1, 0); | ||
188 | if (chip->base == 0) { | ||
189 | dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__); | ||
190 | ret = -ENOMEM; | ||
191 | goto err_iomap; | ||
192 | } | ||
193 | |||
194 | chip->reg = chip->base; | ||
195 | pci_set_drvdata(pdev, chip); | ||
196 | mutex_init(&chip->lock); | ||
197 | pch_gpio_setup(chip); | ||
198 | ret = gpiochip_add(&chip->gpio); | ||
199 | if (ret) { | ||
200 | dev_err(&pdev->dev, "PCH gpio: Failed to register GPIO\n"); | ||
201 | goto err_gpiochip_add; | ||
202 | } | ||
203 | |||
204 | return 0; | ||
205 | |||
206 | err_gpiochip_add: | ||
207 | pci_iounmap(pdev, chip->base); | ||
208 | |||
209 | err_iomap: | ||
210 | pci_release_regions(pdev); | ||
211 | |||
212 | err_request_regions: | ||
213 | pci_disable_device(pdev); | ||
214 | |||
215 | err_pci_enable: | ||
216 | kfree(chip); | ||
217 | dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); | ||
218 | return ret; | ||
219 | } | ||
220 | |||
221 | static void __devexit pch_gpio_remove(struct pci_dev *pdev) | ||
222 | { | ||
223 | int err; | ||
224 | struct pch_gpio *chip = pci_get_drvdata(pdev); | ||
225 | |||
226 | err = gpiochip_remove(&chip->gpio); | ||
227 | if (err) | ||
228 | dev_err(&pdev->dev, "Failed gpiochip_remove\n"); | ||
229 | |||
230 | pci_iounmap(pdev, chip->base); | ||
231 | pci_release_regions(pdev); | ||
232 | pci_disable_device(pdev); | ||
233 | kfree(chip); | ||
234 | } | ||
235 | |||
236 | #ifdef CONFIG_PM | ||
237 | static int pch_gpio_suspend(struct pci_dev *pdev, pm_message_t state) | ||
238 | { | ||
239 | s32 ret; | ||
240 | struct pch_gpio *chip = pci_get_drvdata(pdev); | ||
241 | |||
242 | pch_gpio_save_reg_conf(chip); | ||
243 | pch_gpio_restore_reg_conf(chip); | ||
244 | |||
245 | ret = pci_save_state(pdev); | ||
246 | if (ret) { | ||
247 | dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret); | ||
248 | return ret; | ||
249 | } | ||
250 | pci_disable_device(pdev); | ||
251 | pci_set_power_state(pdev, PCI_D0); | ||
252 | ret = pci_enable_wake(pdev, PCI_D0, 1); | ||
253 | if (ret) | ||
254 | dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static int pch_gpio_resume(struct pci_dev *pdev) | ||
260 | { | ||
261 | s32 ret; | ||
262 | struct pch_gpio *chip = pci_get_drvdata(pdev); | ||
263 | |||
264 | ret = pci_enable_wake(pdev, PCI_D0, 0); | ||
265 | |||
266 | pci_set_power_state(pdev, PCI_D0); | ||
267 | ret = pci_enable_device(pdev); | ||
268 | if (ret) { | ||
269 | dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret); | ||
270 | return ret; | ||
271 | } | ||
272 | pci_restore_state(pdev); | ||
273 | |||
274 | iowrite32(0x01, &chip->reg->reset); | ||
275 | iowrite32(0x00, &chip->reg->reset); | ||
276 | pch_gpio_restore_reg_conf(chip); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | #else | ||
281 | #define pch_gpio_suspend NULL | ||
282 | #define pch_gpio_resume NULL | ||
283 | #endif | ||
284 | |||
285 | static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = { | ||
286 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) }, | ||
287 | { 0, } | ||
288 | }; | ||
289 | |||
290 | static struct pci_driver pch_gpio_driver = { | ||
291 | .name = "pch_gpio", | ||
292 | .id_table = pch_gpio_pcidev_id, | ||
293 | .probe = pch_gpio_probe, | ||
294 | .remove = __devexit_p(pch_gpio_remove), | ||
295 | .suspend = pch_gpio_suspend, | ||
296 | .resume = pch_gpio_resume | ||
297 | }; | ||
298 | |||
299 | static int __init pch_gpio_pci_init(void) | ||
300 | { | ||
301 | return pci_register_driver(&pch_gpio_driver); | ||
302 | } | ||
303 | module_init(pch_gpio_pci_init); | ||
304 | |||
305 | static void __exit pch_gpio_pci_exit(void) | ||
306 | { | ||
307 | pci_unregister_driver(&pch_gpio_driver); | ||
308 | } | ||
309 | module_exit(pch_gpio_pci_exit); | ||
310 | |||
311 | MODULE_DESCRIPTION("PCH GPIO PCI Driver"); | ||
312 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c index ddd053108a13..45293662e950 100644 --- a/drivers/gpio/timbgpio.c +++ b/drivers/gpio/timbgpio.c | |||
@@ -47,6 +47,7 @@ struct timbgpio { | |||
47 | spinlock_t lock; /* mutual exclusion */ | 47 | spinlock_t lock; /* mutual exclusion */ |
48 | struct gpio_chip gpio; | 48 | struct gpio_chip gpio; |
49 | int irq_base; | 49 | int irq_base; |
50 | unsigned long last_ier; | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, | 53 | static int timbgpio_update_bit(struct gpio_chip *gpio, unsigned index, |
@@ -112,16 +113,24 @@ static void timbgpio_irq_disable(unsigned irq) | |||
112 | { | 113 | { |
113 | struct timbgpio *tgpio = get_irq_chip_data(irq); | 114 | struct timbgpio *tgpio = get_irq_chip_data(irq); |
114 | int offset = irq - tgpio->irq_base; | 115 | int offset = irq - tgpio->irq_base; |
116 | unsigned long flags; | ||
115 | 117 | ||
116 | timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 0); | 118 | spin_lock_irqsave(&tgpio->lock, flags); |
119 | tgpio->last_ier &= ~(1 << offset); | ||
120 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); | ||
121 | spin_unlock_irqrestore(&tgpio->lock, flags); | ||
117 | } | 122 | } |
118 | 123 | ||
119 | static void timbgpio_irq_enable(unsigned irq) | 124 | static void timbgpio_irq_enable(unsigned irq) |
120 | { | 125 | { |
121 | struct timbgpio *tgpio = get_irq_chip_data(irq); | 126 | struct timbgpio *tgpio = get_irq_chip_data(irq); |
122 | int offset = irq - tgpio->irq_base; | 127 | int offset = irq - tgpio->irq_base; |
128 | unsigned long flags; | ||
123 | 129 | ||
124 | timbgpio_update_bit(&tgpio->gpio, offset, TGPIO_IER, 1); | 130 | spin_lock_irqsave(&tgpio->lock, flags); |
131 | tgpio->last_ier |= 1 << offset; | ||
132 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); | ||
133 | spin_unlock_irqrestore(&tgpio->lock, flags); | ||
125 | } | 134 | } |
126 | 135 | ||
127 | static int timbgpio_irq_type(unsigned irq, unsigned trigger) | 136 | static int timbgpio_irq_type(unsigned irq, unsigned trigger) |
@@ -194,8 +203,16 @@ static void timbgpio_irq(unsigned int irq, struct irq_desc *desc) | |||
194 | ipr = ioread32(tgpio->membase + TGPIO_IPR); | 203 | ipr = ioread32(tgpio->membase + TGPIO_IPR); |
195 | iowrite32(ipr, tgpio->membase + TGPIO_ICR); | 204 | iowrite32(ipr, tgpio->membase + TGPIO_ICR); |
196 | 205 | ||
206 | /* | ||
207 | * Some versions of the hardware trash the IER register if more than | ||
208 | * one interrupt is received simultaneously. | ||
209 | */ | ||
210 | iowrite32(0, tgpio->membase + TGPIO_IER); | ||
211 | |||
197 | for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio) | 212 | for_each_set_bit(offset, &ipr, tgpio->gpio.ngpio) |
198 | generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset)); | 213 | generic_handle_irq(timbgpio_to_irq(&tgpio->gpio, offset)); |
214 | |||
215 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); | ||
199 | } | 216 | } |
200 | 217 | ||
201 | static struct irq_chip timbgpio_irqchip = { | 218 | static struct irq_chip timbgpio_irqchip = { |
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c index 0acf6396e068..202581808bdc 100644 --- a/drivers/media/IR/lirc_dev.c +++ b/drivers/media/IR/lirc_dev.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/poll.h> | 28 | #include <linux/poll.h> |
29 | #include <linux/completion.h> | 29 | #include <linux/completion.h> |
30 | #include <linux/errno.h> | ||
31 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
32 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
33 | #include <linux/unistd.h> | 32 | #include <linux/unistd.h> |
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index f540ff96c53f..e61db9dfebef 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #include <linux/interrupt.h> | ||
33 | #include <asm/intel_scu_ipc.h> | 32 | #include <asm/intel_scu_ipc.h> |
34 | #include <linux/device.h> | 33 | #include <linux/device.h> |
35 | #include <linux/intel_pmic_gpio.h> | 34 | #include <linux/intel_pmic_gpio.h> |
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 3222fa3c808c..0f4a53bdaa3c 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c | |||
@@ -192,7 +192,7 @@ static int rio_match_bus(struct device *dev, struct device_driver *drv) | |||
192 | out:return 0; | 192 | out:return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | static struct device rio_bus = { | 195 | struct device rio_bus = { |
196 | .init_name = "rapidio", | 196 | .init_name = "rapidio", |
197 | }; | 197 | }; |
198 | 198 | ||
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 8070e074c739..1eb82c4c712e 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -48,7 +48,7 @@ DEFINE_SPINLOCK(rio_global_list_lock); | |||
48 | static int next_destid = 0; | 48 | static int next_destid = 0; |
49 | static int next_switchid = 0; | 49 | static int next_switchid = 0; |
50 | static int next_net = 0; | 50 | static int next_net = 0; |
51 | static int next_comptag; | 51 | static int next_comptag = 1; |
52 | 52 | ||
53 | static struct timer_list rio_enum_timer = | 53 | static struct timer_list rio_enum_timer = |
54 | TIMER_INITIALIZER(rio_enum_timeout, 0, 0); | 54 | TIMER_INITIALIZER(rio_enum_timeout, 0, 0); |
@@ -121,27 +121,6 @@ static int rio_clear_locks(struct rio_mport *port) | |||
121 | u32 result; | 121 | u32 result; |
122 | int ret = 0; | 122 | int ret = 0; |
123 | 123 | ||
124 | /* Assign component tag to all devices */ | ||
125 | next_comptag = 1; | ||
126 | rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR, next_comptag++); | ||
127 | |||
128 | list_for_each_entry(rdev, &rio_devices, global_list) { | ||
129 | /* Mark device as discovered */ | ||
130 | rio_read_config_32(rdev, | ||
131 | rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, | ||
132 | &result); | ||
133 | rio_write_config_32(rdev, | ||
134 | rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, | ||
135 | result | RIO_PORT_GEN_DISCOVERED); | ||
136 | |||
137 | rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR, next_comptag); | ||
138 | rdev->comp_tag = next_comptag++; | ||
139 | if (next_comptag >= 0x10000) { | ||
140 | pr_err("RIO: Component Tag Counter Overflow\n"); | ||
141 | break; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | /* Release host device id locks */ | 124 | /* Release host device id locks */ |
146 | rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR, | 125 | rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR, |
147 | port->host_deviceid); | 126 | port->host_deviceid); |
@@ -162,6 +141,15 @@ static int rio_clear_locks(struct rio_mport *port) | |||
162 | rdev->vid, rdev->did); | 141 | rdev->vid, rdev->did); |
163 | ret = -EINVAL; | 142 | ret = -EINVAL; |
164 | } | 143 | } |
144 | |||
145 | /* Mark device as discovered and enable master */ | ||
146 | rio_read_config_32(rdev, | ||
147 | rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, | ||
148 | &result); | ||
149 | result |= RIO_PORT_GEN_DISCOVERED | RIO_PORT_GEN_MASTER; | ||
150 | rio_write_config_32(rdev, | ||
151 | rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR, | ||
152 | result); | ||
165 | } | 153 | } |
166 | 154 | ||
167 | return ret; | 155 | return ret; |
@@ -420,11 +408,27 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
420 | hopcount, RIO_EFB_ERR_MGMNT); | 408 | hopcount, RIO_EFB_ERR_MGMNT); |
421 | } | 409 | } |
422 | 410 | ||
411 | if (rdev->pef & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) { | ||
412 | rio_mport_read_config_32(port, destid, hopcount, | ||
413 | RIO_SWP_INFO_CAR, &rdev->swpinfo); | ||
414 | } | ||
415 | |||
423 | rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, | 416 | rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, |
424 | &rdev->src_ops); | 417 | &rdev->src_ops); |
425 | rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, | 418 | rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, |
426 | &rdev->dst_ops); | 419 | &rdev->dst_ops); |
427 | 420 | ||
421 | if (do_enum) { | ||
422 | /* Assign component tag to device */ | ||
423 | if (next_comptag >= 0x10000) { | ||
424 | pr_err("RIO: Component Tag Counter Overflow\n"); | ||
425 | goto cleanup; | ||
426 | } | ||
427 | rio_mport_write_config_32(port, destid, hopcount, | ||
428 | RIO_COMPONENT_TAG_CSR, next_comptag); | ||
429 | rdev->comp_tag = next_comptag++; | ||
430 | } | ||
431 | |||
428 | if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { | 432 | if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { |
429 | if (do_enum) { | 433 | if (do_enum) { |
430 | rio_set_device_id(port, destid, hopcount, next_destid); | 434 | rio_set_device_id(port, destid, hopcount, next_destid); |
@@ -439,9 +443,10 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
439 | 443 | ||
440 | /* If a PE has both switch and other functions, show it as a switch */ | 444 | /* If a PE has both switch and other functions, show it as a switch */ |
441 | if (rio_is_switch(rdev)) { | 445 | if (rio_is_switch(rdev)) { |
442 | rio_mport_read_config_32(port, destid, hopcount, | 446 | rswitch = kzalloc(sizeof(*rswitch) + |
443 | RIO_SWP_INFO_CAR, &rdev->swpinfo); | 447 | RIO_GET_TOTAL_PORTS(rdev->swpinfo) * |
444 | rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL); | 448 | sizeof(rswitch->nextdev[0]), |
449 | GFP_KERNEL); | ||
445 | if (!rswitch) | 450 | if (!rswitch) |
446 | goto cleanup; | 451 | goto cleanup; |
447 | rswitch->switchid = next_switchid; | 452 | rswitch->switchid = next_switchid; |
@@ -458,6 +463,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
458 | rdid++) | 463 | rdid++) |
459 | rswitch->route_table[rdid] = RIO_INVALID_ROUTE; | 464 | rswitch->route_table[rdid] = RIO_INVALID_ROUTE; |
460 | rdev->rswitch = rswitch; | 465 | rdev->rswitch = rswitch; |
466 | rswitch->rdev = rdev; | ||
461 | dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, | 467 | dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, |
462 | rdev->rswitch->switchid); | 468 | rdev->rswitch->switchid); |
463 | rio_switch_init(rdev, do_enum); | 469 | rio_switch_init(rdev, do_enum); |
@@ -478,6 +484,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
478 | } | 484 | } |
479 | 485 | ||
480 | rdev->dev.bus = &rio_bus_type; | 486 | rdev->dev.bus = &rio_bus_type; |
487 | rdev->dev.parent = &rio_bus; | ||
481 | 488 | ||
482 | device_initialize(&rdev->dev); | 489 | device_initialize(&rdev->dev); |
483 | rdev->dev.release = rio_release_dev; | 490 | rdev->dev.release = rio_release_dev; |
@@ -718,86 +725,53 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount) | |||
718 | } | 725 | } |
719 | 726 | ||
720 | /** | 727 | /** |
721 | * rio_get_swpinfo_inport- Gets the ingress port number | ||
722 | * @mport: Master port to send transaction | ||
723 | * @destid: Destination ID associated with the switch | ||
724 | * @hopcount: Number of hops to the device | ||
725 | * | ||
726 | * Returns port number being used to access the switch device. | ||
727 | */ | ||
728 | static u8 | ||
729 | rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount) | ||
730 | { | ||
731 | u32 result; | ||
732 | |||
733 | rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, | ||
734 | &result); | ||
735 | |||
736 | return (u8) (result & 0xff); | ||
737 | } | ||
738 | |||
739 | /** | ||
740 | * rio_get_swpinfo_tports- Gets total number of ports on the switch | ||
741 | * @mport: Master port to send transaction | ||
742 | * @destid: Destination ID associated with the switch | ||
743 | * @hopcount: Number of hops to the device | ||
744 | * | ||
745 | * Returns total numbers of ports implemented by the switch device. | ||
746 | */ | ||
747 | static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid, | ||
748 | u8 hopcount) | ||
749 | { | ||
750 | u32 result; | ||
751 | |||
752 | rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, | ||
753 | &result); | ||
754 | |||
755 | return RIO_GET_TOTAL_PORTS(result); | ||
756 | } | ||
757 | |||
758 | /** | ||
759 | * rio_net_add_mport- Add a master port to a RIO network | ||
760 | * @net: RIO network | ||
761 | * @port: Master port to add | ||
762 | * | ||
763 | * Adds a master port to the network list of associated master | ||
764 | * ports.. | ||
765 | */ | ||
766 | static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port) | ||
767 | { | ||
768 | spin_lock(&rio_global_list_lock); | ||
769 | list_add_tail(&port->nnode, &net->mports); | ||
770 | spin_unlock(&rio_global_list_lock); | ||
771 | } | ||
772 | |||
773 | /** | ||
774 | * rio_enum_peer- Recursively enumerate a RIO network through a master port | 728 | * rio_enum_peer- Recursively enumerate a RIO network through a master port |
775 | * @net: RIO network being enumerated | 729 | * @net: RIO network being enumerated |
776 | * @port: Master port to send transactions | 730 | * @port: Master port to send transactions |
777 | * @hopcount: Number of hops into the network | 731 | * @hopcount: Number of hops into the network |
732 | * @prev: Previous RIO device connected to the enumerated one | ||
733 | * @prev_port: Port on previous RIO device | ||
778 | * | 734 | * |
779 | * Recursively enumerates a RIO network. Transactions are sent via the | 735 | * Recursively enumerates a RIO network. Transactions are sent via the |
780 | * master port passed in @port. | 736 | * master port passed in @port. |
781 | */ | 737 | */ |
782 | static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | 738 | static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, |
783 | u8 hopcount) | 739 | u8 hopcount, struct rio_dev *prev, int prev_port) |
784 | { | 740 | { |
785 | int port_num; | 741 | int port_num; |
786 | int num_ports; | ||
787 | int cur_destid; | 742 | int cur_destid; |
788 | int sw_destid; | 743 | int sw_destid; |
789 | int sw_inport; | 744 | int sw_inport; |
790 | struct rio_dev *rdev; | 745 | struct rio_dev *rdev; |
791 | u16 destid; | 746 | u16 destid; |
747 | u32 regval; | ||
792 | int tmp; | 748 | int tmp; |
793 | 749 | ||
750 | if (rio_mport_chk_dev_access(port, | ||
751 | RIO_ANY_DESTID(port->sys_size), hopcount)) { | ||
752 | pr_debug("RIO: device access check failed\n"); | ||
753 | return -1; | ||
754 | } | ||
755 | |||
794 | if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) { | 756 | if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) { |
795 | pr_debug("RIO: PE already discovered by this host\n"); | 757 | pr_debug("RIO: PE already discovered by this host\n"); |
796 | /* | 758 | /* |
797 | * Already discovered by this host. Add it as another | 759 | * Already discovered by this host. Add it as another |
798 | * master port for the current network. | 760 | * link to the existing device. |
799 | */ | 761 | */ |
800 | rio_net_add_mport(net, port); | 762 | rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), |
763 | hopcount, RIO_COMPONENT_TAG_CSR, ®val); | ||
764 | |||
765 | if (regval) { | ||
766 | rdev = rio_get_comptag((regval & 0xffff), NULL); | ||
767 | |||
768 | if (rdev && prev && rio_is_switch(prev)) { | ||
769 | pr_debug("RIO: redundant path to %s\n", | ||
770 | rio_name(rdev)); | ||
771 | prev->rswitch->nextdev[prev_port] = rdev; | ||
772 | } | ||
773 | } | ||
774 | |||
801 | return 0; | 775 | return 0; |
802 | } | 776 | } |
803 | 777 | ||
@@ -828,13 +802,15 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
828 | if (rdev) { | 802 | if (rdev) { |
829 | /* Add device to the global and bus/net specific list. */ | 803 | /* Add device to the global and bus/net specific list. */ |
830 | list_add_tail(&rdev->net_list, &net->devices); | 804 | list_add_tail(&rdev->net_list, &net->devices); |
805 | rdev->prev = prev; | ||
806 | if (prev && rio_is_switch(prev)) | ||
807 | prev->rswitch->nextdev[prev_port] = rdev; | ||
831 | } else | 808 | } else |
832 | return -1; | 809 | return -1; |
833 | 810 | ||
834 | if (rio_is_switch(rdev)) { | 811 | if (rio_is_switch(rdev)) { |
835 | next_switchid++; | 812 | next_switchid++; |
836 | sw_inport = rio_get_swpinfo_inport(port, | 813 | sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo); |
837 | RIO_ANY_DESTID(port->sys_size), hopcount); | ||
838 | rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, | 814 | rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, |
839 | port->host_deviceid, sw_inport, 0); | 815 | port->host_deviceid, sw_inport, 0); |
840 | rdev->rswitch->route_table[port->host_deviceid] = sw_inport; | 816 | rdev->rswitch->route_table[port->host_deviceid] = sw_inport; |
@@ -847,14 +823,14 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
847 | rdev->rswitch->route_table[destid] = sw_inport; | 823 | rdev->rswitch->route_table[destid] = sw_inport; |
848 | } | 824 | } |
849 | 825 | ||
850 | num_ports = | ||
851 | rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size), | ||
852 | hopcount); | ||
853 | pr_debug( | 826 | pr_debug( |
854 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", | 827 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", |
855 | rio_name(rdev), rdev->vid, rdev->did, num_ports); | 828 | rio_name(rdev), rdev->vid, rdev->did, |
829 | RIO_GET_TOTAL_PORTS(rdev->swpinfo)); | ||
856 | sw_destid = next_destid; | 830 | sw_destid = next_destid; |
857 | for (port_num = 0; port_num < num_ports; port_num++) { | 831 | for (port_num = 0; |
832 | port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo); | ||
833 | port_num++) { | ||
858 | /*Enable Input Output Port (transmitter reviever)*/ | 834 | /*Enable Input Output Port (transmitter reviever)*/ |
859 | rio_enable_rx_tx_port(port, 0, | 835 | rio_enable_rx_tx_port(port, 0, |
860 | RIO_ANY_DESTID(port->sys_size), | 836 | RIO_ANY_DESTID(port->sys_size), |
@@ -879,7 +855,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
879 | RIO_ANY_DESTID(port->sys_size), | 855 | RIO_ANY_DESTID(port->sys_size), |
880 | port_num, 0); | 856 | port_num, 0); |
881 | 857 | ||
882 | if (rio_enum_peer(net, port, hopcount + 1) < 0) | 858 | if (rio_enum_peer(net, port, hopcount + 1, |
859 | rdev, port_num) < 0) | ||
883 | return -1; | 860 | return -1; |
884 | 861 | ||
885 | /* Update routing tables */ | 862 | /* Update routing tables */ |
@@ -945,10 +922,11 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
945 | */ | 922 | */ |
946 | static int rio_enum_complete(struct rio_mport *port) | 923 | static int rio_enum_complete(struct rio_mport *port) |
947 | { | 924 | { |
948 | u32 tag_csr; | 925 | u32 regval; |
949 | 926 | ||
950 | rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr); | 927 | rio_local_read_config_32(port, port->phys_efptr + RIO_PORT_GEN_CTL_CSR, |
951 | return (tag_csr & 0xffff) ? 1 : 0; | 928 | ®val); |
929 | return (regval & RIO_PORT_GEN_MASTER) ? 1 : 0; | ||
952 | } | 930 | } |
953 | 931 | ||
954 | /** | 932 | /** |
@@ -966,7 +944,6 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
966 | u8 hopcount) | 944 | u8 hopcount) |
967 | { | 945 | { |
968 | u8 port_num, route_port; | 946 | u8 port_num, route_port; |
969 | int num_ports; | ||
970 | struct rio_dev *rdev; | 947 | struct rio_dev *rdev; |
971 | u16 ndestid; | 948 | u16 ndestid; |
972 | 949 | ||
@@ -983,13 +960,14 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
983 | /* Associated destid is how we accessed this switch */ | 960 | /* Associated destid is how we accessed this switch */ |
984 | rdev->rswitch->destid = destid; | 961 | rdev->rswitch->destid = destid; |
985 | 962 | ||
986 | num_ports = rio_get_swpinfo_tports(port, destid, hopcount); | ||
987 | pr_debug( | 963 | pr_debug( |
988 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", | 964 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", |
989 | rio_name(rdev), rdev->vid, rdev->did, num_ports); | 965 | rio_name(rdev), rdev->vid, rdev->did, |
990 | for (port_num = 0; port_num < num_ports; port_num++) { | 966 | RIO_GET_TOTAL_PORTS(rdev->swpinfo)); |
991 | if (rio_get_swpinfo_inport(port, destid, hopcount) == | 967 | for (port_num = 0; |
992 | port_num) | 968 | port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo); |
969 | port_num++) { | ||
970 | if (RIO_GET_PORT_NUM(rdev->swpinfo) == port_num) | ||
993 | continue; | 971 | continue; |
994 | 972 | ||
995 | if (rio_sport_is_active | 973 | if (rio_sport_is_active |
@@ -1011,6 +989,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
1011 | break; | 989 | break; |
1012 | } | 990 | } |
1013 | 991 | ||
992 | if (ndestid == RIO_ANY_DESTID(port->sys_size)) | ||
993 | continue; | ||
1014 | rio_unlock_device(port, destid, hopcount); | 994 | rio_unlock_device(port, destid, hopcount); |
1015 | if (rio_disc_peer | 995 | if (rio_disc_peer |
1016 | (net, port, ndestid, hopcount + 1) < 0) | 996 | (net, port, ndestid, hopcount + 1) < 0) |
@@ -1108,8 +1088,7 @@ static void rio_update_route_tables(struct rio_mport *port) | |||
1108 | if (rswitch->destid == destid) | 1088 | if (rswitch->destid == destid) |
1109 | continue; | 1089 | continue; |
1110 | 1090 | ||
1111 | sport = rio_get_swpinfo_inport(port, | 1091 | sport = RIO_GET_PORT_NUM(rswitch->rdev->swpinfo); |
1112 | rswitch->destid, rswitch->hopcount); | ||
1113 | 1092 | ||
1114 | if (rswitch->add_entry) { | 1093 | if (rswitch->add_entry) { |
1115 | rio_route_add_entry(port, rswitch, | 1094 | rio_route_add_entry(port, rswitch, |
@@ -1184,7 +1163,11 @@ int __devinit rio_enum_mport(struct rio_mport *mport) | |||
1184 | /* Enable Input Output Port (transmitter reviever) */ | 1163 | /* Enable Input Output Port (transmitter reviever) */ |
1185 | rio_enable_rx_tx_port(mport, 1, 0, 0, 0); | 1164 | rio_enable_rx_tx_port(mport, 1, 0, 0, 0); |
1186 | 1165 | ||
1187 | if (rio_enum_peer(net, mport, 0) < 0) { | 1166 | /* Set component tag for host */ |
1167 | rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR, | ||
1168 | next_comptag++); | ||
1169 | |||
1170 | if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) { | ||
1188 | /* A higher priority host won enumeration, bail. */ | 1171 | /* A higher priority host won enumeration, bail. */ |
1189 | printk(KERN_INFO | 1172 | printk(KERN_INFO |
1190 | "RIO: master port %d device has lost enumeration to a remote host\n", | 1173 | "RIO: master port %d device has lost enumeration to a remote host\n", |
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c index 00b475658356..137ed93ee33f 100644 --- a/drivers/rapidio/rio-sysfs.c +++ b/drivers/rapidio/rio-sysfs.c | |||
@@ -40,9 +40,6 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch | |||
40 | char *str = buf; | 40 | char *str = buf; |
41 | int i; | 41 | int i; |
42 | 42 | ||
43 | if (!rdev->rswitch) | ||
44 | goto out; | ||
45 | |||
46 | for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); | 43 | for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); |
47 | i++) { | 44 | i++) { |
48 | if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE) | 45 | if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE) |
@@ -52,7 +49,6 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch | |||
52 | rdev->rswitch->route_table[i]); | 49 | rdev->rswitch->route_table[i]); |
53 | } | 50 | } |
54 | 51 | ||
55 | out: | ||
56 | return (str - buf); | 52 | return (str - buf); |
57 | } | 53 | } |
58 | 54 | ||
@@ -63,10 +59,11 @@ struct device_attribute rio_dev_attrs[] = { | |||
63 | __ATTR_RO(asm_did), | 59 | __ATTR_RO(asm_did), |
64 | __ATTR_RO(asm_vid), | 60 | __ATTR_RO(asm_vid), |
65 | __ATTR_RO(asm_rev), | 61 | __ATTR_RO(asm_rev), |
66 | __ATTR_RO(routes), | ||
67 | __ATTR_NULL, | 62 | __ATTR_NULL, |
68 | }; | 63 | }; |
69 | 64 | ||
65 | static DEVICE_ATTR(routes, S_IRUGO, routes_show, NULL); | ||
66 | |||
70 | static ssize_t | 67 | static ssize_t |
71 | rio_read_config(struct file *filp, struct kobject *kobj, | 68 | rio_read_config(struct file *filp, struct kobject *kobj, |
72 | struct bin_attribute *bin_attr, | 69 | struct bin_attribute *bin_attr, |
@@ -218,7 +215,17 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) | |||
218 | { | 215 | { |
219 | int err = 0; | 216 | int err = 0; |
220 | 217 | ||
221 | err = sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr); | 218 | err = device_create_bin_file(&rdev->dev, &rio_config_attr); |
219 | |||
220 | if (!err && rdev->rswitch) { | ||
221 | err = device_create_file(&rdev->dev, &dev_attr_routes); | ||
222 | if (!err && rdev->rswitch->sw_sysfs) | ||
223 | err = rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_CREATE); | ||
224 | } | ||
225 | |||
226 | if (err) | ||
227 | pr_warning("RIO: Failed to create attribute file(s) for %s\n", | ||
228 | rio_name(rdev)); | ||
222 | 229 | ||
223 | return err; | 230 | return err; |
224 | } | 231 | } |
@@ -231,5 +238,10 @@ int rio_create_sysfs_dev_files(struct rio_dev *rdev) | |||
231 | */ | 238 | */ |
232 | void rio_remove_sysfs_dev_files(struct rio_dev *rdev) | 239 | void rio_remove_sysfs_dev_files(struct rio_dev *rdev) |
233 | { | 240 | { |
234 | sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr); | 241 | device_remove_bin_file(&rdev->dev, &rio_config_attr); |
242 | if (rdev->rswitch) { | ||
243 | device_remove_file(&rdev->dev, &dev_attr_routes); | ||
244 | if (rdev->rswitch->sw_sysfs) | ||
245 | rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE); | ||
246 | } | ||
235 | } | 247 | } |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 74e9d22d95fb..68cf0c99138a 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -443,7 +443,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local, | |||
443 | * @from is not %NULL, searches continue from next device on the global | 443 | * @from is not %NULL, searches continue from next device on the global |
444 | * list. | 444 | * list. |
445 | */ | 445 | */ |
446 | static struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) | 446 | struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from) |
447 | { | 447 | { |
448 | struct list_head *n; | 448 | struct list_head *n; |
449 | struct rio_dev *rdev; | 449 | struct rio_dev *rdev; |
@@ -495,6 +495,232 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) | |||
495 | } | 495 | } |
496 | 496 | ||
497 | /** | 497 | /** |
498 | * rio_chk_dev_route - Validate route to the specified device. | ||
499 | * @rdev: RIO device failed to respond | ||
500 | * @nrdev: Last active device on the route to rdev | ||
501 | * @npnum: nrdev's port number on the route to rdev | ||
502 | * | ||
503 | * Follows a route to the specified RIO device to determine the last available | ||
504 | * device (and corresponding RIO port) on the route. | ||
505 | */ | ||
506 | static int | ||
507 | rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum) | ||
508 | { | ||
509 | u32 result; | ||
510 | int p_port, dstid, rc = -EIO; | ||
511 | struct rio_dev *prev = NULL; | ||
512 | |||
513 | /* Find switch with failed RIO link */ | ||
514 | while (rdev->prev && (rdev->prev->pef & RIO_PEF_SWITCH)) { | ||
515 | if (!rio_read_config_32(rdev->prev, RIO_DEV_ID_CAR, &result)) { | ||
516 | prev = rdev->prev; | ||
517 | break; | ||
518 | } | ||
519 | rdev = rdev->prev; | ||
520 | } | ||
521 | |||
522 | if (prev == NULL) | ||
523 | goto err_out; | ||
524 | |||
525 | dstid = (rdev->pef & RIO_PEF_SWITCH) ? | ||
526 | rdev->rswitch->destid : rdev->destid; | ||
527 | p_port = prev->rswitch->route_table[dstid]; | ||
528 | |||
529 | if (p_port != RIO_INVALID_ROUTE) { | ||
530 | pr_debug("RIO: link failed on [%s]-P%d\n", | ||
531 | rio_name(prev), p_port); | ||
532 | *nrdev = prev; | ||
533 | *npnum = p_port; | ||
534 | rc = 0; | ||
535 | } else | ||
536 | pr_debug("RIO: failed to trace route to %s\n", rio_name(rdev)); | ||
537 | err_out: | ||
538 | return rc; | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * rio_mport_chk_dev_access - Validate access to the specified device. | ||
543 | * @mport: Master port to send transactions | ||
544 | * @destid: Device destination ID in network | ||
545 | * @hopcount: Number of hops into the network | ||
546 | */ | ||
547 | int | ||
548 | rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount) | ||
549 | { | ||
550 | int i = 0; | ||
551 | u32 tmp; | ||
552 | |||
553 | while (rio_mport_read_config_32(mport, destid, hopcount, | ||
554 | RIO_DEV_ID_CAR, &tmp)) { | ||
555 | i++; | ||
556 | if (i == RIO_MAX_CHK_RETRY) | ||
557 | return -EIO; | ||
558 | mdelay(1); | ||
559 | } | ||
560 | |||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | /** | ||
565 | * rio_chk_dev_access - Validate access to the specified device. | ||
566 | * @rdev: Pointer to RIO device control structure | ||
567 | */ | ||
568 | static int rio_chk_dev_access(struct rio_dev *rdev) | ||
569 | { | ||
570 | u8 hopcount = 0xff; | ||
571 | u16 destid = rdev->destid; | ||
572 | |||
573 | if (rdev->rswitch) { | ||
574 | destid = rdev->rswitch->destid; | ||
575 | hopcount = rdev->rswitch->hopcount; | ||
576 | } | ||
577 | |||
578 | return rio_mport_chk_dev_access(rdev->net->hport, destid, hopcount); | ||
579 | } | ||
580 | |||
581 | /** | ||
582 | * rio_get_input_status - Sends a Link-Request/Input-Status control symbol and | ||
583 | * returns link-response (if requested). | ||
584 | * @rdev: RIO devive to issue Input-status command | ||
585 | * @pnum: Device port number to issue the command | ||
586 | * @lnkresp: Response from a link partner | ||
587 | */ | ||
588 | static int | ||
589 | rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) | ||
590 | { | ||
591 | struct rio_mport *mport = rdev->net->hport; | ||
592 | u16 destid = rdev->rswitch->destid; | ||
593 | u8 hopcount = rdev->rswitch->hopcount; | ||
594 | u32 regval; | ||
595 | int checkcount; | ||
596 | |||
597 | if (lnkresp) { | ||
598 | /* Read from link maintenance response register | ||
599 | * to clear valid bit */ | ||
600 | rio_mport_read_config_32(mport, destid, hopcount, | ||
601 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), | ||
602 | ®val); | ||
603 | udelay(50); | ||
604 | } | ||
605 | |||
606 | /* Issue Input-status command */ | ||
607 | rio_mport_write_config_32(mport, destid, hopcount, | ||
608 | rdev->phys_efptr + RIO_PORT_N_MNT_REQ_CSR(pnum), | ||
609 | RIO_MNT_REQ_CMD_IS); | ||
610 | |||
611 | /* Exit if the response is not expected */ | ||
612 | if (lnkresp == NULL) | ||
613 | return 0; | ||
614 | |||
615 | checkcount = 3; | ||
616 | while (checkcount--) { | ||
617 | udelay(50); | ||
618 | rio_mport_read_config_32(mport, destid, hopcount, | ||
619 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), | ||
620 | ®val); | ||
621 | if (regval & RIO_PORT_N_MNT_RSP_RVAL) { | ||
622 | *lnkresp = regval; | ||
623 | return 0; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | return -EIO; | ||
628 | } | ||
629 | |||
630 | /** | ||
631 | * rio_clr_err_stopped - Clears port Error-stopped states. | ||
632 | * @rdev: Pointer to RIO device control structure | ||
633 | * @pnum: Switch port number to clear errors | ||
634 | * @err_status: port error status (if 0 reads register from device) | ||
635 | */ | ||
636 | static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | ||
637 | { | ||
638 | struct rio_mport *mport = rdev->net->hport; | ||
639 | u16 destid = rdev->rswitch->destid; | ||
640 | u8 hopcount = rdev->rswitch->hopcount; | ||
641 | struct rio_dev *nextdev = rdev->rswitch->nextdev[pnum]; | ||
642 | u32 regval; | ||
643 | u32 far_ackid, far_linkstat, near_ackid; | ||
644 | |||
645 | if (err_status == 0) | ||
646 | rio_mport_read_config_32(mport, destid, hopcount, | ||
647 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | ||
648 | &err_status); | ||
649 | |||
650 | if (err_status & RIO_PORT_N_ERR_STS_PW_OUT_ES) { | ||
651 | pr_debug("RIO_EM: servicing Output Error-Stopped state\n"); | ||
652 | /* | ||
653 | * Send a Link-Request/Input-Status control symbol | ||
654 | */ | ||
655 | if (rio_get_input_status(rdev, pnum, ®val)) { | ||
656 | pr_debug("RIO_EM: Input-status response timeout\n"); | ||
657 | goto rd_err; | ||
658 | } | ||
659 | |||
660 | pr_debug("RIO_EM: SP%d Input-status response=0x%08x\n", | ||
661 | pnum, regval); | ||
662 | far_ackid = (regval & RIO_PORT_N_MNT_RSP_ASTAT) >> 5; | ||
663 | far_linkstat = regval & RIO_PORT_N_MNT_RSP_LSTAT; | ||
664 | rio_mport_read_config_32(mport, destid, hopcount, | ||
665 | rdev->phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum), | ||
666 | ®val); | ||
667 | pr_debug("RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n", pnum, regval); | ||
668 | near_ackid = (regval & RIO_PORT_N_ACK_INBOUND) >> 24; | ||
669 | pr_debug("RIO_EM: SP%d far_ackID=0x%02x far_linkstat=0x%02x" \ | ||
670 | " near_ackID=0x%02x\n", | ||
671 | pnum, far_ackid, far_linkstat, near_ackid); | ||
672 | |||
673 | /* | ||
674 | * If required, synchronize ackIDs of near and | ||
675 | * far sides. | ||
676 | */ | ||
677 | if ((far_ackid != ((regval & RIO_PORT_N_ACK_OUTSTAND) >> 8)) || | ||
678 | (far_ackid != (regval & RIO_PORT_N_ACK_OUTBOUND))) { | ||
679 | /* Align near outstanding/outbound ackIDs with | ||
680 | * far inbound. | ||
681 | */ | ||
682 | rio_mport_write_config_32(mport, destid, | ||
683 | hopcount, rdev->phys_efptr + | ||
684 | RIO_PORT_N_ACK_STS_CSR(pnum), | ||
685 | (near_ackid << 24) | | ||
686 | (far_ackid << 8) | far_ackid); | ||
687 | /* Align far outstanding/outbound ackIDs with | ||
688 | * near inbound. | ||
689 | */ | ||
690 | far_ackid++; | ||
691 | if (nextdev) | ||
692 | rio_write_config_32(nextdev, | ||
693 | nextdev->phys_efptr + | ||
694 | RIO_PORT_N_ACK_STS_CSR(RIO_GET_PORT_NUM(nextdev->swpinfo)), | ||
695 | (far_ackid << 24) | | ||
696 | (near_ackid << 8) | near_ackid); | ||
697 | else | ||
698 | pr_debug("RIO_EM: Invalid nextdev pointer (NULL)\n"); | ||
699 | } | ||
700 | rd_err: | ||
701 | rio_mport_read_config_32(mport, destid, hopcount, | ||
702 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | ||
703 | &err_status); | ||
704 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); | ||
705 | } | ||
706 | |||
707 | if ((err_status & RIO_PORT_N_ERR_STS_PW_INP_ES) && nextdev) { | ||
708 | pr_debug("RIO_EM: servicing Input Error-Stopped state\n"); | ||
709 | rio_get_input_status(nextdev, | ||
710 | RIO_GET_PORT_NUM(nextdev->swpinfo), NULL); | ||
711 | udelay(50); | ||
712 | |||
713 | rio_mport_read_config_32(mport, destid, hopcount, | ||
714 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | ||
715 | &err_status); | ||
716 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); | ||
717 | } | ||
718 | |||
719 | return (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | | ||
720 | RIO_PORT_N_ERR_STS_PW_INP_ES)) ? 1 : 0; | ||
721 | } | ||
722 | |||
723 | /** | ||
498 | * rio_inb_pwrite_handler - process inbound port-write message | 724 | * rio_inb_pwrite_handler - process inbound port-write message |
499 | * @pw_msg: pointer to inbound port-write message | 725 | * @pw_msg: pointer to inbound port-write message |
500 | * | 726 | * |
@@ -507,13 +733,13 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
507 | struct rio_mport *mport; | 733 | struct rio_mport *mport; |
508 | u8 hopcount; | 734 | u8 hopcount; |
509 | u16 destid; | 735 | u16 destid; |
510 | u32 err_status; | 736 | u32 err_status, em_perrdet, em_ltlerrdet; |
511 | int rc, portnum; | 737 | int rc, portnum; |
512 | 738 | ||
513 | rdev = rio_get_comptag(pw_msg->em.comptag, NULL); | 739 | rdev = rio_get_comptag(pw_msg->em.comptag, NULL); |
514 | if (rdev == NULL) { | 740 | if (rdev == NULL) { |
515 | /* Someting bad here (probably enumeration error) */ | 741 | /* Device removed or enumeration error */ |
516 | pr_err("RIO: %s No matching device for CTag 0x%08x\n", | 742 | pr_debug("RIO: %s No matching device for CTag 0x%08x\n", |
517 | __func__, pw_msg->em.comptag); | 743 | __func__, pw_msg->em.comptag); |
518 | return -EIO; | 744 | return -EIO; |
519 | } | 745 | } |
@@ -524,12 +750,11 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
524 | { | 750 | { |
525 | u32 i; | 751 | u32 i; |
526 | for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32);) { | 752 | for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32);) { |
527 | pr_debug("0x%02x: %08x %08x %08x %08x", | 753 | pr_debug("0x%02x: %08x %08x %08x %08x\n", |
528 | i*4, pw_msg->raw[i], pw_msg->raw[i + 1], | 754 | i*4, pw_msg->raw[i], pw_msg->raw[i + 1], |
529 | pw_msg->raw[i + 2], pw_msg->raw[i + 3]); | 755 | pw_msg->raw[i + 2], pw_msg->raw[i + 3]); |
530 | i += 4; | 756 | i += 4; |
531 | } | 757 | } |
532 | pr_debug("\n"); | ||
533 | } | 758 | } |
534 | #endif | 759 | #endif |
535 | 760 | ||
@@ -545,6 +770,26 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
545 | return 0; | 770 | return 0; |
546 | } | 771 | } |
547 | 772 | ||
773 | portnum = pw_msg->em.is_port & 0xFF; | ||
774 | |||
775 | /* Check if device and route to it are functional: | ||
776 | * Sometimes devices may send PW message(s) just before being | ||
777 | * powered down (or link being lost). | ||
778 | */ | ||
779 | if (rio_chk_dev_access(rdev)) { | ||
780 | pr_debug("RIO: device access failed - get link partner\n"); | ||
781 | /* Scan route to the device and identify failed link. | ||
782 | * This will replace device and port reported in PW message. | ||
783 | * PW message should not be used after this point. | ||
784 | */ | ||
785 | if (rio_chk_dev_route(rdev, &rdev, &portnum)) { | ||
786 | pr_err("RIO: Route trace for %s failed\n", | ||
787 | rio_name(rdev)); | ||
788 | return -EIO; | ||
789 | } | ||
790 | pw_msg = NULL; | ||
791 | } | ||
792 | |||
548 | /* For End-point devices processing stops here */ | 793 | /* For End-point devices processing stops here */ |
549 | if (!(rdev->pef & RIO_PEF_SWITCH)) | 794 | if (!(rdev->pef & RIO_PEF_SWITCH)) |
550 | return 0; | 795 | return 0; |
@@ -562,9 +807,6 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
562 | /* | 807 | /* |
563 | * Process the port-write notification from switch | 808 | * Process the port-write notification from switch |
564 | */ | 809 | */ |
565 | |||
566 | portnum = pw_msg->em.is_port & 0xFF; | ||
567 | |||
568 | if (rdev->rswitch->em_handle) | 810 | if (rdev->rswitch->em_handle) |
569 | rdev->rswitch->em_handle(rdev, portnum); | 811 | rdev->rswitch->em_handle(rdev, portnum); |
570 | 812 | ||
@@ -573,29 +815,28 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
573 | &err_status); | 815 | &err_status); |
574 | pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status); | 816 | pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status); |
575 | 817 | ||
576 | if (pw_msg->em.errdetect) { | 818 | if (err_status & RIO_PORT_N_ERR_STS_PORT_OK) { |
577 | pr_debug("RIO_PW: RIO_EM_P%d_ERR_DETECT=0x%08x\n", | ||
578 | portnum, pw_msg->em.errdetect); | ||
579 | /* Clear EM Port N Error Detect CSR */ | ||
580 | rio_mport_write_config_32(mport, destid, hopcount, | ||
581 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), 0); | ||
582 | } | ||
583 | 819 | ||
584 | if (pw_msg->em.ltlerrdet) { | 820 | if (!(rdev->rswitch->port_ok & (1 << portnum))) { |
585 | pr_debug("RIO_PW: RIO_EM_LTL_ERR_DETECT=0x%08x\n", | 821 | rdev->rswitch->port_ok |= (1 << portnum); |
586 | pw_msg->em.ltlerrdet); | 822 | rio_set_port_lockout(rdev, portnum, 0); |
587 | /* Clear EM L/T Layer Error Detect CSR */ | 823 | /* Schedule Insertion Service */ |
588 | rio_mport_write_config_32(mport, destid, hopcount, | 824 | pr_debug("RIO_PW: Device Insertion on [%s]-P%d\n", |
589 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, 0); | 825 | rio_name(rdev), portnum); |
590 | } | 826 | } |
591 | 827 | ||
592 | /* Clear Port Errors */ | 828 | /* Clear error-stopped states (if reported). |
593 | rio_mport_write_config_32(mport, destid, hopcount, | 829 | * Depending on the link partner state, two attempts |
594 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 830 | * may be needed for successful recovery. |
595 | err_status & RIO_PORT_N_ERR_STS_CLR_MASK); | 831 | */ |
832 | if (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | | ||
833 | RIO_PORT_N_ERR_STS_PW_INP_ES)) { | ||
834 | if (rio_clr_err_stopped(rdev, portnum, err_status)) | ||
835 | rio_clr_err_stopped(rdev, portnum, 0); | ||
836 | } | ||
837 | } else { /* if (err_status & RIO_PORT_N_ERR_STS_PORT_UNINIT) */ | ||
596 | 838 | ||
597 | if (rdev->rswitch->port_ok & (1 << portnum)) { | 839 | if (rdev->rswitch->port_ok & (1 << portnum)) { |
598 | if (err_status & RIO_PORT_N_ERR_STS_PORT_UNINIT) { | ||
599 | rdev->rswitch->port_ok &= ~(1 << portnum); | 840 | rdev->rswitch->port_ok &= ~(1 << portnum); |
600 | rio_set_port_lockout(rdev, portnum, 1); | 841 | rio_set_port_lockout(rdev, portnum, 1); |
601 | 842 | ||
@@ -608,21 +849,32 @@ int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg) | |||
608 | pr_debug("RIO_PW: Device Extraction on [%s]-P%d\n", | 849 | pr_debug("RIO_PW: Device Extraction on [%s]-P%d\n", |
609 | rio_name(rdev), portnum); | 850 | rio_name(rdev), portnum); |
610 | } | 851 | } |
611 | } else { | 852 | } |
612 | if (err_status & RIO_PORT_N_ERR_STS_PORT_OK) { | ||
613 | rdev->rswitch->port_ok |= (1 << portnum); | ||
614 | rio_set_port_lockout(rdev, portnum, 0); | ||
615 | 853 | ||
616 | /* Schedule Insertion Service */ | 854 | rio_mport_read_config_32(mport, destid, hopcount, |
617 | pr_debug("RIO_PW: Device Insertion on [%s]-P%d\n", | 855 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet); |
618 | rio_name(rdev), portnum); | 856 | if (em_perrdet) { |
619 | } | 857 | pr_debug("RIO_PW: RIO_EM_P%d_ERR_DETECT=0x%08x\n", |
858 | portnum, em_perrdet); | ||
859 | /* Clear EM Port N Error Detect CSR */ | ||
860 | rio_mport_write_config_32(mport, destid, hopcount, | ||
861 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), 0); | ||
862 | } | ||
863 | |||
864 | rio_mport_read_config_32(mport, destid, hopcount, | ||
865 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet); | ||
866 | if (em_ltlerrdet) { | ||
867 | pr_debug("RIO_PW: RIO_EM_LTL_ERR_DETECT=0x%08x\n", | ||
868 | em_ltlerrdet); | ||
869 | /* Clear EM L/T Layer Error Detect CSR */ | ||
870 | rio_mport_write_config_32(mport, destid, hopcount, | ||
871 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, 0); | ||
620 | } | 872 | } |
621 | 873 | ||
622 | /* Clear Port-Write Pending bit */ | 874 | /* Clear remaining error bits and Port-Write Pending bit */ |
623 | rio_mport_write_config_32(mport, destid, hopcount, | 875 | rio_mport_write_config_32(mport, destid, hopcount, |
624 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 876 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), |
625 | RIO_PORT_N_ERR_STS_PW_PEND); | 877 | err_status); |
626 | 878 | ||
627 | return 0; | 879 | return 0; |
628 | } | 880 | } |
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index f27b7a9c47d2..b1af414f15e6 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/rio.h> | 15 | #include <linux/rio.h> |
16 | 16 | ||
17 | #define RIO_MAX_CHK_RETRY 3 | ||
18 | |||
17 | /* Functions internal to the RIO core code */ | 19 | /* Functions internal to the RIO core code */ |
18 | 20 | ||
19 | extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid, | 21 | extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid, |
@@ -22,6 +24,8 @@ extern u32 rio_mport_get_physefb(struct rio_mport *port, int local, | |||
22 | u16 destid, u8 hopcount); | 24 | u16 destid, u8 hopcount); |
23 | extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, | 25 | extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, |
24 | u8 hopcount, u32 from); | 26 | u8 hopcount, u32 from); |
27 | extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, | ||
28 | u8 hopcount); | ||
25 | extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); | 29 | extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); |
26 | extern int rio_enum_mport(struct rio_mport *mport); | 30 | extern int rio_enum_mport(struct rio_mport *mport); |
27 | extern int rio_disc_mport(struct rio_mport *mport); | 31 | extern int rio_disc_mport(struct rio_mport *mport); |
@@ -34,6 +38,7 @@ extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, | |||
34 | extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, | 38 | extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, |
35 | u8 hopcount, u16 table); | 39 | u8 hopcount, u16 table); |
36 | extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); | 40 | extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); |
41 | extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); | ||
37 | 42 | ||
38 | /* Structures internal to the RIO core code */ | 43 | /* Structures internal to the RIO core code */ |
39 | extern struct device_attribute rio_dev_attrs[]; | 44 | extern struct device_attribute rio_dev_attrs[]; |
diff --git a/drivers/rapidio/switches/Kconfig b/drivers/rapidio/switches/Kconfig index 2b4e9b2b6631..f47fee5d4563 100644 --- a/drivers/rapidio/switches/Kconfig +++ b/drivers/rapidio/switches/Kconfig | |||
@@ -20,6 +20,13 @@ config RAPIDIO_TSI568 | |||
20 | ---help--- | 20 | ---help--- |
21 | Includes support for IDT Tsi568 serial RapidIO switch. | 21 | Includes support for IDT Tsi568 serial RapidIO switch. |
22 | 22 | ||
23 | config RAPIDIO_CPS_GEN2 | ||
24 | bool "IDT CPS Gen.2 SRIO switch support" | ||
25 | depends on RAPIDIO | ||
26 | default n | ||
27 | ---help--- | ||
28 | Includes support for ITD CPS Gen.2 serial RapidIO switches. | ||
29 | |||
23 | config RAPIDIO_TSI500 | 30 | config RAPIDIO_TSI500 |
24 | bool "Tsi500 Parallel RapidIO switch support" | 31 | bool "Tsi500 Parallel RapidIO switch support" |
25 | depends on RAPIDIO | 32 | depends on RAPIDIO |
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile index fe4adc3e8d5f..48d67a6b98c8 100644 --- a/drivers/rapidio/switches/Makefile +++ b/drivers/rapidio/switches/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_RAPIDIO_TSI57X) += tsi57x.o | |||
6 | obj-$(CONFIG_RAPIDIO_CPS_XX) += idtcps.o | 6 | obj-$(CONFIG_RAPIDIO_CPS_XX) += idtcps.o |
7 | obj-$(CONFIG_RAPIDIO_TSI568) += tsi568.o | 7 | obj-$(CONFIG_RAPIDIO_TSI568) += tsi568.o |
8 | obj-$(CONFIG_RAPIDIO_TSI500) += tsi500.o | 8 | obj-$(CONFIG_RAPIDIO_TSI500) += tsi500.o |
9 | obj-$(CONFIG_RAPIDIO_CPS_GEN2) += idt_gen2.o | ||
9 | 10 | ||
10 | ifeq ($(CONFIG_RAPIDIO_DEBUG),y) | 11 | ifeq ($(CONFIG_RAPIDIO_DEBUG),y) |
11 | EXTRA_CFLAGS += -DDEBUG | 12 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/rapidio/switches/idt_gen2.c b/drivers/rapidio/switches/idt_gen2.c new file mode 100644 index 000000000000..0bb871cb5c40 --- /dev/null +++ b/drivers/rapidio/switches/idt_gen2.c | |||
@@ -0,0 +1,447 @@ | |||
1 | /* | ||
2 | * IDT CPS Gen.2 Serial RapidIO switch family support | ||
3 | * | ||
4 | * Copyright 2010 Integrated Device Technology, Inc. | ||
5 | * Alexandre Bounine <alexandre.bounine@idt.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/rio.h> | ||
14 | #include <linux/rio_drv.h> | ||
15 | #include <linux/rio_ids.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include "../rio.h" | ||
18 | |||
19 | #define LOCAL_RTE_CONF_DESTID_SEL 0x010070 | ||
20 | #define LOCAL_RTE_CONF_DESTID_SEL_PSEL 0x0000001f | ||
21 | |||
22 | #define IDT_LT_ERR_REPORT_EN 0x03100c | ||
23 | |||
24 | #define IDT_PORT_ERR_REPORT_EN(n) (0x031044 + (n)*0x40) | ||
25 | #define IDT_PORT_ERR_REPORT_EN_BC 0x03ff04 | ||
26 | |||
27 | #define IDT_PORT_ISERR_REPORT_EN(n) (0x03104C + (n)*0x40) | ||
28 | #define IDT_PORT_ISERR_REPORT_EN_BC 0x03ff0c | ||
29 | #define IDT_PORT_INIT_TX_ACQUIRED 0x00000020 | ||
30 | |||
31 | #define IDT_LANE_ERR_REPORT_EN(n) (0x038010 + (n)*0x100) | ||
32 | #define IDT_LANE_ERR_REPORT_EN_BC 0x03ff10 | ||
33 | |||
34 | #define IDT_DEV_CTRL_1 0xf2000c | ||
35 | #define IDT_DEV_CTRL_1_GENPW 0x02000000 | ||
36 | #define IDT_DEV_CTRL_1_PRSTBEH 0x00000001 | ||
37 | |||
38 | #define IDT_CFGBLK_ERR_CAPTURE_EN 0x020008 | ||
39 | #define IDT_CFGBLK_ERR_REPORT 0xf20014 | ||
40 | #define IDT_CFGBLK_ERR_REPORT_GENPW 0x00000002 | ||
41 | |||
42 | #define IDT_AUX_PORT_ERR_CAP_EN 0x020000 | ||
43 | #define IDT_AUX_ERR_REPORT_EN 0xf20018 | ||
44 | #define IDT_AUX_PORT_ERR_LOG_I2C 0x00000002 | ||
45 | #define IDT_AUX_PORT_ERR_LOG_JTAG 0x00000001 | ||
46 | |||
47 | #define IDT_ISLTL_ADDRESS_CAP 0x021014 | ||
48 | |||
49 | #define IDT_RIO_DOMAIN 0xf20020 | ||
50 | #define IDT_RIO_DOMAIN_MASK 0x000000ff | ||
51 | |||
52 | #define IDT_PW_INFO_CSR 0xf20024 | ||
53 | |||
54 | #define IDT_SOFT_RESET 0xf20040 | ||
55 | #define IDT_SOFT_RESET_REQ 0x00030097 | ||
56 | |||
57 | #define IDT_I2C_MCTRL 0xf20050 | ||
58 | #define IDT_I2C_MCTRL_GENPW 0x04000000 | ||
59 | |||
60 | #define IDT_JTAG_CTRL 0xf2005c | ||
61 | #define IDT_JTAG_CTRL_GENPW 0x00000002 | ||
62 | |||
63 | #define IDT_LANE_CTRL(n) (0xff8000 + (n)*0x100) | ||
64 | #define IDT_LANE_CTRL_BC 0xffff00 | ||
65 | #define IDT_LANE_CTRL_GENPW 0x00200000 | ||
66 | #define IDT_LANE_DFE_1_BC 0xffff18 | ||
67 | #define IDT_LANE_DFE_2_BC 0xffff1c | ||
68 | |||
69 | #define IDT_PORT_OPS(n) (0xf40004 + (n)*0x100) | ||
70 | #define IDT_PORT_OPS_GENPW 0x08000000 | ||
71 | #define IDT_PORT_OPS_PL_ELOG 0x00000040 | ||
72 | #define IDT_PORT_OPS_LL_ELOG 0x00000020 | ||
73 | #define IDT_PORT_OPS_LT_ELOG 0x00000010 | ||
74 | #define IDT_PORT_OPS_BC 0xf4ff04 | ||
75 | |||
76 | #define IDT_PORT_ISERR_DET(n) (0xf40008 + (n)*0x100) | ||
77 | |||
78 | #define IDT_ERR_CAP 0xfd0000 | ||
79 | #define IDT_ERR_CAP_LOG_OVERWR 0x00000004 | ||
80 | |||
81 | #define IDT_ERR_RD 0xfd0004 | ||
82 | |||
83 | #define IDT_DEFAULT_ROUTE 0xde | ||
84 | #define IDT_NO_ROUTE 0xdf | ||
85 | |||
86 | static int | ||
87 | idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
88 | u16 table, u16 route_destid, u8 route_port) | ||
89 | { | ||
90 | /* | ||
91 | * Select routing table to update | ||
92 | */ | ||
93 | if (table == RIO_GLOBAL_TABLE) | ||
94 | table = 0; | ||
95 | else | ||
96 | table++; | ||
97 | |||
98 | rio_mport_write_config_32(mport, destid, hopcount, | ||
99 | LOCAL_RTE_CONF_DESTID_SEL, table); | ||
100 | |||
101 | /* | ||
102 | * Program destination port for the specified destID | ||
103 | */ | ||
104 | rio_mport_write_config_32(mport, destid, hopcount, | ||
105 | RIO_STD_RTE_CONF_DESTID_SEL_CSR, | ||
106 | (u32)route_destid); | ||
107 | |||
108 | rio_mport_write_config_32(mport, destid, hopcount, | ||
109 | RIO_STD_RTE_CONF_PORT_SEL_CSR, | ||
110 | (u32)route_port); | ||
111 | udelay(10); | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | static int | ||
117 | idtg2_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
118 | u16 table, u16 route_destid, u8 *route_port) | ||
119 | { | ||
120 | u32 result; | ||
121 | |||
122 | /* | ||
123 | * Select routing table to read | ||
124 | */ | ||
125 | if (table == RIO_GLOBAL_TABLE) | ||
126 | table = 0; | ||
127 | else | ||
128 | table++; | ||
129 | |||
130 | rio_mport_write_config_32(mport, destid, hopcount, | ||
131 | LOCAL_RTE_CONF_DESTID_SEL, table); | ||
132 | |||
133 | rio_mport_write_config_32(mport, destid, hopcount, | ||
134 | RIO_STD_RTE_CONF_DESTID_SEL_CSR, | ||
135 | route_destid); | ||
136 | |||
137 | rio_mport_read_config_32(mport, destid, hopcount, | ||
138 | RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); | ||
139 | |||
140 | if (IDT_DEFAULT_ROUTE == (u8)result || IDT_NO_ROUTE == (u8)result) | ||
141 | *route_port = RIO_INVALID_ROUTE; | ||
142 | else | ||
143 | *route_port = (u8)result; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static int | ||
149 | idtg2_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
150 | u16 table) | ||
151 | { | ||
152 | u32 i; | ||
153 | |||
154 | /* | ||
155 | * Select routing table to read | ||
156 | */ | ||
157 | if (table == RIO_GLOBAL_TABLE) | ||
158 | table = 0; | ||
159 | else | ||
160 | table++; | ||
161 | |||
162 | rio_mport_write_config_32(mport, destid, hopcount, | ||
163 | LOCAL_RTE_CONF_DESTID_SEL, table); | ||
164 | |||
165 | for (i = RIO_STD_RTE_CONF_EXTCFGEN; | ||
166 | i <= (RIO_STD_RTE_CONF_EXTCFGEN | 0xff);) { | ||
167 | rio_mport_write_config_32(mport, destid, hopcount, | ||
168 | RIO_STD_RTE_CONF_DESTID_SEL_CSR, i); | ||
169 | rio_mport_write_config_32(mport, destid, hopcount, | ||
170 | RIO_STD_RTE_CONF_PORT_SEL_CSR, | ||
171 | (IDT_DEFAULT_ROUTE << 24) | (IDT_DEFAULT_ROUTE << 16) | | ||
172 | (IDT_DEFAULT_ROUTE << 8) | IDT_DEFAULT_ROUTE); | ||
173 | i += 4; | ||
174 | } | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | |||
180 | static int | ||
181 | idtg2_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
182 | u8 sw_domain) | ||
183 | { | ||
184 | /* | ||
185 | * Switch domain configuration operates only at global level | ||
186 | */ | ||
187 | rio_mport_write_config_32(mport, destid, hopcount, | ||
188 | IDT_RIO_DOMAIN, (u32)sw_domain); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | idtg2_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
194 | u8 *sw_domain) | ||
195 | { | ||
196 | u32 regval; | ||
197 | |||
198 | /* | ||
199 | * Switch domain configuration operates only at global level | ||
200 | */ | ||
201 | rio_mport_read_config_32(mport, destid, hopcount, | ||
202 | IDT_RIO_DOMAIN, ®val); | ||
203 | |||
204 | *sw_domain = (u8)(regval & 0xff); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int | ||
210 | idtg2_em_init(struct rio_dev *rdev) | ||
211 | { | ||
212 | struct rio_mport *mport = rdev->net->hport; | ||
213 | u16 destid = rdev->rswitch->destid; | ||
214 | u8 hopcount = rdev->rswitch->hopcount; | ||
215 | u32 regval; | ||
216 | int i, tmp; | ||
217 | |||
218 | /* | ||
219 | * This routine performs device-specific initialization only. | ||
220 | * All standard EM configuration should be performed at upper level. | ||
221 | */ | ||
222 | |||
223 | pr_debug("RIO: %s [%d:%d]\n", __func__, destid, hopcount); | ||
224 | |||
225 | /* Set Port-Write info CSR: PRIO=3 and CRF=1 */ | ||
226 | rio_mport_write_config_32(mport, destid, hopcount, | ||
227 | IDT_PW_INFO_CSR, 0x0000e000); | ||
228 | |||
229 | /* | ||
230 | * Configure LT LAYER error reporting. | ||
231 | */ | ||
232 | |||
233 | /* Enable standard (RIO.p8) error reporting */ | ||
234 | rio_mport_write_config_32(mport, destid, hopcount, | ||
235 | IDT_LT_ERR_REPORT_EN, | ||
236 | REM_LTL_ERR_ILLTRAN | REM_LTL_ERR_UNSOLR | | ||
237 | REM_LTL_ERR_UNSUPTR); | ||
238 | |||
239 | /* Use Port-Writes for LT layer error reporting. | ||
240 | * Enable per-port reset | ||
241 | */ | ||
242 | rio_mport_read_config_32(mport, destid, hopcount, | ||
243 | IDT_DEV_CTRL_1, ®val); | ||
244 | rio_mport_write_config_32(mport, destid, hopcount, | ||
245 | IDT_DEV_CTRL_1, | ||
246 | regval | IDT_DEV_CTRL_1_GENPW | IDT_DEV_CTRL_1_PRSTBEH); | ||
247 | |||
248 | /* | ||
249 | * Configure PORT error reporting. | ||
250 | */ | ||
251 | |||
252 | /* Report all RIO.p8 errors supported by device */ | ||
253 | rio_mport_write_config_32(mport, destid, hopcount, | ||
254 | IDT_PORT_ERR_REPORT_EN_BC, 0x807e8037); | ||
255 | |||
256 | /* Configure reporting of implementation specific errors/events */ | ||
257 | rio_mport_write_config_32(mport, destid, hopcount, | ||
258 | IDT_PORT_ISERR_REPORT_EN_BC, IDT_PORT_INIT_TX_ACQUIRED); | ||
259 | |||
260 | /* Use Port-Writes for port error reporting and enable error logging */ | ||
261 | tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo); | ||
262 | for (i = 0; i < tmp; i++) { | ||
263 | rio_mport_read_config_32(mport, destid, hopcount, | ||
264 | IDT_PORT_OPS(i), ®val); | ||
265 | rio_mport_write_config_32(mport, destid, hopcount, | ||
266 | IDT_PORT_OPS(i), regval | IDT_PORT_OPS_GENPW | | ||
267 | IDT_PORT_OPS_PL_ELOG | | ||
268 | IDT_PORT_OPS_LL_ELOG | | ||
269 | IDT_PORT_OPS_LT_ELOG); | ||
270 | } | ||
271 | /* Overwrite error log if full */ | ||
272 | rio_mport_write_config_32(mport, destid, hopcount, | ||
273 | IDT_ERR_CAP, IDT_ERR_CAP_LOG_OVERWR); | ||
274 | |||
275 | /* | ||
276 | * Configure LANE error reporting. | ||
277 | */ | ||
278 | |||
279 | /* Disable line error reporting */ | ||
280 | rio_mport_write_config_32(mport, destid, hopcount, | ||
281 | IDT_LANE_ERR_REPORT_EN_BC, 0); | ||
282 | |||
283 | /* Use Port-Writes for lane error reporting (when enabled) | ||
284 | * (do per-lane update because lanes may have different configuration) | ||
285 | */ | ||
286 | tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16; | ||
287 | for (i = 0; i < tmp; i++) { | ||
288 | rio_mport_read_config_32(mport, destid, hopcount, | ||
289 | IDT_LANE_CTRL(i), ®val); | ||
290 | rio_mport_write_config_32(mport, destid, hopcount, | ||
291 | IDT_LANE_CTRL(i), regval | IDT_LANE_CTRL_GENPW); | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Configure AUX error reporting. | ||
296 | */ | ||
297 | |||
298 | /* Disable JTAG and I2C Error capture */ | ||
299 | rio_mport_write_config_32(mport, destid, hopcount, | ||
300 | IDT_AUX_PORT_ERR_CAP_EN, 0); | ||
301 | |||
302 | /* Disable JTAG and I2C Error reporting/logging */ | ||
303 | rio_mport_write_config_32(mport, destid, hopcount, | ||
304 | IDT_AUX_ERR_REPORT_EN, 0); | ||
305 | |||
306 | /* Disable Port-Write notification from JTAG */ | ||
307 | rio_mport_write_config_32(mport, destid, hopcount, | ||
308 | IDT_JTAG_CTRL, 0); | ||
309 | |||
310 | /* Disable Port-Write notification from I2C */ | ||
311 | rio_mport_read_config_32(mport, destid, hopcount, | ||
312 | IDT_I2C_MCTRL, ®val); | ||
313 | rio_mport_write_config_32(mport, destid, hopcount, | ||
314 | IDT_I2C_MCTRL, | ||
315 | regval & ~IDT_I2C_MCTRL_GENPW); | ||
316 | |||
317 | /* | ||
318 | * Configure CFG_BLK error reporting. | ||
319 | */ | ||
320 | |||
321 | /* Disable Configuration Block error capture */ | ||
322 | rio_mport_write_config_32(mport, destid, hopcount, | ||
323 | IDT_CFGBLK_ERR_CAPTURE_EN, 0); | ||
324 | |||
325 | /* Disable Port-Writes for Configuration Block error reporting */ | ||
326 | rio_mport_read_config_32(mport, destid, hopcount, | ||
327 | IDT_CFGBLK_ERR_REPORT, ®val); | ||
328 | rio_mport_write_config_32(mport, destid, hopcount, | ||
329 | IDT_CFGBLK_ERR_REPORT, | ||
330 | regval & ~IDT_CFGBLK_ERR_REPORT_GENPW); | ||
331 | |||
332 | /* set TVAL = ~50us */ | ||
333 | rio_mport_write_config_32(mport, destid, hopcount, | ||
334 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); | ||
335 | |||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static int | ||
340 | idtg2_em_handler(struct rio_dev *rdev, u8 portnum) | ||
341 | { | ||
342 | struct rio_mport *mport = rdev->net->hport; | ||
343 | u16 destid = rdev->rswitch->destid; | ||
344 | u8 hopcount = rdev->rswitch->hopcount; | ||
345 | u32 regval, em_perrdet, em_ltlerrdet; | ||
346 | |||
347 | rio_mport_read_config_32(mport, destid, hopcount, | ||
348 | rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet); | ||
349 | if (em_ltlerrdet) { | ||
350 | /* Service Logical/Transport Layer Error(s) */ | ||
351 | if (em_ltlerrdet & REM_LTL_ERR_IMPSPEC) { | ||
352 | /* Implementation specific error reported */ | ||
353 | rio_mport_read_config_32(mport, destid, hopcount, | ||
354 | IDT_ISLTL_ADDRESS_CAP, ®val); | ||
355 | |||
356 | pr_debug("RIO: %s Implementation Specific LTL errors" \ | ||
357 | " 0x%x @(0x%x)\n", | ||
358 | rio_name(rdev), em_ltlerrdet, regval); | ||
359 | |||
360 | /* Clear implementation specific address capture CSR */ | ||
361 | rio_mport_write_config_32(mport, destid, hopcount, | ||
362 | IDT_ISLTL_ADDRESS_CAP, 0); | ||
363 | |||
364 | } | ||
365 | } | ||
366 | |||
367 | rio_mport_read_config_32(mport, destid, hopcount, | ||
368 | rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet); | ||
369 | if (em_perrdet) { | ||
370 | /* Service Port-Level Error(s) */ | ||
371 | if (em_perrdet & REM_PED_IMPL_SPEC) { | ||
372 | /* Implementation Specific port error reported */ | ||
373 | |||
374 | /* Get IS errors reported */ | ||
375 | rio_mport_read_config_32(mport, destid, hopcount, | ||
376 | IDT_PORT_ISERR_DET(portnum), ®val); | ||
377 | |||
378 | pr_debug("RIO: %s Implementation Specific Port" \ | ||
379 | " errors 0x%x\n", rio_name(rdev), regval); | ||
380 | |||
381 | /* Clear all implementation specific events */ | ||
382 | rio_mport_write_config_32(mport, destid, hopcount, | ||
383 | IDT_PORT_ISERR_DET(portnum), 0); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static ssize_t | ||
391 | idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf) | ||
392 | { | ||
393 | struct rio_dev *rdev = to_rio_dev(dev); | ||
394 | struct rio_mport *mport = rdev->net->hport; | ||
395 | u16 destid = rdev->rswitch->destid; | ||
396 | u8 hopcount = rdev->rswitch->hopcount; | ||
397 | ssize_t len = 0; | ||
398 | u32 regval; | ||
399 | |||
400 | while (!rio_mport_read_config_32(mport, destid, hopcount, | ||
401 | IDT_ERR_RD, ®val)) { | ||
402 | if (!regval) /* 0 = end of log */ | ||
403 | break; | ||
404 | len += snprintf(buf + len, PAGE_SIZE - len, | ||
405 | "%08x\n", regval); | ||
406 | if (len >= (PAGE_SIZE - 10)) | ||
407 | break; | ||
408 | } | ||
409 | |||
410 | return len; | ||
411 | } | ||
412 | |||
413 | static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL); | ||
414 | |||
415 | static int idtg2_sysfs(struct rio_dev *rdev, int create) | ||
416 | { | ||
417 | struct device *dev = &rdev->dev; | ||
418 | int err = 0; | ||
419 | |||
420 | if (create == RIO_SW_SYSFS_CREATE) { | ||
421 | /* Initialize sysfs entries */ | ||
422 | err = device_create_file(dev, &dev_attr_errlog); | ||
423 | if (err) | ||
424 | dev_err(dev, "Unable create sysfs errlog file\n"); | ||
425 | } else | ||
426 | device_remove_file(dev, &dev_attr_errlog); | ||
427 | |||
428 | return err; | ||
429 | } | ||
430 | |||
431 | static int idtg2_switch_init(struct rio_dev *rdev, int do_enum) | ||
432 | { | ||
433 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | ||
434 | rdev->rswitch->add_entry = idtg2_route_add_entry; | ||
435 | rdev->rswitch->get_entry = idtg2_route_get_entry; | ||
436 | rdev->rswitch->clr_table = idtg2_route_clr_table; | ||
437 | rdev->rswitch->set_domain = idtg2_set_domain; | ||
438 | rdev->rswitch->get_domain = idtg2_get_domain; | ||
439 | rdev->rswitch->em_init = idtg2_em_init; | ||
440 | rdev->rswitch->em_handle = idtg2_em_handler; | ||
441 | rdev->rswitch->sw_sysfs = idtg2_sysfs; | ||
442 | |||
443 | return 0; | ||
444 | } | ||
445 | |||
446 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init); | ||
447 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init); | ||
diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c index 2c790c144f89..fc9f6374f759 100644 --- a/drivers/rapidio/switches/idtcps.c +++ b/drivers/rapidio/switches/idtcps.c | |||
@@ -117,6 +117,10 @@ idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, | |||
117 | 117 | ||
118 | static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) | 118 | static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) |
119 | { | 119 | { |
120 | struct rio_mport *mport = rdev->net->hport; | ||
121 | u16 destid = rdev->rswitch->destid; | ||
122 | u8 hopcount = rdev->rswitch->hopcount; | ||
123 | |||
120 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); | 124 | pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev)); |
121 | rdev->rswitch->add_entry = idtcps_route_add_entry; | 125 | rdev->rswitch->add_entry = idtcps_route_add_entry; |
122 | rdev->rswitch->get_entry = idtcps_route_get_entry; | 126 | rdev->rswitch->get_entry = idtcps_route_get_entry; |
@@ -126,6 +130,12 @@ static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) | |||
126 | rdev->rswitch->em_init = NULL; | 130 | rdev->rswitch->em_init = NULL; |
127 | rdev->rswitch->em_handle = NULL; | 131 | rdev->rswitch->em_handle = NULL; |
128 | 132 | ||
133 | if (do_enum) { | ||
134 | /* set TVAL = ~50us */ | ||
135 | rio_mport_write_config_32(mport, destid, hopcount, | ||
136 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); | ||
137 | } | ||
138 | |||
129 | return 0; | 139 | return 0; |
130 | } | 140 | } |
131 | 141 | ||
diff --git a/drivers/rapidio/switches/tsi568.c b/drivers/rapidio/switches/tsi568.c index f7fd7898606e..b9a389b9f812 100644 --- a/drivers/rapidio/switches/tsi568.c +++ b/drivers/rapidio/switches/tsi568.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n) | 29 | #define SPP_ROUTE_CFG_DESTID(n) (0x11070 + 0x100*n) |
30 | #define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n) | 30 | #define SPP_ROUTE_CFG_PORT(n) (0x11074 + 0x100*n) |
31 | 31 | ||
32 | #define TSI568_SP_MODE_BC 0x10004 | 32 | #define TSI568_SP_MODE(n) (0x11004 + 0x100*n) |
33 | #define TSI568_SP_MODE_PW_DIS 0x08000000 | 33 | #define TSI568_SP_MODE_PW_DIS 0x08000000 |
34 | 34 | ||
35 | static int | 35 | static int |
@@ -117,14 +117,19 @@ tsi568_em_init(struct rio_dev *rdev) | |||
117 | u16 destid = rdev->rswitch->destid; | 117 | u16 destid = rdev->rswitch->destid; |
118 | u8 hopcount = rdev->rswitch->hopcount; | 118 | u8 hopcount = rdev->rswitch->hopcount; |
119 | u32 regval; | 119 | u32 regval; |
120 | int portnum; | ||
120 | 121 | ||
121 | pr_debug("TSI568 %s [%d:%d]\n", __func__, destid, hopcount); | 122 | pr_debug("TSI568 %s [%d:%d]\n", __func__, destid, hopcount); |
122 | 123 | ||
123 | /* Make sure that Port-Writes are disabled (for all ports) */ | 124 | /* Make sure that Port-Writes are disabled (for all ports) */ |
124 | rio_mport_read_config_32(mport, destid, hopcount, | 125 | for (portnum = 0; |
125 | TSI568_SP_MODE_BC, ®val); | 126 | portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) { |
126 | rio_mport_write_config_32(mport, destid, hopcount, | 127 | rio_mport_read_config_32(mport, destid, hopcount, |
127 | TSI568_SP_MODE_BC, regval | TSI568_SP_MODE_PW_DIS); | 128 | TSI568_SP_MODE(portnum), ®val); |
129 | rio_mport_write_config_32(mport, destid, hopcount, | ||
130 | TSI568_SP_MODE(portnum), | ||
131 | regval | TSI568_SP_MODE_PW_DIS); | ||
132 | } | ||
128 | 133 | ||
129 | return 0; | 134 | return 0; |
130 | } | 135 | } |
diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index d34df722d95f..2003fb63c404 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c | |||
@@ -166,7 +166,8 @@ tsi57x_em_init(struct rio_dev *rdev) | |||
166 | 166 | ||
167 | pr_debug("TSI578 %s [%d:%d]\n", __func__, destid, hopcount); | 167 | pr_debug("TSI578 %s [%d:%d]\n", __func__, destid, hopcount); |
168 | 168 | ||
169 | for (portnum = 0; portnum < 16; portnum++) { | 169 | for (portnum = 0; |
170 | portnum < RIO_GET_TOTAL_PORTS(rdev->swpinfo); portnum++) { | ||
170 | /* Make sure that Port-Writes are enabled (for all ports) */ | 171 | /* Make sure that Port-Writes are enabled (for all ports) */ |
171 | rio_mport_read_config_32(mport, destid, hopcount, | 172 | rio_mport_read_config_32(mport, destid, hopcount, |
172 | TSI578_SP_MODE(portnum), ®val); | 173 | TSI578_SP_MODE(portnum), ®val); |
@@ -205,6 +206,10 @@ tsi57x_em_init(struct rio_dev *rdev) | |||
205 | portnum++; | 206 | portnum++; |
206 | } | 207 | } |
207 | 208 | ||
209 | /* set TVAL = ~50us */ | ||
210 | rio_mport_write_config_32(mport, destid, hopcount, | ||
211 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x9a << 8); | ||
212 | |||
208 | return 0; | 213 | return 0; |
209 | } | 214 | } |
210 | 215 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 2785a0f16c9f..6a77437d4f5a 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -171,7 +171,8 @@ config RTC_DRV_DS3232 | |||
171 | depends on RTC_CLASS && I2C | 171 | depends on RTC_CLASS && I2C |
172 | help | 172 | help |
173 | If you say yes here you get support for Dallas Semiconductor | 173 | If you say yes here you get support for Dallas Semiconductor |
174 | DS3232 real-time clock chips. | 174 | DS3232 real-time clock chips. If an interrupt is associated |
175 | with the device, the alarm functionality is supported. | ||
175 | 176 | ||
176 | This driver can also be built as a module. If so, the module | 177 | This driver can also be built as a module. If so, the module |
177 | will be called rtc-ds3232. | 178 | will be called rtc-ds3232. |
@@ -952,4 +953,13 @@ config RTC_DRV_JZ4740 | |||
952 | This driver can also be buillt as a module. If so, the module | 953 | This driver can also be buillt as a module. If so, the module |
953 | will be called rtc-jz4740. | 954 | will be called rtc-jz4740. |
954 | 955 | ||
956 | config RTC_DRV_LPC32XX | ||
957 | depends on ARCH_LPC32XX | ||
958 | tristate "NXP LPC32XX RTC" | ||
959 | help | ||
960 | This enables support for the NXP RTC in the LPC32XX | ||
961 | |||
962 | This driver can also be buillt as a module. If so, the module | ||
963 | will be called rtc-lpc32xx. | ||
964 | |||
955 | endif # RTC_CLASS | 965 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 0f207b3b5833..7a7cb3228a1d 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -51,6 +51,7 @@ obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o | |||
51 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 51 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
52 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o | 52 | obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o |
53 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o | 53 | obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o |
54 | obj-$(CONFIG_RTC_DRV_LPC32XX) += rtc-lpc32xx.o | ||
54 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 55 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
55 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o | 56 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o |
56 | obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o | 57 | obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 565562ba6ac9..e6539cbabb35 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -158,8 +158,10 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
158 | rtc_dev_prepare(rtc); | 158 | rtc_dev_prepare(rtc); |
159 | 159 | ||
160 | err = device_register(&rtc->dev); | 160 | err = device_register(&rtc->dev); |
161 | if (err) | 161 | if (err) { |
162 | put_device(&rtc->dev); | ||
162 | goto exit_kfree; | 163 | goto exit_kfree; |
164 | } | ||
163 | 165 | ||
164 | rtc_dev_add_device(rtc); | 166 | rtc_dev_add_device(rtc); |
165 | rtc_sysfs_add_device(rtc); | 167 | rtc_sysfs_add_device(rtc); |
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index d4fb82d85e9b..b4b6087f2234 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Blackfin On-Chip Real Time Clock Driver | 2 | * Blackfin On-Chip Real Time Clock Driver |
3 | * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x | 3 | * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x |
4 | * | 4 | * |
5 | * Copyright 2004-2009 Analog Devices Inc. | 5 | * Copyright 2004-2010 Analog Devices Inc. |
6 | * | 6 | * |
7 | * Enter bugs at http://blackfin.uclinux.org/ | 7 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * | 8 | * |
@@ -183,29 +183,33 @@ static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) | |||
183 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 183 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
184 | unsigned long events = 0; | 184 | unsigned long events = 0; |
185 | bool write_complete = false; | 185 | bool write_complete = false; |
186 | u16 rtc_istat, rtc_ictl; | 186 | u16 rtc_istat, rtc_istat_clear, rtc_ictl, bits; |
187 | 187 | ||
188 | dev_dbg_stamp(dev); | 188 | dev_dbg_stamp(dev); |
189 | 189 | ||
190 | rtc_istat = bfin_read_RTC_ISTAT(); | 190 | rtc_istat = bfin_read_RTC_ISTAT(); |
191 | rtc_ictl = bfin_read_RTC_ICTL(); | 191 | rtc_ictl = bfin_read_RTC_ICTL(); |
192 | rtc_istat_clear = 0; | ||
192 | 193 | ||
193 | if (rtc_istat & RTC_ISTAT_WRITE_COMPLETE) { | 194 | bits = RTC_ISTAT_WRITE_COMPLETE; |
194 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); | 195 | if (rtc_istat & bits) { |
196 | rtc_istat_clear |= bits; | ||
195 | write_complete = true; | 197 | write_complete = true; |
196 | complete(&bfin_write_complete); | 198 | complete(&bfin_write_complete); |
197 | } | 199 | } |
198 | 200 | ||
199 | if (rtc_ictl & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { | 201 | bits = (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); |
200 | if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { | 202 | if (rtc_ictl & bits) { |
201 | bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); | 203 | if (rtc_istat & bits) { |
204 | rtc_istat_clear |= bits; | ||
202 | events |= RTC_AF | RTC_IRQF; | 205 | events |= RTC_AF | RTC_IRQF; |
203 | } | 206 | } |
204 | } | 207 | } |
205 | 208 | ||
206 | if (rtc_ictl & RTC_ISTAT_SEC) { | 209 | bits = RTC_ISTAT_SEC; |
207 | if (rtc_istat & RTC_ISTAT_SEC) { | 210 | if (rtc_ictl & bits) { |
208 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | 211 | if (rtc_istat & bits) { |
212 | rtc_istat_clear |= bits; | ||
209 | events |= RTC_UF | RTC_IRQF; | 213 | events |= RTC_UF | RTC_IRQF; |
210 | } | 214 | } |
211 | } | 215 | } |
@@ -213,9 +217,10 @@ static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) | |||
213 | if (events) | 217 | if (events) |
214 | rtc_update_irq(rtc->rtc_dev, 1, events); | 218 | rtc_update_irq(rtc->rtc_dev, 1, events); |
215 | 219 | ||
216 | if (write_complete || events) | 220 | if (write_complete || events) { |
221 | bfin_write_RTC_ISTAT(rtc_istat_clear); | ||
217 | return IRQ_HANDLED; | 222 | return IRQ_HANDLED; |
218 | else | 223 | } else |
219 | return IRQ_NONE; | 224 | return IRQ_NONE; |
220 | } | 225 | } |
221 | 226 | ||
@@ -422,9 +427,13 @@ static int __devexit bfin_rtc_remove(struct platform_device *pdev) | |||
422 | #ifdef CONFIG_PM | 427 | #ifdef CONFIG_PM |
423 | static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 428 | static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
424 | { | 429 | { |
425 | if (device_may_wakeup(&pdev->dev)) { | 430 | struct device *dev = &pdev->dev; |
431 | |||
432 | dev_dbg_stamp(dev); | ||
433 | |||
434 | if (device_may_wakeup(dev)) { | ||
426 | enable_irq_wake(IRQ_RTC); | 435 | enable_irq_wake(IRQ_RTC); |
427 | bfin_rtc_sync_pending(&pdev->dev); | 436 | bfin_rtc_sync_pending(dev); |
428 | } else | 437 | } else |
429 | bfin_rtc_int_clear(0); | 438 | bfin_rtc_int_clear(0); |
430 | 439 | ||
@@ -433,7 +442,11 @@ static int bfin_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
433 | 442 | ||
434 | static int bfin_rtc_resume(struct platform_device *pdev) | 443 | static int bfin_rtc_resume(struct platform_device *pdev) |
435 | { | 444 | { |
436 | if (device_may_wakeup(&pdev->dev)) | 445 | struct device *dev = &pdev->dev; |
446 | |||
447 | dev_dbg_stamp(dev); | ||
448 | |||
449 | if (device_may_wakeup(dev)) | ||
437 | disable_irq_wake(IRQ_RTC); | 450 | disable_irq_wake(IRQ_RTC); |
438 | 451 | ||
439 | /* | 452 | /* |
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 9de8516e3531..57063552d3b7 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C | 2 | * RTC client/driver for the Maxim/Dallas DS3232 Real-Time Clock over I2C |
3 | * | 3 | * |
4 | * Copyright (C) 2009-2010 Freescale Semiconductor. | 4 | * Copyright (C) 2009-2010 Freescale Semiconductor. |
5 | * Author: Jack Lan <jack.lan@freescale.com> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
@@ -175,6 +176,182 @@ static int ds3232_set_time(struct device *dev, struct rtc_time *time) | |||
175 | DS3232_REG_SECONDS, 7, buf); | 176 | DS3232_REG_SECONDS, 7, buf); |
176 | } | 177 | } |
177 | 178 | ||
179 | /* | ||
180 | * DS3232 has two alarm, we only use alarm1 | ||
181 | * According to linux specification, only support one-shot alarm | ||
182 | * no periodic alarm mode | ||
183 | */ | ||
184 | static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
185 | { | ||
186 | struct i2c_client *client = to_i2c_client(dev); | ||
187 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
188 | int control, stat; | ||
189 | int ret; | ||
190 | u8 buf[4]; | ||
191 | |||
192 | mutex_lock(&ds3232->mutex); | ||
193 | |||
194 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR); | ||
195 | if (ret < 0) | ||
196 | goto out; | ||
197 | stat = ret; | ||
198 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR); | ||
199 | if (ret < 0) | ||
200 | goto out; | ||
201 | control = ret; | ||
202 | ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
203 | if (ret < 0) | ||
204 | goto out; | ||
205 | |||
206 | alarm->time.tm_sec = bcd2bin(buf[0] & 0x7F); | ||
207 | alarm->time.tm_min = bcd2bin(buf[1] & 0x7F); | ||
208 | alarm->time.tm_hour = bcd2bin(buf[2] & 0x7F); | ||
209 | alarm->time.tm_mday = bcd2bin(buf[3] & 0x7F); | ||
210 | |||
211 | alarm->time.tm_mon = -1; | ||
212 | alarm->time.tm_year = -1; | ||
213 | alarm->time.tm_wday = -1; | ||
214 | alarm->time.tm_yday = -1; | ||
215 | alarm->time.tm_isdst = -1; | ||
216 | |||
217 | alarm->enabled = !!(control & DS3232_REG_CR_A1IE); | ||
218 | alarm->pending = !!(stat & DS3232_REG_SR_A1F); | ||
219 | |||
220 | ret = 0; | ||
221 | out: | ||
222 | mutex_unlock(&ds3232->mutex); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * linux rtc-module does not support wday alarm | ||
228 | * and only 24h time mode supported indeed | ||
229 | */ | ||
230 | static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
231 | { | ||
232 | struct i2c_client *client = to_i2c_client(dev); | ||
233 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
234 | int control, stat; | ||
235 | int ret; | ||
236 | u8 buf[4]; | ||
237 | |||
238 | if (client->irq <= 0) | ||
239 | return -EINVAL; | ||
240 | |||
241 | mutex_lock(&ds3232->mutex); | ||
242 | |||
243 | buf[0] = bin2bcd(alarm->time.tm_sec); | ||
244 | buf[1] = bin2bcd(alarm->time.tm_min); | ||
245 | buf[2] = bin2bcd(alarm->time.tm_hour); | ||
246 | buf[3] = bin2bcd(alarm->time.tm_mday); | ||
247 | |||
248 | /* clear alarm interrupt enable bit */ | ||
249 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_CR); | ||
250 | if (ret < 0) | ||
251 | goto out; | ||
252 | control = ret; | ||
253 | control &= ~(DS3232_REG_CR_A1IE | DS3232_REG_CR_A2IE); | ||
254 | ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control); | ||
255 | if (ret < 0) | ||
256 | goto out; | ||
257 | |||
258 | /* clear any pending alarm flag */ | ||
259 | ret = i2c_smbus_read_byte_data(client, DS3232_REG_SR); | ||
260 | if (ret < 0) | ||
261 | goto out; | ||
262 | stat = ret; | ||
263 | stat &= ~(DS3232_REG_SR_A1F | DS3232_REG_SR_A2F); | ||
264 | ret = i2c_smbus_write_byte_data(client, DS3232_REG_SR, stat); | ||
265 | if (ret < 0) | ||
266 | goto out; | ||
267 | |||
268 | ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
269 | |||
270 | if (alarm->enabled) { | ||
271 | control |= DS3232_REG_CR_A1IE; | ||
272 | ret = i2c_smbus_write_byte_data(client, DS3232_REG_CR, control); | ||
273 | } | ||
274 | out: | ||
275 | mutex_unlock(&ds3232->mutex); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | static void ds3232_update_alarm(struct i2c_client *client) | ||
280 | { | ||
281 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
282 | int control; | ||
283 | int ret; | ||
284 | u8 buf[4]; | ||
285 | |||
286 | mutex_lock(&ds3232->mutex); | ||
287 | |||
288 | ret = i2c_smbus_read_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
289 | if (ret < 0) | ||
290 | goto unlock; | ||
291 | |||
292 | buf[0] = bcd2bin(buf[0]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
293 | 0x80 : buf[0]; | ||
294 | buf[1] = bcd2bin(buf[1]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
295 | 0x80 : buf[1]; | ||
296 | buf[2] = bcd2bin(buf[2]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
297 | 0x80 : buf[2]; | ||
298 | buf[3] = bcd2bin(buf[3]) < 0 || (ds3232->rtc->irq_data & RTC_UF) ? | ||
299 | 0x80 : buf[3]; | ||
300 | |||
301 | ret = i2c_smbus_write_i2c_block_data(client, DS3232_REG_ALARM1, 4, buf); | ||
302 | if (ret < 0) | ||
303 | goto unlock; | ||
304 | |||
305 | control = i2c_smbus_read_byte_data(client, DS3232_REG_CR); | ||
306 | if (control < 0) | ||
307 | goto unlock; | ||
308 | |||
309 | if (ds3232->rtc->irq_data & (RTC_AF | RTC_UF)) | ||
310 | /* enable alarm1 interrupt */ | ||
311 | control |= DS3232_REG_CR_A1IE; | ||
312 | else | ||
313 | /* disable alarm1 interrupt */ | ||
314 | control &= ~(DS3232_REG_CR_A1IE); | ||
315 | i2c_smbus_write_byte_data(client, DS3232_REG_CR, control); | ||
316 | |||
317 | unlock: | ||
318 | mutex_unlock(&ds3232->mutex); | ||
319 | } | ||
320 | |||
321 | static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
322 | { | ||
323 | struct i2c_client *client = to_i2c_client(dev); | ||
324 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
325 | |||
326 | if (client->irq <= 0) | ||
327 | return -EINVAL; | ||
328 | |||
329 | if (enabled) | ||
330 | ds3232->rtc->irq_data |= RTC_AF; | ||
331 | else | ||
332 | ds3232->rtc->irq_data &= ~RTC_AF; | ||
333 | |||
334 | ds3232_update_alarm(client); | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static int ds3232_update_irq_enable(struct device *dev, unsigned int enabled) | ||
339 | { | ||
340 | struct i2c_client *client = to_i2c_client(dev); | ||
341 | struct ds3232 *ds3232 = i2c_get_clientdata(client); | ||
342 | |||
343 | if (client->irq <= 0) | ||
344 | return -EINVAL; | ||
345 | |||
346 | if (enabled) | ||
347 | ds3232->rtc->irq_data |= RTC_UF; | ||
348 | else | ||
349 | ds3232->rtc->irq_data &= ~RTC_UF; | ||
350 | |||
351 | ds3232_update_alarm(client); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
178 | static irqreturn_t ds3232_irq(int irq, void *dev_id) | 355 | static irqreturn_t ds3232_irq(int irq, void *dev_id) |
179 | { | 356 | { |
180 | struct i2c_client *client = dev_id; | 357 | struct i2c_client *client = dev_id; |
@@ -222,6 +399,10 @@ unlock: | |||
222 | static const struct rtc_class_ops ds3232_rtc_ops = { | 399 | static const struct rtc_class_ops ds3232_rtc_ops = { |
223 | .read_time = ds3232_read_time, | 400 | .read_time = ds3232_read_time, |
224 | .set_time = ds3232_set_time, | 401 | .set_time = ds3232_set_time, |
402 | .read_alarm = ds3232_read_alarm, | ||
403 | .set_alarm = ds3232_set_alarm, | ||
404 | .alarm_irq_enable = ds3232_alarm_irq_enable, | ||
405 | .update_irq_enable = ds3232_update_irq_enable, | ||
225 | }; | 406 | }; |
226 | 407 | ||
227 | static int __devinit ds3232_probe(struct i2c_client *client, | 408 | static int __devinit ds3232_probe(struct i2c_client *client, |
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 2619d57b91d7..2e16f72c9056 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> | 2 | * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> |
3 | * Copyright (C) 2010, Paul Cercueil <paul@crapouillou.net> | ||
3 | * JZ4740 SoC RTC driver | 4 | * JZ4740 SoC RTC driver |
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
@@ -161,7 +162,8 @@ static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
161 | 162 | ||
162 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs); | 163 | ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs); |
163 | if (!ret) | 164 | if (!ret) |
164 | ret = jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE, alrm->enabled); | 165 | ret = jz4740_rtc_ctrl_set_bits(rtc, |
166 | JZ_RTC_CTRL_AE | JZ_RTC_CTRL_AF_IRQ, alrm->enabled); | ||
165 | 167 | ||
166 | return ret; | 168 | return ret; |
167 | } | 169 | } |
@@ -258,6 +260,8 @@ static int __devinit jz4740_rtc_probe(struct platform_device *pdev) | |||
258 | 260 | ||
259 | platform_set_drvdata(pdev, rtc); | 261 | platform_set_drvdata(pdev, rtc); |
260 | 262 | ||
263 | device_init_wakeup(&pdev->dev, 1); | ||
264 | |||
261 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops, | 265 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops, |
262 | THIS_MODULE); | 266 | THIS_MODULE); |
263 | if (IS_ERR(rtc->rtc)) { | 267 | if (IS_ERR(rtc->rtc)) { |
@@ -318,12 +322,43 @@ static int __devexit jz4740_rtc_remove(struct platform_device *pdev) | |||
318 | return 0; | 322 | return 0; |
319 | } | 323 | } |
320 | 324 | ||
325 | |||
326 | #ifdef CONFIG_PM | ||
327 | static int jz4740_rtc_suspend(struct device *dev) | ||
328 | { | ||
329 | struct jz4740_rtc *rtc = dev_get_drvdata(dev); | ||
330 | |||
331 | if (device_may_wakeup(dev)) | ||
332 | enable_irq_wake(rtc->irq); | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int jz4740_rtc_resume(struct device *dev) | ||
337 | { | ||
338 | struct jz4740_rtc *rtc = dev_get_drvdata(dev); | ||
339 | |||
340 | if (device_may_wakeup(dev)) | ||
341 | disable_irq_wake(rtc->irq); | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static const struct dev_pm_ops jz4740_pm_ops = { | ||
346 | .suspend = jz4740_rtc_suspend, | ||
347 | .resume = jz4740_rtc_resume, | ||
348 | }; | ||
349 | #define JZ4740_RTC_PM_OPS (&jz4740_pm_ops) | ||
350 | |||
351 | #else | ||
352 | #define JZ4740_RTC_PM_OPS NULL | ||
353 | #endif /* CONFIG_PM */ | ||
354 | |||
321 | struct platform_driver jz4740_rtc_driver = { | 355 | struct platform_driver jz4740_rtc_driver = { |
322 | .probe = jz4740_rtc_probe, | 356 | .probe = jz4740_rtc_probe, |
323 | .remove = __devexit_p(jz4740_rtc_remove), | 357 | .remove = __devexit_p(jz4740_rtc_remove), |
324 | .driver = { | 358 | .driver = { |
325 | .name = "jz4740-rtc", | 359 | .name = "jz4740-rtc", |
326 | .owner = THIS_MODULE, | 360 | .owner = THIS_MODULE, |
361 | .pm = JZ4740_RTC_PM_OPS, | ||
327 | }, | 362 | }, |
328 | }; | 363 | }; |
329 | 364 | ||
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c new file mode 100644 index 000000000000..ec8701ce99f9 --- /dev/null +++ b/drivers/rtc/rtc-lpc32xx.c | |||
@@ -0,0 +1,414 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 NXP Semiconductors | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * You should have received a copy of the GNU General Public License along | ||
10 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
11 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/io.h> | ||
22 | |||
23 | /* | ||
24 | * Clock and Power control register offsets | ||
25 | */ | ||
26 | #define LPC32XX_RTC_UCOUNT 0x00 | ||
27 | #define LPC32XX_RTC_DCOUNT 0x04 | ||
28 | #define LPC32XX_RTC_MATCH0 0x08 | ||
29 | #define LPC32XX_RTC_MATCH1 0x0C | ||
30 | #define LPC32XX_RTC_CTRL 0x10 | ||
31 | #define LPC32XX_RTC_INTSTAT 0x14 | ||
32 | #define LPC32XX_RTC_KEY 0x18 | ||
33 | #define LPC32XX_RTC_SRAM 0x80 | ||
34 | |||
35 | #define LPC32XX_RTC_CTRL_MATCH0 (1 << 0) | ||
36 | #define LPC32XX_RTC_CTRL_MATCH1 (1 << 1) | ||
37 | #define LPC32XX_RTC_CTRL_ONSW_MATCH0 (1 << 2) | ||
38 | #define LPC32XX_RTC_CTRL_ONSW_MATCH1 (1 << 3) | ||
39 | #define LPC32XX_RTC_CTRL_SW_RESET (1 << 4) | ||
40 | #define LPC32XX_RTC_CTRL_CNTR_DIS (1 << 6) | ||
41 | #define LPC32XX_RTC_CTRL_ONSW_FORCE_HI (1 << 7) | ||
42 | |||
43 | #define LPC32XX_RTC_INTSTAT_MATCH0 (1 << 0) | ||
44 | #define LPC32XX_RTC_INTSTAT_MATCH1 (1 << 1) | ||
45 | #define LPC32XX_RTC_INTSTAT_ONSW (1 << 2) | ||
46 | |||
47 | #define LPC32XX_RTC_KEY_ONSW_LOADVAL 0xB5C13F27 | ||
48 | |||
49 | #define RTC_NAME "rtc-lpc32xx" | ||
50 | |||
51 | #define rtc_readl(dev, reg) \ | ||
52 | __raw_readl((dev)->rtc_base + (reg)) | ||
53 | #define rtc_writel(dev, reg, val) \ | ||
54 | __raw_writel((val), (dev)->rtc_base + (reg)) | ||
55 | |||
56 | struct lpc32xx_rtc { | ||
57 | void __iomem *rtc_base; | ||
58 | int irq; | ||
59 | unsigned char alarm_enabled; | ||
60 | struct rtc_device *rtc; | ||
61 | spinlock_t lock; | ||
62 | }; | ||
63 | |||
64 | static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time) | ||
65 | { | ||
66 | unsigned long elapsed_sec; | ||
67 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
68 | |||
69 | elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT); | ||
70 | rtc_time_to_tm(elapsed_sec, time); | ||
71 | |||
72 | return rtc_valid_tm(time); | ||
73 | } | ||
74 | |||
75 | static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs) | ||
76 | { | ||
77 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
78 | u32 tmp; | ||
79 | |||
80 | spin_lock_irq(&rtc->lock); | ||
81 | |||
82 | /* RTC must be disabled during count update */ | ||
83 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
84 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | LPC32XX_RTC_CTRL_CNTR_DIS); | ||
85 | rtc_writel(rtc, LPC32XX_RTC_UCOUNT, secs); | ||
86 | rtc_writel(rtc, LPC32XX_RTC_DCOUNT, 0xFFFFFFFF - secs); | ||
87 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp &= ~LPC32XX_RTC_CTRL_CNTR_DIS); | ||
88 | |||
89 | spin_unlock_irq(&rtc->lock); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int lpc32xx_rtc_read_alarm(struct device *dev, | ||
95 | struct rtc_wkalrm *wkalrm) | ||
96 | { | ||
97 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
98 | |||
99 | rtc_time_to_tm(rtc_readl(rtc, LPC32XX_RTC_MATCH0), &wkalrm->time); | ||
100 | wkalrm->enabled = rtc->alarm_enabled; | ||
101 | wkalrm->pending = !!(rtc_readl(rtc, LPC32XX_RTC_INTSTAT) & | ||
102 | LPC32XX_RTC_INTSTAT_MATCH0); | ||
103 | |||
104 | return rtc_valid_tm(&wkalrm->time); | ||
105 | } | ||
106 | |||
107 | static int lpc32xx_rtc_set_alarm(struct device *dev, | ||
108 | struct rtc_wkalrm *wkalrm) | ||
109 | { | ||
110 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
111 | unsigned long alarmsecs; | ||
112 | u32 tmp; | ||
113 | int ret; | ||
114 | |||
115 | ret = rtc_tm_to_time(&wkalrm->time, &alarmsecs); | ||
116 | if (ret < 0) { | ||
117 | dev_warn(dev, "Failed to convert time: %d\n", ret); | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | spin_lock_irq(&rtc->lock); | ||
122 | |||
123 | /* Disable alarm during update */ | ||
124 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
125 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp & ~LPC32XX_RTC_CTRL_MATCH0); | ||
126 | |||
127 | rtc_writel(rtc, LPC32XX_RTC_MATCH0, alarmsecs); | ||
128 | |||
129 | rtc->alarm_enabled = wkalrm->enabled; | ||
130 | if (wkalrm->enabled) { | ||
131 | rtc_writel(rtc, LPC32XX_RTC_INTSTAT, | ||
132 | LPC32XX_RTC_INTSTAT_MATCH0); | ||
133 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | | ||
134 | LPC32XX_RTC_CTRL_MATCH0); | ||
135 | } | ||
136 | |||
137 | spin_unlock_irq(&rtc->lock); | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int lpc32xx_rtc_alarm_irq_enable(struct device *dev, | ||
143 | unsigned int enabled) | ||
144 | { | ||
145 | struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); | ||
146 | u32 tmp; | ||
147 | |||
148 | spin_lock_irq(&rtc->lock); | ||
149 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
150 | |||
151 | if (enabled) { | ||
152 | rtc->alarm_enabled = 1; | ||
153 | tmp |= LPC32XX_RTC_CTRL_MATCH0; | ||
154 | } else { | ||
155 | rtc->alarm_enabled = 0; | ||
156 | tmp &= ~LPC32XX_RTC_CTRL_MATCH0; | ||
157 | } | ||
158 | |||
159 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); | ||
160 | spin_unlock_irq(&rtc->lock); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev) | ||
166 | { | ||
167 | struct lpc32xx_rtc *rtc = dev; | ||
168 | |||
169 | spin_lock(&rtc->lock); | ||
170 | |||
171 | /* Disable alarm interrupt */ | ||
172 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
173 | rtc_readl(rtc, LPC32XX_RTC_CTRL) & | ||
174 | ~LPC32XX_RTC_CTRL_MATCH0); | ||
175 | rtc->alarm_enabled = 0; | ||
176 | |||
177 | /* | ||
178 | * Write a large value to the match value so the RTC won't | ||
179 | * keep firing the match status | ||
180 | */ | ||
181 | rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); | ||
182 | rtc_writel(rtc, LPC32XX_RTC_INTSTAT, LPC32XX_RTC_INTSTAT_MATCH0); | ||
183 | |||
184 | spin_unlock(&rtc->lock); | ||
185 | |||
186 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
187 | |||
188 | return IRQ_HANDLED; | ||
189 | } | ||
190 | |||
191 | static const struct rtc_class_ops lpc32xx_rtc_ops = { | ||
192 | .read_time = lpc32xx_rtc_read_time, | ||
193 | .set_mmss = lpc32xx_rtc_set_mmss, | ||
194 | .read_alarm = lpc32xx_rtc_read_alarm, | ||
195 | .set_alarm = lpc32xx_rtc_set_alarm, | ||
196 | .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, | ||
197 | }; | ||
198 | |||
199 | static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev) | ||
200 | { | ||
201 | struct resource *res; | ||
202 | struct lpc32xx_rtc *rtc; | ||
203 | resource_size_t size; | ||
204 | int rtcirq; | ||
205 | u32 tmp; | ||
206 | |||
207 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
208 | if (!res) { | ||
209 | dev_err(&pdev->dev, "Can't get memory resource\n"); | ||
210 | return -ENOENT; | ||
211 | } | ||
212 | |||
213 | rtcirq = platform_get_irq(pdev, 0); | ||
214 | if (rtcirq < 0 || rtcirq >= NR_IRQS) { | ||
215 | dev_warn(&pdev->dev, "Can't get interrupt resource\n"); | ||
216 | rtcirq = -1; | ||
217 | } | ||
218 | |||
219 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
220 | if (unlikely(!rtc)) { | ||
221 | dev_err(&pdev->dev, "Can't allocate memory\n"); | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | rtc->irq = rtcirq; | ||
225 | |||
226 | size = resource_size(res); | ||
227 | |||
228 | if (!devm_request_mem_region(&pdev->dev, res->start, size, | ||
229 | pdev->name)) { | ||
230 | dev_err(&pdev->dev, "RTC registers are not free\n"); | ||
231 | return -EBUSY; | ||
232 | } | ||
233 | |||
234 | rtc->rtc_base = devm_ioremap(&pdev->dev, res->start, size); | ||
235 | if (!rtc->rtc_base) { | ||
236 | dev_err(&pdev->dev, "Can't map memory\n"); | ||
237 | return -ENOMEM; | ||
238 | } | ||
239 | |||
240 | spin_lock_init(&rtc->lock); | ||
241 | |||
242 | /* | ||
243 | * The RTC is on a seperate power domain and can keep it's state | ||
244 | * across a chip power cycle. If the RTC has never been previously | ||
245 | * setup, then set it up now for the first time. | ||
246 | */ | ||
247 | tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); | ||
248 | if (rtc_readl(rtc, LPC32XX_RTC_KEY) != LPC32XX_RTC_KEY_ONSW_LOADVAL) { | ||
249 | tmp &= ~(LPC32XX_RTC_CTRL_SW_RESET | | ||
250 | LPC32XX_RTC_CTRL_CNTR_DIS | | ||
251 | LPC32XX_RTC_CTRL_MATCH0 | | ||
252 | LPC32XX_RTC_CTRL_MATCH1 | | ||
253 | LPC32XX_RTC_CTRL_ONSW_MATCH0 | | ||
254 | LPC32XX_RTC_CTRL_ONSW_MATCH1 | | ||
255 | LPC32XX_RTC_CTRL_ONSW_FORCE_HI); | ||
256 | rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); | ||
257 | |||
258 | /* Clear latched interrupt states */ | ||
259 | rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); | ||
260 | rtc_writel(rtc, LPC32XX_RTC_INTSTAT, | ||
261 | LPC32XX_RTC_INTSTAT_MATCH0 | | ||
262 | LPC32XX_RTC_INTSTAT_MATCH1 | | ||
263 | LPC32XX_RTC_INTSTAT_ONSW); | ||
264 | |||
265 | /* Write key value to RTC so it won't reload on reset */ | ||
266 | rtc_writel(rtc, LPC32XX_RTC_KEY, | ||
267 | LPC32XX_RTC_KEY_ONSW_LOADVAL); | ||
268 | } else { | ||
269 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
270 | tmp & ~LPC32XX_RTC_CTRL_MATCH0); | ||
271 | } | ||
272 | |||
273 | platform_set_drvdata(pdev, rtc); | ||
274 | |||
275 | rtc->rtc = rtc_device_register(RTC_NAME, &pdev->dev, &lpc32xx_rtc_ops, | ||
276 | THIS_MODULE); | ||
277 | if (IS_ERR(rtc->rtc)) { | ||
278 | dev_err(&pdev->dev, "Can't get RTC\n"); | ||
279 | platform_set_drvdata(pdev, NULL); | ||
280 | return PTR_ERR(rtc->rtc); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * IRQ is enabled after device registration in case alarm IRQ | ||
285 | * is pending upon suspend exit. | ||
286 | */ | ||
287 | if (rtc->irq >= 0) { | ||
288 | if (devm_request_irq(&pdev->dev, rtc->irq, | ||
289 | lpc32xx_rtc_alarm_interrupt, | ||
290 | IRQF_DISABLED, pdev->name, rtc) < 0) { | ||
291 | dev_warn(&pdev->dev, "Can't request interrupt.\n"); | ||
292 | rtc->irq = -1; | ||
293 | } else { | ||
294 | device_init_wakeup(&pdev->dev, 1); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int __devexit lpc32xx_rtc_remove(struct platform_device *pdev) | ||
302 | { | ||
303 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
304 | |||
305 | if (rtc->irq >= 0) | ||
306 | device_init_wakeup(&pdev->dev, 0); | ||
307 | |||
308 | platform_set_drvdata(pdev, NULL); | ||
309 | rtc_device_unregister(rtc->rtc); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | #ifdef CONFIG_PM | ||
315 | static int lpc32xx_rtc_suspend(struct device *dev) | ||
316 | { | ||
317 | struct platform_device *pdev = to_platform_device(dev); | ||
318 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
319 | |||
320 | if (rtc->irq >= 0) { | ||
321 | if (device_may_wakeup(&pdev->dev)) | ||
322 | enable_irq_wake(rtc->irq); | ||
323 | else | ||
324 | disable_irq_wake(rtc->irq); | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int lpc32xx_rtc_resume(struct device *dev) | ||
331 | { | ||
332 | struct platform_device *pdev = to_platform_device(dev); | ||
333 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
334 | |||
335 | if (rtc->irq >= 0 && device_may_wakeup(&pdev->dev)) | ||
336 | disable_irq_wake(rtc->irq); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | /* Unconditionally disable the alarm */ | ||
342 | static int lpc32xx_rtc_freeze(struct device *dev) | ||
343 | { | ||
344 | struct platform_device *pdev = to_platform_device(dev); | ||
345 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
346 | |||
347 | spin_lock_irq(&rtc->lock); | ||
348 | |||
349 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
350 | rtc_readl(rtc, LPC32XX_RTC_CTRL) & | ||
351 | ~LPC32XX_RTC_CTRL_MATCH0); | ||
352 | |||
353 | spin_unlock_irq(&rtc->lock); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int lpc32xx_rtc_thaw(struct device *dev) | ||
359 | { | ||
360 | struct platform_device *pdev = to_platform_device(dev); | ||
361 | struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); | ||
362 | |||
363 | if (rtc->alarm_enabled) { | ||
364 | spin_lock_irq(&rtc->lock); | ||
365 | |||
366 | rtc_writel(rtc, LPC32XX_RTC_CTRL, | ||
367 | rtc_readl(rtc, LPC32XX_RTC_CTRL) | | ||
368 | LPC32XX_RTC_CTRL_MATCH0); | ||
369 | |||
370 | spin_unlock_irq(&rtc->lock); | ||
371 | } | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static const struct dev_pm_ops lpc32xx_rtc_pm_ops = { | ||
377 | .suspend = lpc32xx_rtc_suspend, | ||
378 | .resume = lpc32xx_rtc_resume, | ||
379 | .freeze = lpc32xx_rtc_freeze, | ||
380 | .thaw = lpc32xx_rtc_thaw, | ||
381 | .restore = lpc32xx_rtc_resume | ||
382 | }; | ||
383 | |||
384 | #define LPC32XX_RTC_PM_OPS (&lpc32xx_rtc_pm_ops) | ||
385 | #else | ||
386 | #define LPC32XX_RTC_PM_OPS NULL | ||
387 | #endif | ||
388 | |||
389 | static struct platform_driver lpc32xx_rtc_driver = { | ||
390 | .probe = lpc32xx_rtc_probe, | ||
391 | .remove = __devexit_p(lpc32xx_rtc_remove), | ||
392 | .driver = { | ||
393 | .name = RTC_NAME, | ||
394 | .owner = THIS_MODULE, | ||
395 | .pm = LPC32XX_RTC_PM_OPS | ||
396 | }, | ||
397 | }; | ||
398 | |||
399 | static int __init lpc32xx_rtc_init(void) | ||
400 | { | ||
401 | return platform_driver_register(&lpc32xx_rtc_driver); | ||
402 | } | ||
403 | module_init(lpc32xx_rtc_init); | ||
404 | |||
405 | static void __exit lpc32xx_rtc_exit(void) | ||
406 | { | ||
407 | platform_driver_unregister(&lpc32xx_rtc_driver); | ||
408 | } | ||
409 | module_exit(lpc32xx_rtc_exit); | ||
410 | |||
411 | MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com"); | ||
412 | MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC"); | ||
413 | MODULE_LICENSE("GPL"); | ||
414 | MODULE_ALIAS("platform:rtc-lpc32xx"); | ||
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 64d9727b7229..73377b0d65da 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -34,7 +34,8 @@ | |||
34 | * Board-specific wiring options include using split power mode with | 34 | * Board-specific wiring options include using split power mode with |
35 | * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset), | 35 | * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset), |
36 | * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from | 36 | * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from |
37 | * low power modes). See the BOARD-SPECIFIC CUSTOMIZATION comment. | 37 | * low power modes) for OMAP1 boards (OMAP-L138 has this built into |
38 | * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. | ||
38 | */ | 39 | */ |
39 | 40 | ||
40 | #define OMAP_RTC_BASE 0xfffb4800 | 41 | #define OMAP_RTC_BASE 0xfffb4800 |
@@ -401,16 +402,17 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
401 | 402 | ||
402 | /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: | 403 | /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: |
403 | * | 404 | * |
404 | * - Boards wired so that RTC_WAKE_INT does something, and muxed | 405 | * - Device wake-up capability setting should come through chip |
405 | * right (W13_1610_RTC_WAKE_INT is the default after chip reset), | 406 | * init logic. OMAP1 boards should initialize the "wakeup capable" |
406 | * should initialize the device wakeup flag appropriately. | 407 | * flag in the platform device if the board is wired right for |
408 | * being woken up by RTC alarm. For OMAP-L138, this capability | ||
409 | * is built into the SoC by the "Deep Sleep" capability. | ||
407 | * | 410 | * |
408 | * - Boards wired so RTC_ON_nOFF is used as the reset signal, | 411 | * - Boards wired so RTC_ON_nOFF is used as the reset signal, |
409 | * rather than nPWRON_RESET, should forcibly enable split | 412 | * rather than nPWRON_RESET, should forcibly enable split |
410 | * power mode. (Some chip errata report that RTC_CTRL_SPLIT | 413 | * power mode. (Some chip errata report that RTC_CTRL_SPLIT |
411 | * is write-only, and always reads as zero...) | 414 | * is write-only, and always reads as zero...) |
412 | */ | 415 | */ |
413 | device_init_wakeup(&pdev->dev, 0); | ||
414 | 416 | ||
415 | if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) | 417 | if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) |
416 | pr_info("%s: split power mode\n", pdev->name); | 418 | pr_info("%s: split power mode\n", pdev->name); |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index f57a87f4ae96..cf953ecbfca9 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -100,7 +100,7 @@ static int s3c_rtc_setpie(struct device *dev, int enabled) | |||
100 | spin_lock_irq(&s3c_rtc_pie_lock); | 100 | spin_lock_irq(&s3c_rtc_pie_lock); |
101 | 101 | ||
102 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 102 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
103 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | 103 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); |
104 | tmp &= ~S3C64XX_RTCCON_TICEN; | 104 | tmp &= ~S3C64XX_RTCCON_TICEN; |
105 | 105 | ||
106 | if (enabled) | 106 | if (enabled) |
@@ -171,8 +171,8 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
171 | goto retry_get_time; | 171 | goto retry_get_time; |
172 | } | 172 | } |
173 | 173 | ||
174 | pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n", | 174 | pr_debug("read time %04d.%02d.%02d %02d:%02d:%02d\n", |
175 | rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, | 175 | 1900 + rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, |
176 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); | 176 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); |
177 | 177 | ||
178 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); | 178 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
@@ -185,7 +185,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
185 | rtc_tm->tm_year += 100; | 185 | rtc_tm->tm_year += 100; |
186 | rtc_tm->tm_mon -= 1; | 186 | rtc_tm->tm_mon -= 1; |
187 | 187 | ||
188 | return 0; | 188 | return rtc_valid_tm(rtc_tm); |
189 | } | 189 | } |
190 | 190 | ||
191 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | 191 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) |
@@ -193,8 +193,8 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
193 | void __iomem *base = s3c_rtc_base; | 193 | void __iomem *base = s3c_rtc_base; |
194 | int year = tm->tm_year - 100; | 194 | int year = tm->tm_year - 100; |
195 | 195 | ||
196 | pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n", | 196 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", |
197 | tm->tm_year, tm->tm_mon, tm->tm_mday, | 197 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
198 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 198 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
199 | 199 | ||
200 | /* we get around y2k by simply not supporting it */ | 200 | /* we get around y2k by simply not supporting it */ |
@@ -231,9 +231,9 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
231 | 231 | ||
232 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; | 232 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; |
233 | 233 | ||
234 | pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n", | 234 | pr_debug("read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
235 | alm_en, | 235 | alm_en, |
236 | alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, | 236 | 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, |
237 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); | 237 | alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); |
238 | 238 | ||
239 | 239 | ||
@@ -242,34 +242,34 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
242 | if (alm_en & S3C2410_RTCALM_SECEN) | 242 | if (alm_en & S3C2410_RTCALM_SECEN) |
243 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); | 243 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
244 | else | 244 | else |
245 | alm_tm->tm_sec = 0xff; | 245 | alm_tm->tm_sec = -1; |
246 | 246 | ||
247 | if (alm_en & S3C2410_RTCALM_MINEN) | 247 | if (alm_en & S3C2410_RTCALM_MINEN) |
248 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); | 248 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
249 | else | 249 | else |
250 | alm_tm->tm_min = 0xff; | 250 | alm_tm->tm_min = -1; |
251 | 251 | ||
252 | if (alm_en & S3C2410_RTCALM_HOUREN) | 252 | if (alm_en & S3C2410_RTCALM_HOUREN) |
253 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); | 253 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
254 | else | 254 | else |
255 | alm_tm->tm_hour = 0xff; | 255 | alm_tm->tm_hour = -1; |
256 | 256 | ||
257 | if (alm_en & S3C2410_RTCALM_DAYEN) | 257 | if (alm_en & S3C2410_RTCALM_DAYEN) |
258 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); | 258 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); |
259 | else | 259 | else |
260 | alm_tm->tm_mday = 0xff; | 260 | alm_tm->tm_mday = -1; |
261 | 261 | ||
262 | if (alm_en & S3C2410_RTCALM_MONEN) { | 262 | if (alm_en & S3C2410_RTCALM_MONEN) { |
263 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); | 263 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); |
264 | alm_tm->tm_mon -= 1; | 264 | alm_tm->tm_mon -= 1; |
265 | } else { | 265 | } else { |
266 | alm_tm->tm_mon = 0xff; | 266 | alm_tm->tm_mon = -1; |
267 | } | 267 | } |
268 | 268 | ||
269 | if (alm_en & S3C2410_RTCALM_YEAREN) | 269 | if (alm_en & S3C2410_RTCALM_YEAREN) |
270 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); | 270 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); |
271 | else | 271 | else |
272 | alm_tm->tm_year = 0xffff; | 272 | alm_tm->tm_year = -1; |
273 | 273 | ||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
@@ -280,10 +280,10 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
280 | void __iomem *base = s3c_rtc_base; | 280 | void __iomem *base = s3c_rtc_base; |
281 | unsigned int alrm_en; | 281 | unsigned int alrm_en; |
282 | 282 | ||
283 | pr_debug("s3c_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n", | 283 | pr_debug("s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
284 | alrm->enabled, | 284 | alrm->enabled, |
285 | tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff, | 285 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
286 | tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec); | 286 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
287 | 287 | ||
288 | 288 | ||
289 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; | 289 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; |
@@ -318,7 +318,7 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | |||
318 | unsigned int ticnt; | 318 | unsigned int ticnt; |
319 | 319 | ||
320 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 320 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
321 | ticnt = readb(s3c_rtc_base + S3C2410_RTCCON); | 321 | ticnt = readw(s3c_rtc_base + S3C2410_RTCCON); |
322 | ticnt &= S3C64XX_RTCCON_TICEN; | 322 | ticnt &= S3C64XX_RTCCON_TICEN; |
323 | } else { | 323 | } else { |
324 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 324 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); |
@@ -379,7 +379,8 @@ static const struct rtc_class_ops s3c_rtcops = { | |||
379 | .set_alarm = s3c_rtc_setalarm, | 379 | .set_alarm = s3c_rtc_setalarm, |
380 | .irq_set_freq = s3c_rtc_setfreq, | 380 | .irq_set_freq = s3c_rtc_setfreq, |
381 | .irq_set_state = s3c_rtc_setpie, | 381 | .irq_set_state = s3c_rtc_setpie, |
382 | .proc = s3c_rtc_proc, | 382 | .proc = s3c_rtc_proc, |
383 | .alarm_irq_enable = s3c_rtc_setaie, | ||
383 | }; | 384 | }; |
384 | 385 | ||
385 | static void s3c_rtc_enable(struct platform_device *pdev, int en) | 386 | static void s3c_rtc_enable(struct platform_device *pdev, int en) |
@@ -391,11 +392,11 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
391 | return; | 392 | return; |
392 | 393 | ||
393 | if (!en) { | 394 | if (!en) { |
394 | tmp = readb(base + S3C2410_RTCCON); | 395 | tmp = readw(base + S3C2410_RTCCON); |
395 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | 396 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
396 | tmp &= ~S3C64XX_RTCCON_TICEN; | 397 | tmp &= ~S3C64XX_RTCCON_TICEN; |
397 | tmp &= ~S3C2410_RTCCON_RTCEN; | 398 | tmp &= ~S3C2410_RTCCON_RTCEN; |
398 | writeb(tmp, base + S3C2410_RTCCON); | 399 | writew(tmp, base + S3C2410_RTCCON); |
399 | 400 | ||
400 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { | 401 | if (s3c_rtc_cpu_type == TYPE_S3C2410) { |
401 | tmp = readb(base + S3C2410_TICNT); | 402 | tmp = readb(base + S3C2410_TICNT); |
@@ -405,25 +406,28 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en) | |||
405 | } else { | 406 | } else { |
406 | /* re-enable the device, and check it is ok */ | 407 | /* re-enable the device, and check it is ok */ |
407 | 408 | ||
408 | if ((readb(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0){ | 409 | if ((readw(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0) { |
409 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); | 410 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); |
410 | 411 | ||
411 | tmp = readb(base + S3C2410_RTCCON); | 412 | tmp = readw(base + S3C2410_RTCCON); |
412 | writeb(tmp|S3C2410_RTCCON_RTCEN, base+S3C2410_RTCCON); | 413 | writew(tmp | S3C2410_RTCCON_RTCEN, |
414 | base + S3C2410_RTCCON); | ||
413 | } | 415 | } |
414 | 416 | ||
415 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)){ | 417 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)) { |
416 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); | 418 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); |
417 | 419 | ||
418 | tmp = readb(base + S3C2410_RTCCON); | 420 | tmp = readw(base + S3C2410_RTCCON); |
419 | writeb(tmp& ~S3C2410_RTCCON_CNTSEL, base+S3C2410_RTCCON); | 421 | writew(tmp & ~S3C2410_RTCCON_CNTSEL, |
422 | base + S3C2410_RTCCON); | ||
420 | } | 423 | } |
421 | 424 | ||
422 | if ((readb(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)){ | 425 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)) { |
423 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); | 426 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); |
424 | 427 | ||
425 | tmp = readb(base + S3C2410_RTCCON); | 428 | tmp = readw(base + S3C2410_RTCCON); |
426 | writeb(tmp & ~S3C2410_RTCCON_CLKRST, base+S3C2410_RTCCON); | 429 | writew(tmp & ~S3C2410_RTCCON_CLKRST, |
430 | base + S3C2410_RTCCON); | ||
427 | } | 431 | } |
428 | } | 432 | } |
429 | } | 433 | } |
@@ -452,8 +456,8 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) | |||
452 | static int __devinit s3c_rtc_probe(struct platform_device *pdev) | 456 | static int __devinit s3c_rtc_probe(struct platform_device *pdev) |
453 | { | 457 | { |
454 | struct rtc_device *rtc; | 458 | struct rtc_device *rtc; |
459 | struct rtc_time rtc_tm; | ||
455 | struct resource *res; | 460 | struct resource *res; |
456 | unsigned int tmp, i; | ||
457 | int ret; | 461 | int ret; |
458 | 462 | ||
459 | pr_debug("%s: probe=%p\n", __func__, pdev); | 463 | pr_debug("%s: probe=%p\n", __func__, pdev); |
@@ -514,8 +518,8 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
514 | 518 | ||
515 | s3c_rtc_enable(pdev, 1); | 519 | s3c_rtc_enable(pdev, 1); |
516 | 520 | ||
517 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", | 521 | pr_debug("s3c2410_rtc: RTCCON=%02x\n", |
518 | readb(s3c_rtc_base + S3C2410_RTCCON)); | 522 | readw(s3c_rtc_base + S3C2410_RTCCON)); |
519 | 523 | ||
520 | device_init_wakeup(&pdev->dev, 1); | 524 | device_init_wakeup(&pdev->dev, 1); |
521 | 525 | ||
@@ -534,11 +538,19 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
534 | 538 | ||
535 | /* Check RTC Time */ | 539 | /* Check RTC Time */ |
536 | 540 | ||
537 | for (i = S3C2410_RTCSEC; i <= S3C2410_RTCYEAR; i += 0x4) { | 541 | s3c_rtc_gettime(NULL, &rtc_tm); |
538 | tmp = readb(s3c_rtc_base + i); | 542 | |
543 | if (rtc_valid_tm(&rtc_tm)) { | ||
544 | rtc_tm.tm_year = 100; | ||
545 | rtc_tm.tm_mon = 0; | ||
546 | rtc_tm.tm_mday = 1; | ||
547 | rtc_tm.tm_hour = 0; | ||
548 | rtc_tm.tm_min = 0; | ||
549 | rtc_tm.tm_sec = 0; | ||
550 | |||
551 | s3c_rtc_settime(NULL, &rtc_tm); | ||
539 | 552 | ||
540 | if ((tmp & 0xf) > 0x9 || ((tmp >> 4) & 0xf) > 0x9) | 553 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); |
541 | writeb(0, s3c_rtc_base + i); | ||
542 | } | 554 | } |
543 | 555 | ||
544 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | 556 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) |
@@ -578,7 +590,7 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | |||
578 | /* save TICNT for anyone using periodic interrupts */ | 590 | /* save TICNT for anyone using periodic interrupts */ |
579 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | 591 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); |
580 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 592 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
581 | ticnt_en_save = readb(s3c_rtc_base + S3C2410_RTCCON); | 593 | ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); |
582 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | 594 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; |
583 | } | 595 | } |
584 | s3c_rtc_enable(pdev, 0); | 596 | s3c_rtc_enable(pdev, 0); |
@@ -596,8 +608,8 @@ static int s3c_rtc_resume(struct platform_device *pdev) | |||
596 | s3c_rtc_enable(pdev, 1); | 608 | s3c_rtc_enable(pdev, 1); |
597 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | 609 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
598 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { | 610 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { |
599 | tmp = readb(s3c_rtc_base + S3C2410_RTCCON); | 611 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); |
600 | writeb(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); | 612 | writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); |
601 | } | 613 | } |
602 | 614 | ||
603 | if (device_may_wakeup(&pdev->dev)) | 615 | if (device_may_wakeup(&pdev->dev)) |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 42e303ff862a..0e6aa3d96a42 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -697,9 +697,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
697 | struct inode *inode = file->f_path.dentry->d_inode; | 697 | struct inode *inode = file->f_path.dentry->d_inode; |
698 | int fbidx = iminor(inode); | 698 | int fbidx = iminor(inode); |
699 | struct fb_info *info = registered_fb[fbidx]; | 699 | struct fb_info *info = registered_fb[fbidx]; |
700 | u32 *buffer, *dst; | 700 | u8 *buffer, *dst; |
701 | u32 __iomem *src; | 701 | u8 __iomem *src; |
702 | int c, i, cnt = 0, err = 0; | 702 | int c, cnt = 0, err = 0; |
703 | unsigned long total_size; | 703 | unsigned long total_size; |
704 | 704 | ||
705 | if (!info || ! info->screen_base) | 705 | if (!info || ! info->screen_base) |
@@ -730,7 +730,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
730 | if (!buffer) | 730 | if (!buffer) |
731 | return -ENOMEM; | 731 | return -ENOMEM; |
732 | 732 | ||
733 | src = (u32 __iomem *) (info->screen_base + p); | 733 | src = (u8 __iomem *) (info->screen_base + p); |
734 | 734 | ||
735 | if (info->fbops->fb_sync) | 735 | if (info->fbops->fb_sync) |
736 | info->fbops->fb_sync(info); | 736 | info->fbops->fb_sync(info); |
@@ -738,17 +738,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
738 | while (count) { | 738 | while (count) { |
739 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; | 739 | c = (count > PAGE_SIZE) ? PAGE_SIZE : count; |
740 | dst = buffer; | 740 | dst = buffer; |
741 | for (i = c >> 2; i--; ) | 741 | fb_memcpy_fromfb(dst, src, c); |
742 | *dst++ = fb_readl(src++); | 742 | dst += c; |
743 | if (c & 3) { | 743 | src += c; |
744 | u8 *dst8 = (u8 *) dst; | ||
745 | u8 __iomem *src8 = (u8 __iomem *) src; | ||
746 | |||
747 | for (i = c & 3; i--;) | ||
748 | *dst8++ = fb_readb(src8++); | ||
749 | |||
750 | src = (u32 __iomem *) src8; | ||
751 | } | ||
752 | 744 | ||
753 | if (copy_to_user(buf, buffer, c)) { | 745 | if (copy_to_user(buf, buffer, c)) { |
754 | err = -EFAULT; | 746 | err = -EFAULT; |
@@ -772,9 +764,9 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
772 | struct inode *inode = file->f_path.dentry->d_inode; | 764 | struct inode *inode = file->f_path.dentry->d_inode; |
773 | int fbidx = iminor(inode); | 765 | int fbidx = iminor(inode); |
774 | struct fb_info *info = registered_fb[fbidx]; | 766 | struct fb_info *info = registered_fb[fbidx]; |
775 | u32 *buffer, *src; | 767 | u8 *buffer, *src; |
776 | u32 __iomem *dst; | 768 | u8 __iomem *dst; |
777 | int c, i, cnt = 0, err = 0; | 769 | int c, cnt = 0, err = 0; |
778 | unsigned long total_size; | 770 | unsigned long total_size; |
779 | 771 | ||
780 | if (!info || !info->screen_base) | 772 | if (!info || !info->screen_base) |
@@ -811,7 +803,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
811 | if (!buffer) | 803 | if (!buffer) |
812 | return -ENOMEM; | 804 | return -ENOMEM; |
813 | 805 | ||
814 | dst = (u32 __iomem *) (info->screen_base + p); | 806 | dst = (u8 __iomem *) (info->screen_base + p); |
815 | 807 | ||
816 | if (info->fbops->fb_sync) | 808 | if (info->fbops->fb_sync) |
817 | info->fbops->fb_sync(info); | 809 | info->fbops->fb_sync(info); |
@@ -825,19 +817,9 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
825 | break; | 817 | break; |
826 | } | 818 | } |
827 | 819 | ||
828 | for (i = c >> 2; i--; ) | 820 | fb_memcpy_tofb(dst, src, c); |
829 | fb_writel(*src++, dst++); | 821 | dst += c; |
830 | 822 | src += c; | |
831 | if (c & 3) { | ||
832 | u8 *src8 = (u8 *) src; | ||
833 | u8 __iomem *dst8 = (u8 __iomem *) dst; | ||
834 | |||
835 | for (i = c & 3; i--; ) | ||
836 | fb_writeb(*src8++, dst8++); | ||
837 | |||
838 | dst = (u32 __iomem *) dst8; | ||
839 | } | ||
840 | |||
841 | *ppos += c; | 823 | *ppos += c; |
842 | buf += c; | 824 | buf += c; |
843 | cnt += c; | 825 | cnt += c; |
@@ -877,13 +859,13 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) | |||
877 | 859 | ||
878 | if ((err = info->fbops->fb_pan_display(var, info))) | 860 | if ((err = info->fbops->fb_pan_display(var, info))) |
879 | return err; | 861 | return err; |
880 | info->var.xoffset = var->xoffset; | 862 | info->var.xoffset = var->xoffset; |
881 | info->var.yoffset = var->yoffset; | 863 | info->var.yoffset = var->yoffset; |
882 | if (var->vmode & FB_VMODE_YWRAP) | 864 | if (var->vmode & FB_VMODE_YWRAP) |
883 | info->var.vmode |= FB_VMODE_YWRAP; | 865 | info->var.vmode |= FB_VMODE_YWRAP; |
884 | else | 866 | else |
885 | info->var.vmode &= ~FB_VMODE_YWRAP; | 867 | info->var.vmode &= ~FB_VMODE_YWRAP; |
886 | return 0; | 868 | return 0; |
887 | } | 869 | } |
888 | 870 | ||
889 | static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, | 871 | static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, |
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index ca3355e430bf..933899dca33a 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c | |||
@@ -1143,8 +1143,10 @@ static int __devinit gbefb_probe(struct platform_device *p_dev) | |||
1143 | return -ENOMEM; | 1143 | return -ENOMEM; |
1144 | 1144 | ||
1145 | #ifndef MODULE | 1145 | #ifndef MODULE |
1146 | if (fb_get_options("gbefb", &options)) | 1146 | if (fb_get_options("gbefb", &options)) { |
1147 | return -ENODEV; | 1147 | ret = -ENODEV; |
1148 | goto out_release_framebuffer; | ||
1149 | } | ||
1148 | gbefb_setup(options); | 1150 | gbefb_setup(options); |
1149 | #endif | 1151 | #endif |
1150 | 1152 | ||
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c index f9fa0fd00292..1717623aabc0 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/matrox/matroxfb_DAC1064.c | |||
@@ -869,12 +869,9 @@ static int MGAG100_preinit(struct matrox_fb_info *minfo) | |||
869 | minfo->capable.plnwt = minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100 | 869 | minfo->capable.plnwt = minfo->devflags.accelerator == FB_ACCEL_MATROX_MGAG100 |
870 | ? minfo->devflags.sgram : 1; | 870 | ? minfo->devflags.sgram : 1; |
871 | 871 | ||
872 | #ifdef CONFIG_FB_MATROX_G | ||
873 | if (minfo->devflags.g450dac) { | 872 | if (minfo->devflags.g450dac) { |
874 | minfo->outputs[0].output = &g450out; | 873 | minfo->outputs[0].output = &g450out; |
875 | } else | 874 | } else { |
876 | #endif | ||
877 | { | ||
878 | minfo->outputs[0].output = &m1064; | 875 | minfo->outputs[0].output = &m1064; |
879 | } | 876 | } |
880 | minfo->outputs[0].src = minfo->outputs[0].default_src; | 877 | minfo->outputs[0].src = minfo->outputs[0].default_src; |
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index 1e3e8f19783e..31b8f67477b7 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c | |||
@@ -280,7 +280,7 @@ static int matroxfb_PLL_mavenclock(const struct matrox_pll_features2* pll, | |||
280 | return fxtal * (*feed) / (*in) * ctl->den; | 280 | return fxtal * (*feed) / (*in) * ctl->den; |
281 | } | 281 | } |
282 | 282 | ||
283 | static unsigned int matroxfb_mavenclock(const struct matrox_pll_ctl* ctl, | 283 | static int matroxfb_mavenclock(const struct matrox_pll_ctl *ctl, |
284 | unsigned int htotal, unsigned int vtotal, | 284 | unsigned int htotal, unsigned int vtotal, |
285 | unsigned int* in, unsigned int* feed, unsigned int* post, | 285 | unsigned int* in, unsigned int* feed, unsigned int* post, |
286 | unsigned int* htotal2) { | 286 | unsigned int* htotal2) { |
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c index 2ffb34af4c59..87785c215a52 100644 --- a/drivers/video/omap/blizzard.c +++ b/drivers/video/omap/blizzard.c | |||
@@ -1590,7 +1590,7 @@ static int blizzard_init(struct omapfb_device *fbdev, int ext_mode, | |||
1590 | blizzard.auto_update_window.width = fbdev->panel->x_res; | 1590 | blizzard.auto_update_window.width = fbdev->panel->x_res; |
1591 | blizzard.auto_update_window.height = fbdev->panel->y_res; | 1591 | blizzard.auto_update_window.height = fbdev->panel->y_res; |
1592 | blizzard.auto_update_window.out_x = 0; | 1592 | blizzard.auto_update_window.out_x = 0; |
1593 | blizzard.auto_update_window.out_x = 0; | 1593 | blizzard.auto_update_window.out_y = 0; |
1594 | blizzard.auto_update_window.out_width = fbdev->panel->x_res; | 1594 | blizzard.auto_update_window.out_width = fbdev->panel->x_res; |
1595 | blizzard.auto_update_window.out_height = fbdev->panel->y_res; | 1595 | blizzard.auto_update_window.out_height = fbdev->panel->y_res; |
1596 | blizzard.auto_update_window.format = 0; | 1596 | blizzard.auto_update_window.format = 0; |
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index ed371c868b3a..b16e6138fdd4 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c | |||
@@ -181,6 +181,15 @@ void savagefb_create_i2c_busses(struct fb_info *info) | |||
181 | par->chan.algo.getscl = prosavage_gpio_getscl; | 181 | par->chan.algo.getscl = prosavage_gpio_getscl; |
182 | break; | 182 | break; |
183 | case FB_ACCEL_SAVAGE4: | 183 | case FB_ACCEL_SAVAGE4: |
184 | par->chan.reg = CR_SERIAL1; | ||
185 | if (par->pcidev->revision > 1 && !(VGArCR(0xa6, par) & 0x40)) | ||
186 | par->chan.reg = CR_SERIAL2; | ||
187 | par->chan.ioaddr = par->mmio.vbase; | ||
188 | par->chan.algo.setsda = prosavage_gpio_setsda; | ||
189 | par->chan.algo.setscl = prosavage_gpio_setscl; | ||
190 | par->chan.algo.getsda = prosavage_gpio_getsda; | ||
191 | par->chan.algo.getscl = prosavage_gpio_getscl; | ||
192 | break; | ||
184 | case FB_ACCEL_SAVAGE2000: | 193 | case FB_ACCEL_SAVAGE2000: |
185 | par->chan.reg = 0xff20; | 194 | par->chan.reg = 0xff20; |
186 | par->chan.ioaddr = par->mmio.vbase; | 195 | par->chan.ioaddr = par->mmio.vbase; |
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 2839e281cd65..b7b5014ff714 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -517,10 +517,10 @@ static W1_MASTER_ATTR_RO(max_slave_count, S_IRUGO); | |||
517 | static W1_MASTER_ATTR_RO(attempts, S_IRUGO); | 517 | static W1_MASTER_ATTR_RO(attempts, S_IRUGO); |
518 | static W1_MASTER_ATTR_RO(timeout, S_IRUGO); | 518 | static W1_MASTER_ATTR_RO(timeout, S_IRUGO); |
519 | static W1_MASTER_ATTR_RO(pointer, S_IRUGO); | 519 | static W1_MASTER_ATTR_RO(pointer, S_IRUGO); |
520 | static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO); | 520 | static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUSR | S_IWGRP); |
521 | static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUGO); | 521 | static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUSR | S_IWGRP); |
522 | static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUGO); | 522 | static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUSR | S_IWGRP); |
523 | static W1_MASTER_ATTR_RW(remove, S_IRUGO | S_IWUGO); | 523 | static W1_MASTER_ATTR_RW(remove, S_IRUGO | S_IWUSR | S_IWGRP); |
524 | 524 | ||
525 | static struct attribute *w1_master_default_attrs[] = { | 525 | static struct attribute *w1_master_default_attrs[] = { |
526 | &w1_master_attribute_name.attr, | 526 | &w1_master_attribute_name.attr, |
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index bb4cc5b8abc8..79e2ca7973b7 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt | |||
@@ -42,7 +42,7 @@ config BINFMT_ELF_FDPIC | |||
42 | 42 | ||
43 | config CORE_DUMP_DEFAULT_ELF_HEADERS | 43 | config CORE_DUMP_DEFAULT_ELF_HEADERS |
44 | bool "Write ELF core dumps with partial segments" | 44 | bool "Write ELF core dumps with partial segments" |
45 | default n | 45 | default y |
46 | depends on BINFMT_ELF && ELF_CORE | 46 | depends on BINFMT_ELF && ELF_CORE |
47 | help | 47 | help |
48 | ELF core dump files describe each memory mapping of the crashed | 48 | ELF core dump files describe each memory mapping of the crashed |
@@ -60,7 +60,7 @@ config CORE_DUMP_DEFAULT_ELF_HEADERS | |||
60 | inherited. See Documentation/filesystems/proc.txt for details. | 60 | inherited. See Documentation/filesystems/proc.txt for details. |
61 | 61 | ||
62 | This config option changes the default setting of coredump_filter | 62 | This config option changes the default setting of coredump_filter |
63 | seen at boot time. If unsure, say N. | 63 | seen at boot time. If unsure, say Y. |
64 | 64 | ||
65 | config BINFMT_FLAT | 65 | config BINFMT_FLAT |
66 | bool "Kernel support for flat binaries" | 66 | bool "Kernel support for flat binaries" |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 256bb7bb102a..8cf07242067d 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -77,9 +77,6 @@ | |||
77 | /* Maximum number of nesting allowed inside epoll sets */ | 77 | /* Maximum number of nesting allowed inside epoll sets */ |
78 | #define EP_MAX_NESTS 4 | 78 | #define EP_MAX_NESTS 4 |
79 | 79 | ||
80 | /* Maximum msec timeout value storeable in a long int */ | ||
81 | #define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ) | ||
82 | |||
83 | #define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) | 80 | #define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) |
84 | 81 | ||
85 | #define EP_UNACTIVE_PTR ((void *) -1L) | 82 | #define EP_UNACTIVE_PTR ((void *) -1L) |
@@ -1117,18 +1114,22 @@ static int ep_send_events(struct eventpoll *ep, | |||
1117 | static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, | 1114 | static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, |
1118 | int maxevents, long timeout) | 1115 | int maxevents, long timeout) |
1119 | { | 1116 | { |
1120 | int res, eavail; | 1117 | int res, eavail, timed_out = 0; |
1121 | unsigned long flags; | 1118 | unsigned long flags; |
1122 | long jtimeout; | 1119 | long slack; |
1123 | wait_queue_t wait; | 1120 | wait_queue_t wait; |
1124 | 1121 | struct timespec end_time; | |
1125 | /* | 1122 | ktime_t expires, *to = NULL; |
1126 | * Calculate the timeout by checking for the "infinite" value (-1) | 1123 | |
1127 | * and the overflow condition. The passed timeout is in milliseconds, | 1124 | if (timeout > 0) { |
1128 | * that why (t * HZ) / 1000. | 1125 | ktime_get_ts(&end_time); |
1129 | */ | 1126 | timespec_add_ns(&end_time, (u64)timeout * NSEC_PER_MSEC); |
1130 | jtimeout = (timeout < 0 || timeout >= EP_MAX_MSTIMEO) ? | 1127 | slack = select_estimate_accuracy(&end_time); |
1131 | MAX_SCHEDULE_TIMEOUT : (timeout * HZ + 999) / 1000; | 1128 | to = &expires; |
1129 | *to = timespec_to_ktime(end_time); | ||
1130 | } else if (timeout == 0) { | ||
1131 | timed_out = 1; | ||
1132 | } | ||
1132 | 1133 | ||
1133 | retry: | 1134 | retry: |
1134 | spin_lock_irqsave(&ep->lock, flags); | 1135 | spin_lock_irqsave(&ep->lock, flags); |
@@ -1150,7 +1151,7 @@ retry: | |||
1150 | * to TASK_INTERRUPTIBLE before doing the checks. | 1151 | * to TASK_INTERRUPTIBLE before doing the checks. |
1151 | */ | 1152 | */ |
1152 | set_current_state(TASK_INTERRUPTIBLE); | 1153 | set_current_state(TASK_INTERRUPTIBLE); |
1153 | if (!list_empty(&ep->rdllist) || !jtimeout) | 1154 | if (!list_empty(&ep->rdllist) || timed_out) |
1154 | break; | 1155 | break; |
1155 | if (signal_pending(current)) { | 1156 | if (signal_pending(current)) { |
1156 | res = -EINTR; | 1157 | res = -EINTR; |
@@ -1158,7 +1159,9 @@ retry: | |||
1158 | } | 1159 | } |
1159 | 1160 | ||
1160 | spin_unlock_irqrestore(&ep->lock, flags); | 1161 | spin_unlock_irqrestore(&ep->lock, flags); |
1161 | jtimeout = schedule_timeout(jtimeout); | 1162 | if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) |
1163 | timed_out = 1; | ||
1164 | |||
1162 | spin_lock_irqsave(&ep->lock, flags); | 1165 | spin_lock_irqsave(&ep->lock, flags); |
1163 | } | 1166 | } |
1164 | __remove_wait_queue(&ep->wq, &wait); | 1167 | __remove_wait_queue(&ep->wq, &wait); |
@@ -1176,7 +1179,7 @@ retry: | |||
1176 | * more luck. | 1179 | * more luck. |
1177 | */ | 1180 | */ |
1178 | if (!res && eavail && | 1181 | if (!res && eavail && |
1179 | !(res = ep_send_events(ep, events, maxevents)) && jtimeout) | 1182 | !(res = ep_send_events(ep, events, maxevents)) && !timed_out) |
1180 | goto retry; | 1183 | goto retry; |
1181 | 1184 | ||
1182 | return res; | 1185 | return res; |
@@ -66,6 +66,12 @@ char core_pattern[CORENAME_MAX_SIZE] = "core"; | |||
66 | unsigned int core_pipe_limit; | 66 | unsigned int core_pipe_limit; |
67 | int suid_dumpable = 0; | 67 | int suid_dumpable = 0; |
68 | 68 | ||
69 | struct core_name { | ||
70 | char *corename; | ||
71 | int used, size; | ||
72 | }; | ||
73 | static atomic_t call_count = ATOMIC_INIT(1); | ||
74 | |||
69 | /* The maximal length of core_pattern is also specified in sysctl.c */ | 75 | /* The maximal length of core_pattern is also specified in sysctl.c */ |
70 | 76 | ||
71 | static LIST_HEAD(formats); | 77 | static LIST_HEAD(formats); |
@@ -1003,7 +1009,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1003 | 1009 | ||
1004 | bprm->mm = NULL; /* We're using it now */ | 1010 | bprm->mm = NULL; /* We're using it now */ |
1005 | 1011 | ||
1006 | current->flags &= ~PF_RANDOMIZE; | 1012 | current->flags &= ~(PF_RANDOMIZE | PF_KTHREAD); |
1007 | flush_thread(); | 1013 | flush_thread(); |
1008 | current->personality &= ~bprm->per_clear; | 1014 | current->personality &= ~bprm->per_clear; |
1009 | 1015 | ||
@@ -1083,14 +1089,14 @@ EXPORT_SYMBOL(setup_new_exec); | |||
1083 | */ | 1089 | */ |
1084 | int prepare_bprm_creds(struct linux_binprm *bprm) | 1090 | int prepare_bprm_creds(struct linux_binprm *bprm) |
1085 | { | 1091 | { |
1086 | if (mutex_lock_interruptible(¤t->cred_guard_mutex)) | 1092 | if (mutex_lock_interruptible(¤t->signal->cred_guard_mutex)) |
1087 | return -ERESTARTNOINTR; | 1093 | return -ERESTARTNOINTR; |
1088 | 1094 | ||
1089 | bprm->cred = prepare_exec_creds(); | 1095 | bprm->cred = prepare_exec_creds(); |
1090 | if (likely(bprm->cred)) | 1096 | if (likely(bprm->cred)) |
1091 | return 0; | 1097 | return 0; |
1092 | 1098 | ||
1093 | mutex_unlock(¤t->cred_guard_mutex); | 1099 | mutex_unlock(¤t->signal->cred_guard_mutex); |
1094 | return -ENOMEM; | 1100 | return -ENOMEM; |
1095 | } | 1101 | } |
1096 | 1102 | ||
@@ -1098,7 +1104,7 @@ void free_bprm(struct linux_binprm *bprm) | |||
1098 | { | 1104 | { |
1099 | free_arg_pages(bprm); | 1105 | free_arg_pages(bprm); |
1100 | if (bprm->cred) { | 1106 | if (bprm->cred) { |
1101 | mutex_unlock(¤t->cred_guard_mutex); | 1107 | mutex_unlock(¤t->signal->cred_guard_mutex); |
1102 | abort_creds(bprm->cred); | 1108 | abort_creds(bprm->cred); |
1103 | } | 1109 | } |
1104 | kfree(bprm); | 1110 | kfree(bprm); |
@@ -1119,13 +1125,13 @@ void install_exec_creds(struct linux_binprm *bprm) | |||
1119 | * credentials; any time after this it may be unlocked. | 1125 | * credentials; any time after this it may be unlocked. |
1120 | */ | 1126 | */ |
1121 | security_bprm_committed_creds(bprm); | 1127 | security_bprm_committed_creds(bprm); |
1122 | mutex_unlock(¤t->cred_guard_mutex); | 1128 | mutex_unlock(¤t->signal->cred_guard_mutex); |
1123 | } | 1129 | } |
1124 | EXPORT_SYMBOL(install_exec_creds); | 1130 | EXPORT_SYMBOL(install_exec_creds); |
1125 | 1131 | ||
1126 | /* | 1132 | /* |
1127 | * determine how safe it is to execute the proposed program | 1133 | * determine how safe it is to execute the proposed program |
1128 | * - the caller must hold current->cred_guard_mutex to protect against | 1134 | * - the caller must hold ->cred_guard_mutex to protect against |
1129 | * PTRACE_ATTACH | 1135 | * PTRACE_ATTACH |
1130 | */ | 1136 | */ |
1131 | int check_unsafe_exec(struct linux_binprm *bprm) | 1137 | int check_unsafe_exec(struct linux_binprm *bprm) |
@@ -1406,7 +1412,6 @@ int do_execve(const char * filename, | |||
1406 | if (retval < 0) | 1412 | if (retval < 0) |
1407 | goto out; | 1413 | goto out; |
1408 | 1414 | ||
1409 | current->flags &= ~PF_KTHREAD; | ||
1410 | retval = search_binary_handler(bprm,regs); | 1415 | retval = search_binary_handler(bprm,regs); |
1411 | if (retval < 0) | 1416 | if (retval < 0) |
1412 | goto out; | 1417 | goto out; |
@@ -1459,127 +1464,148 @@ void set_binfmt(struct linux_binfmt *new) | |||
1459 | 1464 | ||
1460 | EXPORT_SYMBOL(set_binfmt); | 1465 | EXPORT_SYMBOL(set_binfmt); |
1461 | 1466 | ||
1467 | static int expand_corename(struct core_name *cn) | ||
1468 | { | ||
1469 | char *old_corename = cn->corename; | ||
1470 | |||
1471 | cn->size = CORENAME_MAX_SIZE * atomic_inc_return(&call_count); | ||
1472 | cn->corename = krealloc(old_corename, cn->size, GFP_KERNEL); | ||
1473 | |||
1474 | if (!cn->corename) { | ||
1475 | kfree(old_corename); | ||
1476 | return -ENOMEM; | ||
1477 | } | ||
1478 | |||
1479 | return 0; | ||
1480 | } | ||
1481 | |||
1482 | static int cn_printf(struct core_name *cn, const char *fmt, ...) | ||
1483 | { | ||
1484 | char *cur; | ||
1485 | int need; | ||
1486 | int ret; | ||
1487 | va_list arg; | ||
1488 | |||
1489 | va_start(arg, fmt); | ||
1490 | need = vsnprintf(NULL, 0, fmt, arg); | ||
1491 | va_end(arg); | ||
1492 | |||
1493 | if (likely(need < cn->size - cn->used - 1)) | ||
1494 | goto out_printf; | ||
1495 | |||
1496 | ret = expand_corename(cn); | ||
1497 | if (ret) | ||
1498 | goto expand_fail; | ||
1499 | |||
1500 | out_printf: | ||
1501 | cur = cn->corename + cn->used; | ||
1502 | va_start(arg, fmt); | ||
1503 | vsnprintf(cur, need + 1, fmt, arg); | ||
1504 | va_end(arg); | ||
1505 | cn->used += need; | ||
1506 | return 0; | ||
1507 | |||
1508 | expand_fail: | ||
1509 | return ret; | ||
1510 | } | ||
1511 | |||
1462 | /* format_corename will inspect the pattern parameter, and output a | 1512 | /* format_corename will inspect the pattern parameter, and output a |
1463 | * name into corename, which must have space for at least | 1513 | * name into corename, which must have space for at least |
1464 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. | 1514 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. |
1465 | */ | 1515 | */ |
1466 | static int format_corename(char *corename, long signr) | 1516 | static int format_corename(struct core_name *cn, long signr) |
1467 | { | 1517 | { |
1468 | const struct cred *cred = current_cred(); | 1518 | const struct cred *cred = current_cred(); |
1469 | const char *pat_ptr = core_pattern; | 1519 | const char *pat_ptr = core_pattern; |
1470 | int ispipe = (*pat_ptr == '|'); | 1520 | int ispipe = (*pat_ptr == '|'); |
1471 | char *out_ptr = corename; | ||
1472 | char *const out_end = corename + CORENAME_MAX_SIZE; | ||
1473 | int rc; | ||
1474 | int pid_in_pattern = 0; | 1521 | int pid_in_pattern = 0; |
1522 | int err = 0; | ||
1523 | |||
1524 | cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count); | ||
1525 | cn->corename = kmalloc(cn->size, GFP_KERNEL); | ||
1526 | cn->used = 0; | ||
1527 | |||
1528 | if (!cn->corename) | ||
1529 | return -ENOMEM; | ||
1475 | 1530 | ||
1476 | /* Repeat as long as we have more pattern to process and more output | 1531 | /* Repeat as long as we have more pattern to process and more output |
1477 | space */ | 1532 | space */ |
1478 | while (*pat_ptr) { | 1533 | while (*pat_ptr) { |
1479 | if (*pat_ptr != '%') { | 1534 | if (*pat_ptr != '%') { |
1480 | if (out_ptr == out_end) | 1535 | if (*pat_ptr == 0) |
1481 | goto out; | 1536 | goto out; |
1482 | *out_ptr++ = *pat_ptr++; | 1537 | err = cn_printf(cn, "%c", *pat_ptr++); |
1483 | } else { | 1538 | } else { |
1484 | switch (*++pat_ptr) { | 1539 | switch (*++pat_ptr) { |
1540 | /* single % at the end, drop that */ | ||
1485 | case 0: | 1541 | case 0: |
1486 | goto out; | 1542 | goto out; |
1487 | /* Double percent, output one percent */ | 1543 | /* Double percent, output one percent */ |
1488 | case '%': | 1544 | case '%': |
1489 | if (out_ptr == out_end) | 1545 | err = cn_printf(cn, "%c", '%'); |
1490 | goto out; | ||
1491 | *out_ptr++ = '%'; | ||
1492 | break; | 1546 | break; |
1493 | /* pid */ | 1547 | /* pid */ |
1494 | case 'p': | 1548 | case 'p': |
1495 | pid_in_pattern = 1; | 1549 | pid_in_pattern = 1; |
1496 | rc = snprintf(out_ptr, out_end - out_ptr, | 1550 | err = cn_printf(cn, "%d", |
1497 | "%d", task_tgid_vnr(current)); | 1551 | task_tgid_vnr(current)); |
1498 | if (rc > out_end - out_ptr) | ||
1499 | goto out; | ||
1500 | out_ptr += rc; | ||
1501 | break; | 1552 | break; |
1502 | /* uid */ | 1553 | /* uid */ |
1503 | case 'u': | 1554 | case 'u': |
1504 | rc = snprintf(out_ptr, out_end - out_ptr, | 1555 | err = cn_printf(cn, "%d", cred->uid); |
1505 | "%d", cred->uid); | ||
1506 | if (rc > out_end - out_ptr) | ||
1507 | goto out; | ||
1508 | out_ptr += rc; | ||
1509 | break; | 1556 | break; |
1510 | /* gid */ | 1557 | /* gid */ |
1511 | case 'g': | 1558 | case 'g': |
1512 | rc = snprintf(out_ptr, out_end - out_ptr, | 1559 | err = cn_printf(cn, "%d", cred->gid); |
1513 | "%d", cred->gid); | ||
1514 | if (rc > out_end - out_ptr) | ||
1515 | goto out; | ||
1516 | out_ptr += rc; | ||
1517 | break; | 1560 | break; |
1518 | /* signal that caused the coredump */ | 1561 | /* signal that caused the coredump */ |
1519 | case 's': | 1562 | case 's': |
1520 | rc = snprintf(out_ptr, out_end - out_ptr, | 1563 | err = cn_printf(cn, "%ld", signr); |
1521 | "%ld", signr); | ||
1522 | if (rc > out_end - out_ptr) | ||
1523 | goto out; | ||
1524 | out_ptr += rc; | ||
1525 | break; | 1564 | break; |
1526 | /* UNIX time of coredump */ | 1565 | /* UNIX time of coredump */ |
1527 | case 't': { | 1566 | case 't': { |
1528 | struct timeval tv; | 1567 | struct timeval tv; |
1529 | do_gettimeofday(&tv); | 1568 | do_gettimeofday(&tv); |
1530 | rc = snprintf(out_ptr, out_end - out_ptr, | 1569 | err = cn_printf(cn, "%lu", tv.tv_sec); |
1531 | "%lu", tv.tv_sec); | ||
1532 | if (rc > out_end - out_ptr) | ||
1533 | goto out; | ||
1534 | out_ptr += rc; | ||
1535 | break; | 1570 | break; |
1536 | } | 1571 | } |
1537 | /* hostname */ | 1572 | /* hostname */ |
1538 | case 'h': | 1573 | case 'h': |
1539 | down_read(&uts_sem); | 1574 | down_read(&uts_sem); |
1540 | rc = snprintf(out_ptr, out_end - out_ptr, | 1575 | err = cn_printf(cn, "%s", |
1541 | "%s", utsname()->nodename); | 1576 | utsname()->nodename); |
1542 | up_read(&uts_sem); | 1577 | up_read(&uts_sem); |
1543 | if (rc > out_end - out_ptr) | ||
1544 | goto out; | ||
1545 | out_ptr += rc; | ||
1546 | break; | 1578 | break; |
1547 | /* executable */ | 1579 | /* executable */ |
1548 | case 'e': | 1580 | case 'e': |
1549 | rc = snprintf(out_ptr, out_end - out_ptr, | 1581 | err = cn_printf(cn, "%s", current->comm); |
1550 | "%s", current->comm); | ||
1551 | if (rc > out_end - out_ptr) | ||
1552 | goto out; | ||
1553 | out_ptr += rc; | ||
1554 | break; | 1582 | break; |
1555 | /* core limit size */ | 1583 | /* core limit size */ |
1556 | case 'c': | 1584 | case 'c': |
1557 | rc = snprintf(out_ptr, out_end - out_ptr, | 1585 | err = cn_printf(cn, "%lu", |
1558 | "%lu", rlimit(RLIMIT_CORE)); | 1586 | rlimit(RLIMIT_CORE)); |
1559 | if (rc > out_end - out_ptr) | ||
1560 | goto out; | ||
1561 | out_ptr += rc; | ||
1562 | break; | 1587 | break; |
1563 | default: | 1588 | default: |
1564 | break; | 1589 | break; |
1565 | } | 1590 | } |
1566 | ++pat_ptr; | 1591 | ++pat_ptr; |
1567 | } | 1592 | } |
1593 | |||
1594 | if (err) | ||
1595 | return err; | ||
1568 | } | 1596 | } |
1597 | |||
1569 | /* Backward compatibility with core_uses_pid: | 1598 | /* Backward compatibility with core_uses_pid: |
1570 | * | 1599 | * |
1571 | * If core_pattern does not include a %p (as is the default) | 1600 | * If core_pattern does not include a %p (as is the default) |
1572 | * and core_uses_pid is set, then .%pid will be appended to | 1601 | * and core_uses_pid is set, then .%pid will be appended to |
1573 | * the filename. Do not do this for piped commands. */ | 1602 | * the filename. Do not do this for piped commands. */ |
1574 | if (!ispipe && !pid_in_pattern && core_uses_pid) { | 1603 | if (!ispipe && !pid_in_pattern && core_uses_pid) { |
1575 | rc = snprintf(out_ptr, out_end - out_ptr, | 1604 | err = cn_printf(cn, ".%d", task_tgid_vnr(current)); |
1576 | ".%d", task_tgid_vnr(current)); | 1605 | if (err) |
1577 | if (rc > out_end - out_ptr) | 1606 | return err; |
1578 | goto out; | ||
1579 | out_ptr += rc; | ||
1580 | } | 1607 | } |
1581 | out: | 1608 | out: |
1582 | *out_ptr = 0; | ||
1583 | return ispipe; | 1609 | return ispipe; |
1584 | } | 1610 | } |
1585 | 1611 | ||
@@ -1856,7 +1882,7 @@ static int umh_pipe_setup(struct subprocess_info *info) | |||
1856 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) | 1882 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) |
1857 | { | 1883 | { |
1858 | struct core_state core_state; | 1884 | struct core_state core_state; |
1859 | char corename[CORENAME_MAX_SIZE + 1]; | 1885 | struct core_name cn; |
1860 | struct mm_struct *mm = current->mm; | 1886 | struct mm_struct *mm = current->mm; |
1861 | struct linux_binfmt * binfmt; | 1887 | struct linux_binfmt * binfmt; |
1862 | const struct cred *old_cred; | 1888 | const struct cred *old_cred; |
@@ -1911,7 +1937,13 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1911 | */ | 1937 | */ |
1912 | clear_thread_flag(TIF_SIGPENDING); | 1938 | clear_thread_flag(TIF_SIGPENDING); |
1913 | 1939 | ||
1914 | ispipe = format_corename(corename, signr); | 1940 | ispipe = format_corename(&cn, signr); |
1941 | |||
1942 | if (ispipe == -ENOMEM) { | ||
1943 | printk(KERN_WARNING "format_corename failed\n"); | ||
1944 | printk(KERN_WARNING "Aborting core\n"); | ||
1945 | goto fail_corename; | ||
1946 | } | ||
1915 | 1947 | ||
1916 | if (ispipe) { | 1948 | if (ispipe) { |
1917 | int dump_count; | 1949 | int dump_count; |
@@ -1948,7 +1980,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1948 | goto fail_dropcount; | 1980 | goto fail_dropcount; |
1949 | } | 1981 | } |
1950 | 1982 | ||
1951 | helper_argv = argv_split(GFP_KERNEL, corename+1, NULL); | 1983 | helper_argv = argv_split(GFP_KERNEL, cn.corename+1, NULL); |
1952 | if (!helper_argv) { | 1984 | if (!helper_argv) { |
1953 | printk(KERN_WARNING "%s failed to allocate memory\n", | 1985 | printk(KERN_WARNING "%s failed to allocate memory\n", |
1954 | __func__); | 1986 | __func__); |
@@ -1961,7 +1993,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1961 | argv_free(helper_argv); | 1993 | argv_free(helper_argv); |
1962 | if (retval) { | 1994 | if (retval) { |
1963 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1995 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1964 | corename); | 1996 | cn.corename); |
1965 | goto close_fail; | 1997 | goto close_fail; |
1966 | } | 1998 | } |
1967 | } else { | 1999 | } else { |
@@ -1970,7 +2002,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1970 | if (cprm.limit < binfmt->min_coredump) | 2002 | if (cprm.limit < binfmt->min_coredump) |
1971 | goto fail_unlock; | 2003 | goto fail_unlock; |
1972 | 2004 | ||
1973 | cprm.file = filp_open(corename, | 2005 | cprm.file = filp_open(cn.corename, |
1974 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, | 2006 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1975 | 0600); | 2007 | 0600); |
1976 | if (IS_ERR(cprm.file)) | 2008 | if (IS_ERR(cprm.file)) |
@@ -2012,6 +2044,8 @@ fail_dropcount: | |||
2012 | if (ispipe) | 2044 | if (ispipe) |
2013 | atomic_dec(&core_dump_count); | 2045 | atomic_dec(&core_dump_count); |
2014 | fail_unlock: | 2046 | fail_unlock: |
2047 | kfree(cn.corename); | ||
2048 | fail_corename: | ||
2015 | coredump_finish(mm); | 2049 | coredump_finish(mm); |
2016 | revert_creds(old_cred); | 2050 | revert_creds(old_cred); |
2017 | fail_creds: | 2051 | fail_creds: |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index b98664275f02..6e07696308dc 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -1334,12 +1334,7 @@ out_finish: | |||
1334 | 1334 | ||
1335 | static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) | 1335 | static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) |
1336 | { | 1336 | { |
1337 | int i; | 1337 | release_pages(req->pages, req->num_pages, 0); |
1338 | |||
1339 | for (i = 0; i < req->num_pages; i++) { | ||
1340 | struct page *page = req->pages[i]; | ||
1341 | page_cache_release(page); | ||
1342 | } | ||
1343 | } | 1338 | } |
1344 | 1339 | ||
1345 | static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | 1340 | static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 60c2b944d762..79cf7f616bbe 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -544,6 +544,34 @@ static unsigned int isofs_get_last_session(struct super_block *sb, s32 session) | |||
544 | } | 544 | } |
545 | 545 | ||
546 | /* | 546 | /* |
547 | * Check if root directory is empty (has less than 3 files). | ||
548 | * | ||
549 | * Used to detect broken CDs where ISO root directory is empty but Joliet root | ||
550 | * directory is OK. If such CD has Rock Ridge extensions, they will be disabled | ||
551 | * (and Joliet used instead) or else no files would be visible. | ||
552 | */ | ||
553 | static bool rootdir_empty(struct super_block *sb, unsigned long block) | ||
554 | { | ||
555 | int offset = 0, files = 0, de_len; | ||
556 | struct iso_directory_record *de; | ||
557 | struct buffer_head *bh; | ||
558 | |||
559 | bh = sb_bread(sb, block); | ||
560 | if (!bh) | ||
561 | return true; | ||
562 | while (files < 3) { | ||
563 | de = (struct iso_directory_record *) (bh->b_data + offset); | ||
564 | de_len = *(unsigned char *) de; | ||
565 | if (de_len == 0) | ||
566 | break; | ||
567 | files++; | ||
568 | offset += de_len; | ||
569 | } | ||
570 | brelse(bh); | ||
571 | return files < 3; | ||
572 | } | ||
573 | |||
574 | /* | ||
547 | * Initialize the superblock and read the root inode. | 575 | * Initialize the superblock and read the root inode. |
548 | * | 576 | * |
549 | * Note: a check_disk_change() has been done immediately prior | 577 | * Note: a check_disk_change() has been done immediately prior |
@@ -843,6 +871,18 @@ root_found: | |||
843 | goto out_no_root; | 871 | goto out_no_root; |
844 | 872 | ||
845 | /* | 873 | /* |
874 | * Fix for broken CDs with Rock Ridge and empty ISO root directory but | ||
875 | * correct Joliet root directory. | ||
876 | */ | ||
877 | if (sbi->s_rock == 1 && joliet_level && | ||
878 | rootdir_empty(s, sbi->s_firstdatazone)) { | ||
879 | printk(KERN_NOTICE | ||
880 | "ISOFS: primary root directory is empty. " | ||
881 | "Disabling Rock Ridge and switching to Joliet."); | ||
882 | sbi->s_rock = 0; | ||
883 | } | ||
884 | |||
885 | /* | ||
846 | * If this disk has both Rock Ridge and Joliet on it, then we | 886 | * If this disk has both Rock Ridge and Joliet on it, then we |
847 | * want to use Rock Ridge by default. This can be overridden | 887 | * want to use Rock Ridge by default. This can be overridden |
848 | * by using the norock mount option. There is still one other | 888 | * by using the norock mount option. There is still one other |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 9b094c1c8465..f3d02ca461ec 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -226,7 +226,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task) | |||
226 | { | 226 | { |
227 | struct mm_struct *mm; | 227 | struct mm_struct *mm; |
228 | 228 | ||
229 | if (mutex_lock_killable(&task->cred_guard_mutex)) | 229 | if (mutex_lock_killable(&task->signal->cred_guard_mutex)) |
230 | return NULL; | 230 | return NULL; |
231 | 231 | ||
232 | mm = get_task_mm(task); | 232 | mm = get_task_mm(task); |
@@ -235,7 +235,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task) | |||
235 | mmput(mm); | 235 | mmput(mm); |
236 | mm = NULL; | 236 | mm = NULL; |
237 | } | 237 | } |
238 | mutex_unlock(&task->cred_guard_mutex); | 238 | mutex_unlock(&task->signal->cred_guard_mutex); |
239 | 239 | ||
240 | return mm; | 240 | return mm; |
241 | } | 241 | } |
@@ -2354,14 +2354,14 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, | |||
2354 | goto out_free; | 2354 | goto out_free; |
2355 | 2355 | ||
2356 | /* Guard against adverse ptrace interaction */ | 2356 | /* Guard against adverse ptrace interaction */ |
2357 | length = mutex_lock_interruptible(&task->cred_guard_mutex); | 2357 | length = mutex_lock_interruptible(&task->signal->cred_guard_mutex); |
2358 | if (length < 0) | 2358 | if (length < 0) |
2359 | goto out_free; | 2359 | goto out_free; |
2360 | 2360 | ||
2361 | length = security_setprocattr(task, | 2361 | length = security_setprocattr(task, |
2362 | (char*)file->f_path.dentry->d_name.name, | 2362 | (char*)file->f_path.dentry->d_name.name, |
2363 | (void*)page, count); | 2363 | (void*)page, count); |
2364 | mutex_unlock(&task->cred_guard_mutex); | 2364 | mutex_unlock(&task->signal->cred_guard_mutex); |
2365 | out_free: | 2365 | out_free: |
2366 | free_page((unsigned long) page); | 2366 | free_page((unsigned long) page); |
2367 | out: | 2367 | out: |
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c index 1807c2419f17..37994737c983 100644 --- a/fs/proc/softirqs.c +++ b/fs/proc/softirqs.c | |||
@@ -10,13 +10,13 @@ static int show_softirqs(struct seq_file *p, void *v) | |||
10 | { | 10 | { |
11 | int i, j; | 11 | int i, j; |
12 | 12 | ||
13 | seq_printf(p, " "); | 13 | seq_printf(p, " "); |
14 | for_each_possible_cpu(i) | 14 | for_each_possible_cpu(i) |
15 | seq_printf(p, "CPU%-8d", i); | 15 | seq_printf(p, "CPU%-8d", i); |
16 | seq_printf(p, "\n"); | 16 | seq_printf(p, "\n"); |
17 | 17 | ||
18 | for (i = 0; i < NR_SOFTIRQS; i++) { | 18 | for (i = 0; i < NR_SOFTIRQS; i++) { |
19 | seq_printf(p, "%8s:", softirq_to_name[i]); | 19 | seq_printf(p, "%12s:", softirq_to_name[i]); |
20 | for_each_possible_cpu(j) | 20 | for_each_possible_cpu(j) |
21 | seq_printf(p, " %10u", kstat_softirqs_cpu(i, j)); | 21 | seq_printf(p, " %10u", kstat_softirqs_cpu(i, j)); |
22 | seq_printf(p, "\n"); | 22 | seq_printf(p, "\n"); |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index bf31b03fc275..e15a19c93bae 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -31,7 +31,6 @@ static int show_stat(struct seq_file *p, void *v) | |||
31 | u64 sum_softirq = 0; | 31 | u64 sum_softirq = 0; |
32 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; | 32 | unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; |
33 | struct timespec boottime; | 33 | struct timespec boottime; |
34 | unsigned int per_irq_sum; | ||
35 | 34 | ||
36 | user = nice = system = idle = iowait = | 35 | user = nice = system = idle = iowait = |
37 | irq = softirq = steal = cputime64_zero; | 36 | irq = softirq = steal = cputime64_zero; |
@@ -52,9 +51,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
52 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); | 51 | guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); |
53 | guest_nice = cputime64_add(guest_nice, | 52 | guest_nice = cputime64_add(guest_nice, |
54 | kstat_cpu(i).cpustat.guest_nice); | 53 | kstat_cpu(i).cpustat.guest_nice); |
55 | for_each_irq_nr(j) { | 54 | sum += kstat_cpu_irqs_sum(i); |
56 | sum += kstat_irqs_cpu(j, i); | ||
57 | } | ||
58 | sum += arch_irq_stat_cpu(i); | 55 | sum += arch_irq_stat_cpu(i); |
59 | 56 | ||
60 | for (j = 0; j < NR_SOFTIRQS; j++) { | 57 | for (j = 0; j < NR_SOFTIRQS; j++) { |
@@ -110,13 +107,8 @@ static int show_stat(struct seq_file *p, void *v) | |||
110 | seq_printf(p, "intr %llu", (unsigned long long)sum); | 107 | seq_printf(p, "intr %llu", (unsigned long long)sum); |
111 | 108 | ||
112 | /* sum again ? it could be updated? */ | 109 | /* sum again ? it could be updated? */ |
113 | for_each_irq_nr(j) { | 110 | for_each_irq_nr(j) |
114 | per_irq_sum = 0; | 111 | seq_printf(p, " %u", kstat_irqs(j)); |
115 | for_each_possible_cpu(i) | ||
116 | per_irq_sum += kstat_irqs_cpu(j, i); | ||
117 | |||
118 | seq_printf(p, " %u", per_irq_sum); | ||
119 | } | ||
120 | 112 | ||
121 | seq_printf(p, | 113 | seq_printf(p, |
122 | "\nctxt %llu\n" | 114 | "\nctxt %llu\n" |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 871e25ed0069..da6b01d70f01 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -327,6 +327,7 @@ struct mem_size_stats { | |||
327 | unsigned long private_clean; | 327 | unsigned long private_clean; |
328 | unsigned long private_dirty; | 328 | unsigned long private_dirty; |
329 | unsigned long referenced; | 329 | unsigned long referenced; |
330 | unsigned long anonymous; | ||
330 | unsigned long swap; | 331 | unsigned long swap; |
331 | u64 pss; | 332 | u64 pss; |
332 | }; | 333 | }; |
@@ -357,6 +358,9 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
357 | if (!page) | 358 | if (!page) |
358 | continue; | 359 | continue; |
359 | 360 | ||
361 | if (PageAnon(page)) | ||
362 | mss->anonymous += PAGE_SIZE; | ||
363 | |||
360 | mss->resident += PAGE_SIZE; | 364 | mss->resident += PAGE_SIZE; |
361 | /* Accumulate the size in pages that have been accessed. */ | 365 | /* Accumulate the size in pages that have been accessed. */ |
362 | if (pte_young(ptent) || PageReferenced(page)) | 366 | if (pte_young(ptent) || PageReferenced(page)) |
@@ -410,6 +414,7 @@ static int show_smap(struct seq_file *m, void *v) | |||
410 | "Private_Clean: %8lu kB\n" | 414 | "Private_Clean: %8lu kB\n" |
411 | "Private_Dirty: %8lu kB\n" | 415 | "Private_Dirty: %8lu kB\n" |
412 | "Referenced: %8lu kB\n" | 416 | "Referenced: %8lu kB\n" |
417 | "Anonymous: %8lu kB\n" | ||
413 | "Swap: %8lu kB\n" | 418 | "Swap: %8lu kB\n" |
414 | "KernelPageSize: %8lu kB\n" | 419 | "KernelPageSize: %8lu kB\n" |
415 | "MMUPageSize: %8lu kB\n", | 420 | "MMUPageSize: %8lu kB\n", |
@@ -421,6 +426,7 @@ static int show_smap(struct seq_file *m, void *v) | |||
421 | mss.private_clean >> 10, | 426 | mss.private_clean >> 10, |
422 | mss.private_dirty >> 10, | 427 | mss.private_dirty >> 10, |
423 | mss.referenced >> 10, | 428 | mss.referenced >> 10, |
429 | mss.anonymous >> 10, | ||
424 | mss.swap >> 10, | 430 | mss.swap >> 10, |
425 | vma_kernel_pagesize(vma) >> 10, | 431 | vma_kernel_pagesize(vma) >> 10, |
426 | vma_mmu_pagesize(vma) >> 10); | 432 | vma_mmu_pagesize(vma) >> 10); |
diff --git a/fs/select.c b/fs/select.c index 500a669f7790..b7b10aa30861 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -67,7 +67,7 @@ static long __estimate_accuracy(struct timespec *tv) | |||
67 | return slack; | 67 | return slack; |
68 | } | 68 | } |
69 | 69 | ||
70 | static long estimate_accuracy(struct timespec *tv) | 70 | long select_estimate_accuracy(struct timespec *tv) |
71 | { | 71 | { |
72 | unsigned long ret; | 72 | unsigned long ret; |
73 | struct timespec now; | 73 | struct timespec now; |
@@ -417,7 +417,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
417 | } | 417 | } |
418 | 418 | ||
419 | if (end_time && !timed_out) | 419 | if (end_time && !timed_out) |
420 | slack = estimate_accuracy(end_time); | 420 | slack = select_estimate_accuracy(end_time); |
421 | 421 | ||
422 | retval = 0; | 422 | retval = 0; |
423 | for (;;) { | 423 | for (;;) { |
@@ -769,7 +769,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
769 | } | 769 | } |
770 | 770 | ||
771 | if (end_time && !timed_out) | 771 | if (end_time && !timed_out) |
772 | slack = estimate_accuracy(end_time); | 772 | slack = select_estimate_accuracy(end_time); |
773 | 773 | ||
774 | for (;;) { | 774 | for (;;) { |
775 | struct poll_list *walk; | 775 | struct poll_list *walk; |
diff --git a/include/asm-generic/cputime.h b/include/asm-generic/cputime.h index ca0f239f0e13..2bcc5c7c22a6 100644 --- a/include/asm-generic/cputime.h +++ b/include/asm-generic/cputime.h | |||
@@ -33,10 +33,10 @@ typedef u64 cputime64_t; | |||
33 | 33 | ||
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Convert cputime to milliseconds and back. | 36 | * Convert cputime to microseconds and back. |
37 | */ | 37 | */ |
38 | #define cputime_to_msecs(__ct) jiffies_to_msecs(__ct) | 38 | #define cputime_to_usecs(__ct) jiffies_to_usecs(__ct); |
39 | #define msecs_to_cputime(__msecs) msecs_to_jiffies(__msecs) | 39 | #define usecs_to_cputime(__msecs) usecs_to_jiffies(__msecs); |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * Convert cputime to seconds and back. | 42 | * Convert cputime to seconds and back. |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 8ca18e26d7e3..ff5c66080c8c 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -210,7 +210,7 @@ extern void gpio_unexport(unsigned gpio); | |||
210 | 210 | ||
211 | #endif /* CONFIG_GPIO_SYSFS */ | 211 | #endif /* CONFIG_GPIO_SYSFS */ |
212 | 212 | ||
213 | #else /* !CONFIG_HAVE_GPIO_LIB */ | 213 | #else /* !CONFIG_GPIOLIB */ |
214 | 214 | ||
215 | static inline int gpio_is_valid(int number) | 215 | static inline int gpio_is_valid(int number) |
216 | { | 216 | { |
@@ -239,7 +239,7 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value) | |||
239 | gpio_set_value(gpio, value); | 239 | gpio_set_value(gpio, value); |
240 | } | 240 | } |
241 | 241 | ||
242 | #endif /* !CONFIG_HAVE_GPIO_LIB */ | 242 | #endif /* !CONFIG_GPIOLIB */ |
243 | 243 | ||
244 | #ifndef CONFIG_GPIO_SYSFS | 244 | #ifndef CONFIG_GPIO_SYSFS |
245 | 245 | ||
diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h new file mode 100644 index 000000000000..198087a16fc4 --- /dev/null +++ b/include/linux/basic_mmio_gpio.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Basic memory-mapped GPIO controllers. | ||
3 | * | ||
4 | * Copyright 2008 MontaVista Software, Inc. | ||
5 | * Copyright 2008,2010 Anton Vorontsov <cbouatmailru@gmail.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef __BASIC_MMIO_GPIO_H | ||
14 | #define __BASIC_MMIO_GPIO_H | ||
15 | |||
16 | struct bgpio_pdata { | ||
17 | int base; | ||
18 | }; | ||
19 | |||
20 | #endif /* __BASIC_MMIO_GPIO_H */ | ||
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 709dfb901d11..ed4ba111bc8d 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h | |||
@@ -154,6 +154,10 @@ enum { | |||
154 | * A thread in rmdir() is wating for this cgroup. | 154 | * A thread in rmdir() is wating for this cgroup. |
155 | */ | 155 | */ |
156 | CGRP_WAIT_ON_RMDIR, | 156 | CGRP_WAIT_ON_RMDIR, |
157 | /* | ||
158 | * Clone cgroup values when creating a new child cgroup | ||
159 | */ | ||
160 | CGRP_CLONE_CHILDREN, | ||
157 | }; | 161 | }; |
158 | 162 | ||
159 | /* which pidlist file are we talking about? */ | 163 | /* which pidlist file are we talking about? */ |
diff --git a/include/linux/fb.h b/include/linux/fb.h index f0268deca658..7fca3dc4e475 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -931,6 +931,8 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { | |||
931 | #define fb_writel sbus_writel | 931 | #define fb_writel sbus_writel |
932 | #define fb_writeq sbus_writeq | 932 | #define fb_writeq sbus_writeq |
933 | #define fb_memset sbus_memset_io | 933 | #define fb_memset sbus_memset_io |
934 | #define fb_memcpy_fromfb sbus_memcpy_fromio | ||
935 | #define fb_memcpy_tofb sbus_memcpy_toio | ||
934 | 936 | ||
935 | #elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) | 937 | #elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) |
936 | 938 | ||
@@ -943,6 +945,8 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { | |||
943 | #define fb_writel __raw_writel | 945 | #define fb_writel __raw_writel |
944 | #define fb_writeq __raw_writeq | 946 | #define fb_writeq __raw_writeq |
945 | #define fb_memset memset_io | 947 | #define fb_memset memset_io |
948 | #define fb_memcpy_fromfb memcpy_fromio | ||
949 | #define fb_memcpy_tofb memcpy_toio | ||
946 | 950 | ||
947 | #else | 951 | #else |
948 | 952 | ||
@@ -955,6 +959,8 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { | |||
955 | #define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b)) | 959 | #define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b)) |
956 | #define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b)) | 960 | #define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b)) |
957 | #define fb_memset memset | 961 | #define fb_memset memset |
962 | #define fb_memcpy_fromfb memcpy | ||
963 | #define fb_memcpy_tofb memcpy | ||
958 | 964 | ||
959 | #endif | 965 | #endif |
960 | 966 | ||
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 8a85ec109a3a..e9138198e823 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -37,27 +37,6 @@ extern unsigned long totalhigh_pages; | |||
37 | 37 | ||
38 | void kmap_flush_unused(void); | 38 | void kmap_flush_unused(void); |
39 | 39 | ||
40 | DECLARE_PER_CPU(int, __kmap_atomic_idx); | ||
41 | |||
42 | static inline int kmap_atomic_idx_push(void) | ||
43 | { | ||
44 | int idx = __get_cpu_var(__kmap_atomic_idx)++; | ||
45 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
46 | WARN_ON_ONCE(in_irq() && !irqs_disabled()); | ||
47 | BUG_ON(idx > KM_TYPE_NR); | ||
48 | #endif | ||
49 | return idx; | ||
50 | } | ||
51 | |||
52 | static inline int kmap_atomic_idx_pop(void) | ||
53 | { | ||
54 | int idx = --__get_cpu_var(__kmap_atomic_idx); | ||
55 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
56 | BUG_ON(idx < 0); | ||
57 | #endif | ||
58 | return idx; | ||
59 | } | ||
60 | |||
61 | #else /* CONFIG_HIGHMEM */ | 40 | #else /* CONFIG_HIGHMEM */ |
62 | 41 | ||
63 | static inline unsigned int nr_free_highpages(void) { return 0; } | 42 | static inline unsigned int nr_free_highpages(void) { return 0; } |
@@ -95,6 +74,36 @@ static inline void __kunmap_atomic(void *addr) | |||
95 | 74 | ||
96 | #endif /* CONFIG_HIGHMEM */ | 75 | #endif /* CONFIG_HIGHMEM */ |
97 | 76 | ||
77 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32) | ||
78 | |||
79 | DECLARE_PER_CPU(int, __kmap_atomic_idx); | ||
80 | |||
81 | static inline int kmap_atomic_idx_push(void) | ||
82 | { | ||
83 | int idx = __get_cpu_var(__kmap_atomic_idx)++; | ||
84 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
85 | WARN_ON_ONCE(in_irq() && !irqs_disabled()); | ||
86 | BUG_ON(idx > KM_TYPE_NR); | ||
87 | #endif | ||
88 | return idx; | ||
89 | } | ||
90 | |||
91 | static inline int kmap_atomic_idx(void) | ||
92 | { | ||
93 | return __get_cpu_var(__kmap_atomic_idx) - 1; | ||
94 | } | ||
95 | |||
96 | static inline int kmap_atomic_idx_pop(void) | ||
97 | { | ||
98 | int idx = --__get_cpu_var(__kmap_atomic_idx); | ||
99 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
100 | BUG_ON(idx < 0); | ||
101 | #endif | ||
102 | return idx; | ||
103 | } | ||
104 | |||
105 | #endif | ||
106 | |||
98 | /* | 107 | /* |
99 | * Make both: kmap_atomic(page, idx) and kmap_atomic(page) work. | 108 | * Make both: kmap_atomic(page, idx) and kmap_atomic(page) work. |
100 | */ | 109 | */ |
diff --git a/include/linux/i2c/adp5588.h b/include/linux/i2c/adp5588.h index 269181b8f623..3c5d6b6e765c 100644 --- a/include/linux/i2c/adp5588.h +++ b/include/linux/i2c/adp5588.h | |||
@@ -74,6 +74,20 @@ | |||
74 | 74 | ||
75 | #define ADP5588_DEVICE_ID_MASK 0xF | 75 | #define ADP5588_DEVICE_ID_MASK 0xF |
76 | 76 | ||
77 | /* Configuration Register1 */ | ||
78 | #define ADP5588_AUTO_INC (1 << 7) | ||
79 | #define ADP5588_GPIEM_CFG (1 << 6) | ||
80 | #define ADP5588_INT_CFG (1 << 4) | ||
81 | #define ADP5588_GPI_IEN (1 << 1) | ||
82 | |||
83 | /* Interrupt Status Register */ | ||
84 | #define ADP5588_GPI_INT (1 << 1) | ||
85 | #define ADP5588_KE_INT (1 << 0) | ||
86 | |||
87 | #define ADP5588_MAXGPIO 18 | ||
88 | #define ADP5588_BANK(offs) ((offs) >> 3) | ||
89 | #define ADP5588_BIT(offs) (1u << ((offs) & 0x7)) | ||
90 | |||
77 | /* Put one of these structures in i2c_board_info platform_data */ | 91 | /* Put one of these structures in i2c_board_info platform_data */ |
78 | 92 | ||
79 | #define ADP5588_KEYMAPSIZE 80 | 93 | #define ADP5588_KEYMAPSIZE 80 |
@@ -126,9 +140,12 @@ struct adp5588_kpad_platform_data { | |||
126 | const struct adp5588_gpio_platform_data *gpio_data; | 140 | const struct adp5588_gpio_platform_data *gpio_data; |
127 | }; | 141 | }; |
128 | 142 | ||
143 | struct i2c_client; /* forward declaration */ | ||
144 | |||
129 | struct adp5588_gpio_platform_data { | 145 | struct adp5588_gpio_platform_data { |
130 | unsigned gpio_start; /* GPIO Chip base # */ | 146 | int gpio_start; /* GPIO Chip base # */ |
131 | unsigned pullup_dis_mask; /* Pull-Up Disable Mask */ | 147 | unsigned irq_base; /* interrupt base # */ |
148 | unsigned pullup_dis_mask; /* Pull-Up Disable Mask */ | ||
132 | int (*setup)(struct i2c_client *client, | 149 | int (*setup)(struct i2c_client *client, |
133 | int gpio, unsigned ngpio, | 150 | int gpio, unsigned ngpio, |
134 | void *context); | 151 | void *context); |
diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 2fea6c8ef6ba..1f8c06ce0fa6 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h | |||
@@ -29,6 +29,8 @@ extern struct fs_struct init_fs; | |||
29 | .running = 0, \ | 29 | .running = 0, \ |
30 | .lock = __SPIN_LOCK_UNLOCKED(sig.cputimer.lock), \ | 30 | .lock = __SPIN_LOCK_UNLOCKED(sig.cputimer.lock), \ |
31 | }, \ | 31 | }, \ |
32 | .cred_guard_mutex = \ | ||
33 | __MUTEX_INITIALIZER(sig.cred_guard_mutex), \ | ||
32 | } | 34 | } |
33 | 35 | ||
34 | extern struct nsproxy init_nsproxy; | 36 | extern struct nsproxy init_nsproxy; |
@@ -145,8 +147,6 @@ extern struct cred init_cred; | |||
145 | .group_leader = &tsk, \ | 147 | .group_leader = &tsk, \ |
146 | RCU_INIT_POINTER(.real_cred, &init_cred), \ | 148 | RCU_INIT_POINTER(.real_cred, &init_cred), \ |
147 | RCU_INIT_POINTER(.cred, &init_cred), \ | 149 | RCU_INIT_POINTER(.cred, &init_cred), \ |
148 | .cred_guard_mutex = \ | ||
149 | __MUTEX_INITIALIZER(tsk.cred_guard_mutex), \ | ||
150 | .comm = "swapper", \ | 150 | .comm = "swapper", \ |
151 | .thread = INIT_THREAD, \ | 151 | .thread = INIT_THREAD, \ |
152 | .fs = &init_fs, \ | 152 | .fs = &init_fs, \ |
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index c059044bc6dc..ad54c846911b 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h | |||
@@ -33,6 +33,7 @@ struct kernel_stat { | |||
33 | #ifndef CONFIG_GENERIC_HARDIRQS | 33 | #ifndef CONFIG_GENERIC_HARDIRQS |
34 | unsigned int irqs[NR_IRQS]; | 34 | unsigned int irqs[NR_IRQS]; |
35 | #endif | 35 | #endif |
36 | unsigned long irqs_sum; | ||
36 | unsigned int softirqs[NR_SOFTIRQS]; | 37 | unsigned int softirqs[NR_SOFTIRQS]; |
37 | }; | 38 | }; |
38 | 39 | ||
@@ -54,6 +55,7 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, | |||
54 | struct irq_desc *desc) | 55 | struct irq_desc *desc) |
55 | { | 56 | { |
56 | kstat_this_cpu.irqs[irq]++; | 57 | kstat_this_cpu.irqs[irq]++; |
58 | kstat_this_cpu.irqs_sum++; | ||
57 | } | 59 | } |
58 | 60 | ||
59 | static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) | 61 | static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) |
@@ -65,8 +67,9 @@ static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) | |||
65 | extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu); | 67 | extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu); |
66 | #define kstat_irqs_this_cpu(DESC) \ | 68 | #define kstat_irqs_this_cpu(DESC) \ |
67 | ((DESC)->kstat_irqs[smp_processor_id()]) | 69 | ((DESC)->kstat_irqs[smp_processor_id()]) |
68 | #define kstat_incr_irqs_this_cpu(irqno, DESC) \ | 70 | #define kstat_incr_irqs_this_cpu(irqno, DESC) do {\ |
69 | ((DESC)->kstat_irqs[smp_processor_id()]++) | 71 | ((DESC)->kstat_irqs[smp_processor_id()]++);\ |
72 | kstat_this_cpu.irqs_sum++; } while (0) | ||
70 | 73 | ||
71 | #endif | 74 | #endif |
72 | 75 | ||
@@ -83,6 +86,7 @@ static inline unsigned int kstat_softirqs_cpu(unsigned int irq, int cpu) | |||
83 | /* | 86 | /* |
84 | * Number of interrupts per specific IRQ source, since bootup | 87 | * Number of interrupts per specific IRQ source, since bootup |
85 | */ | 88 | */ |
89 | #ifndef CONFIG_GENERIC_HARDIRQS | ||
86 | static inline unsigned int kstat_irqs(unsigned int irq) | 90 | static inline unsigned int kstat_irqs(unsigned int irq) |
87 | { | 91 | { |
88 | unsigned int sum = 0; | 92 | unsigned int sum = 0; |
@@ -93,7 +97,17 @@ static inline unsigned int kstat_irqs(unsigned int irq) | |||
93 | 97 | ||
94 | return sum; | 98 | return sum; |
95 | } | 99 | } |
100 | #else | ||
101 | extern unsigned int kstat_irqs(unsigned int irq); | ||
102 | #endif | ||
96 | 103 | ||
104 | /* | ||
105 | * Number of interrupts per cpu, since bootup | ||
106 | */ | ||
107 | static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu) | ||
108 | { | ||
109 | return kstat_cpu(cpu).irqs_sum; | ||
110 | } | ||
97 | 111 | ||
98 | /* | 112 | /* |
99 | * Lock/unlock the current runqueue - to extract task statistics: | 113 | * Lock/unlock the current runqueue - to extract task statistics: |
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index c238ad2f82ea..10308c6a3d1c 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h | |||
@@ -171,8 +171,17 @@ struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); | |||
171 | } | 171 | } |
172 | 172 | ||
173 | 173 | ||
174 | /* __kfifo_must_check_helper() is temporarily disabled because it was faulty */ | 174 | static inline unsigned int __must_check |
175 | #define __kfifo_must_check_helper(x) (x) | 175 | __kfifo_uint_must_check_helper(unsigned int val) |
176 | { | ||
177 | return val; | ||
178 | } | ||
179 | |||
180 | static inline int __must_check | ||
181 | __kfifo_int_must_check_helper(int val) | ||
182 | { | ||
183 | return val; | ||
184 | } | ||
176 | 185 | ||
177 | /** | 186 | /** |
178 | * kfifo_initialized - Check if the fifo is initialized | 187 | * kfifo_initialized - Check if the fifo is initialized |
@@ -264,7 +273,7 @@ struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); | |||
264 | * @fifo: address of the fifo to be used | 273 | * @fifo: address of the fifo to be used |
265 | */ | 274 | */ |
266 | #define kfifo_avail(fifo) \ | 275 | #define kfifo_avail(fifo) \ |
267 | __kfifo_must_check_helper( \ | 276 | __kfifo_uint_must_check_helper( \ |
268 | ({ \ | 277 | ({ \ |
269 | typeof((fifo) + 1) __tmpq = (fifo); \ | 278 | typeof((fifo) + 1) __tmpq = (fifo); \ |
270 | const size_t __recsize = sizeof(*__tmpq->rectype); \ | 279 | const size_t __recsize = sizeof(*__tmpq->rectype); \ |
@@ -297,7 +306,7 @@ __kfifo_must_check_helper( \ | |||
297 | * This function returns the size of the next fifo record in number of bytes. | 306 | * This function returns the size of the next fifo record in number of bytes. |
298 | */ | 307 | */ |
299 | #define kfifo_peek_len(fifo) \ | 308 | #define kfifo_peek_len(fifo) \ |
300 | __kfifo_must_check_helper( \ | 309 | __kfifo_uint_must_check_helper( \ |
301 | ({ \ | 310 | ({ \ |
302 | typeof((fifo) + 1) __tmp = (fifo); \ | 311 | typeof((fifo) + 1) __tmp = (fifo); \ |
303 | const size_t __recsize = sizeof(*__tmp->rectype); \ | 312 | const size_t __recsize = sizeof(*__tmp->rectype); \ |
@@ -320,7 +329,7 @@ __kfifo_must_check_helper( \ | |||
320 | * Return 0 if no error, otherwise an error code. | 329 | * Return 0 if no error, otherwise an error code. |
321 | */ | 330 | */ |
322 | #define kfifo_alloc(fifo, size, gfp_mask) \ | 331 | #define kfifo_alloc(fifo, size, gfp_mask) \ |
323 | __kfifo_must_check_helper( \ | 332 | __kfifo_int_must_check_helper( \ |
324 | ({ \ | 333 | ({ \ |
325 | typeof((fifo) + 1) __tmp = (fifo); \ | 334 | typeof((fifo) + 1) __tmp = (fifo); \ |
326 | struct __kfifo *__kfifo = &__tmp->kfifo; \ | 335 | struct __kfifo *__kfifo = &__tmp->kfifo; \ |
@@ -416,7 +425,7 @@ __kfifo_must_check_helper( \ | |||
416 | * writer, you don't need extra locking to use these macro. | 425 | * writer, you don't need extra locking to use these macro. |
417 | */ | 426 | */ |
418 | #define kfifo_get(fifo, val) \ | 427 | #define kfifo_get(fifo, val) \ |
419 | __kfifo_must_check_helper( \ | 428 | __kfifo_uint_must_check_helper( \ |
420 | ({ \ | 429 | ({ \ |
421 | typeof((fifo) + 1) __tmp = (fifo); \ | 430 | typeof((fifo) + 1) __tmp = (fifo); \ |
422 | typeof((val) + 1) __val = (val); \ | 431 | typeof((val) + 1) __val = (val); \ |
@@ -457,7 +466,7 @@ __kfifo_must_check_helper( \ | |||
457 | * writer, you don't need extra locking to use these macro. | 466 | * writer, you don't need extra locking to use these macro. |
458 | */ | 467 | */ |
459 | #define kfifo_peek(fifo, val) \ | 468 | #define kfifo_peek(fifo, val) \ |
460 | __kfifo_must_check_helper( \ | 469 | __kfifo_uint_must_check_helper( \ |
461 | ({ \ | 470 | ({ \ |
462 | typeof((fifo) + 1) __tmp = (fifo); \ | 471 | typeof((fifo) + 1) __tmp = (fifo); \ |
463 | typeof((val) + 1) __val = (val); \ | 472 | typeof((val) + 1) __val = (val); \ |
@@ -549,7 +558,7 @@ __kfifo_must_check_helper( \ | |||
549 | * writer, you don't need extra locking to use these macro. | 558 | * writer, you don't need extra locking to use these macro. |
550 | */ | 559 | */ |
551 | #define kfifo_out(fifo, buf, n) \ | 560 | #define kfifo_out(fifo, buf, n) \ |
552 | __kfifo_must_check_helper( \ | 561 | __kfifo_uint_must_check_helper( \ |
553 | ({ \ | 562 | ({ \ |
554 | typeof((fifo) + 1) __tmp = (fifo); \ | 563 | typeof((fifo) + 1) __tmp = (fifo); \ |
555 | typeof((buf) + 1) __buf = (buf); \ | 564 | typeof((buf) + 1) __buf = (buf); \ |
@@ -577,7 +586,7 @@ __kfifo_must_check_helper( \ | |||
577 | * copied. | 586 | * copied. |
578 | */ | 587 | */ |
579 | #define kfifo_out_spinlocked(fifo, buf, n, lock) \ | 588 | #define kfifo_out_spinlocked(fifo, buf, n, lock) \ |
580 | __kfifo_must_check_helper( \ | 589 | __kfifo_uint_must_check_helper( \ |
581 | ({ \ | 590 | ({ \ |
582 | unsigned long __flags; \ | 591 | unsigned long __flags; \ |
583 | unsigned int __ret; \ | 592 | unsigned int __ret; \ |
@@ -606,7 +615,7 @@ __kfifo_must_check_helper( \ | |||
606 | * writer, you don't need extra locking to use these macro. | 615 | * writer, you don't need extra locking to use these macro. |
607 | */ | 616 | */ |
608 | #define kfifo_from_user(fifo, from, len, copied) \ | 617 | #define kfifo_from_user(fifo, from, len, copied) \ |
609 | __kfifo_must_check_helper( \ | 618 | __kfifo_uint_must_check_helper( \ |
610 | ({ \ | 619 | ({ \ |
611 | typeof((fifo) + 1) __tmp = (fifo); \ | 620 | typeof((fifo) + 1) __tmp = (fifo); \ |
612 | const void __user *__from = (from); \ | 621 | const void __user *__from = (from); \ |
@@ -634,7 +643,7 @@ __kfifo_must_check_helper( \ | |||
634 | * writer, you don't need extra locking to use these macro. | 643 | * writer, you don't need extra locking to use these macro. |
635 | */ | 644 | */ |
636 | #define kfifo_to_user(fifo, to, len, copied) \ | 645 | #define kfifo_to_user(fifo, to, len, copied) \ |
637 | __kfifo_must_check_helper( \ | 646 | __kfifo_uint_must_check_helper( \ |
638 | ({ \ | 647 | ({ \ |
639 | typeof((fifo) + 1) __tmp = (fifo); \ | 648 | typeof((fifo) + 1) __tmp = (fifo); \ |
640 | void __user *__to = (to); \ | 649 | void __user *__to = (to); \ |
@@ -761,7 +770,7 @@ __kfifo_must_check_helper( \ | |||
761 | * writer, you don't need extra locking to use these macro. | 770 | * writer, you don't need extra locking to use these macro. |
762 | */ | 771 | */ |
763 | #define kfifo_out_peek(fifo, buf, n) \ | 772 | #define kfifo_out_peek(fifo, buf, n) \ |
764 | __kfifo_must_check_helper( \ | 773 | __kfifo_uint_must_check_helper( \ |
765 | ({ \ | 774 | ({ \ |
766 | typeof((fifo) + 1) __tmp = (fifo); \ | 775 | typeof((fifo) + 1) __tmp = (fifo); \ |
767 | typeof((buf) + 1) __buf = (buf); \ | 776 | typeof((buf) + 1) __buf = (buf); \ |
diff --git a/include/linux/poll.h b/include/linux/poll.h index 600cc1fde64d..56e76af78102 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h | |||
@@ -73,6 +73,8 @@ extern void poll_initwait(struct poll_wqueues *pwq); | |||
73 | extern void poll_freewait(struct poll_wqueues *pwq); | 73 | extern void poll_freewait(struct poll_wqueues *pwq); |
74 | extern int poll_schedule_timeout(struct poll_wqueues *pwq, int state, | 74 | extern int poll_schedule_timeout(struct poll_wqueues *pwq, int state, |
75 | ktime_t *expires, unsigned long slack); | 75 | ktime_t *expires, unsigned long slack); |
76 | extern long select_estimate_accuracy(struct timespec *tv); | ||
77 | |||
76 | 78 | ||
77 | static inline int poll_schedule(struct poll_wqueues *pwq, int state) | 79 | static inline int poll_schedule(struct poll_wqueues *pwq, int state) |
78 | { | 80 | { |
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 4272521e29e9..092a04f874a8 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h | |||
@@ -100,7 +100,8 @@ | |||
100 | #include <linux/sched.h> /* For struct task_struct. */ | 100 | #include <linux/sched.h> /* For struct task_struct. */ |
101 | 101 | ||
102 | 102 | ||
103 | extern long arch_ptrace(struct task_struct *child, long request, long addr, long data); | 103 | extern long arch_ptrace(struct task_struct *child, long request, |
104 | unsigned long addr, unsigned long data); | ||
104 | extern int ptrace_traceme(void); | 105 | extern int ptrace_traceme(void); |
105 | extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); | 106 | extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); |
106 | extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); | 107 | extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); |
@@ -108,7 +109,8 @@ extern int ptrace_attach(struct task_struct *tsk); | |||
108 | extern int ptrace_detach(struct task_struct *, unsigned int); | 109 | extern int ptrace_detach(struct task_struct *, unsigned int); |
109 | extern void ptrace_disable(struct task_struct *); | 110 | extern void ptrace_disable(struct task_struct *); |
110 | extern int ptrace_check_attach(struct task_struct *task, int kill); | 111 | extern int ptrace_check_attach(struct task_struct *task, int kill); |
111 | extern int ptrace_request(struct task_struct *child, long request, long addr, long data); | 112 | extern int ptrace_request(struct task_struct *child, long request, |
113 | unsigned long addr, unsigned long data); | ||
112 | extern void ptrace_notify(int exit_code); | 114 | extern void ptrace_notify(int exit_code); |
113 | extern void __ptrace_link(struct task_struct *child, | 115 | extern void __ptrace_link(struct task_struct *child, |
114 | struct task_struct *new_parent); | 116 | struct task_struct *new_parent); |
@@ -132,8 +134,10 @@ static inline void ptrace_unlink(struct task_struct *child) | |||
132 | __ptrace_unlink(child); | 134 | __ptrace_unlink(child); |
133 | } | 135 | } |
134 | 136 | ||
135 | int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data); | 137 | int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, |
136 | int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data); | 138 | unsigned long data); |
139 | int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, | ||
140 | unsigned long data); | ||
137 | 141 | ||
138 | /** | 142 | /** |
139 | * task_ptrace - return %PT_* flags that apply to a task | 143 | * task_ptrace - return %PT_* flags that apply to a task |
diff --git a/include/linux/ramoops.h b/include/linux/ramoops.h new file mode 100644 index 000000000000..0ae68a2c1212 --- /dev/null +++ b/include/linux/ramoops.h | |||
@@ -0,0 +1,15 @@ | |||
1 | #ifndef __RAMOOPS_H | ||
2 | #define __RAMOOPS_H | ||
3 | |||
4 | /* | ||
5 | * Ramoops platform data | ||
6 | * @mem_size memory size for ramoops | ||
7 | * @mem_address physical memory address to contain ramoops | ||
8 | */ | ||
9 | |||
10 | struct ramoops_platform_data { | ||
11 | unsigned long mem_size; | ||
12 | unsigned long mem_address; | ||
13 | }; | ||
14 | |||
15 | #endif | ||
diff --git a/include/linux/rio.h b/include/linux/rio.h index bd6eb0ed34a7..0bed941f9b13 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h | |||
@@ -67,6 +67,7 @@ | |||
67 | #define RIO_PW_MSG_SIZE 64 | 67 | #define RIO_PW_MSG_SIZE 64 |
68 | 68 | ||
69 | extern struct bus_type rio_bus_type; | 69 | extern struct bus_type rio_bus_type; |
70 | extern struct device rio_bus; | ||
70 | extern struct list_head rio_devices; /* list of all devices */ | 71 | extern struct list_head rio_devices; /* list of all devices */ |
71 | 72 | ||
72 | struct rio_mport; | 73 | struct rio_mport; |
@@ -98,6 +99,7 @@ union rio_pw_msg; | |||
98 | * @riores: RIO resources this device owns | 99 | * @riores: RIO resources this device owns |
99 | * @pwcback: port-write callback function for this device | 100 | * @pwcback: port-write callback function for this device |
100 | * @destid: Network destination ID | 101 | * @destid: Network destination ID |
102 | * @prev: Previous RIO device connected to the current one | ||
101 | */ | 103 | */ |
102 | struct rio_dev { | 104 | struct rio_dev { |
103 | struct list_head global_list; /* node in list of all RIO devices */ | 105 | struct list_head global_list; /* node in list of all RIO devices */ |
@@ -111,7 +113,7 @@ struct rio_dev { | |||
111 | u16 asm_rev; | 113 | u16 asm_rev; |
112 | u16 efptr; | 114 | u16 efptr; |
113 | u32 pef; | 115 | u32 pef; |
114 | u32 swpinfo; /* Only used for switches */ | 116 | u32 swpinfo; |
115 | u32 src_ops; | 117 | u32 src_ops; |
116 | u32 dst_ops; | 118 | u32 dst_ops; |
117 | u32 comp_tag; | 119 | u32 comp_tag; |
@@ -124,6 +126,7 @@ struct rio_dev { | |||
124 | struct resource riores[RIO_MAX_DEV_RESOURCES]; | 126 | struct resource riores[RIO_MAX_DEV_RESOURCES]; |
125 | int (*pwcback) (struct rio_dev *rdev, union rio_pw_msg *msg, int step); | 127 | int (*pwcback) (struct rio_dev *rdev, union rio_pw_msg *msg, int step); |
126 | u16 destid; | 128 | u16 destid; |
129 | struct rio_dev *prev; | ||
127 | }; | 130 | }; |
128 | 131 | ||
129 | #define rio_dev_g(n) list_entry(n, struct rio_dev, global_list) | 132 | #define rio_dev_g(n) list_entry(n, struct rio_dev, global_list) |
@@ -174,6 +177,7 @@ enum rio_phy_type { | |||
174 | * @index: Port index, unique among all port interfaces of the same type | 177 | * @index: Port index, unique among all port interfaces of the same type |
175 | * @sys_size: RapidIO common transport system size | 178 | * @sys_size: RapidIO common transport system size |
176 | * @phy_type: RapidIO phy type | 179 | * @phy_type: RapidIO phy type |
180 | * @phys_efptr: RIO port extended features pointer | ||
177 | * @name: Port name string | 181 | * @name: Port name string |
178 | * @priv: Master port private data | 182 | * @priv: Master port private data |
179 | */ | 183 | */ |
@@ -195,6 +199,7 @@ struct rio_mport { | |||
195 | * 1 - Large size, 65536 devices. | 199 | * 1 - Large size, 65536 devices. |
196 | */ | 200 | */ |
197 | enum rio_phy_type phy_type; /* RapidIO phy type */ | 201 | enum rio_phy_type phy_type; /* RapidIO phy type */ |
202 | u32 phys_efptr; | ||
198 | unsigned char name[40]; | 203 | unsigned char name[40]; |
199 | void *priv; /* Master port private data */ | 204 | void *priv; /* Master port private data */ |
200 | }; | 205 | }; |
@@ -215,9 +220,14 @@ struct rio_net { | |||
215 | unsigned char id; /* RIO network ID */ | 220 | unsigned char id; /* RIO network ID */ |
216 | }; | 221 | }; |
217 | 222 | ||
223 | /* Definitions used by switch sysfs initialization callback */ | ||
224 | #define RIO_SW_SYSFS_CREATE 1 /* Create switch attributes */ | ||
225 | #define RIO_SW_SYSFS_REMOVE 0 /* Remove switch attributes */ | ||
226 | |||
218 | /** | 227 | /** |
219 | * struct rio_switch - RIO switch info | 228 | * struct rio_switch - RIO switch info |
220 | * @node: Node in global list of switches | 229 | * @node: Node in global list of switches |
230 | * @rdev: Associated RIO device structure | ||
221 | * @switchid: Switch ID that is unique across a network | 231 | * @switchid: Switch ID that is unique across a network |
222 | * @hopcount: Hopcount to this switch | 232 | * @hopcount: Hopcount to this switch |
223 | * @destid: Associated destid in the path | 233 | * @destid: Associated destid in the path |
@@ -230,9 +240,12 @@ struct rio_net { | |||
230 | * @get_domain: Callback for switch-specific domain get function | 240 | * @get_domain: Callback for switch-specific domain get function |
231 | * @em_init: Callback for switch-specific error management initialization function | 241 | * @em_init: Callback for switch-specific error management initialization function |
232 | * @em_handle: Callback for switch-specific error management handler function | 242 | * @em_handle: Callback for switch-specific error management handler function |
243 | * @sw_sysfs: Callback that initializes switch-specific sysfs attributes | ||
244 | * @nextdev: Array of per-port pointers to the next attached device | ||
233 | */ | 245 | */ |
234 | struct rio_switch { | 246 | struct rio_switch { |
235 | struct list_head node; | 247 | struct list_head node; |
248 | struct rio_dev *rdev; | ||
236 | u16 switchid; | 249 | u16 switchid; |
237 | u16 hopcount; | 250 | u16 hopcount; |
238 | u16 destid; | 251 | u16 destid; |
@@ -250,6 +263,8 @@ struct rio_switch { | |||
250 | u8 *sw_domain); | 263 | u8 *sw_domain); |
251 | int (*em_init) (struct rio_dev *dev); | 264 | int (*em_init) (struct rio_dev *dev); |
252 | int (*em_handle) (struct rio_dev *dev, u8 swport); | 265 | int (*em_handle) (struct rio_dev *dev, u8 swport); |
266 | int (*sw_sysfs) (struct rio_dev *dev, int create); | ||
267 | struct rio_dev *nextdev[0]; | ||
253 | }; | 268 | }; |
254 | 269 | ||
255 | /* Low-level architecture-dependent routines */ | 270 | /* Low-level architecture-dependent routines */ |
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h index db50e1c288b7..ee7b6ada188f 100644 --- a/include/linux/rio_ids.h +++ b/include/linux/rio_ids.h | |||
@@ -34,5 +34,7 @@ | |||
34 | #define RIO_DID_IDTCPS16 0x035b | 34 | #define RIO_DID_IDTCPS16 0x035b |
35 | #define RIO_DID_IDTCPS6Q 0x035f | 35 | #define RIO_DID_IDTCPS6Q 0x035f |
36 | #define RIO_DID_IDTCPS10Q 0x035e | 36 | #define RIO_DID_IDTCPS10Q 0x035e |
37 | #define RIO_DID_IDTCPS1848 0x0374 | ||
38 | #define RIO_DID_IDTCPS1616 0x0379 | ||
37 | 39 | ||
38 | #endif /* LINUX_RIO_IDS_H */ | 40 | #endif /* LINUX_RIO_IDS_H */ |
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h index aedee0489fb4..d63dcbaea169 100644 --- a/include/linux/rio_regs.h +++ b/include/linux/rio_regs.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #define RIO_PEF_MEMORY 0x40000000 /* [I] MMIO */ | 33 | #define RIO_PEF_MEMORY 0x40000000 /* [I] MMIO */ |
34 | #define RIO_PEF_PROCESSOR 0x20000000 /* [I] Processor */ | 34 | #define RIO_PEF_PROCESSOR 0x20000000 /* [I] Processor */ |
35 | #define RIO_PEF_SWITCH 0x10000000 /* [I] Switch */ | 35 | #define RIO_PEF_SWITCH 0x10000000 /* [I] Switch */ |
36 | #define RIO_PEF_MULTIPORT 0x08000000 /* [VI, 2.1] Multiport */ | ||
36 | #define RIO_PEF_INB_MBOX 0x00f00000 /* [II] Mailboxes */ | 37 | #define RIO_PEF_INB_MBOX 0x00f00000 /* [II] Mailboxes */ |
37 | #define RIO_PEF_INB_MBOX0 0x00800000 /* [II] Mailbox 0 */ | 38 | #define RIO_PEF_INB_MBOX0 0x00800000 /* [II] Mailbox 0 */ |
38 | #define RIO_PEF_INB_MBOX1 0x00400000 /* [II] Mailbox 1 */ | 39 | #define RIO_PEF_INB_MBOX1 0x00400000 /* [II] Mailbox 1 */ |
@@ -51,6 +52,7 @@ | |||
51 | #define RIO_SWP_INFO_PORT_TOTAL_MASK 0x0000ff00 /* [I] Total number of ports */ | 52 | #define RIO_SWP_INFO_PORT_TOTAL_MASK 0x0000ff00 /* [I] Total number of ports */ |
52 | #define RIO_SWP_INFO_PORT_NUM_MASK 0x000000ff /* [I] Maintenance transaction port number */ | 53 | #define RIO_SWP_INFO_PORT_NUM_MASK 0x000000ff /* [I] Maintenance transaction port number */ |
53 | #define RIO_GET_TOTAL_PORTS(x) ((x & RIO_SWP_INFO_PORT_TOTAL_MASK) >> 8) | 54 | #define RIO_GET_TOTAL_PORTS(x) ((x & RIO_SWP_INFO_PORT_TOTAL_MASK) >> 8) |
55 | #define RIO_GET_PORT_NUM(x) (x & RIO_SWP_INFO_PORT_NUM_MASK) | ||
54 | 56 | ||
55 | #define RIO_SRC_OPS_CAR 0x18 /* [I] Source Operations CAR */ | 57 | #define RIO_SRC_OPS_CAR 0x18 /* [I] Source Operations CAR */ |
56 | #define RIO_SRC_OPS_READ 0x00008000 /* [I] Read op */ | 58 | #define RIO_SRC_OPS_READ 0x00008000 /* [I] Read op */ |
@@ -159,6 +161,7 @@ | |||
159 | #define RIO_COMPONENT_TAG_CSR 0x6c /* [III] Component Tag CSR */ | 161 | #define RIO_COMPONENT_TAG_CSR 0x6c /* [III] Component Tag CSR */ |
160 | 162 | ||
161 | #define RIO_STD_RTE_CONF_DESTID_SEL_CSR 0x70 | 163 | #define RIO_STD_RTE_CONF_DESTID_SEL_CSR 0x70 |
164 | #define RIO_STD_RTE_CONF_EXTCFGEN 0x80000000 | ||
162 | #define RIO_STD_RTE_CONF_PORT_SEL_CSR 0x74 | 165 | #define RIO_STD_RTE_CONF_PORT_SEL_CSR 0x74 |
163 | #define RIO_STD_RTE_DEFAULT_PORT 0x78 | 166 | #define RIO_STD_RTE_DEFAULT_PORT 0x78 |
164 | 167 | ||
@@ -222,15 +225,17 @@ | |||
222 | #define RIO_PORT_GEN_MASTER 0x40000000 | 225 | #define RIO_PORT_GEN_MASTER 0x40000000 |
223 | #define RIO_PORT_GEN_DISCOVERED 0x20000000 | 226 | #define RIO_PORT_GEN_DISCOVERED 0x20000000 |
224 | #define RIO_PORT_N_MNT_REQ_CSR(x) (0x0040 + x*0x20) /* 0x0002 */ | 227 | #define RIO_PORT_N_MNT_REQ_CSR(x) (0x0040 + x*0x20) /* 0x0002 */ |
228 | #define RIO_MNT_REQ_CMD_RD 0x03 /* Reset-device command */ | ||
229 | #define RIO_MNT_REQ_CMD_IS 0x04 /* Input-status command */ | ||
225 | #define RIO_PORT_N_MNT_RSP_CSR(x) (0x0044 + x*0x20) /* 0x0002 */ | 230 | #define RIO_PORT_N_MNT_RSP_CSR(x) (0x0044 + x*0x20) /* 0x0002 */ |
226 | #define RIO_PORT_N_MNT_RSP_RVAL 0x80000000 /* Response Valid */ | 231 | #define RIO_PORT_N_MNT_RSP_RVAL 0x80000000 /* Response Valid */ |
227 | #define RIO_PORT_N_MNT_RSP_ASTAT 0x000003e0 /* ackID Status */ | 232 | #define RIO_PORT_N_MNT_RSP_ASTAT 0x000007e0 /* ackID Status */ |
228 | #define RIO_PORT_N_MNT_RSP_LSTAT 0x0000001f /* Link Status */ | 233 | #define RIO_PORT_N_MNT_RSP_LSTAT 0x0000001f /* Link Status */ |
229 | #define RIO_PORT_N_ACK_STS_CSR(x) (0x0048 + x*0x20) /* 0x0002 */ | 234 | #define RIO_PORT_N_ACK_STS_CSR(x) (0x0048 + x*0x20) /* 0x0002 */ |
230 | #define RIO_PORT_N_ACK_CLEAR 0x80000000 | 235 | #define RIO_PORT_N_ACK_CLEAR 0x80000000 |
231 | #define RIO_PORT_N_ACK_INBOUND 0x1f000000 | 236 | #define RIO_PORT_N_ACK_INBOUND 0x3f000000 |
232 | #define RIO_PORT_N_ACK_OUTSTAND 0x00001f00 | 237 | #define RIO_PORT_N_ACK_OUTSTAND 0x00003f00 |
233 | #define RIO_PORT_N_ACK_OUTBOUND 0x0000001f | 238 | #define RIO_PORT_N_ACK_OUTBOUND 0x0000003f |
234 | #define RIO_PORT_N_ERR_STS_CSR(x) (0x0058 + x*0x20) | 239 | #define RIO_PORT_N_ERR_STS_CSR(x) (0x0058 + x*0x20) |
235 | #define RIO_PORT_N_ERR_STS_PW_OUT_ES 0x00010000 /* Output Error-stopped */ | 240 | #define RIO_PORT_N_ERR_STS_PW_OUT_ES 0x00010000 /* Output Error-stopped */ |
236 | #define RIO_PORT_N_ERR_STS_PW_INP_ES 0x00000100 /* Input Error-stopped */ | 241 | #define RIO_PORT_N_ERR_STS_PW_INP_ES 0x00000100 /* Input Error-stopped */ |
@@ -238,7 +243,6 @@ | |||
238 | #define RIO_PORT_N_ERR_STS_PORT_ERR 0x00000004 | 243 | #define RIO_PORT_N_ERR_STS_PORT_ERR 0x00000004 |
239 | #define RIO_PORT_N_ERR_STS_PORT_OK 0x00000002 | 244 | #define RIO_PORT_N_ERR_STS_PORT_OK 0x00000002 |
240 | #define RIO_PORT_N_ERR_STS_PORT_UNINIT 0x00000001 | 245 | #define RIO_PORT_N_ERR_STS_PORT_UNINIT 0x00000001 |
241 | #define RIO_PORT_N_ERR_STS_CLR_MASK 0x07120204 | ||
242 | #define RIO_PORT_N_CTL_CSR(x) (0x005c + x*0x20) | 246 | #define RIO_PORT_N_CTL_CSR(x) (0x005c + x*0x20) |
243 | #define RIO_PORT_N_CTL_PWIDTH 0xc0000000 | 247 | #define RIO_PORT_N_CTL_PWIDTH 0xc0000000 |
244 | #define RIO_PORT_N_CTL_PWIDTH_1 0x00000000 | 248 | #define RIO_PORT_N_CTL_PWIDTH_1 0x00000000 |
@@ -261,6 +265,10 @@ | |||
261 | #define RIO_EM_EFB_HEADER 0x000 /* Error Management Extensions Block Header */ | 265 | #define RIO_EM_EFB_HEADER 0x000 /* Error Management Extensions Block Header */ |
262 | #define RIO_EM_LTL_ERR_DETECT 0x008 /* Logical/Transport Layer Error Detect CSR */ | 266 | #define RIO_EM_LTL_ERR_DETECT 0x008 /* Logical/Transport Layer Error Detect CSR */ |
263 | #define RIO_EM_LTL_ERR_EN 0x00c /* Logical/Transport Layer Error Enable CSR */ | 267 | #define RIO_EM_LTL_ERR_EN 0x00c /* Logical/Transport Layer Error Enable CSR */ |
268 | #define REM_LTL_ERR_ILLTRAN 0x08000000 /* Illegal Transaction decode */ | ||
269 | #define REM_LTL_ERR_UNSOLR 0x00800000 /* Unsolicited Response */ | ||
270 | #define REM_LTL_ERR_UNSUPTR 0x00400000 /* Unsupported Transaction */ | ||
271 | #define REM_LTL_ERR_IMPSPEC 0x000000ff /* Implementation Specific */ | ||
264 | #define RIO_EM_LTL_HIADDR_CAP 0x010 /* Logical/Transport Layer High Address Capture CSR */ | 272 | #define RIO_EM_LTL_HIADDR_CAP 0x010 /* Logical/Transport Layer High Address Capture CSR */ |
265 | #define RIO_EM_LTL_ADDR_CAP 0x014 /* Logical/Transport Layer Address Capture CSR */ | 273 | #define RIO_EM_LTL_ADDR_CAP 0x014 /* Logical/Transport Layer Address Capture CSR */ |
266 | #define RIO_EM_LTL_DEVID_CAP 0x018 /* Logical/Transport Layer Device ID Capture CSR */ | 274 | #define RIO_EM_LTL_DEVID_CAP 0x018 /* Logical/Transport Layer Device ID Capture CSR */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 393ce94e54b7..be7adb7588e5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -626,6 +626,10 @@ struct signal_struct { | |||
626 | 626 | ||
627 | int oom_adj; /* OOM kill score adjustment (bit shift) */ | 627 | int oom_adj; /* OOM kill score adjustment (bit shift) */ |
628 | int oom_score_adj; /* OOM kill score adjustment */ | 628 | int oom_score_adj; /* OOM kill score adjustment */ |
629 | |||
630 | struct mutex cred_guard_mutex; /* guard against foreign influences on | ||
631 | * credential calculations | ||
632 | * (notably. ptrace) */ | ||
629 | }; | 633 | }; |
630 | 634 | ||
631 | /* Context switch must be unlocked if interrupts are to be enabled */ | 635 | /* Context switch must be unlocked if interrupts are to be enabled */ |
@@ -1305,9 +1309,6 @@ struct task_struct { | |||
1305 | * credentials (COW) */ | 1309 | * credentials (COW) */ |
1306 | const struct cred __rcu *cred; /* effective (overridable) subjective task | 1310 | const struct cred __rcu *cred; /* effective (overridable) subjective task |
1307 | * credentials (COW) */ | 1311 | * credentials (COW) */ |
1308 | struct mutex cred_guard_mutex; /* guard against foreign influences on | ||
1309 | * credential calculations | ||
1310 | * (notably. ptrace) */ | ||
1311 | struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */ | 1312 | struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */ |
1312 | 1313 | ||
1313 | char comm[TASK_COMM_LEN]; /* executable name excluding path | 1314 | char comm[TASK_COMM_LEN]; /* executable name excluding path |
@@ -2236,9 +2237,16 @@ static inline void task_unlock(struct task_struct *p) | |||
2236 | spin_unlock(&p->alloc_lock); | 2237 | spin_unlock(&p->alloc_lock); |
2237 | } | 2238 | } |
2238 | 2239 | ||
2239 | extern struct sighand_struct *lock_task_sighand(struct task_struct *tsk, | 2240 | extern struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, |
2240 | unsigned long *flags); | 2241 | unsigned long *flags); |
2241 | 2242 | ||
2243 | #define lock_task_sighand(tsk, flags) \ | ||
2244 | ({ struct sighand_struct *__ss; \ | ||
2245 | __cond_lock(&(tsk)->sighand->siglock, \ | ||
2246 | (__ss = __lock_task_sighand(tsk, flags))); \ | ||
2247 | __ss; \ | ||
2248 | }) \ | ||
2249 | |||
2242 | static inline void unlock_task_sighand(struct task_struct *tsk, | 2250 | static inline void unlock_task_sighand(struct task_struct *tsk, |
2243 | unsigned long *flags) | 2251 | unsigned long *flags) |
2244 | { | 2252 | { |
diff --git a/include/linux/spi/74x164.h b/include/linux/spi/74x164.h new file mode 100644 index 000000000000..d85c52f294a0 --- /dev/null +++ b/include/linux/spi/74x164.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef LINUX_SPI_74X164_H | ||
2 | #define LINUX_SPI_74X164_H | ||
3 | |||
4 | #define GEN_74X164_DRIVER_NAME "74x164" | ||
5 | |||
6 | struct gen_74x164_chip_platform_data { | ||
7 | /* number assigned to the first GPIO */ | ||
8 | unsigned base; | ||
9 | }; | ||
10 | |||
11 | #endif | ||
diff --git a/include/linux/synclink.h b/include/linux/synclink.h index 0ff2779c44d0..2e7d81c4e5ad 100644 --- a/include/linux/synclink.h +++ b/include/linux/synclink.h | |||
@@ -126,6 +126,7 @@ | |||
126 | #define MGSL_MODE_BISYNC 4 | 126 | #define MGSL_MODE_BISYNC 4 |
127 | #define MGSL_MODE_RAW 6 | 127 | #define MGSL_MODE_RAW 6 |
128 | #define MGSL_MODE_BASE_CLOCK 7 | 128 | #define MGSL_MODE_BASE_CLOCK 7 |
129 | #define MGSL_MODE_XSYNC 8 | ||
129 | 130 | ||
130 | #define MGSL_BUS_TYPE_ISA 1 | 131 | #define MGSL_BUS_TYPE_ISA 1 |
131 | #define MGSL_BUS_TYPE_EISA 2 | 132 | #define MGSL_BUS_TYPE_EISA 2 |
@@ -290,6 +291,10 @@ struct gpio_desc { | |||
290 | #define MGSL_IOCSGPIO _IOW(MGSL_MAGIC_IOC,16,struct gpio_desc) | 291 | #define MGSL_IOCSGPIO _IOW(MGSL_MAGIC_IOC,16,struct gpio_desc) |
291 | #define MGSL_IOCGGPIO _IOR(MGSL_MAGIC_IOC,17,struct gpio_desc) | 292 | #define MGSL_IOCGGPIO _IOR(MGSL_MAGIC_IOC,17,struct gpio_desc) |
292 | #define MGSL_IOCWAITGPIO _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc) | 293 | #define MGSL_IOCWAITGPIO _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc) |
294 | #define MGSL_IOCSXSYNC _IO(MGSL_MAGIC_IOC, 19) | ||
295 | #define MGSL_IOCGXSYNC _IO(MGSL_MAGIC_IOC, 20) | ||
296 | #define MGSL_IOCSXCTRL _IO(MGSL_MAGIC_IOC, 21) | ||
297 | #define MGSL_IOCGXCTRL _IO(MGSL_MAGIC_IOC, 22) | ||
293 | 298 | ||
294 | #ifdef __KERNEL__ | 299 | #ifdef __KERNEL__ |
295 | /* provide 32 bit ioctl compatibility on 64 bit systems */ | 300 | /* provide 32 bit ioctl compatibility on 64 bit systems */ |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index e6319d18a55d..cacc27a0e285 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -701,7 +701,8 @@ asmlinkage long sys_nfsservctl(int cmd, | |||
701 | asmlinkage long sys_syslog(int type, char __user *buf, int len); | 701 | asmlinkage long sys_syslog(int type, char __user *buf, int len); |
702 | asmlinkage long sys_uselib(const char __user *library); | 702 | asmlinkage long sys_uselib(const char __user *library); |
703 | asmlinkage long sys_ni_syscall(void); | 703 | asmlinkage long sys_ni_syscall(void); |
704 | asmlinkage long sys_ptrace(long request, long pid, long addr, long data); | 704 | asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, |
705 | unsigned long data); | ||
705 | 706 | ||
706 | asmlinkage long sys_add_key(const char __user *_type, | 707 | asmlinkage long sys_add_key(const char __user *_type, |
707 | const char __user *_description, | 708 | const char __user *_description, |
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 10db0102a890..3a2e66d88a32 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h | |||
@@ -150,7 +150,7 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) | |||
150 | * | 150 | * |
151 | * Return %LSM_UNSAFE_* bits applied to an exec because of tracing. | 151 | * Return %LSM_UNSAFE_* bits applied to an exec because of tracing. |
152 | * | 152 | * |
153 | * @task->cred_guard_mutex is held by the caller through the do_execve(). | 153 | * @task->signal->cred_guard_mutex is held by the caller through the do_execve(). |
154 | */ | 154 | */ |
155 | static inline int tracehook_unsafe_exec(struct task_struct *task) | 155 | static inline int tracehook_unsafe_exec(struct task_struct *task) |
156 | { | 156 | { |
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h index 1faa80d92f05..e68b439b2860 100644 --- a/include/linux/virtio_9p.h +++ b/include/linux/virtio_9p.h | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | #include <linux/virtio_ids.h> | 6 | #include <linux/virtio_ids.h> |
7 | #include <linux/virtio_config.h> | 7 | #include <linux/virtio_config.h> |
8 | #include <linux/types.h> | ||
9 | 8 | ||
10 | /* The feature bitmap for virtio 9P */ | 9 | /* The feature bitmap for virtio 9P */ |
11 | 10 | ||
diff --git a/init/Kconfig b/init/Kconfig index 3ae8ffe738eb..88c10468db46 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -518,7 +518,6 @@ if CGROUPS | |||
518 | 518 | ||
519 | config CGROUP_DEBUG | 519 | config CGROUP_DEBUG |
520 | bool "Example debug cgroup subsystem" | 520 | bool "Example debug cgroup subsystem" |
521 | depends on CGROUPS | ||
522 | default n | 521 | default n |
523 | help | 522 | help |
524 | This option enables a simple cgroup subsystem that | 523 | This option enables a simple cgroup subsystem that |
@@ -529,7 +528,6 @@ config CGROUP_DEBUG | |||
529 | 528 | ||
530 | config CGROUP_NS | 529 | config CGROUP_NS |
531 | bool "Namespace cgroup subsystem" | 530 | bool "Namespace cgroup subsystem" |
532 | depends on CGROUPS | ||
533 | help | 531 | help |
534 | Provides a simple namespace cgroup subsystem to | 532 | Provides a simple namespace cgroup subsystem to |
535 | provide hierarchical naming of sets of namespaces, | 533 | provide hierarchical naming of sets of namespaces, |
@@ -538,21 +536,18 @@ config CGROUP_NS | |||
538 | 536 | ||
539 | config CGROUP_FREEZER | 537 | config CGROUP_FREEZER |
540 | bool "Freezer cgroup subsystem" | 538 | bool "Freezer cgroup subsystem" |
541 | depends on CGROUPS | ||
542 | help | 539 | help |
543 | Provides a way to freeze and unfreeze all tasks in a | 540 | Provides a way to freeze and unfreeze all tasks in a |
544 | cgroup. | 541 | cgroup. |
545 | 542 | ||
546 | config CGROUP_DEVICE | 543 | config CGROUP_DEVICE |
547 | bool "Device controller for cgroups" | 544 | bool "Device controller for cgroups" |
548 | depends on CGROUPS && EXPERIMENTAL | ||
549 | help | 545 | help |
550 | Provides a cgroup implementing whitelists for devices which | 546 | Provides a cgroup implementing whitelists for devices which |
551 | a process in the cgroup can mknod or open. | 547 | a process in the cgroup can mknod or open. |
552 | 548 | ||
553 | config CPUSETS | 549 | config CPUSETS |
554 | bool "Cpuset support" | 550 | bool "Cpuset support" |
555 | depends on CGROUPS | ||
556 | help | 551 | help |
557 | This option will let you create and manage CPUSETs which | 552 | This option will let you create and manage CPUSETs which |
558 | allow dynamically partitioning a system into sets of CPUs and | 553 | allow dynamically partitioning a system into sets of CPUs and |
@@ -568,7 +563,6 @@ config PROC_PID_CPUSET | |||
568 | 563 | ||
569 | config CGROUP_CPUACCT | 564 | config CGROUP_CPUACCT |
570 | bool "Simple CPU accounting cgroup subsystem" | 565 | bool "Simple CPU accounting cgroup subsystem" |
571 | depends on CGROUPS | ||
572 | help | 566 | help |
573 | Provides a simple Resource Controller for monitoring the | 567 | Provides a simple Resource Controller for monitoring the |
574 | total CPU consumed by the tasks in a cgroup. | 568 | total CPU consumed by the tasks in a cgroup. |
@@ -578,11 +572,10 @@ config RESOURCE_COUNTERS | |||
578 | help | 572 | help |
579 | This option enables controller independent resource accounting | 573 | This option enables controller independent resource accounting |
580 | infrastructure that works with cgroups. | 574 | infrastructure that works with cgroups. |
581 | depends on CGROUPS | ||
582 | 575 | ||
583 | config CGROUP_MEM_RES_CTLR | 576 | config CGROUP_MEM_RES_CTLR |
584 | bool "Memory Resource Controller for Control Groups" | 577 | bool "Memory Resource Controller for Control Groups" |
585 | depends on CGROUPS && RESOURCE_COUNTERS | 578 | depends on RESOURCE_COUNTERS |
586 | select MM_OWNER | 579 | select MM_OWNER |
587 | help | 580 | help |
588 | Provides a memory resource controller that manages both anonymous | 581 | Provides a memory resource controller that manages both anonymous |
@@ -623,7 +616,7 @@ config CGROUP_MEM_RES_CTLR_SWAP | |||
623 | 616 | ||
624 | menuconfig CGROUP_SCHED | 617 | menuconfig CGROUP_SCHED |
625 | bool "Group CPU scheduler" | 618 | bool "Group CPU scheduler" |
626 | depends on EXPERIMENTAL && CGROUPS | 619 | depends on EXPERIMENTAL |
627 | default n | 620 | default n |
628 | help | 621 | help |
629 | This feature lets CPU scheduler recognize task groups and control CPU | 622 | This feature lets CPU scheduler recognize task groups and control CPU |
@@ -652,7 +645,7 @@ endif #CGROUP_SCHED | |||
652 | 645 | ||
653 | config BLK_CGROUP | 646 | config BLK_CGROUP |
654 | tristate "Block IO controller" | 647 | tristate "Block IO controller" |
655 | depends on CGROUPS && BLOCK | 648 | depends on BLOCK |
656 | default n | 649 | default n |
657 | ---help--- | 650 | ---help--- |
658 | Generic block IO controller cgroup interface. This is the common | 651 | Generic block IO controller cgroup interface. This is the common |
@@ -682,6 +675,59 @@ config DEBUG_BLK_CGROUP | |||
682 | 675 | ||
683 | endif # CGROUPS | 676 | endif # CGROUPS |
684 | 677 | ||
678 | menuconfig NAMESPACES | ||
679 | bool "Namespaces support" if EMBEDDED | ||
680 | default !EMBEDDED | ||
681 | help | ||
682 | Provides the way to make tasks work with different objects using | ||
683 | the same id. For example same IPC id may refer to different objects | ||
684 | or same user id or pid may refer to different tasks when used in | ||
685 | different namespaces. | ||
686 | |||
687 | if NAMESPACES | ||
688 | |||
689 | config UTS_NS | ||
690 | bool "UTS namespace" | ||
691 | default y | ||
692 | help | ||
693 | In this namespace tasks see different info provided with the | ||
694 | uname() system call | ||
695 | |||
696 | config IPC_NS | ||
697 | bool "IPC namespace" | ||
698 | depends on (SYSVIPC || POSIX_MQUEUE) | ||
699 | default y | ||
700 | help | ||
701 | In this namespace tasks work with IPC ids which correspond to | ||
702 | different IPC objects in different namespaces. | ||
703 | |||
704 | config USER_NS | ||
705 | bool "User namespace (EXPERIMENTAL)" | ||
706 | depends on EXPERIMENTAL | ||
707 | default y | ||
708 | help | ||
709 | This allows containers, i.e. vservers, to use user namespaces | ||
710 | to provide different user info for different servers. | ||
711 | If unsure, say N. | ||
712 | |||
713 | config PID_NS | ||
714 | bool "PID Namespaces" | ||
715 | default y | ||
716 | help | ||
717 | Support process id namespaces. This allows having multiple | ||
718 | processes with the same pid as long as they are in different | ||
719 | pid namespaces. This is a building block of containers. | ||
720 | |||
721 | config NET_NS | ||
722 | bool "Network namespace" | ||
723 | depends on NET | ||
724 | default y | ||
725 | help | ||
726 | Allow user space to create what appear to be multiple instances | ||
727 | of the network stack. | ||
728 | |||
729 | endif # NAMESPACES | ||
730 | |||
685 | config MM_OWNER | 731 | config MM_OWNER |
686 | bool | 732 | bool |
687 | 733 | ||
@@ -734,57 +780,6 @@ config RELAY | |||
734 | 780 | ||
735 | If unsure, say N. | 781 | If unsure, say N. |
736 | 782 | ||
737 | config NAMESPACES | ||
738 | bool "Namespaces support" if EMBEDDED | ||
739 | default !EMBEDDED | ||
740 | help | ||
741 | Provides the way to make tasks work with different objects using | ||
742 | the same id. For example same IPC id may refer to different objects | ||
743 | or same user id or pid may refer to different tasks when used in | ||
744 | different namespaces. | ||
745 | |||
746 | config UTS_NS | ||
747 | bool "UTS namespace" | ||
748 | depends on NAMESPACES | ||
749 | help | ||
750 | In this namespace tasks see different info provided with the | ||
751 | uname() system call | ||
752 | |||
753 | config IPC_NS | ||
754 | bool "IPC namespace" | ||
755 | depends on NAMESPACES && (SYSVIPC || POSIX_MQUEUE) | ||
756 | help | ||
757 | In this namespace tasks work with IPC ids which correspond to | ||
758 | different IPC objects in different namespaces. | ||
759 | |||
760 | config USER_NS | ||
761 | bool "User namespace (EXPERIMENTAL)" | ||
762 | depends on NAMESPACES && EXPERIMENTAL | ||
763 | help | ||
764 | This allows containers, i.e. vservers, to use user namespaces | ||
765 | to provide different user info for different servers. | ||
766 | If unsure, say N. | ||
767 | |||
768 | config PID_NS | ||
769 | bool "PID Namespaces (EXPERIMENTAL)" | ||
770 | default n | ||
771 | depends on NAMESPACES && EXPERIMENTAL | ||
772 | help | ||
773 | Support process id namespaces. This allows having multiple | ||
774 | processes with the same pid as long as they are in different | ||
775 | pid namespaces. This is a building block of containers. | ||
776 | |||
777 | Unless you want to work with an experimental feature | ||
778 | say N here. | ||
779 | |||
780 | config NET_NS | ||
781 | bool "Network namespace" | ||
782 | default n | ||
783 | depends on NAMESPACES && EXPERIMENTAL && NET | ||
784 | help | ||
785 | Allow user space to create what appear to be multiple instances | ||
786 | of the network stack. | ||
787 | |||
788 | config BLK_DEV_INITRD | 783 | config BLK_DEV_INITRD |
789 | bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" | 784 | bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" |
790 | depends on BROKEN || !FRV | 785 | depends on BROKEN || !FRV |
diff --git a/ipc/compat.c b/ipc/compat.c index 9dc2c7d3c9e6..845a28738d3a 100644 --- a/ipc/compat.c +++ b/ipc/compat.c | |||
@@ -241,6 +241,8 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr) | |||
241 | struct semid64_ds __user *up64; | 241 | struct semid64_ds __user *up64; |
242 | int version = compat_ipc_parse_version(&third); | 242 | int version = compat_ipc_parse_version(&third); |
243 | 243 | ||
244 | memset(&s64, 0, sizeof(s64)); | ||
245 | |||
244 | if (!uptr) | 246 | if (!uptr) |
245 | return -EINVAL; | 247 | return -EINVAL; |
246 | if (get_user(pad, (u32 __user *) uptr)) | 248 | if (get_user(pad, (u32 __user *) uptr)) |
@@ -421,6 +423,8 @@ long compat_sys_msgctl(int first, int second, void __user *uptr) | |||
421 | int version = compat_ipc_parse_version(&second); | 423 | int version = compat_ipc_parse_version(&second); |
422 | void __user *p; | 424 | void __user *p; |
423 | 425 | ||
426 | memset(&m64, 0, sizeof(m64)); | ||
427 | |||
424 | switch (second & (~IPC_64)) { | 428 | switch (second & (~IPC_64)) { |
425 | case IPC_INFO: | 429 | case IPC_INFO: |
426 | case IPC_RMID: | 430 | case IPC_RMID: |
@@ -594,6 +598,8 @@ long compat_sys_shmctl(int first, int second, void __user *uptr) | |||
594 | int err, err2; | 598 | int err, err2; |
595 | int version = compat_ipc_parse_version(&second); | 599 | int version = compat_ipc_parse_version(&second); |
596 | 600 | ||
601 | memset(&s64, 0, sizeof(s64)); | ||
602 | |||
597 | switch (second & (~IPC_64)) { | 603 | switch (second & (~IPC_64)) { |
598 | case IPC_RMID: | 604 | case IPC_RMID: |
599 | case SHM_LOCK: | 605 | case SHM_LOCK: |
diff --git a/ipc/compat_mq.c b/ipc/compat_mq.c index d8d1e9ff4e88..380ea4fe08e7 100644 --- a/ipc/compat_mq.c +++ b/ipc/compat_mq.c | |||
@@ -53,6 +53,9 @@ asmlinkage long compat_sys_mq_open(const char __user *u_name, | |||
53 | void __user *p = NULL; | 53 | void __user *p = NULL; |
54 | if (u_attr && oflag & O_CREAT) { | 54 | if (u_attr && oflag & O_CREAT) { |
55 | struct mq_attr attr; | 55 | struct mq_attr attr; |
56 | |||
57 | memset(&attr, 0, sizeof(attr)); | ||
58 | |||
56 | p = compat_alloc_user_space(sizeof(attr)); | 59 | p = compat_alloc_user_space(sizeof(attr)); |
57 | if (get_compat_mq_attr(&attr, u_attr) || | 60 | if (get_compat_mq_attr(&attr, u_attr) || |
58 | copy_to_user(p, &attr, sizeof(attr))) | 61 | copy_to_user(p, &attr, sizeof(attr))) |
@@ -127,6 +130,8 @@ asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes, | |||
127 | struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p)); | 130 | struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p)); |
128 | long ret; | 131 | long ret; |
129 | 132 | ||
133 | memset(&mqstat, 0, sizeof(mqstat)); | ||
134 | |||
130 | if (u_mqstat) { | 135 | if (u_mqstat) { |
131 | if (get_compat_mq_attr(&mqstat, u_mqstat) || | 136 | if (get_compat_mq_attr(&mqstat, u_mqstat) || |
132 | copy_to_user(p, &mqstat, sizeof(mqstat))) | 137 | copy_to_user(p, &mqstat, sizeof(mqstat))) |
@@ -108,7 +108,11 @@ void __init shm_init (void) | |||
108 | { | 108 | { |
109 | shm_init_ns(&init_ipc_ns); | 109 | shm_init_ns(&init_ipc_ns); |
110 | ipc_init_proc_interface("sysvipc/shm", | 110 | ipc_init_proc_interface("sysvipc/shm", |
111 | " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n", | 111 | #if BITS_PER_LONG <= 32 |
112 | " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", | ||
113 | #else | ||
114 | " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", | ||
115 | #endif | ||
112 | IPC_SHM_IDS, sysvipc_shm_proc_show); | 116 | IPC_SHM_IDS, sysvipc_shm_proc_show); |
113 | } | 117 | } |
114 | 118 | ||
@@ -544,6 +548,34 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf | |||
544 | } | 548 | } |
545 | 549 | ||
546 | /* | 550 | /* |
551 | * Calculate and add used RSS and swap pages of a shm. | ||
552 | * Called with shm_ids.rw_mutex held as a reader | ||
553 | */ | ||
554 | static void shm_add_rss_swap(struct shmid_kernel *shp, | ||
555 | unsigned long *rss_add, unsigned long *swp_add) | ||
556 | { | ||
557 | struct inode *inode; | ||
558 | |||
559 | inode = shp->shm_file->f_path.dentry->d_inode; | ||
560 | |||
561 | if (is_file_hugepages(shp->shm_file)) { | ||
562 | struct address_space *mapping = inode->i_mapping; | ||
563 | struct hstate *h = hstate_file(shp->shm_file); | ||
564 | *rss_add += pages_per_huge_page(h) * mapping->nrpages; | ||
565 | } else { | ||
566 | #ifdef CONFIG_SHMEM | ||
567 | struct shmem_inode_info *info = SHMEM_I(inode); | ||
568 | spin_lock(&info->lock); | ||
569 | *rss_add += inode->i_mapping->nrpages; | ||
570 | *swp_add += info->swapped; | ||
571 | spin_unlock(&info->lock); | ||
572 | #else | ||
573 | *rss_add += inode->i_mapping->nrpages; | ||
574 | #endif | ||
575 | } | ||
576 | } | ||
577 | |||
578 | /* | ||
547 | * Called with shm_ids.rw_mutex held as a reader | 579 | * Called with shm_ids.rw_mutex held as a reader |
548 | */ | 580 | */ |
549 | static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, | 581 | static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, |
@@ -560,30 +592,13 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, | |||
560 | for (total = 0, next_id = 0; total < in_use; next_id++) { | 592 | for (total = 0, next_id = 0; total < in_use; next_id++) { |
561 | struct kern_ipc_perm *ipc; | 593 | struct kern_ipc_perm *ipc; |
562 | struct shmid_kernel *shp; | 594 | struct shmid_kernel *shp; |
563 | struct inode *inode; | ||
564 | 595 | ||
565 | ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id); | 596 | ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id); |
566 | if (ipc == NULL) | 597 | if (ipc == NULL) |
567 | continue; | 598 | continue; |
568 | shp = container_of(ipc, struct shmid_kernel, shm_perm); | 599 | shp = container_of(ipc, struct shmid_kernel, shm_perm); |
569 | 600 | ||
570 | inode = shp->shm_file->f_path.dentry->d_inode; | 601 | shm_add_rss_swap(shp, rss, swp); |
571 | |||
572 | if (is_file_hugepages(shp->shm_file)) { | ||
573 | struct address_space *mapping = inode->i_mapping; | ||
574 | struct hstate *h = hstate_file(shp->shm_file); | ||
575 | *rss += pages_per_huge_page(h) * mapping->nrpages; | ||
576 | } else { | ||
577 | #ifdef CONFIG_SHMEM | ||
578 | struct shmem_inode_info *info = SHMEM_I(inode); | ||
579 | spin_lock(&info->lock); | ||
580 | *rss += inode->i_mapping->nrpages; | ||
581 | *swp += info->swapped; | ||
582 | spin_unlock(&info->lock); | ||
583 | #else | ||
584 | *rss += inode->i_mapping->nrpages; | ||
585 | #endif | ||
586 | } | ||
587 | 602 | ||
588 | total++; | 603 | total++; |
589 | } | 604 | } |
@@ -1072,6 +1087,9 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) | |||
1072 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | 1087 | static int sysvipc_shm_proc_show(struct seq_file *s, void *it) |
1073 | { | 1088 | { |
1074 | struct shmid_kernel *shp = it; | 1089 | struct shmid_kernel *shp = it; |
1090 | unsigned long rss = 0, swp = 0; | ||
1091 | |||
1092 | shm_add_rss_swap(shp, &rss, &swp); | ||
1075 | 1093 | ||
1076 | #if BITS_PER_LONG <= 32 | 1094 | #if BITS_PER_LONG <= 32 |
1077 | #define SIZE_SPEC "%10lu" | 1095 | #define SIZE_SPEC "%10lu" |
@@ -1081,7 +1099,8 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | |||
1081 | 1099 | ||
1082 | return seq_printf(s, | 1100 | return seq_printf(s, |
1083 | "%10d %10d %4o " SIZE_SPEC " %5u %5u " | 1101 | "%10d %10d %4o " SIZE_SPEC " %5u %5u " |
1084 | "%5lu %5u %5u %5u %5u %10lu %10lu %10lu\n", | 1102 | "%5lu %5u %5u %5u %5u %10lu %10lu %10lu " |
1103 | SIZE_SPEC " " SIZE_SPEC "\n", | ||
1085 | shp->shm_perm.key, | 1104 | shp->shm_perm.key, |
1086 | shp->shm_perm.id, | 1105 | shp->shm_perm.id, |
1087 | shp->shm_perm.mode, | 1106 | shp->shm_perm.mode, |
@@ -1095,6 +1114,8 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) | |||
1095 | shp->shm_perm.cgid, | 1114 | shp->shm_perm.cgid, |
1096 | shp->shm_atim, | 1115 | shp->shm_atim, |
1097 | shp->shm_dtim, | 1116 | shp->shm_dtim, |
1098 | shp->shm_ctim); | 1117 | shp->shm_ctim, |
1118 | rss * PAGE_SIZE, | ||
1119 | swp * PAGE_SIZE); | ||
1099 | } | 1120 | } |
1100 | #endif | 1121 | #endif |
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 9270d532ec3c..5cf366965d0c 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -243,6 +243,11 @@ static int notify_on_release(const struct cgroup *cgrp) | |||
243 | return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); | 243 | return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); |
244 | } | 244 | } |
245 | 245 | ||
246 | static int clone_children(const struct cgroup *cgrp) | ||
247 | { | ||
248 | return test_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
249 | } | ||
250 | |||
246 | /* | 251 | /* |
247 | * for_each_subsys() allows you to iterate on each subsystem attached to | 252 | * for_each_subsys() allows you to iterate on each subsystem attached to |
248 | * an active hierarchy | 253 | * an active hierarchy |
@@ -1040,6 +1045,8 @@ static int cgroup_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
1040 | seq_puts(seq, ",noprefix"); | 1045 | seq_puts(seq, ",noprefix"); |
1041 | if (strlen(root->release_agent_path)) | 1046 | if (strlen(root->release_agent_path)) |
1042 | seq_printf(seq, ",release_agent=%s", root->release_agent_path); | 1047 | seq_printf(seq, ",release_agent=%s", root->release_agent_path); |
1048 | if (clone_children(&root->top_cgroup)) | ||
1049 | seq_puts(seq, ",clone_children"); | ||
1043 | if (strlen(root->name)) | 1050 | if (strlen(root->name)) |
1044 | seq_printf(seq, ",name=%s", root->name); | 1051 | seq_printf(seq, ",name=%s", root->name); |
1045 | mutex_unlock(&cgroup_mutex); | 1052 | mutex_unlock(&cgroup_mutex); |
@@ -1050,6 +1057,7 @@ struct cgroup_sb_opts { | |||
1050 | unsigned long subsys_bits; | 1057 | unsigned long subsys_bits; |
1051 | unsigned long flags; | 1058 | unsigned long flags; |
1052 | char *release_agent; | 1059 | char *release_agent; |
1060 | bool clone_children; | ||
1053 | char *name; | 1061 | char *name; |
1054 | /* User explicitly requested empty subsystem */ | 1062 | /* User explicitly requested empty subsystem */ |
1055 | bool none; | 1063 | bool none; |
@@ -1066,7 +1074,8 @@ struct cgroup_sb_opts { | |||
1066 | */ | 1074 | */ |
1067 | static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | 1075 | static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) |
1068 | { | 1076 | { |
1069 | char *token, *o = data ?: "all"; | 1077 | char *token, *o = data; |
1078 | bool all_ss = false, one_ss = false; | ||
1070 | unsigned long mask = (unsigned long)-1; | 1079 | unsigned long mask = (unsigned long)-1; |
1071 | int i; | 1080 | int i; |
1072 | bool module_pin_failed = false; | 1081 | bool module_pin_failed = false; |
@@ -1082,22 +1091,27 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1082 | while ((token = strsep(&o, ",")) != NULL) { | 1091 | while ((token = strsep(&o, ",")) != NULL) { |
1083 | if (!*token) | 1092 | if (!*token) |
1084 | return -EINVAL; | 1093 | return -EINVAL; |
1085 | if (!strcmp(token, "all")) { | 1094 | if (!strcmp(token, "none")) { |
1086 | /* Add all non-disabled subsystems */ | ||
1087 | opts->subsys_bits = 0; | ||
1088 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | ||
1089 | struct cgroup_subsys *ss = subsys[i]; | ||
1090 | if (ss == NULL) | ||
1091 | continue; | ||
1092 | if (!ss->disabled) | ||
1093 | opts->subsys_bits |= 1ul << i; | ||
1094 | } | ||
1095 | } else if (!strcmp(token, "none")) { | ||
1096 | /* Explicitly have no subsystems */ | 1095 | /* Explicitly have no subsystems */ |
1097 | opts->none = true; | 1096 | opts->none = true; |
1098 | } else if (!strcmp(token, "noprefix")) { | 1097 | continue; |
1098 | } | ||
1099 | if (!strcmp(token, "all")) { | ||
1100 | /* Mutually exclusive option 'all' + subsystem name */ | ||
1101 | if (one_ss) | ||
1102 | return -EINVAL; | ||
1103 | all_ss = true; | ||
1104 | continue; | ||
1105 | } | ||
1106 | if (!strcmp(token, "noprefix")) { | ||
1099 | set_bit(ROOT_NOPREFIX, &opts->flags); | 1107 | set_bit(ROOT_NOPREFIX, &opts->flags); |
1100 | } else if (!strncmp(token, "release_agent=", 14)) { | 1108 | continue; |
1109 | } | ||
1110 | if (!strcmp(token, "clone_children")) { | ||
1111 | opts->clone_children = true; | ||
1112 | continue; | ||
1113 | } | ||
1114 | if (!strncmp(token, "release_agent=", 14)) { | ||
1101 | /* Specifying two release agents is forbidden */ | 1115 | /* Specifying two release agents is forbidden */ |
1102 | if (opts->release_agent) | 1116 | if (opts->release_agent) |
1103 | return -EINVAL; | 1117 | return -EINVAL; |
@@ -1105,7 +1119,9 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1105 | kstrndup(token + 14, PATH_MAX - 1, GFP_KERNEL); | 1119 | kstrndup(token + 14, PATH_MAX - 1, GFP_KERNEL); |
1106 | if (!opts->release_agent) | 1120 | if (!opts->release_agent) |
1107 | return -ENOMEM; | 1121 | return -ENOMEM; |
1108 | } else if (!strncmp(token, "name=", 5)) { | 1122 | continue; |
1123 | } | ||
1124 | if (!strncmp(token, "name=", 5)) { | ||
1109 | const char *name = token + 5; | 1125 | const char *name = token + 5; |
1110 | /* Can't specify an empty name */ | 1126 | /* Can't specify an empty name */ |
1111 | if (!strlen(name)) | 1127 | if (!strlen(name)) |
@@ -1127,20 +1143,44 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1127 | GFP_KERNEL); | 1143 | GFP_KERNEL); |
1128 | if (!opts->name) | 1144 | if (!opts->name) |
1129 | return -ENOMEM; | 1145 | return -ENOMEM; |
1130 | } else { | 1146 | |
1131 | struct cgroup_subsys *ss; | 1147 | continue; |
1132 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | 1148 | } |
1133 | ss = subsys[i]; | 1149 | |
1134 | if (ss == NULL) | 1150 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { |
1135 | continue; | 1151 | struct cgroup_subsys *ss = subsys[i]; |
1136 | if (!strcmp(token, ss->name)) { | 1152 | if (ss == NULL) |
1137 | if (!ss->disabled) | 1153 | continue; |
1138 | set_bit(i, &opts->subsys_bits); | 1154 | if (strcmp(token, ss->name)) |
1139 | break; | 1155 | continue; |
1140 | } | 1156 | if (ss->disabled) |
1141 | } | 1157 | continue; |
1142 | if (i == CGROUP_SUBSYS_COUNT) | 1158 | |
1143 | return -ENOENT; | 1159 | /* Mutually exclusive option 'all' + subsystem name */ |
1160 | if (all_ss) | ||
1161 | return -EINVAL; | ||
1162 | set_bit(i, &opts->subsys_bits); | ||
1163 | one_ss = true; | ||
1164 | |||
1165 | break; | ||
1166 | } | ||
1167 | if (i == CGROUP_SUBSYS_COUNT) | ||
1168 | return -ENOENT; | ||
1169 | } | ||
1170 | |||
1171 | /* | ||
1172 | * If the 'all' option was specified select all the subsystems, | ||
1173 | * otherwise 'all, 'none' and a subsystem name options were not | ||
1174 | * specified, let's default to 'all' | ||
1175 | */ | ||
1176 | if (all_ss || (!all_ss && !one_ss && !opts->none)) { | ||
1177 | for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { | ||
1178 | struct cgroup_subsys *ss = subsys[i]; | ||
1179 | if (ss == NULL) | ||
1180 | continue; | ||
1181 | if (ss->disabled) | ||
1182 | continue; | ||
1183 | set_bit(i, &opts->subsys_bits); | ||
1144 | } | 1184 | } |
1145 | } | 1185 | } |
1146 | 1186 | ||
@@ -1355,6 +1395,8 @@ static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts) | |||
1355 | strcpy(root->release_agent_path, opts->release_agent); | 1395 | strcpy(root->release_agent_path, opts->release_agent); |
1356 | if (opts->name) | 1396 | if (opts->name) |
1357 | strcpy(root->name, opts->name); | 1397 | strcpy(root->name, opts->name); |
1398 | if (opts->clone_children) | ||
1399 | set_bit(CGRP_CLONE_CHILDREN, &root->top_cgroup.flags); | ||
1358 | return root; | 1400 | return root; |
1359 | } | 1401 | } |
1360 | 1402 | ||
@@ -1880,6 +1922,8 @@ static int cgroup_release_agent_write(struct cgroup *cgrp, struct cftype *cft, | |||
1880 | const char *buffer) | 1922 | const char *buffer) |
1881 | { | 1923 | { |
1882 | BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); | 1924 | BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); |
1925 | if (strlen(buffer) >= PATH_MAX) | ||
1926 | return -EINVAL; | ||
1883 | if (!cgroup_lock_live_group(cgrp)) | 1927 | if (!cgroup_lock_live_group(cgrp)) |
1884 | return -ENODEV; | 1928 | return -ENODEV; |
1885 | strcpy(cgrp->root->release_agent_path, buffer); | 1929 | strcpy(cgrp->root->release_agent_path, buffer); |
@@ -3173,6 +3217,23 @@ fail: | |||
3173 | return ret; | 3217 | return ret; |
3174 | } | 3218 | } |
3175 | 3219 | ||
3220 | static u64 cgroup_clone_children_read(struct cgroup *cgrp, | ||
3221 | struct cftype *cft) | ||
3222 | { | ||
3223 | return clone_children(cgrp); | ||
3224 | } | ||
3225 | |||
3226 | static int cgroup_clone_children_write(struct cgroup *cgrp, | ||
3227 | struct cftype *cft, | ||
3228 | u64 val) | ||
3229 | { | ||
3230 | if (val) | ||
3231 | set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
3232 | else | ||
3233 | clear_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
3234 | return 0; | ||
3235 | } | ||
3236 | |||
3176 | /* | 3237 | /* |
3177 | * for the common functions, 'private' gives the type of file | 3238 | * for the common functions, 'private' gives the type of file |
3178 | */ | 3239 | */ |
@@ -3203,6 +3264,11 @@ static struct cftype files[] = { | |||
3203 | .write_string = cgroup_write_event_control, | 3264 | .write_string = cgroup_write_event_control, |
3204 | .mode = S_IWUGO, | 3265 | .mode = S_IWUGO, |
3205 | }, | 3266 | }, |
3267 | { | ||
3268 | .name = "cgroup.clone_children", | ||
3269 | .read_u64 = cgroup_clone_children_read, | ||
3270 | .write_u64 = cgroup_clone_children_write, | ||
3271 | }, | ||
3206 | }; | 3272 | }; |
3207 | 3273 | ||
3208 | static struct cftype cft_release_agent = { | 3274 | static struct cftype cft_release_agent = { |
@@ -3332,6 +3398,9 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
3332 | if (notify_on_release(parent)) | 3398 | if (notify_on_release(parent)) |
3333 | set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); | 3399 | set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); |
3334 | 3400 | ||
3401 | if (clone_children(parent)) | ||
3402 | set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags); | ||
3403 | |||
3335 | for_each_subsys(root, ss) { | 3404 | for_each_subsys(root, ss) { |
3336 | struct cgroup_subsys_state *css = ss->create(ss, cgrp); | 3405 | struct cgroup_subsys_state *css = ss->create(ss, cgrp); |
3337 | 3406 | ||
@@ -3346,6 +3415,8 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
3346 | goto err_destroy; | 3415 | goto err_destroy; |
3347 | } | 3416 | } |
3348 | /* At error, ->destroy() callback has to free assigned ID. */ | 3417 | /* At error, ->destroy() callback has to free assigned ID. */ |
3418 | if (clone_children(parent) && ss->post_clone) | ||
3419 | ss->post_clone(ss, cgrp); | ||
3349 | } | 3420 | } |
3350 | 3421 | ||
3351 | cgroup_lock_hierarchy(root); | 3422 | cgroup_lock_hierarchy(root); |
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index ce71ed53e88f..e7bebb7c6c38 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
@@ -48,20 +48,19 @@ static inline struct freezer *task_freezer(struct task_struct *task) | |||
48 | struct freezer, css); | 48 | struct freezer, css); |
49 | } | 49 | } |
50 | 50 | ||
51 | int cgroup_freezing_or_frozen(struct task_struct *task) | 51 | static inline int __cgroup_freezing_or_frozen(struct task_struct *task) |
52 | { | 52 | { |
53 | struct freezer *freezer; | 53 | enum freezer_state state = task_freezer(task)->state; |
54 | enum freezer_state state; | 54 | return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN); |
55 | } | ||
55 | 56 | ||
57 | int cgroup_freezing_or_frozen(struct task_struct *task) | ||
58 | { | ||
59 | int result; | ||
56 | task_lock(task); | 60 | task_lock(task); |
57 | freezer = task_freezer(task); | 61 | result = __cgroup_freezing_or_frozen(task); |
58 | if (!freezer->css.cgroup->parent) | ||
59 | state = CGROUP_THAWED; /* root cgroup can't be frozen */ | ||
60 | else | ||
61 | state = freezer->state; | ||
62 | task_unlock(task); | 62 | task_unlock(task); |
63 | 63 | return result; | |
64 | return (state == CGROUP_FREEZING) || (state == CGROUP_FROZEN); | ||
65 | } | 64 | } |
66 | 65 | ||
67 | /* | 66 | /* |
@@ -154,13 +153,6 @@ static void freezer_destroy(struct cgroup_subsys *ss, | |||
154 | kfree(cgroup_freezer(cgroup)); | 153 | kfree(cgroup_freezer(cgroup)); |
155 | } | 154 | } |
156 | 155 | ||
157 | /* Task is frozen or will freeze immediately when next it gets woken */ | ||
158 | static bool is_task_frozen_enough(struct task_struct *task) | ||
159 | { | ||
160 | return frozen(task) || | ||
161 | (task_is_stopped_or_traced(task) && freezing(task)); | ||
162 | } | ||
163 | |||
164 | /* | 156 | /* |
165 | * The call to cgroup_lock() in the freezer.state write method prevents | 157 | * The call to cgroup_lock() in the freezer.state write method prevents |
166 | * a write to that file racing against an attach, and hence the | 158 | * a write to that file racing against an attach, and hence the |
@@ -174,24 +166,25 @@ static int freezer_can_attach(struct cgroup_subsys *ss, | |||
174 | 166 | ||
175 | /* | 167 | /* |
176 | * Anything frozen can't move or be moved to/from. | 168 | * Anything frozen can't move or be moved to/from. |
177 | * | ||
178 | * Since orig_freezer->state == FROZEN means that @task has been | ||
179 | * frozen, so it's sufficient to check the latter condition. | ||
180 | */ | 169 | */ |
181 | 170 | ||
182 | if (is_task_frozen_enough(task)) | 171 | freezer = cgroup_freezer(new_cgroup); |
172 | if (freezer->state != CGROUP_THAWED) | ||
183 | return -EBUSY; | 173 | return -EBUSY; |
184 | 174 | ||
185 | freezer = cgroup_freezer(new_cgroup); | 175 | rcu_read_lock(); |
186 | if (freezer->state == CGROUP_FROZEN) | 176 | if (__cgroup_freezing_or_frozen(task)) { |
177 | rcu_read_unlock(); | ||
187 | return -EBUSY; | 178 | return -EBUSY; |
179 | } | ||
180 | rcu_read_unlock(); | ||
188 | 181 | ||
189 | if (threadgroup) { | 182 | if (threadgroup) { |
190 | struct task_struct *c; | 183 | struct task_struct *c; |
191 | 184 | ||
192 | rcu_read_lock(); | 185 | rcu_read_lock(); |
193 | list_for_each_entry_rcu(c, &task->thread_group, thread_group) { | 186 | list_for_each_entry_rcu(c, &task->thread_group, thread_group) { |
194 | if (is_task_frozen_enough(c)) { | 187 | if (__cgroup_freezing_or_frozen(c)) { |
195 | rcu_read_unlock(); | 188 | rcu_read_unlock(); |
196 | return -EBUSY; | 189 | return -EBUSY; |
197 | } | 190 | } |
@@ -236,31 +229,30 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task) | |||
236 | /* | 229 | /* |
237 | * caller must hold freezer->lock | 230 | * caller must hold freezer->lock |
238 | */ | 231 | */ |
239 | static void update_freezer_state(struct cgroup *cgroup, | 232 | static void update_if_frozen(struct cgroup *cgroup, |
240 | struct freezer *freezer) | 233 | struct freezer *freezer) |
241 | { | 234 | { |
242 | struct cgroup_iter it; | 235 | struct cgroup_iter it; |
243 | struct task_struct *task; | 236 | struct task_struct *task; |
244 | unsigned int nfrozen = 0, ntotal = 0; | 237 | unsigned int nfrozen = 0, ntotal = 0; |
238 | enum freezer_state old_state = freezer->state; | ||
245 | 239 | ||
246 | cgroup_iter_start(cgroup, &it); | 240 | cgroup_iter_start(cgroup, &it); |
247 | while ((task = cgroup_iter_next(cgroup, &it))) { | 241 | while ((task = cgroup_iter_next(cgroup, &it))) { |
248 | ntotal++; | 242 | ntotal++; |
249 | if (is_task_frozen_enough(task)) | 243 | if (frozen(task)) |
250 | nfrozen++; | 244 | nfrozen++; |
251 | } | 245 | } |
252 | 246 | ||
253 | /* | 247 | if (old_state == CGROUP_THAWED) { |
254 | * Transition to FROZEN when no new tasks can be added ensures | 248 | BUG_ON(nfrozen > 0); |
255 | * that we never exist in the FROZEN state while there are unfrozen | 249 | } else if (old_state == CGROUP_FREEZING) { |
256 | * tasks. | 250 | if (nfrozen == ntotal) |
257 | */ | 251 | freezer->state = CGROUP_FROZEN; |
258 | if (nfrozen == ntotal) | 252 | } else { /* old_state == CGROUP_FROZEN */ |
259 | freezer->state = CGROUP_FROZEN; | 253 | BUG_ON(nfrozen != ntotal); |
260 | else if (nfrozen > 0) | 254 | } |
261 | freezer->state = CGROUP_FREEZING; | 255 | |
262 | else | ||
263 | freezer->state = CGROUP_THAWED; | ||
264 | cgroup_iter_end(cgroup, &it); | 256 | cgroup_iter_end(cgroup, &it); |
265 | } | 257 | } |
266 | 258 | ||
@@ -279,7 +271,7 @@ static int freezer_read(struct cgroup *cgroup, struct cftype *cft, | |||
279 | if (state == CGROUP_FREEZING) { | 271 | if (state == CGROUP_FREEZING) { |
280 | /* We change from FREEZING to FROZEN lazily if the cgroup was | 272 | /* We change from FREEZING to FROZEN lazily if the cgroup was |
281 | * only partially frozen when we exitted write. */ | 273 | * only partially frozen when we exitted write. */ |
282 | update_freezer_state(cgroup, freezer); | 274 | update_if_frozen(cgroup, freezer); |
283 | state = freezer->state; | 275 | state = freezer->state; |
284 | } | 276 | } |
285 | spin_unlock_irq(&freezer->lock); | 277 | spin_unlock_irq(&freezer->lock); |
@@ -301,7 +293,7 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) | |||
301 | while ((task = cgroup_iter_next(cgroup, &it))) { | 293 | while ((task = cgroup_iter_next(cgroup, &it))) { |
302 | if (!freeze_task(task, true)) | 294 | if (!freeze_task(task, true)) |
303 | continue; | 295 | continue; |
304 | if (is_task_frozen_enough(task)) | 296 | if (frozen(task)) |
305 | continue; | 297 | continue; |
306 | if (!freezing(task) && !freezer_should_skip(task)) | 298 | if (!freezing(task) && !freezer_should_skip(task)) |
307 | num_cant_freeze_now++; | 299 | num_cant_freeze_now++; |
@@ -335,7 +327,7 @@ static int freezer_change_state(struct cgroup *cgroup, | |||
335 | 327 | ||
336 | spin_lock_irq(&freezer->lock); | 328 | spin_lock_irq(&freezer->lock); |
337 | 329 | ||
338 | update_freezer_state(cgroup, freezer); | 330 | update_if_frozen(cgroup, freezer); |
339 | if (goal_state == freezer->state) | 331 | if (goal_state == freezer->state) |
340 | goto out; | 332 | goto out; |
341 | 333 | ||
diff --git a/kernel/cred.c b/kernel/cred.c index 9a3e22641fe7..6a1aa004e376 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -325,7 +325,7 @@ EXPORT_SYMBOL(prepare_creds); | |||
325 | 325 | ||
326 | /* | 326 | /* |
327 | * Prepare credentials for current to perform an execve() | 327 | * Prepare credentials for current to perform an execve() |
328 | * - The caller must hold current->cred_guard_mutex | 328 | * - The caller must hold ->cred_guard_mutex |
329 | */ | 329 | */ |
330 | struct cred *prepare_exec_creds(void) | 330 | struct cred *prepare_exec_creds(void) |
331 | { | 331 | { |
@@ -384,8 +384,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) | |||
384 | struct cred *new; | 384 | struct cred *new; |
385 | int ret; | 385 | int ret; |
386 | 386 | ||
387 | mutex_init(&p->cred_guard_mutex); | ||
388 | |||
389 | if ( | 387 | if ( |
390 | #ifdef CONFIG_KEYS | 388 | #ifdef CONFIG_KEYS |
391 | !p->cred->thread_keyring && | 389 | !p->cred->thread_keyring && |
diff --git a/kernel/exit.c b/kernel/exit.c index 894179a32ec1..b194febf5799 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -703,6 +703,8 @@ static void exit_mm(struct task_struct * tsk) | |||
703 | * space. | 703 | * space. |
704 | */ | 704 | */ |
705 | static struct task_struct *find_new_reaper(struct task_struct *father) | 705 | static struct task_struct *find_new_reaper(struct task_struct *father) |
706 | __releases(&tasklist_lock) | ||
707 | __acquires(&tasklist_lock) | ||
706 | { | 708 | { |
707 | struct pid_namespace *pid_ns = task_active_pid_ns(father); | 709 | struct pid_namespace *pid_ns = task_active_pid_ns(father); |
708 | struct task_struct *thread; | 710 | struct task_struct *thread; |
diff --git a/kernel/fork.c b/kernel/fork.c index e87aaaaf5131..3b159c5991b7 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -908,6 +908,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
908 | sig->oom_adj = current->signal->oom_adj; | 908 | sig->oom_adj = current->signal->oom_adj; |
909 | sig->oom_score_adj = current->signal->oom_score_adj; | 909 | sig->oom_score_adj = current->signal->oom_score_adj; |
910 | 910 | ||
911 | mutex_init(&sig->cred_guard_mutex); | ||
912 | |||
911 | return 0; | 913 | return 0; |
912 | } | 914 | } |
913 | 915 | ||
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 9d917ff72675..9988d03797f5 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c | |||
@@ -393,3 +393,18 @@ unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) | |||
393 | struct irq_desc *desc = irq_to_desc(irq); | 393 | struct irq_desc *desc = irq_to_desc(irq); |
394 | return desc ? desc->kstat_irqs[cpu] : 0; | 394 | return desc ? desc->kstat_irqs[cpu] : 0; |
395 | } | 395 | } |
396 | |||
397 | #ifdef CONFIG_GENERIC_HARDIRQS | ||
398 | unsigned int kstat_irqs(unsigned int irq) | ||
399 | { | ||
400 | struct irq_desc *desc = irq_to_desc(irq); | ||
401 | int cpu; | ||
402 | int sum = 0; | ||
403 | |||
404 | if (!desc) | ||
405 | return 0; | ||
406 | for_each_possible_cpu(cpu) | ||
407 | sum += desc->kstat_irqs[cpu]; | ||
408 | return sum; | ||
409 | } | ||
410 | #endif /* CONFIG_GENERIC_HARDIRQS */ | ||
diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c index 2a5dfec8efe0..2c98ad94ba0e 100644 --- a/kernel/ns_cgroup.c +++ b/kernel/ns_cgroup.c | |||
@@ -85,6 +85,14 @@ static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss, | |||
85 | return ERR_PTR(-EPERM); | 85 | return ERR_PTR(-EPERM); |
86 | if (!cgroup_is_descendant(cgroup, current)) | 86 | if (!cgroup_is_descendant(cgroup, current)) |
87 | return ERR_PTR(-EPERM); | 87 | return ERR_PTR(-EPERM); |
88 | if (test_bit(CGRP_CLONE_CHILDREN, &cgroup->flags)) { | ||
89 | printk("ns_cgroup can't be created with parent " | ||
90 | "'clone_children' set.\n"); | ||
91 | return ERR_PTR(-EINVAL); | ||
92 | } | ||
93 | |||
94 | printk_once("ns_cgroup deprecated: consider using the " | ||
95 | "'clone_children' flag without the ns_cgroup.\n"); | ||
88 | 96 | ||
89 | ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL); | 97 | ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL); |
90 | if (!ns_cgroup) | 98 | if (!ns_cgroup) |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index f34d798ef4a2..99bbaa3e5b0d 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -181,7 +181,7 @@ int ptrace_attach(struct task_struct *task) | |||
181 | * under ptrace. | 181 | * under ptrace. |
182 | */ | 182 | */ |
183 | retval = -ERESTARTNOINTR; | 183 | retval = -ERESTARTNOINTR; |
184 | if (mutex_lock_interruptible(&task->cred_guard_mutex)) | 184 | if (mutex_lock_interruptible(&task->signal->cred_guard_mutex)) |
185 | goto out; | 185 | goto out; |
186 | 186 | ||
187 | task_lock(task); | 187 | task_lock(task); |
@@ -208,7 +208,7 @@ int ptrace_attach(struct task_struct *task) | |||
208 | unlock_tasklist: | 208 | unlock_tasklist: |
209 | write_unlock_irq(&tasklist_lock); | 209 | write_unlock_irq(&tasklist_lock); |
210 | unlock_creds: | 210 | unlock_creds: |
211 | mutex_unlock(&task->cred_guard_mutex); | 211 | mutex_unlock(&task->signal->cred_guard_mutex); |
212 | out: | 212 | out: |
213 | return retval; | 213 | return retval; |
214 | } | 214 | } |
@@ -329,6 +329,8 @@ int ptrace_detach(struct task_struct *child, unsigned int data) | |||
329 | * and reacquire the lock. | 329 | * and reacquire the lock. |
330 | */ | 330 | */ |
331 | void exit_ptrace(struct task_struct *tracer) | 331 | void exit_ptrace(struct task_struct *tracer) |
332 | __releases(&tasklist_lock) | ||
333 | __acquires(&tasklist_lock) | ||
332 | { | 334 | { |
333 | struct task_struct *p, *n; | 335 | struct task_struct *p, *n; |
334 | LIST_HEAD(ptrace_dead); | 336 | LIST_HEAD(ptrace_dead); |
@@ -402,7 +404,7 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds | |||
402 | return copied; | 404 | return copied; |
403 | } | 405 | } |
404 | 406 | ||
405 | static int ptrace_setoptions(struct task_struct *child, long data) | 407 | static int ptrace_setoptions(struct task_struct *child, unsigned long data) |
406 | { | 408 | { |
407 | child->ptrace &= ~PT_TRACE_MASK; | 409 | child->ptrace &= ~PT_TRACE_MASK; |
408 | 410 | ||
@@ -481,7 +483,8 @@ static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) | |||
481 | #define is_sysemu_singlestep(request) 0 | 483 | #define is_sysemu_singlestep(request) 0 |
482 | #endif | 484 | #endif |
483 | 485 | ||
484 | static int ptrace_resume(struct task_struct *child, long request, long data) | 486 | static int ptrace_resume(struct task_struct *child, long request, |
487 | unsigned long data) | ||
485 | { | 488 | { |
486 | if (!valid_signal(data)) | 489 | if (!valid_signal(data)) |
487 | return -EIO; | 490 | return -EIO; |
@@ -558,10 +561,12 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type, | |||
558 | #endif | 561 | #endif |
559 | 562 | ||
560 | int ptrace_request(struct task_struct *child, long request, | 563 | int ptrace_request(struct task_struct *child, long request, |
561 | long addr, long data) | 564 | unsigned long addr, unsigned long data) |
562 | { | 565 | { |
563 | int ret = -EIO; | 566 | int ret = -EIO; |
564 | siginfo_t siginfo; | 567 | siginfo_t siginfo; |
568 | void __user *datavp = (void __user *) data; | ||
569 | unsigned long __user *datalp = datavp; | ||
565 | 570 | ||
566 | switch (request) { | 571 | switch (request) { |
567 | case PTRACE_PEEKTEXT: | 572 | case PTRACE_PEEKTEXT: |
@@ -578,19 +583,17 @@ int ptrace_request(struct task_struct *child, long request, | |||
578 | ret = ptrace_setoptions(child, data); | 583 | ret = ptrace_setoptions(child, data); |
579 | break; | 584 | break; |
580 | case PTRACE_GETEVENTMSG: | 585 | case PTRACE_GETEVENTMSG: |
581 | ret = put_user(child->ptrace_message, (unsigned long __user *) data); | 586 | ret = put_user(child->ptrace_message, datalp); |
582 | break; | 587 | break; |
583 | 588 | ||
584 | case PTRACE_GETSIGINFO: | 589 | case PTRACE_GETSIGINFO: |
585 | ret = ptrace_getsiginfo(child, &siginfo); | 590 | ret = ptrace_getsiginfo(child, &siginfo); |
586 | if (!ret) | 591 | if (!ret) |
587 | ret = copy_siginfo_to_user((siginfo_t __user *) data, | 592 | ret = copy_siginfo_to_user(datavp, &siginfo); |
588 | &siginfo); | ||
589 | break; | 593 | break; |
590 | 594 | ||
591 | case PTRACE_SETSIGINFO: | 595 | case PTRACE_SETSIGINFO: |
592 | if (copy_from_user(&siginfo, (siginfo_t __user *) data, | 596 | if (copy_from_user(&siginfo, datavp, sizeof siginfo)) |
593 | sizeof siginfo)) | ||
594 | ret = -EFAULT; | 597 | ret = -EFAULT; |
595 | else | 598 | else |
596 | ret = ptrace_setsiginfo(child, &siginfo); | 599 | ret = ptrace_setsiginfo(child, &siginfo); |
@@ -621,7 +624,7 @@ int ptrace_request(struct task_struct *child, long request, | |||
621 | } | 624 | } |
622 | mmput(mm); | 625 | mmput(mm); |
623 | 626 | ||
624 | ret = put_user(tmp, (unsigned long __user *) data); | 627 | ret = put_user(tmp, datalp); |
625 | break; | 628 | break; |
626 | } | 629 | } |
627 | #endif | 630 | #endif |
@@ -650,7 +653,7 @@ int ptrace_request(struct task_struct *child, long request, | |||
650 | case PTRACE_SETREGSET: | 653 | case PTRACE_SETREGSET: |
651 | { | 654 | { |
652 | struct iovec kiov; | 655 | struct iovec kiov; |
653 | struct iovec __user *uiov = (struct iovec __user *) data; | 656 | struct iovec __user *uiov = datavp; |
654 | 657 | ||
655 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) | 658 | if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov))) |
656 | return -EFAULT; | 659 | return -EFAULT; |
@@ -691,7 +694,8 @@ static struct task_struct *ptrace_get_task_struct(pid_t pid) | |||
691 | #define arch_ptrace_attach(child) do { } while (0) | 694 | #define arch_ptrace_attach(child) do { } while (0) |
692 | #endif | 695 | #endif |
693 | 696 | ||
694 | SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) | 697 | SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, |
698 | unsigned long, data) | ||
695 | { | 699 | { |
696 | struct task_struct *child; | 700 | struct task_struct *child; |
697 | long ret; | 701 | long ret; |
@@ -732,7 +736,8 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) | |||
732 | return ret; | 736 | return ret; |
733 | } | 737 | } |
734 | 738 | ||
735 | int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) | 739 | int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr, |
740 | unsigned long data) | ||
736 | { | 741 | { |
737 | unsigned long tmp; | 742 | unsigned long tmp; |
738 | int copied; | 743 | int copied; |
@@ -743,7 +748,8 @@ int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data) | |||
743 | return put_user(tmp, (unsigned long __user *)data); | 748 | return put_user(tmp, (unsigned long __user *)data); |
744 | } | 749 | } |
745 | 750 | ||
746 | int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data) | 751 | int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr, |
752 | unsigned long data) | ||
747 | { | 753 | { |
748 | int copied; | 754 | int copied; |
749 | 755 | ||
diff --git a/kernel/resource.c b/kernel/resource.c index 7b36976e5dea..9c9841cb6902 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -453,6 +453,8 @@ static struct resource * __insert_resource(struct resource *parent, struct resou | |||
453 | 453 | ||
454 | if (first == parent) | 454 | if (first == parent) |
455 | return first; | 455 | return first; |
456 | if (WARN_ON(first == new)) /* duplicated insertion */ | ||
457 | return first; | ||
456 | 458 | ||
457 | if ((first->start > new->start) || (first->end < new->end)) | 459 | if ((first->start > new->start) || (first->end < new->end)) |
458 | break; | 460 | break; |
diff --git a/kernel/signal.c b/kernel/signal.c index 919562c3d6b7..4e3cff10fdce 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1105,7 +1105,8 @@ int zap_other_threads(struct task_struct *p) | |||
1105 | return count; | 1105 | return count; |
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) | 1108 | struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, |
1109 | unsigned long *flags) | ||
1109 | { | 1110 | { |
1110 | struct sighand_struct *sighand; | 1111 | struct sighand_struct *sighand; |
1111 | 1112 | ||
@@ -1617,6 +1618,8 @@ static int sigkill_pending(struct task_struct *tsk) | |||
1617 | * is gone, we keep current->exit_code unless clear_code. | 1618 | * is gone, we keep current->exit_code unless clear_code. |
1618 | */ | 1619 | */ |
1619 | static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) | 1620 | static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) |
1621 | __releases(¤t->sighand->siglock) | ||
1622 | __acquires(¤t->sighand->siglock) | ||
1620 | { | 1623 | { |
1621 | if (arch_ptrace_stop_needed(exit_code, info)) { | 1624 | if (arch_ptrace_stop_needed(exit_code, info)) { |
1622 | /* | 1625 | /* |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 11281d5792bd..c8231fb15708 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -175,22 +175,8 @@ static void send_cpu_listeners(struct sk_buff *skb, | |||
175 | up_write(&listeners->sem); | 175 | up_write(&listeners->sem); |
176 | } | 176 | } |
177 | 177 | ||
178 | static int fill_pid(pid_t pid, struct task_struct *tsk, | 178 | static void fill_stats(struct task_struct *tsk, struct taskstats *stats) |
179 | struct taskstats *stats) | ||
180 | { | 179 | { |
181 | int rc = 0; | ||
182 | |||
183 | if (!tsk) { | ||
184 | rcu_read_lock(); | ||
185 | tsk = find_task_by_vpid(pid); | ||
186 | if (tsk) | ||
187 | get_task_struct(tsk); | ||
188 | rcu_read_unlock(); | ||
189 | if (!tsk) | ||
190 | return -ESRCH; | ||
191 | } else | ||
192 | get_task_struct(tsk); | ||
193 | |||
194 | memset(stats, 0, sizeof(*stats)); | 180 | memset(stats, 0, sizeof(*stats)); |
195 | /* | 181 | /* |
196 | * Each accounting subsystem adds calls to its functions to | 182 | * Each accounting subsystem adds calls to its functions to |
@@ -209,17 +195,27 @@ static int fill_pid(pid_t pid, struct task_struct *tsk, | |||
209 | 195 | ||
210 | /* fill in extended acct fields */ | 196 | /* fill in extended acct fields */ |
211 | xacct_add_tsk(stats, tsk); | 197 | xacct_add_tsk(stats, tsk); |
198 | } | ||
212 | 199 | ||
213 | /* Define err: label here if needed */ | 200 | static int fill_stats_for_pid(pid_t pid, struct taskstats *stats) |
214 | put_task_struct(tsk); | 201 | { |
215 | return rc; | 202 | struct task_struct *tsk; |
216 | 203 | ||
204 | rcu_read_lock(); | ||
205 | tsk = find_task_by_vpid(pid); | ||
206 | if (tsk) | ||
207 | get_task_struct(tsk); | ||
208 | rcu_read_unlock(); | ||
209 | if (!tsk) | ||
210 | return -ESRCH; | ||
211 | fill_stats(tsk, stats); | ||
212 | put_task_struct(tsk); | ||
213 | return 0; | ||
217 | } | 214 | } |
218 | 215 | ||
219 | static int fill_tgid(pid_t tgid, struct task_struct *first, | 216 | static int fill_stats_for_tgid(pid_t tgid, struct taskstats *stats) |
220 | struct taskstats *stats) | ||
221 | { | 217 | { |
222 | struct task_struct *tsk; | 218 | struct task_struct *tsk, *first; |
223 | unsigned long flags; | 219 | unsigned long flags; |
224 | int rc = -ESRCH; | 220 | int rc = -ESRCH; |
225 | 221 | ||
@@ -228,8 +224,7 @@ static int fill_tgid(pid_t tgid, struct task_struct *first, | |||
228 | * leaders who are already counted with the dead tasks | 224 | * leaders who are already counted with the dead tasks |
229 | */ | 225 | */ |
230 | rcu_read_lock(); | 226 | rcu_read_lock(); |
231 | if (!first) | 227 | first = find_task_by_vpid(tgid); |
232 | first = find_task_by_vpid(tgid); | ||
233 | 228 | ||
234 | if (!first || !lock_task_sighand(first, &flags)) | 229 | if (!first || !lock_task_sighand(first, &flags)) |
235 | goto out; | 230 | goto out; |
@@ -268,7 +263,6 @@ out: | |||
268 | return rc; | 263 | return rc; |
269 | } | 264 | } |
270 | 265 | ||
271 | |||
272 | static void fill_tgid_exit(struct task_struct *tsk) | 266 | static void fill_tgid_exit(struct task_struct *tsk) |
273 | { | 267 | { |
274 | unsigned long flags; | 268 | unsigned long flags; |
@@ -360,6 +354,12 @@ static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) | |||
360 | struct nlattr *na, *ret; | 354 | struct nlattr *na, *ret; |
361 | int aggr; | 355 | int aggr; |
362 | 356 | ||
357 | /* If we don't pad, we end up with alignment on a 4 byte boundary. | ||
358 | * This causes lots of runtime warnings on systems requiring 8 byte | ||
359 | * alignment */ | ||
360 | u32 pids[2] = { pid, 0 }; | ||
361 | int pid_size = ALIGN(sizeof(pid), sizeof(long)); | ||
362 | |||
363 | aggr = (type == TASKSTATS_TYPE_PID) | 363 | aggr = (type == TASKSTATS_TYPE_PID) |
364 | ? TASKSTATS_TYPE_AGGR_PID | 364 | ? TASKSTATS_TYPE_AGGR_PID |
365 | : TASKSTATS_TYPE_AGGR_TGID; | 365 | : TASKSTATS_TYPE_AGGR_TGID; |
@@ -367,7 +367,7 @@ static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) | |||
367 | na = nla_nest_start(skb, aggr); | 367 | na = nla_nest_start(skb, aggr); |
368 | if (!na) | 368 | if (!na) |
369 | goto err; | 369 | goto err; |
370 | if (nla_put(skb, type, sizeof(pid), &pid) < 0) | 370 | if (nla_put(skb, type, pid_size, pids) < 0) |
371 | goto err; | 371 | goto err; |
372 | ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); | 372 | ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); |
373 | if (!ret) | 373 | if (!ret) |
@@ -424,39 +424,46 @@ err: | |||
424 | return rc; | 424 | return rc; |
425 | } | 425 | } |
426 | 426 | ||
427 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | 427 | static int cmd_attr_register_cpumask(struct genl_info *info) |
428 | { | 428 | { |
429 | int rc; | ||
430 | struct sk_buff *rep_skb; | ||
431 | struct taskstats *stats; | ||
432 | size_t size; | ||
433 | cpumask_var_t mask; | 429 | cpumask_var_t mask; |
430 | int rc; | ||
434 | 431 | ||
435 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | 432 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) |
436 | return -ENOMEM; | 433 | return -ENOMEM; |
437 | |||
438 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); | 434 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK], mask); |
439 | if (rc < 0) | 435 | if (rc < 0) |
440 | goto free_return_rc; | 436 | goto out; |
441 | if (rc == 0) { | 437 | rc = add_del_listener(info->snd_pid, mask, REGISTER); |
442 | rc = add_del_listener(info->snd_pid, mask, REGISTER); | 438 | out: |
443 | goto free_return_rc; | 439 | free_cpumask_var(mask); |
444 | } | 440 | return rc; |
441 | } | ||
442 | |||
443 | static int cmd_attr_deregister_cpumask(struct genl_info *info) | ||
444 | { | ||
445 | cpumask_var_t mask; | ||
446 | int rc; | ||
445 | 447 | ||
448 | if (!alloc_cpumask_var(&mask, GFP_KERNEL)) | ||
449 | return -ENOMEM; | ||
446 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); | 450 | rc = parse(info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK], mask); |
447 | if (rc < 0) | 451 | if (rc < 0) |
448 | goto free_return_rc; | 452 | goto out; |
449 | if (rc == 0) { | 453 | rc = add_del_listener(info->snd_pid, mask, DEREGISTER); |
450 | rc = add_del_listener(info->snd_pid, mask, DEREGISTER); | 454 | out: |
451 | free_return_rc: | ||
452 | free_cpumask_var(mask); | ||
453 | return rc; | ||
454 | } | ||
455 | free_cpumask_var(mask); | 455 | free_cpumask_var(mask); |
456 | return rc; | ||
457 | } | ||
458 | |||
459 | static int cmd_attr_pid(struct genl_info *info) | ||
460 | { | ||
461 | struct taskstats *stats; | ||
462 | struct sk_buff *rep_skb; | ||
463 | size_t size; | ||
464 | u32 pid; | ||
465 | int rc; | ||
456 | 466 | ||
457 | /* | ||
458 | * Size includes space for nested attributes | ||
459 | */ | ||
460 | size = nla_total_size(sizeof(u32)) + | 467 | size = nla_total_size(sizeof(u32)) + |
461 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | 468 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); |
462 | 469 | ||
@@ -465,33 +472,64 @@ free_return_rc: | |||
465 | return rc; | 472 | return rc; |
466 | 473 | ||
467 | rc = -EINVAL; | 474 | rc = -EINVAL; |
468 | if (info->attrs[TASKSTATS_CMD_ATTR_PID]) { | 475 | pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); |
469 | u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]); | 476 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); |
470 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_PID, pid); | 477 | if (!stats) |
471 | if (!stats) | 478 | goto err; |
472 | goto err; | 479 | |
473 | 480 | rc = fill_stats_for_pid(pid, stats); | |
474 | rc = fill_pid(pid, NULL, stats); | 481 | if (rc < 0) |
475 | if (rc < 0) | 482 | goto err; |
476 | goto err; | 483 | return send_reply(rep_skb, info); |
477 | } else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) { | 484 | err: |
478 | u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); | 485 | nlmsg_free(rep_skb); |
479 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); | 486 | return rc; |
480 | if (!stats) | 487 | } |
481 | goto err; | 488 | |
482 | 489 | static int cmd_attr_tgid(struct genl_info *info) | |
483 | rc = fill_tgid(tgid, NULL, stats); | 490 | { |
484 | if (rc < 0) | 491 | struct taskstats *stats; |
485 | goto err; | 492 | struct sk_buff *rep_skb; |
486 | } else | 493 | size_t size; |
494 | u32 tgid; | ||
495 | int rc; | ||
496 | |||
497 | size = nla_total_size(sizeof(u32)) + | ||
498 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | ||
499 | |||
500 | rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); | ||
501 | if (rc < 0) | ||
502 | return rc; | ||
503 | |||
504 | rc = -EINVAL; | ||
505 | tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]); | ||
506 | stats = mk_reply(rep_skb, TASKSTATS_TYPE_TGID, tgid); | ||
507 | if (!stats) | ||
487 | goto err; | 508 | goto err; |
488 | 509 | ||
510 | rc = fill_stats_for_tgid(tgid, stats); | ||
511 | if (rc < 0) | ||
512 | goto err; | ||
489 | return send_reply(rep_skb, info); | 513 | return send_reply(rep_skb, info); |
490 | err: | 514 | err: |
491 | nlmsg_free(rep_skb); | 515 | nlmsg_free(rep_skb); |
492 | return rc; | 516 | return rc; |
493 | } | 517 | } |
494 | 518 | ||
519 | static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | ||
520 | { | ||
521 | if (info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK]) | ||
522 | return cmd_attr_register_cpumask(info); | ||
523 | else if (info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK]) | ||
524 | return cmd_attr_deregister_cpumask(info); | ||
525 | else if (info->attrs[TASKSTATS_CMD_ATTR_PID]) | ||
526 | return cmd_attr_pid(info); | ||
527 | else if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) | ||
528 | return cmd_attr_tgid(info); | ||
529 | else | ||
530 | return -EINVAL; | ||
531 | } | ||
532 | |||
495 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) | 533 | static struct taskstats *taskstats_tgid_alloc(struct task_struct *tsk) |
496 | { | 534 | { |
497 | struct signal_struct *sig = tsk->signal; | 535 | struct signal_struct *sig = tsk->signal; |
@@ -555,9 +593,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | |||
555 | if (!stats) | 593 | if (!stats) |
556 | goto err; | 594 | goto err; |
557 | 595 | ||
558 | rc = fill_pid(-1, tsk, stats); | 596 | fill_stats(tsk, stats); |
559 | if (rc < 0) | ||
560 | goto err; | ||
561 | 597 | ||
562 | /* | 598 | /* |
563 | * Doesn't matter if tsk is the leader or the last group member leaving | 599 | * Doesn't matter if tsk is the leader or the last group member leaving |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index b8d2852baa4a..2dec9bcde8b4 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/perf_event.h> | 31 | #include <linux/perf_event.h> |
32 | #include <linux/stringify.h> | 32 | #include <linux/stringify.h> |
33 | #include <linux/limits.h> | 33 | #include <linux/limits.h> |
34 | #include <linux/uaccess.h> | ||
35 | #include <asm/bitsperlong.h> | 34 | #include <asm/bitsperlong.h> |
36 | 35 | ||
37 | #include "trace.h" | 36 | #include "trace.h" |
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index 0a67e041edf8..24dc60d9fa1f 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c | |||
@@ -63,12 +63,10 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | |||
63 | stats->ac_ppid = pid_alive(tsk) ? | 63 | stats->ac_ppid = pid_alive(tsk) ? |
64 | rcu_dereference(tsk->real_parent)->tgid : 0; | 64 | rcu_dereference(tsk->real_parent)->tgid : 0; |
65 | rcu_read_unlock(); | 65 | rcu_read_unlock(); |
66 | stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; | 66 | stats->ac_utime = cputime_to_usecs(tsk->utime); |
67 | stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; | 67 | stats->ac_stime = cputime_to_usecs(tsk->stime); |
68 | stats->ac_utimescaled = | 68 | stats->ac_utimescaled = cputime_to_usecs(tsk->utimescaled); |
69 | cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC; | 69 | stats->ac_stimescaled = cputime_to_usecs(tsk->stimescaled); |
70 | stats->ac_stimescaled = | ||
71 | cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC; | ||
72 | stats->ac_minflt = tsk->min_flt; | 70 | stats->ac_minflt = tsk->min_flt; |
73 | stats->ac_majflt = tsk->maj_flt; | 71 | stats->ac_majflt = tsk->maj_flt; |
74 | 72 | ||
diff --git a/mm/highmem.c b/mm/highmem.c index 781e754a75ac..693394daa2ed 100644 --- a/mm/highmem.c +++ b/mm/highmem.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #include <linux/kgdb.h> | 29 | #include <linux/kgdb.h> |
30 | #include <asm/tlbflush.h> | 30 | #include <asm/tlbflush.h> |
31 | 31 | ||
32 | |||
33 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_X86_32) | ||
34 | DEFINE_PER_CPU(int, __kmap_atomic_idx); | ||
35 | #endif | ||
36 | |||
32 | /* | 37 | /* |
33 | * Virtual_count is not a pure "count". | 38 | * Virtual_count is not a pure "count". |
34 | * 0 means that it is not mapped, and has not been mapped | 39 | * 0 means that it is not mapped, and has not been mapped |
@@ -43,7 +48,6 @@ unsigned long totalhigh_pages __read_mostly; | |||
43 | EXPORT_SYMBOL(totalhigh_pages); | 48 | EXPORT_SYMBOL(totalhigh_pages); |
44 | 49 | ||
45 | 50 | ||
46 | DEFINE_PER_CPU(int, __kmap_atomic_idx); | ||
47 | EXPORT_PER_CPU_SYMBOL(__kmap_atomic_idx); | 51 | EXPORT_PER_CPU_SYMBOL(__kmap_atomic_idx); |
48 | 52 | ||
49 | unsigned int nr_free_highpages (void) | 53 | unsigned int nr_free_highpages (void) |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 9be3cf8a5da4..9a99cfaf0a19 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -89,7 +89,10 @@ enum mem_cgroup_stat_index { | |||
89 | MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */ | 89 | MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */ |
90 | MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */ | 90 | MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */ |
91 | MEM_CGROUP_STAT_SWAPOUT, /* # of pages, swapped out */ | 91 | MEM_CGROUP_STAT_SWAPOUT, /* # of pages, swapped out */ |
92 | MEM_CGROUP_EVENTS, /* incremented at every pagein/pageout */ | 92 | MEM_CGROUP_STAT_DATA, /* end of data requires synchronization */ |
93 | /* incremented at every pagein/pageout */ | ||
94 | MEM_CGROUP_EVENTS = MEM_CGROUP_STAT_DATA, | ||
95 | MEM_CGROUP_ON_MOVE, /* someone is moving account between groups */ | ||
93 | 96 | ||
94 | MEM_CGROUP_STAT_NSTATS, | 97 | MEM_CGROUP_STAT_NSTATS, |
95 | }; | 98 | }; |
@@ -254,6 +257,12 @@ struct mem_cgroup { | |||
254 | * percpu counter. | 257 | * percpu counter. |
255 | */ | 258 | */ |
256 | struct mem_cgroup_stat_cpu *stat; | 259 | struct mem_cgroup_stat_cpu *stat; |
260 | /* | ||
261 | * used when a cpu is offlined or other synchronizations | ||
262 | * See mem_cgroup_read_stat(). | ||
263 | */ | ||
264 | struct mem_cgroup_stat_cpu nocpu_base; | ||
265 | spinlock_t pcp_counter_lock; | ||
257 | }; | 266 | }; |
258 | 267 | ||
259 | /* Stuffs for move charges at task migration. */ | 268 | /* Stuffs for move charges at task migration. */ |
@@ -530,14 +539,40 @@ mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) | |||
530 | return mz; | 539 | return mz; |
531 | } | 540 | } |
532 | 541 | ||
542 | /* | ||
543 | * Implementation Note: reading percpu statistics for memcg. | ||
544 | * | ||
545 | * Both of vmstat[] and percpu_counter has threshold and do periodic | ||
546 | * synchronization to implement "quick" read. There are trade-off between | ||
547 | * reading cost and precision of value. Then, we may have a chance to implement | ||
548 | * a periodic synchronizion of counter in memcg's counter. | ||
549 | * | ||
550 | * But this _read() function is used for user interface now. The user accounts | ||
551 | * memory usage by memory cgroup and he _always_ requires exact value because | ||
552 | * he accounts memory. Even if we provide quick-and-fuzzy read, we always | ||
553 | * have to visit all online cpus and make sum. So, for now, unnecessary | ||
554 | * synchronization is not implemented. (just implemented for cpu hotplug) | ||
555 | * | ||
556 | * If there are kernel internal actions which can make use of some not-exact | ||
557 | * value, and reading all cpu value can be performance bottleneck in some | ||
558 | * common workload, threashold and synchonization as vmstat[] should be | ||
559 | * implemented. | ||
560 | */ | ||
533 | static s64 mem_cgroup_read_stat(struct mem_cgroup *mem, | 561 | static s64 mem_cgroup_read_stat(struct mem_cgroup *mem, |
534 | enum mem_cgroup_stat_index idx) | 562 | enum mem_cgroup_stat_index idx) |
535 | { | 563 | { |
536 | int cpu; | 564 | int cpu; |
537 | s64 val = 0; | 565 | s64 val = 0; |
538 | 566 | ||
539 | for_each_possible_cpu(cpu) | 567 | get_online_cpus(); |
568 | for_each_online_cpu(cpu) | ||
540 | val += per_cpu(mem->stat->count[idx], cpu); | 569 | val += per_cpu(mem->stat->count[idx], cpu); |
570 | #ifdef CONFIG_HOTPLUG_CPU | ||
571 | spin_lock(&mem->pcp_counter_lock); | ||
572 | val += mem->nocpu_base.count[idx]; | ||
573 | spin_unlock(&mem->pcp_counter_lock); | ||
574 | #endif | ||
575 | put_online_cpus(); | ||
541 | return val; | 576 | return val; |
542 | } | 577 | } |
543 | 578 | ||
@@ -659,40 +694,83 @@ static struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) | |||
659 | return mem; | 694 | return mem; |
660 | } | 695 | } |
661 | 696 | ||
662 | /* | 697 | /* The caller has to guarantee "mem" exists before calling this */ |
663 | * Call callback function against all cgroup under hierarchy tree. | 698 | static struct mem_cgroup *mem_cgroup_start_loop(struct mem_cgroup *mem) |
664 | */ | ||
665 | static int mem_cgroup_walk_tree(struct mem_cgroup *root, void *data, | ||
666 | int (*func)(struct mem_cgroup *, void *)) | ||
667 | { | 699 | { |
668 | int found, ret, nextid; | ||
669 | struct cgroup_subsys_state *css; | 700 | struct cgroup_subsys_state *css; |
670 | struct mem_cgroup *mem; | 701 | int found; |
671 | |||
672 | if (!root->use_hierarchy) | ||
673 | return (*func)(root, data); | ||
674 | 702 | ||
675 | nextid = 1; | 703 | if (!mem) /* ROOT cgroup has the smallest ID */ |
676 | do { | 704 | return root_mem_cgroup; /*css_put/get against root is ignored*/ |
677 | ret = 0; | 705 | if (!mem->use_hierarchy) { |
706 | if (css_tryget(&mem->css)) | ||
707 | return mem; | ||
708 | return NULL; | ||
709 | } | ||
710 | rcu_read_lock(); | ||
711 | /* | ||
712 | * searching a memory cgroup which has the smallest ID under given | ||
713 | * ROOT cgroup. (ID >= 1) | ||
714 | */ | ||
715 | css = css_get_next(&mem_cgroup_subsys, 1, &mem->css, &found); | ||
716 | if (css && css_tryget(css)) | ||
717 | mem = container_of(css, struct mem_cgroup, css); | ||
718 | else | ||
678 | mem = NULL; | 719 | mem = NULL; |
720 | rcu_read_unlock(); | ||
721 | return mem; | ||
722 | } | ||
723 | |||
724 | static struct mem_cgroup *mem_cgroup_get_next(struct mem_cgroup *iter, | ||
725 | struct mem_cgroup *root, | ||
726 | bool cond) | ||
727 | { | ||
728 | int nextid = css_id(&iter->css) + 1; | ||
729 | int found; | ||
730 | int hierarchy_used; | ||
731 | struct cgroup_subsys_state *css; | ||
732 | |||
733 | hierarchy_used = iter->use_hierarchy; | ||
679 | 734 | ||
735 | css_put(&iter->css); | ||
736 | /* If no ROOT, walk all, ignore hierarchy */ | ||
737 | if (!cond || (root && !hierarchy_used)) | ||
738 | return NULL; | ||
739 | |||
740 | if (!root) | ||
741 | root = root_mem_cgroup; | ||
742 | |||
743 | do { | ||
744 | iter = NULL; | ||
680 | rcu_read_lock(); | 745 | rcu_read_lock(); |
681 | css = css_get_next(&mem_cgroup_subsys, nextid, &root->css, | 746 | |
682 | &found); | 747 | css = css_get_next(&mem_cgroup_subsys, nextid, |
748 | &root->css, &found); | ||
683 | if (css && css_tryget(css)) | 749 | if (css && css_tryget(css)) |
684 | mem = container_of(css, struct mem_cgroup, css); | 750 | iter = container_of(css, struct mem_cgroup, css); |
685 | rcu_read_unlock(); | 751 | rcu_read_unlock(); |
686 | 752 | /* If css is NULL, no more cgroups will be found */ | |
687 | if (mem) { | ||
688 | ret = (*func)(mem, data); | ||
689 | css_put(&mem->css); | ||
690 | } | ||
691 | nextid = found + 1; | 753 | nextid = found + 1; |
692 | } while (!ret && css); | 754 | } while (css && !iter); |
693 | 755 | ||
694 | return ret; | 756 | return iter; |
695 | } | 757 | } |
758 | /* | ||
759 | * for_eacn_mem_cgroup_tree() for visiting all cgroup under tree. Please | ||
760 | * be careful that "break" loop is not allowed. We have reference count. | ||
761 | * Instead of that modify "cond" to be false and "continue" to exit the loop. | ||
762 | */ | ||
763 | #define for_each_mem_cgroup_tree_cond(iter, root, cond) \ | ||
764 | for (iter = mem_cgroup_start_loop(root);\ | ||
765 | iter != NULL;\ | ||
766 | iter = mem_cgroup_get_next(iter, root, cond)) | ||
767 | |||
768 | #define for_each_mem_cgroup_tree(iter, root) \ | ||
769 | for_each_mem_cgroup_tree_cond(iter, root, true) | ||
770 | |||
771 | #define for_each_mem_cgroup_all(iter) \ | ||
772 | for_each_mem_cgroup_tree_cond(iter, NULL, true) | ||
773 | |||
696 | 774 | ||
697 | static inline bool mem_cgroup_is_root(struct mem_cgroup *mem) | 775 | static inline bool mem_cgroup_is_root(struct mem_cgroup *mem) |
698 | { | 776 | { |
@@ -1051,7 +1129,52 @@ static unsigned int get_swappiness(struct mem_cgroup *memcg) | |||
1051 | return swappiness; | 1129 | return swappiness; |
1052 | } | 1130 | } |
1053 | 1131 | ||
1054 | /* A routine for testing mem is not under move_account */ | 1132 | static void mem_cgroup_start_move(struct mem_cgroup *mem) |
1133 | { | ||
1134 | int cpu; | ||
1135 | |||
1136 | get_online_cpus(); | ||
1137 | spin_lock(&mem->pcp_counter_lock); | ||
1138 | for_each_online_cpu(cpu) | ||
1139 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) += 1; | ||
1140 | mem->nocpu_base.count[MEM_CGROUP_ON_MOVE] += 1; | ||
1141 | spin_unlock(&mem->pcp_counter_lock); | ||
1142 | put_online_cpus(); | ||
1143 | |||
1144 | synchronize_rcu(); | ||
1145 | } | ||
1146 | |||
1147 | static void mem_cgroup_end_move(struct mem_cgroup *mem) | ||
1148 | { | ||
1149 | int cpu; | ||
1150 | |||
1151 | if (!mem) | ||
1152 | return; | ||
1153 | get_online_cpus(); | ||
1154 | spin_lock(&mem->pcp_counter_lock); | ||
1155 | for_each_online_cpu(cpu) | ||
1156 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) -= 1; | ||
1157 | mem->nocpu_base.count[MEM_CGROUP_ON_MOVE] -= 1; | ||
1158 | spin_unlock(&mem->pcp_counter_lock); | ||
1159 | put_online_cpus(); | ||
1160 | } | ||
1161 | /* | ||
1162 | * 2 routines for checking "mem" is under move_account() or not. | ||
1163 | * | ||
1164 | * mem_cgroup_stealed() - checking a cgroup is mc.from or not. This is used | ||
1165 | * for avoiding race in accounting. If true, | ||
1166 | * pc->mem_cgroup may be overwritten. | ||
1167 | * | ||
1168 | * mem_cgroup_under_move() - checking a cgroup is mc.from or mc.to or | ||
1169 | * under hierarchy of moving cgroups. This is for | ||
1170 | * waiting at hith-memory prressure caused by "move". | ||
1171 | */ | ||
1172 | |||
1173 | static bool mem_cgroup_stealed(struct mem_cgroup *mem) | ||
1174 | { | ||
1175 | VM_BUG_ON(!rcu_read_lock_held()); | ||
1176 | return this_cpu_read(mem->stat->count[MEM_CGROUP_ON_MOVE]) > 0; | ||
1177 | } | ||
1055 | 1178 | ||
1056 | static bool mem_cgroup_under_move(struct mem_cgroup *mem) | 1179 | static bool mem_cgroup_under_move(struct mem_cgroup *mem) |
1057 | { | 1180 | { |
@@ -1092,13 +1215,6 @@ static bool mem_cgroup_wait_acct_move(struct mem_cgroup *mem) | |||
1092 | return false; | 1215 | return false; |
1093 | } | 1216 | } |
1094 | 1217 | ||
1095 | static int mem_cgroup_count_children_cb(struct mem_cgroup *mem, void *data) | ||
1096 | { | ||
1097 | int *val = data; | ||
1098 | (*val)++; | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | /** | 1218 | /** |
1103 | * mem_cgroup_print_oom_info: Called from OOM with tasklist_lock held in read mode. | 1219 | * mem_cgroup_print_oom_info: Called from OOM with tasklist_lock held in read mode. |
1104 | * @memcg: The memory cgroup that went over limit | 1220 | * @memcg: The memory cgroup that went over limit |
@@ -1173,7 +1289,10 @@ done: | |||
1173 | static int mem_cgroup_count_children(struct mem_cgroup *mem) | 1289 | static int mem_cgroup_count_children(struct mem_cgroup *mem) |
1174 | { | 1290 | { |
1175 | int num = 0; | 1291 | int num = 0; |
1176 | mem_cgroup_walk_tree(mem, &num, mem_cgroup_count_children_cb); | 1292 | struct mem_cgroup *iter; |
1293 | |||
1294 | for_each_mem_cgroup_tree(iter, mem) | ||
1295 | num++; | ||
1177 | return num; | 1296 | return num; |
1178 | } | 1297 | } |
1179 | 1298 | ||
@@ -1322,49 +1441,39 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, | |||
1322 | return total; | 1441 | return total; |
1323 | } | 1442 | } |
1324 | 1443 | ||
1325 | static int mem_cgroup_oom_lock_cb(struct mem_cgroup *mem, void *data) | ||
1326 | { | ||
1327 | int *val = (int *)data; | ||
1328 | int x; | ||
1329 | /* | ||
1330 | * Logically, we can stop scanning immediately when we find | ||
1331 | * a memcg is already locked. But condidering unlock ops and | ||
1332 | * creation/removal of memcg, scan-all is simple operation. | ||
1333 | */ | ||
1334 | x = atomic_inc_return(&mem->oom_lock); | ||
1335 | *val = max(x, *val); | ||
1336 | return 0; | ||
1337 | } | ||
1338 | /* | 1444 | /* |
1339 | * Check OOM-Killer is already running under our hierarchy. | 1445 | * Check OOM-Killer is already running under our hierarchy. |
1340 | * If someone is running, return false. | 1446 | * If someone is running, return false. |
1341 | */ | 1447 | */ |
1342 | static bool mem_cgroup_oom_lock(struct mem_cgroup *mem) | 1448 | static bool mem_cgroup_oom_lock(struct mem_cgroup *mem) |
1343 | { | 1449 | { |
1344 | int lock_count = 0; | 1450 | int x, lock_count = 0; |
1451 | struct mem_cgroup *iter; | ||
1345 | 1452 | ||
1346 | mem_cgroup_walk_tree(mem, &lock_count, mem_cgroup_oom_lock_cb); | 1453 | for_each_mem_cgroup_tree(iter, mem) { |
1454 | x = atomic_inc_return(&iter->oom_lock); | ||
1455 | lock_count = max(x, lock_count); | ||
1456 | } | ||
1347 | 1457 | ||
1348 | if (lock_count == 1) | 1458 | if (lock_count == 1) |
1349 | return true; | 1459 | return true; |
1350 | return false; | 1460 | return false; |
1351 | } | 1461 | } |
1352 | 1462 | ||
1353 | static int mem_cgroup_oom_unlock_cb(struct mem_cgroup *mem, void *data) | 1463 | static int mem_cgroup_oom_unlock(struct mem_cgroup *mem) |
1354 | { | 1464 | { |
1465 | struct mem_cgroup *iter; | ||
1466 | |||
1355 | /* | 1467 | /* |
1356 | * When a new child is created while the hierarchy is under oom, | 1468 | * When a new child is created while the hierarchy is under oom, |
1357 | * mem_cgroup_oom_lock() may not be called. We have to use | 1469 | * mem_cgroup_oom_lock() may not be called. We have to use |
1358 | * atomic_add_unless() here. | 1470 | * atomic_add_unless() here. |
1359 | */ | 1471 | */ |
1360 | atomic_add_unless(&mem->oom_lock, -1, 0); | 1472 | for_each_mem_cgroup_tree(iter, mem) |
1473 | atomic_add_unless(&iter->oom_lock, -1, 0); | ||
1361 | return 0; | 1474 | return 0; |
1362 | } | 1475 | } |
1363 | 1476 | ||
1364 | static void mem_cgroup_oom_unlock(struct mem_cgroup *mem) | ||
1365 | { | ||
1366 | mem_cgroup_walk_tree(mem, NULL, mem_cgroup_oom_unlock_cb); | ||
1367 | } | ||
1368 | 1477 | ||
1369 | static DEFINE_MUTEX(memcg_oom_mutex); | 1478 | static DEFINE_MUTEX(memcg_oom_mutex); |
1370 | static DECLARE_WAIT_QUEUE_HEAD(memcg_oom_waitq); | 1479 | static DECLARE_WAIT_QUEUE_HEAD(memcg_oom_waitq); |
@@ -1462,34 +1571,73 @@ bool mem_cgroup_handle_oom(struct mem_cgroup *mem, gfp_t mask) | |||
1462 | /* | 1571 | /* |
1463 | * Currently used to update mapped file statistics, but the routine can be | 1572 | * Currently used to update mapped file statistics, but the routine can be |
1464 | * generalized to update other statistics as well. | 1573 | * generalized to update other statistics as well. |
1574 | * | ||
1575 | * Notes: Race condition | ||
1576 | * | ||
1577 | * We usually use page_cgroup_lock() for accessing page_cgroup member but | ||
1578 | * it tends to be costly. But considering some conditions, we doesn't need | ||
1579 | * to do so _always_. | ||
1580 | * | ||
1581 | * Considering "charge", lock_page_cgroup() is not required because all | ||
1582 | * file-stat operations happen after a page is attached to radix-tree. There | ||
1583 | * are no race with "charge". | ||
1584 | * | ||
1585 | * Considering "uncharge", we know that memcg doesn't clear pc->mem_cgroup | ||
1586 | * at "uncharge" intentionally. So, we always see valid pc->mem_cgroup even | ||
1587 | * if there are race with "uncharge". Statistics itself is properly handled | ||
1588 | * by flags. | ||
1589 | * | ||
1590 | * Considering "move", this is an only case we see a race. To make the race | ||
1591 | * small, we check MEM_CGROUP_ON_MOVE percpu value and detect there are | ||
1592 | * possibility of race condition. If there is, we take a lock. | ||
1465 | */ | 1593 | */ |
1466 | void mem_cgroup_update_file_mapped(struct page *page, int val) | 1594 | |
1595 | static void mem_cgroup_update_file_stat(struct page *page, int idx, int val) | ||
1467 | { | 1596 | { |
1468 | struct mem_cgroup *mem; | 1597 | struct mem_cgroup *mem; |
1469 | struct page_cgroup *pc; | 1598 | struct page_cgroup *pc = lookup_page_cgroup(page); |
1599 | bool need_unlock = false; | ||
1470 | 1600 | ||
1471 | pc = lookup_page_cgroup(page); | ||
1472 | if (unlikely(!pc)) | 1601 | if (unlikely(!pc)) |
1473 | return; | 1602 | return; |
1474 | 1603 | ||
1475 | lock_page_cgroup(pc); | 1604 | rcu_read_lock(); |
1476 | mem = pc->mem_cgroup; | 1605 | mem = pc->mem_cgroup; |
1477 | if (!mem || !PageCgroupUsed(pc)) | 1606 | if (unlikely(!mem || !PageCgroupUsed(pc))) |
1478 | goto done; | 1607 | goto out; |
1608 | /* pc->mem_cgroup is unstable ? */ | ||
1609 | if (unlikely(mem_cgroup_stealed(mem))) { | ||
1610 | /* take a lock against to access pc->mem_cgroup */ | ||
1611 | lock_page_cgroup(pc); | ||
1612 | need_unlock = true; | ||
1613 | mem = pc->mem_cgroup; | ||
1614 | if (!mem || !PageCgroupUsed(pc)) | ||
1615 | goto out; | ||
1616 | } | ||
1479 | 1617 | ||
1480 | /* | 1618 | this_cpu_add(mem->stat->count[idx], val); |
1481 | * Preemption is already disabled. We can use __this_cpu_xxx | 1619 | |
1482 | */ | 1620 | switch (idx) { |
1483 | if (val > 0) { | 1621 | case MEM_CGROUP_STAT_FILE_MAPPED: |
1484 | __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]); | 1622 | if (val > 0) |
1485 | SetPageCgroupFileMapped(pc); | 1623 | SetPageCgroupFileMapped(pc); |
1486 | } else { | 1624 | else if (!page_mapped(page)) |
1487 | __this_cpu_dec(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]); | 1625 | ClearPageCgroupFileMapped(pc); |
1488 | ClearPageCgroupFileMapped(pc); | 1626 | break; |
1627 | default: | ||
1628 | BUG(); | ||
1489 | } | 1629 | } |
1490 | 1630 | ||
1491 | done: | 1631 | out: |
1492 | unlock_page_cgroup(pc); | 1632 | if (unlikely(need_unlock)) |
1633 | unlock_page_cgroup(pc); | ||
1634 | rcu_read_unlock(); | ||
1635 | return; | ||
1636 | } | ||
1637 | |||
1638 | void mem_cgroup_update_file_mapped(struct page *page, int val) | ||
1639 | { | ||
1640 | mem_cgroup_update_file_stat(page, MEM_CGROUP_STAT_FILE_MAPPED, val); | ||
1493 | } | 1641 | } |
1494 | 1642 | ||
1495 | /* | 1643 | /* |
@@ -1605,15 +1753,55 @@ static void drain_all_stock_sync(void) | |||
1605 | atomic_dec(&memcg_drain_count); | 1753 | atomic_dec(&memcg_drain_count); |
1606 | } | 1754 | } |
1607 | 1755 | ||
1608 | static int __cpuinit memcg_stock_cpu_callback(struct notifier_block *nb, | 1756 | /* |
1757 | * This function drains percpu counter value from DEAD cpu and | ||
1758 | * move it to local cpu. Note that this function can be preempted. | ||
1759 | */ | ||
1760 | static void mem_cgroup_drain_pcp_counter(struct mem_cgroup *mem, int cpu) | ||
1761 | { | ||
1762 | int i; | ||
1763 | |||
1764 | spin_lock(&mem->pcp_counter_lock); | ||
1765 | for (i = 0; i < MEM_CGROUP_STAT_DATA; i++) { | ||
1766 | s64 x = per_cpu(mem->stat->count[i], cpu); | ||
1767 | |||
1768 | per_cpu(mem->stat->count[i], cpu) = 0; | ||
1769 | mem->nocpu_base.count[i] += x; | ||
1770 | } | ||
1771 | /* need to clear ON_MOVE value, works as a kind of lock. */ | ||
1772 | per_cpu(mem->stat->count[MEM_CGROUP_ON_MOVE], cpu) = 0; | ||
1773 | spin_unlock(&mem->pcp_counter_lock); | ||
1774 | } | ||
1775 | |||
1776 | static void synchronize_mem_cgroup_on_move(struct mem_cgroup *mem, int cpu) | ||
1777 | { | ||
1778 | int idx = MEM_CGROUP_ON_MOVE; | ||
1779 | |||
1780 | spin_lock(&mem->pcp_counter_lock); | ||
1781 | per_cpu(mem->stat->count[idx], cpu) = mem->nocpu_base.count[idx]; | ||
1782 | spin_unlock(&mem->pcp_counter_lock); | ||
1783 | } | ||
1784 | |||
1785 | static int __cpuinit memcg_cpu_hotplug_callback(struct notifier_block *nb, | ||
1609 | unsigned long action, | 1786 | unsigned long action, |
1610 | void *hcpu) | 1787 | void *hcpu) |
1611 | { | 1788 | { |
1612 | int cpu = (unsigned long)hcpu; | 1789 | int cpu = (unsigned long)hcpu; |
1613 | struct memcg_stock_pcp *stock; | 1790 | struct memcg_stock_pcp *stock; |
1791 | struct mem_cgroup *iter; | ||
1792 | |||
1793 | if ((action == CPU_ONLINE)) { | ||
1794 | for_each_mem_cgroup_all(iter) | ||
1795 | synchronize_mem_cgroup_on_move(iter, cpu); | ||
1796 | return NOTIFY_OK; | ||
1797 | } | ||
1614 | 1798 | ||
1615 | if (action != CPU_DEAD) | 1799 | if ((action != CPU_DEAD) || action != CPU_DEAD_FROZEN) |
1616 | return NOTIFY_OK; | 1800 | return NOTIFY_OK; |
1801 | |||
1802 | for_each_mem_cgroup_all(iter) | ||
1803 | mem_cgroup_drain_pcp_counter(iter, cpu); | ||
1804 | |||
1617 | stock = &per_cpu(memcg_stock, cpu); | 1805 | stock = &per_cpu(memcg_stock, cpu); |
1618 | drain_stock(stock); | 1806 | drain_stock(stock); |
1619 | return NOTIFY_OK; | 1807 | return NOTIFY_OK; |
@@ -3038,6 +3226,7 @@ move_account: | |||
3038 | lru_add_drain_all(); | 3226 | lru_add_drain_all(); |
3039 | drain_all_stock_sync(); | 3227 | drain_all_stock_sync(); |
3040 | ret = 0; | 3228 | ret = 0; |
3229 | mem_cgroup_start_move(mem); | ||
3041 | for_each_node_state(node, N_HIGH_MEMORY) { | 3230 | for_each_node_state(node, N_HIGH_MEMORY) { |
3042 | for (zid = 0; !ret && zid < MAX_NR_ZONES; zid++) { | 3231 | for (zid = 0; !ret && zid < MAX_NR_ZONES; zid++) { |
3043 | enum lru_list l; | 3232 | enum lru_list l; |
@@ -3051,6 +3240,7 @@ move_account: | |||
3051 | if (ret) | 3240 | if (ret) |
3052 | break; | 3241 | break; |
3053 | } | 3242 | } |
3243 | mem_cgroup_end_move(mem); | ||
3054 | memcg_oom_recover(mem); | 3244 | memcg_oom_recover(mem); |
3055 | /* it seems parent cgroup doesn't have enough mem */ | 3245 | /* it seems parent cgroup doesn't have enough mem */ |
3056 | if (ret == -ENOMEM) | 3246 | if (ret == -ENOMEM) |
@@ -3137,33 +3327,25 @@ static int mem_cgroup_hierarchy_write(struct cgroup *cont, struct cftype *cft, | |||
3137 | return retval; | 3327 | return retval; |
3138 | } | 3328 | } |
3139 | 3329 | ||
3140 | struct mem_cgroup_idx_data { | ||
3141 | s64 val; | ||
3142 | enum mem_cgroup_stat_index idx; | ||
3143 | }; | ||
3144 | 3330 | ||
3145 | static int | 3331 | static u64 mem_cgroup_get_recursive_idx_stat(struct mem_cgroup *mem, |
3146 | mem_cgroup_get_idx_stat(struct mem_cgroup *mem, void *data) | 3332 | enum mem_cgroup_stat_index idx) |
3147 | { | 3333 | { |
3148 | struct mem_cgroup_idx_data *d = data; | 3334 | struct mem_cgroup *iter; |
3149 | d->val += mem_cgroup_read_stat(mem, d->idx); | 3335 | s64 val = 0; |
3150 | return 0; | ||
3151 | } | ||
3152 | 3336 | ||
3153 | static void | 3337 | /* each per cpu's value can be minus.Then, use s64 */ |
3154 | mem_cgroup_get_recursive_idx_stat(struct mem_cgroup *mem, | 3338 | for_each_mem_cgroup_tree(iter, mem) |
3155 | enum mem_cgroup_stat_index idx, s64 *val) | 3339 | val += mem_cgroup_read_stat(iter, idx); |
3156 | { | 3340 | |
3157 | struct mem_cgroup_idx_data d; | 3341 | if (val < 0) /* race ? */ |
3158 | d.idx = idx; | 3342 | val = 0; |
3159 | d.val = 0; | 3343 | return val; |
3160 | mem_cgroup_walk_tree(mem, &d, mem_cgroup_get_idx_stat); | ||
3161 | *val = d.val; | ||
3162 | } | 3344 | } |
3163 | 3345 | ||
3164 | static inline u64 mem_cgroup_usage(struct mem_cgroup *mem, bool swap) | 3346 | static inline u64 mem_cgroup_usage(struct mem_cgroup *mem, bool swap) |
3165 | { | 3347 | { |
3166 | u64 idx_val, val; | 3348 | u64 val; |
3167 | 3349 | ||
3168 | if (!mem_cgroup_is_root(mem)) { | 3350 | if (!mem_cgroup_is_root(mem)) { |
3169 | if (!swap) | 3351 | if (!swap) |
@@ -3172,16 +3354,12 @@ static inline u64 mem_cgroup_usage(struct mem_cgroup *mem, bool swap) | |||
3172 | return res_counter_read_u64(&mem->memsw, RES_USAGE); | 3354 | return res_counter_read_u64(&mem->memsw, RES_USAGE); |
3173 | } | 3355 | } |
3174 | 3356 | ||
3175 | mem_cgroup_get_recursive_idx_stat(mem, MEM_CGROUP_STAT_CACHE, &idx_val); | 3357 | val = mem_cgroup_get_recursive_idx_stat(mem, MEM_CGROUP_STAT_CACHE); |
3176 | val = idx_val; | 3358 | val += mem_cgroup_get_recursive_idx_stat(mem, MEM_CGROUP_STAT_RSS); |
3177 | mem_cgroup_get_recursive_idx_stat(mem, MEM_CGROUP_STAT_RSS, &idx_val); | ||
3178 | val += idx_val; | ||
3179 | 3359 | ||
3180 | if (swap) { | 3360 | if (swap) |
3181 | mem_cgroup_get_recursive_idx_stat(mem, | 3361 | val += mem_cgroup_get_recursive_idx_stat(mem, |
3182 | MEM_CGROUP_STAT_SWAPOUT, &idx_val); | 3362 | MEM_CGROUP_STAT_SWAPOUT); |
3183 | val += idx_val; | ||
3184 | } | ||
3185 | 3363 | ||
3186 | return val << PAGE_SHIFT; | 3364 | return val << PAGE_SHIFT; |
3187 | } | 3365 | } |
@@ -3389,9 +3567,9 @@ struct { | |||
3389 | }; | 3567 | }; |
3390 | 3568 | ||
3391 | 3569 | ||
3392 | static int mem_cgroup_get_local_stat(struct mem_cgroup *mem, void *data) | 3570 | static void |
3571 | mem_cgroup_get_local_stat(struct mem_cgroup *mem, struct mcs_total_stat *s) | ||
3393 | { | 3572 | { |
3394 | struct mcs_total_stat *s = data; | ||
3395 | s64 val; | 3573 | s64 val; |
3396 | 3574 | ||
3397 | /* per cpu stat */ | 3575 | /* per cpu stat */ |
@@ -3421,13 +3599,15 @@ static int mem_cgroup_get_local_stat(struct mem_cgroup *mem, void *data) | |||
3421 | s->stat[MCS_ACTIVE_FILE] += val * PAGE_SIZE; | 3599 | s->stat[MCS_ACTIVE_FILE] += val * PAGE_SIZE; |
3422 | val = mem_cgroup_get_local_zonestat(mem, LRU_UNEVICTABLE); | 3600 | val = mem_cgroup_get_local_zonestat(mem, LRU_UNEVICTABLE); |
3423 | s->stat[MCS_UNEVICTABLE] += val * PAGE_SIZE; | 3601 | s->stat[MCS_UNEVICTABLE] += val * PAGE_SIZE; |
3424 | return 0; | ||
3425 | } | 3602 | } |
3426 | 3603 | ||
3427 | static void | 3604 | static void |
3428 | mem_cgroup_get_total_stat(struct mem_cgroup *mem, struct mcs_total_stat *s) | 3605 | mem_cgroup_get_total_stat(struct mem_cgroup *mem, struct mcs_total_stat *s) |
3429 | { | 3606 | { |
3430 | mem_cgroup_walk_tree(mem, s, mem_cgroup_get_local_stat); | 3607 | struct mem_cgroup *iter; |
3608 | |||
3609 | for_each_mem_cgroup_tree(iter, mem) | ||
3610 | mem_cgroup_get_local_stat(iter, s); | ||
3431 | } | 3611 | } |
3432 | 3612 | ||
3433 | static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, | 3613 | static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, |
@@ -3604,7 +3784,7 @@ static int compare_thresholds(const void *a, const void *b) | |||
3604 | return _a->threshold - _b->threshold; | 3784 | return _a->threshold - _b->threshold; |
3605 | } | 3785 | } |
3606 | 3786 | ||
3607 | static int mem_cgroup_oom_notify_cb(struct mem_cgroup *mem, void *data) | 3787 | static int mem_cgroup_oom_notify_cb(struct mem_cgroup *mem) |
3608 | { | 3788 | { |
3609 | struct mem_cgroup_eventfd_list *ev; | 3789 | struct mem_cgroup_eventfd_list *ev; |
3610 | 3790 | ||
@@ -3615,7 +3795,10 @@ static int mem_cgroup_oom_notify_cb(struct mem_cgroup *mem, void *data) | |||
3615 | 3795 | ||
3616 | static void mem_cgroup_oom_notify(struct mem_cgroup *mem) | 3796 | static void mem_cgroup_oom_notify(struct mem_cgroup *mem) |
3617 | { | 3797 | { |
3618 | mem_cgroup_walk_tree(mem, NULL, mem_cgroup_oom_notify_cb); | 3798 | struct mem_cgroup *iter; |
3799 | |||
3800 | for_each_mem_cgroup_tree(iter, mem) | ||
3801 | mem_cgroup_oom_notify_cb(iter); | ||
3619 | } | 3802 | } |
3620 | 3803 | ||
3621 | static int mem_cgroup_usage_register_event(struct cgroup *cgrp, | 3804 | static int mem_cgroup_usage_register_event(struct cgroup *cgrp, |
@@ -4032,6 +4215,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) | |||
4032 | vfree(mem); | 4215 | vfree(mem); |
4033 | mem = NULL; | 4216 | mem = NULL; |
4034 | } | 4217 | } |
4218 | spin_lock_init(&mem->pcp_counter_lock); | ||
4035 | return mem; | 4219 | return mem; |
4036 | } | 4220 | } |
4037 | 4221 | ||
@@ -4158,7 +4342,7 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) | |||
4158 | &per_cpu(memcg_stock, cpu); | 4342 | &per_cpu(memcg_stock, cpu); |
4159 | INIT_WORK(&stock->work, drain_local_stock); | 4343 | INIT_WORK(&stock->work, drain_local_stock); |
4160 | } | 4344 | } |
4161 | hotcpu_notifier(memcg_stock_cpu_callback, 0); | 4345 | hotcpu_notifier(memcg_cpu_hotplug_callback, 0); |
4162 | } else { | 4346 | } else { |
4163 | parent = mem_cgroup_from_cont(cont->parent); | 4347 | parent = mem_cgroup_from_cont(cont->parent); |
4164 | mem->use_hierarchy = parent->use_hierarchy; | 4348 | mem->use_hierarchy = parent->use_hierarchy; |
@@ -4513,6 +4697,7 @@ static void mem_cgroup_clear_mc(void) | |||
4513 | mc.to = NULL; | 4697 | mc.to = NULL; |
4514 | mc.moving_task = NULL; | 4698 | mc.moving_task = NULL; |
4515 | spin_unlock(&mc.lock); | 4699 | spin_unlock(&mc.lock); |
4700 | mem_cgroup_end_move(from); | ||
4516 | memcg_oom_recover(from); | 4701 | memcg_oom_recover(from); |
4517 | memcg_oom_recover(to); | 4702 | memcg_oom_recover(to); |
4518 | wake_up_all(&mc.waitq); | 4703 | wake_up_all(&mc.waitq); |
@@ -4543,6 +4728,7 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss, | |||
4543 | VM_BUG_ON(mc.moved_charge); | 4728 | VM_BUG_ON(mc.moved_charge); |
4544 | VM_BUG_ON(mc.moved_swap); | 4729 | VM_BUG_ON(mc.moved_swap); |
4545 | VM_BUG_ON(mc.moving_task); | 4730 | VM_BUG_ON(mc.moving_task); |
4731 | mem_cgroup_start_move(from); | ||
4546 | spin_lock(&mc.lock); | 4732 | spin_lock(&mc.lock); |
4547 | mc.from = from; | 4733 | mc.from = from; |
4548 | mc.to = mem; | 4734 | mc.to = mem; |
@@ -378,6 +378,7 @@ void release_pages(struct page **pages, int nr, int cold) | |||
378 | 378 | ||
379 | pagevec_free(&pages_to_free); | 379 | pagevec_free(&pages_to_free); |
380 | } | 380 | } |
381 | EXPORT_SYMBOL(release_pages); | ||
381 | 382 | ||
382 | /* | 383 | /* |
383 | * The pages which we're about to release may be in the deferred lru-addition | 384 | * The pages which we're about to release may be in the deferred lru-addition |