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 |
