diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:54:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-13 21:54:50 -0400 |
commit | dfe2c6dcc8ca2cdc662d7c0473e9811b72ef3370 (patch) | |
tree | 9ed639a08c16322cdf136d576f42df5b97cd1549 | |
parent | a45d572841a24db02a62cf05e1157c35fdd3705b (diff) | |
parent | 64e455079e1bd7787cc47be30b7f601ce682a5f6 (diff) |
Merge branch 'akpm' (patches from Andrew Morton)
Merge second patch-bomb from Andrew Morton:
- a few hotfixes
- drivers/dma updates
- MAINTAINERS updates
- Quite a lot of lib/ updates
- checkpatch updates
- binfmt updates
- autofs4
- drivers/rtc/
- various small tweaks to less used filesystems
- ipc/ updates
- kernel/watchdog.c changes
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (135 commits)
mm: softdirty: enable write notifications on VMAs after VM_SOFTDIRTY cleared
kernel/param: consolidate __{start,stop}___param[] in <linux/moduleparam.h>
ia64: remove duplicate declarations of __per_cpu_start[] and __per_cpu_end[]
frv: remove unused declarations of __start___ex_table and __stop___ex_table
kvm: ensure hard lockup detection is disabled by default
kernel/watchdog.c: control hard lockup detection default
staging: rtl8192u: use %*pEn to escape buffer
staging: rtl8192e: use %*pEn to escape buffer
staging: wlan-ng: use %*pEhp to print SN
lib80211: remove unused print_ssid()
wireless: hostap: proc: print properly escaped SSID
wireless: ipw2x00: print SSID via %*pE
wireless: libertas: print esaped string via %*pE
lib/vsprintf: add %*pE[achnops] format specifier
lib / string_helpers: introduce string_escape_mem()
lib / string_helpers: refactoring the test suite
lib / string_helpers: move documentation to c-file
include/linux: remove strict_strto* definitions
arch/x86/mm/numa.c: fix boot failure when all nodes are hotpluggable
fs: check bh blocknr earlier when searching lru
...
150 files changed, 5589 insertions, 1657 deletions
diff --git a/Documentation/binfmt_misc.txt b/Documentation/binfmt_misc.txt index c1ed6948ba80..6b1de7058371 100644 --- a/Documentation/binfmt_misc.txt +++ b/Documentation/binfmt_misc.txt | |||
@@ -15,39 +15,50 @@ First you must mount binfmt_misc: | |||
15 | mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc | 15 | mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc |
16 | 16 | ||
17 | To actually register a new binary type, you have to set up a string looking like | 17 | To actually register a new binary type, you have to set up a string looking like |
18 | :name:type:offset:magic:mask:interpreter:flags (where you can choose the ':' upon | 18 | :name:type:offset:magic:mask:interpreter:flags (where you can choose the ':' |
19 | your needs) and echo it to /proc/sys/fs/binfmt_misc/register. | 19 | upon your needs) and echo it to /proc/sys/fs/binfmt_misc/register. |
20 | |||
20 | Here is what the fields mean: | 21 | Here is what the fields mean: |
21 | - 'name' is an identifier string. A new /proc file will be created with this | 22 | - 'name' is an identifier string. A new /proc file will be created with this |
22 | name below /proc/sys/fs/binfmt_misc | 23 | name below /proc/sys/fs/binfmt_misc; cannot contain slashes '/' for obvious |
24 | reasons. | ||
23 | - 'type' is the type of recognition. Give 'M' for magic and 'E' for extension. | 25 | - 'type' is the type of recognition. Give 'M' for magic and 'E' for extension. |
24 | - 'offset' is the offset of the magic/mask in the file, counted in bytes. This | 26 | - 'offset' is the offset of the magic/mask in the file, counted in bytes. This |
25 | defaults to 0 if you omit it (i.e. you write ':name:type::magic...') | 27 | defaults to 0 if you omit it (i.e. you write ':name:type::magic...'). Ignored |
28 | when using filename extension matching. | ||
26 | - 'magic' is the byte sequence binfmt_misc is matching for. The magic string | 29 | - 'magic' is the byte sequence binfmt_misc is matching for. The magic string |
27 | may contain hex-encoded characters like \x0a or \xA4. In a shell environment | 30 | may contain hex-encoded characters like \x0a or \xA4. Note that you must |
28 | you will have to write \\x0a to prevent the shell from eating your \. | 31 | escape any NUL bytes; parsing halts at the first one. In a shell environment |
32 | you might have to write \\x0a to prevent the shell from eating your \. | ||
29 | If you chose filename extension matching, this is the extension to be | 33 | If you chose filename extension matching, this is the extension to be |
30 | recognised (without the '.', the \x0a specials are not allowed). Extension | 34 | recognised (without the '.', the \x0a specials are not allowed). Extension |
31 | matching is case sensitive! | 35 | matching is case sensitive, and slashes '/' are not allowed! |
32 | - 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some | 36 | - 'mask' is an (optional, defaults to all 0xff) mask. You can mask out some |
33 | bits from matching by supplying a string like magic and as long as magic. | 37 | bits from matching by supplying a string like magic and as long as magic. |
34 | The mask is anded with the byte sequence of the file. | 38 | The mask is anded with the byte sequence of the file. Note that you must |
39 | escape any NUL bytes; parsing halts at the first one. Ignored when using | ||
40 | filename extension matching. | ||
35 | - 'interpreter' is the program that should be invoked with the binary as first | 41 | - 'interpreter' is the program that should be invoked with the binary as first |
36 | argument (specify the full path) | 42 | argument (specify the full path) |
37 | - 'flags' is an optional field that controls several aspects of the invocation | 43 | - 'flags' is an optional field that controls several aspects of the invocation |
38 | of the interpreter. It is a string of capital letters, each controls a certain | 44 | of the interpreter. It is a string of capital letters, each controls a |
39 | aspect. The following flags are supported - | 45 | certain aspect. The following flags are supported - |
40 | 'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite the | 46 | 'P' - preserve-argv[0]. Legacy behavior of binfmt_misc is to overwrite |
41 | original argv[0] with the full path to the binary. When this flag is | 47 | the original argv[0] with the full path to the binary. When this |
42 | included, binfmt_misc will add an argument to the argument vector for | 48 | flag is included, binfmt_misc will add an argument to the argument |
43 | this purpose, thus preserving the original argv[0]. | 49 | vector for this purpose, thus preserving the original argv[0]. |
50 | e.g. If your interp is set to /bin/foo and you run `blah` (which is | ||
51 | in /usr/local/bin), then the kernel will execute /bin/foo with | ||
52 | argv[] set to ["/bin/foo", "/usr/local/bin/blah", "blah"]. The | ||
53 | interp has to be aware of this so it can execute /usr/local/bin/blah | ||
54 | with argv[] set to ["blah"]. | ||
44 | 'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path | 55 | 'O' - open-binary. Legacy behavior of binfmt_misc is to pass the full path |
45 | of the binary to the interpreter as an argument. When this flag is | 56 | of the binary to the interpreter as an argument. When this flag is |
46 | included, binfmt_misc will open the file for reading and pass its | 57 | included, binfmt_misc will open the file for reading and pass its |
47 | descriptor as an argument, instead of the full path, thus allowing | 58 | descriptor as an argument, instead of the full path, thus allowing |
48 | the interpreter to execute non-readable binaries. This feature should | 59 | the interpreter to execute non-readable binaries. This feature |
49 | be used with care - the interpreter has to be trusted not to emit | 60 | should be used with care - the interpreter has to be trusted not to |
50 | the contents of the non-readable binary. | 61 | emit the contents of the non-readable binary. |
51 | 'C' - credentials. Currently, the behavior of binfmt_misc is to calculate | 62 | 'C' - credentials. Currently, the behavior of binfmt_misc is to calculate |
52 | the credentials and security token of the new process according to | 63 | the credentials and security token of the new process according to |
53 | the interpreter. When this flag is included, these attributes are | 64 | the interpreter. When this flag is included, these attributes are |
@@ -58,7 +69,7 @@ Here is what the fields mean: | |||
58 | 69 | ||
59 | 70 | ||
60 | There are some restrictions: | 71 | There are some restrictions: |
61 | - the whole register string may not exceed 255 characters | 72 | - the whole register string may not exceed 1920 characters |
62 | - the magic must reside in the first 128 bytes of the file, i.e. | 73 | - the magic must reside in the first 128 bytes of the file, i.e. |
63 | offset+size(magic) has to be less than 128 | 74 | offset+size(magic) has to be less than 128 |
64 | - the interpreter string may not exceed 127 characters | 75 | - the interpreter string may not exceed 127 characters |
@@ -110,7 +121,4 @@ passes it the full filename (or the file descriptor) to use. Using $PATH can | |||
110 | cause unexpected behaviour and can be a security hazard. | 121 | cause unexpected behaviour and can be a security hazard. |
111 | 122 | ||
112 | 123 | ||
113 | There is a web page about binfmt_misc at | ||
114 | http://www.tat.physik.uni-tuebingen.de | ||
115 | |||
116 | Richard Günther <rguenth@tat.physik.uni-tuebingen.de> | 124 | Richard Günther <rguenth@tat.physik.uni-tuebingen.de> |
diff --git a/Documentation/devicetree/bindings/i2c/ti,bq32k.txt b/Documentation/devicetree/bindings/i2c/ti,bq32k.txt new file mode 100644 index 000000000000..e204906b9ad3 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/ti,bq32k.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * TI BQ32000 I2C Serial Real-Time Clock | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should contain "ti,bq32000". | ||
5 | - reg: I2C address for chip | ||
6 | |||
7 | Optional properties: | ||
8 | - trickle-resistor-ohms : Selected resistor for trickle charger | ||
9 | Values usable are 1120 and 20180 | ||
10 | Should be given if trickle charger should be enabled | ||
11 | - trickle-diode-disable : Do not use internal trickle charger diode | ||
12 | Should be given if internal trickle charger diode should be disabled | ||
13 | Example: | ||
14 | bq32000: rtc@68 { | ||
15 | compatible = "ti,bq32000"; | ||
16 | trickle-resistor-ohms = <1120>; | ||
17 | reg = <0x68>; | ||
18 | }; | ||
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 5af3d9df6ecb..fbde415078e6 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt | |||
@@ -35,7 +35,6 @@ catalyst,24c32 i2c serial eeprom | |||
35 | cirrus,cs42l51 Cirrus Logic CS42L51 audio codec | 35 | cirrus,cs42l51 Cirrus Logic CS42L51 audio codec |
36 | dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock | 36 | dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock |
37 | dallas,ds1338 I2C RTC with 56-Byte NV RAM | 37 | dallas,ds1338 I2C RTC with 56-Byte NV RAM |
38 | dallas,ds1339 I2C Serial Real-Time Clock | ||
39 | dallas,ds1340 I2C RTC with Trickle Charger | 38 | dallas,ds1340 I2C RTC with Trickle Charger |
40 | dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output | 39 | dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output |
41 | dallas,ds1631 High-Precision Digital Thermometer | 40 | dallas,ds1631 High-Precision Digital Thermometer |
diff --git a/Documentation/devicetree/bindings/rtc/dallas,ds1339.txt b/Documentation/devicetree/bindings/rtc/dallas,ds1339.txt new file mode 100644 index 000000000000..916f57601a8f --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/dallas,ds1339.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * Dallas DS1339 I2C Serial Real-Time Clock | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should contain "dallas,ds1339". | ||
5 | - reg: I2C address for chip | ||
6 | |||
7 | Optional properties: | ||
8 | - trickle-resistor-ohms : Selected resistor for trickle charger | ||
9 | Values usable for ds1339 are 250, 2000, 4000 | ||
10 | Should be given if trickle charger should be enabled | ||
11 | - trickle-diode-disable : Do not use internal trickle charger diode | ||
12 | Should be given if internal trickle charger diode should be disabled | ||
13 | Example: | ||
14 | ds1339: rtc@68 { | ||
15 | compatible = "dallas,ds1339"; | ||
16 | trickle-resistor-ohms = <250>; | ||
17 | reg = <0x68>; | ||
18 | }; | ||
diff --git a/Documentation/devicetree/bindings/rtc/s3c-rtc.txt b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt index 7ac7259fe9ea..ab757b84daa7 100644 --- a/Documentation/devicetree/bindings/rtc/s3c-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt | |||
@@ -3,7 +3,10 @@ | |||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: should be one of the following. | 4 | - compatible: should be one of the following. |
5 | * "samsung,s3c2410-rtc" - for controllers compatible with s3c2410 rtc. | 5 | * "samsung,s3c2410-rtc" - for controllers compatible with s3c2410 rtc. |
6 | * "samsung,s3c2416-rtc" - for controllers compatible with s3c2416 rtc. | ||
7 | * "samsung,s3c2443-rtc" - for controllers compatible with s3c2443 rtc. | ||
6 | * "samsung,s3c6410-rtc" - for controllers compatible with s3c6410 rtc. | 8 | * "samsung,s3c6410-rtc" - for controllers compatible with s3c6410 rtc. |
9 | * "samsung,exynos3250-rtc" - for controllers compatible with exynos3250 rtc. | ||
7 | - reg: physical base address of the controller and length of memory mapped | 10 | - reg: physical base address of the controller and length of memory mapped |
8 | region. | 11 | region. |
9 | - interrupts: Two interrupt numbers to the cpu should be specified. First | 12 | - interrupts: Two interrupt numbers to the cpu should be specified. First |
diff --git a/Documentation/filesystems/autofs4.txt b/Documentation/filesystems/autofs4.txt new file mode 100644 index 000000000000..39d02e19fb62 --- /dev/null +++ b/Documentation/filesystems/autofs4.txt | |||
@@ -0,0 +1,520 @@ | |||
1 | <head> | ||
2 | <style> p { max-width:50em} ol, ul {max-width: 40em}</style> | ||
3 | </head> | ||
4 | |||
5 | autofs - how it works | ||
6 | ===================== | ||
7 | |||
8 | Purpose | ||
9 | ------- | ||
10 | |||
11 | The goal of autofs is to provide on-demand mounting and race free | ||
12 | automatic unmounting of various other filesystems. This provides two | ||
13 | key advantages: | ||
14 | |||
15 | 1. There is no need to delay boot until all filesystems that | ||
16 | might be needed are mounted. Processes that try to access those | ||
17 | slow filesystems might be delayed but other processes can | ||
18 | continue freely. This is particularly important for | ||
19 | network filesystems (e.g. NFS) or filesystems stored on | ||
20 | media with a media-changing robot. | ||
21 | |||
22 | 2. The names and locations of filesystems can be stored in | ||
23 | a remote database and can change at any time. The content | ||
24 | in that data base at the time of access will be used to provide | ||
25 | a target for the access. The interpretation of names in the | ||
26 | filesystem can even be programmatic rather than database-backed, | ||
27 | allowing wildcards for example, and can vary based on the user who | ||
28 | first accessed a name. | ||
29 | |||
30 | Context | ||
31 | ------- | ||
32 | |||
33 | The "autofs4" filesystem module is only one part of an autofs system. | ||
34 | There also needs to be a user-space program which looks up names | ||
35 | and mounts filesystems. This will often be the "automount" program, | ||
36 | though other tools including "systemd" can make use of "autofs4". | ||
37 | This document describes only the kernel module and the interactions | ||
38 | required with any user-space program. Subsequent text refers to this | ||
39 | as the "automount daemon" or simply "the daemon". | ||
40 | |||
41 | "autofs4" is a Linux kernel module with provides the "autofs" | ||
42 | filesystem type. Several "autofs" filesystems can be mounted and they | ||
43 | can each be managed separately, or all managed by the same daemon. | ||
44 | |||
45 | Content | ||
46 | ------- | ||
47 | |||
48 | An autofs filesystem can contain 3 sorts of objects: directories, | ||
49 | symbolic links and mount traps. Mount traps are directories with | ||
50 | extra properties as described in the next section. | ||
51 | |||
52 | Objects can only be created by the automount daemon: symlinks are | ||
53 | created with a regular `symlink` system call, while directories and | ||
54 | mount traps are created with `mkdir`. The determination of whether a | ||
55 | directory should be a mount trap or not is quite _ad hoc_, largely for | ||
56 | historical reasons, and is determined in part by the | ||
57 | *direct*/*indirect*/*offset* mount options, and the *maxproto* mount option. | ||
58 | |||
59 | If neither the *direct* or *offset* mount options are given (so the | ||
60 | mount is considered to be *indirect*), then the root directory is | ||
61 | always a regular directory, otherwise it is a mount trap when it is | ||
62 | empty and a regular directory when not empty. Note that *direct* and | ||
63 | *offset* are treated identically so a concise summary is that the root | ||
64 | directory is a mount trap only if the filesystem is mounted *direct* | ||
65 | and the root is empty. | ||
66 | |||
67 | Directories created in the root directory are mount traps only if the | ||
68 | filesystem is mounted *indirect* and they are empty. | ||
69 | |||
70 | Directories further down the tree depend on the *maxproto* mount | ||
71 | option and particularly whether it is less than five or not. | ||
72 | When *maxproto* is five, no directories further down the | ||
73 | tree are ever mount traps, they are always regular directories. When | ||
74 | the *maxproto* is four (or three), these directories are mount traps | ||
75 | precisely when they are empty. | ||
76 | |||
77 | So: non-empty (i.e. non-leaf) directories are never mount traps. Empty | ||
78 | directories are sometimes mount traps, and sometimes not depending on | ||
79 | where in the tree they are (root, top level, or lower), the *maxproto*, | ||
80 | and whether the mount was *indirect* or not. | ||
81 | |||
82 | Mount Traps | ||
83 | --------------- | ||
84 | |||
85 | A core element of the implementation of autofs is the Mount Traps | ||
86 | which are provided by the Linux VFS. Any directory provided by a | ||
87 | filesystem can be designated as a trap. This involves two separate | ||
88 | features that work together to allow autofs to do its job. | ||
89 | |||
90 | **DCACHE_NEED_AUTOMOUNT** | ||
91 | |||
92 | If a dentry has the DCACHE_NEED_AUTOMOUNT flag set (which gets set if | ||
93 | the inode has S_AUTOMOUNT set, or can be set directly) then it is | ||
94 | (potentially) a mount trap. Any access to this directory beyond a | ||
95 | "`stat`" will (normally) cause the `d_op->d_automount()` dentry operation | ||
96 | to be called. The task of this method is to find the filesystem that | ||
97 | should be mounted on the directory and to return it. The VFS is | ||
98 | responsible for actually mounting the root of this filesystem on the | ||
99 | directory. | ||
100 | |||
101 | autofs doesn't find the filesystem itself but sends a message to the | ||
102 | automount daemon asking it to find and mount the filesystem. The | ||
103 | autofs `d_automount` method then waits for the daemon to report that | ||
104 | everything is ready. It will then return "`NULL`" indicating that the | ||
105 | mount has already happened. The VFS doesn't try to mount anything but | ||
106 | follows down the mount that is already there. | ||
107 | |||
108 | This functionality is sufficient for some users of mount traps such | ||
109 | as NFS which creates traps so that mountpoints on the server can be | ||
110 | reflected on the client. However it is not sufficient for autofs. As | ||
111 | mounting onto a directory is considered to be "beyond a `stat`", the | ||
112 | automount daemon would not be able to mount a filesystem on the 'trap' | ||
113 | directory without some way to avoid getting caught in the trap. For | ||
114 | that purpose there is another flag. | ||
115 | |||
116 | **DCACHE_MANAGE_TRANSIT** | ||
117 | |||
118 | If a dentry has DCACHE_MANAGE_TRANSIT set then two very different but | ||
119 | related behaviors are invoked, both using the `d_op->d_manage()` | ||
120 | dentry operation. | ||
121 | |||
122 | Firstly, before checking to see if any filesystem is mounted on the | ||
123 | directory, d_manage() will be called with the `rcu_walk` parameter set | ||
124 | to `false`. It may return one of three things: | ||
125 | |||
126 | - A return value of zero indicates that there is nothing special | ||
127 | about this dentry and normal checks for mounts and automounts | ||
128 | should proceed. | ||
129 | |||
130 | autofs normally returns zero, but first waits for any | ||
131 | expiry (automatic unmounting of the mounted filesystem) to | ||
132 | complete. This avoids races. | ||
133 | |||
134 | - A return value of `-EISDIR` tells the VFS to ignore any mounts | ||
135 | on the directory and to not consider calling `->d_automount()`. | ||
136 | This effectively disables the **DCACHE_NEED_AUTOMOUNT** flag | ||
137 | causing the directory not be a mount trap after all. | ||
138 | |||
139 | autofs returns this if it detects that the process performing the | ||
140 | lookup is the automount daemon and that the mount has been | ||
141 | requested but has not yet completed. How it determines this is | ||
142 | discussed later. This allows the automount daemon not to get | ||
143 | caught in the mount trap. | ||
144 | |||
145 | There is a subtlety here. It is possible that a second autofs | ||
146 | filesystem can be mounted below the first and for both of them to | ||
147 | be managed by the same daemon. For the daemon to be able to mount | ||
148 | something on the second it must be able to "walk" down past the | ||
149 | first. This means that d_manage cannot *always* return -EISDIR for | ||
150 | the automount daemon. It must only return it when a mount has | ||
151 | been requested, but has not yet completed. | ||
152 | |||
153 | `d_manage` also returns `-EISDIR` if the dentry shouldn't be a | ||
154 | mount trap, either because it is a symbolic link or because it is | ||
155 | not empty. | ||
156 | |||
157 | - Any other negative value is treated as an error and returned | ||
158 | to the caller. | ||
159 | |||
160 | autofs can return | ||
161 | |||
162 | - -ENOENT if the automount daemon failed to mount anything, | ||
163 | - -ENOMEM if it ran out of memory, | ||
164 | - -EINTR if a signal arrived while waiting for expiry to | ||
165 | complete | ||
166 | - or any other error sent down by the automount daemon. | ||
167 | |||
168 | |||
169 | The second use case only occurs during an "RCU-walk" and so `rcu_walk` | ||
170 | will be set. | ||
171 | |||
172 | An RCU-walk is a fast and lightweight process for walking down a | ||
173 | filename path (i.e. it is like running on tip-toes). RCU-walk cannot | ||
174 | cope with all situations so when it finds a difficulty it falls back | ||
175 | to "REF-walk", which is slower but more robust. | ||
176 | |||
177 | RCU-walk will never call `->d_automount`; the filesystems must already | ||
178 | be mounted or RCU-walk cannot handle the path. | ||
179 | To determine if a mount-trap is safe for RCU-walk mode it calls | ||
180 | `->d_manage()` with `rcu_walk` set to `true`. | ||
181 | |||
182 | In this case `d_manage()` must avoid blocking and should avoid taking | ||
183 | spinlocks if at all possible. Its sole purpose is to determine if it | ||
184 | would be safe to follow down into any mounted directory and the only | ||
185 | reason that it might not be is if an expiry of the mount is | ||
186 | underway. | ||
187 | |||
188 | In the `rcu_walk` case, `d_manage()` cannot return -EISDIR to tell the | ||
189 | VFS that this is a directory that doesn't require d_automount. If | ||
190 | `rcu_walk` sees a dentry with DCACHE_NEED_AUTOMOUNT set but nothing | ||
191 | mounted, it *will* fall back to REF-walk. `d_manage()` cannot make the | ||
192 | VFS remain in RCU-walk mode, but can only tell it to get out of | ||
193 | RCU-walk mode by returning `-ECHILD`. | ||
194 | |||
195 | So `d_manage()`, when called with `rcu_walk` set, should either return | ||
196 | -ECHILD if there is any reason to believe it is unsafe to end the | ||
197 | mounted filesystem, and otherwise should return 0. | ||
198 | |||
199 | autofs will return `-ECHILD` if an expiry of the filesystem has been | ||
200 | initiated or is being considered, otherwise it returns 0. | ||
201 | |||
202 | |||
203 | Mountpoint expiry | ||
204 | ----------------- | ||
205 | |||
206 | The VFS has a mechansim for automatically expiring unused mounts, | ||
207 | much as it can expire any unused dentry information from the dcache. | ||
208 | This is guided by the MNT_SHRINKABLE flag. This only applies to | ||
209 | mounts that were created by `d_automount()` returning a filesystem to be | ||
210 | mounted. As autofs doesn't return such a filesystem but leaves the | ||
211 | mounting to the automount daemon, it must involve the automount daemon | ||
212 | in unmounting as well. This also means that autofs has more control | ||
213 | of expiry. | ||
214 | |||
215 | The VFS also supports "expiry" of mounts using the MNT_EXPIRE flag to | ||
216 | the `umount` system call. Unmounting with MNT_EXPIRE will fail unless | ||
217 | a previous attempt had been made, and the filesystem has been inactive | ||
218 | and untouched since that previous attempt. autofs4 does not depend on | ||
219 | this but has its own internal tracking of whether filesystems were | ||
220 | recently used. This allows individual names in the autofs directory | ||
221 | to expire separately. | ||
222 | |||
223 | With version 4 of the protocol, the automount daemon can try to | ||
224 | unmount any filesystems mounted on the autofs filesystem or remove any | ||
225 | symbolic links or empty directories any time it likes. If the unmount | ||
226 | or removal is successful the filesystem will be returned to the state | ||
227 | it was before the mount or creation, so that any access of the name | ||
228 | will trigger normal auto-mount processing. In particlar, `rmdir` and | ||
229 | `unlink` do not leave negative entries in the dcache as a normal | ||
230 | filesystem would, so an attempt to access a recently-removed object is | ||
231 | passed to autofs for handling. | ||
232 | |||
233 | With version 5, this is not safe except for unmounting from top-level | ||
234 | directories. As lower-level directories are never mount traps, other | ||
235 | processes will see an empty directory as soon as the filesystem is | ||
236 | unmounted. So it is generally safest to use the autofs expiry | ||
237 | protocol described below. | ||
238 | |||
239 | Normally the daemon only wants to remove entries which haven't been | ||
240 | used for a while. For this purpose autofs maintains a "`last_used`" | ||
241 | time stamp on each directory or symlink. For symlinks it genuinely | ||
242 | does record the last time the symlink was "used" or followed to find | ||
243 | out where it points to. For directories the field is a slight | ||
244 | misnomer. It actually records the last time that autofs checked if | ||
245 | the directory or one of its descendents was busy and found that it | ||
246 | was. This is just as useful and doesn't require updating the field so | ||
247 | often. | ||
248 | |||
249 | The daemon is able to ask autofs if anything is due to be expired, | ||
250 | using an `ioctl` as discussed later. For a *direct* mount, autofs | ||
251 | considers if the entire mount-tree can be unmounted or not. For an | ||
252 | *indirect* mount, autofs considers each of the names in the top level | ||
253 | directory to determine if any of those can be unmounted and cleaned | ||
254 | up. | ||
255 | |||
256 | There is an option with indirect mounts to consider each of the leaves | ||
257 | that has been mounted on instead of considering the top-level names. | ||
258 | This is intended for compatability with version 4 of autofs and should | ||
259 | be considered as deprecated. | ||
260 | |||
261 | When autofs considers a directory it checks the `last_used` time and | ||
262 | compares it with the "timeout" value set when the filesystem was | ||
263 | mounted, though this check is ignored in some cases. It also checks if | ||
264 | the directory or anything below it is in use. For symbolic links, | ||
265 | only the `last_used` time is ever considered. | ||
266 | |||
267 | If both appear to support expiring the directory or symlink, an action | ||
268 | is taken. | ||
269 | |||
270 | There are two ways to ask autofs to consider expiry. The first is to | ||
271 | use the **AUTOFS_IOC_EXPIRE** ioctl. This only works for indirect | ||
272 | mounts. If it finds something in the root directory to expire it will | ||
273 | return the name of that thing. Once a name has been returned the | ||
274 | automount daemon needs to unmount any filesystems mounted below the | ||
275 | name normally. As described above, this is unsafe for non-toplevel | ||
276 | mounts in a version-5 autofs. For this reason the current `automountd` | ||
277 | does not use this ioctl. | ||
278 | |||
279 | The second mechanism uses either the **AUTOFS_DEV_IOCTL_EXPIRE_CMD** or | ||
280 | the **AUTOFS_IOC_EXPIRE_MULTI** ioctl. This will work for both direct and | ||
281 | indirect mounts. If it selects an object to expire, it will notify | ||
282 | the daemon using the notification mechanism described below. This | ||
283 | will block until the daemon acknowledges the expiry notification. | ||
284 | This implies that the "`EXPIRE`" ioctl must be sent from a different | ||
285 | thread than the one which handles notification. | ||
286 | |||
287 | While the ioctl is blocking, the entry is marked as "expiring" and | ||
288 | `d_manage` will block until the daemon affirms that the unmount has | ||
289 | completed (together with removing any directories that might have been | ||
290 | necessary), or has been aborted. | ||
291 | |||
292 | Communicating with autofs: detecting the daemon | ||
293 | ----------------------------------------------- | ||
294 | |||
295 | There are several forms of communication between the automount daemon | ||
296 | and the filesystem. As we have already seen, the daemon can create and | ||
297 | remove directories and symlinks using normal filesystem operations. | ||
298 | autofs knows whether a process requesting some operation is the daemon | ||
299 | or not based on its process-group id number (see getpgid(1)). | ||
300 | |||
301 | When an autofs filesystem it mounted the pgid of the mounting | ||
302 | processes is recorded unless the "pgrp=" option is given, in which | ||
303 | case that number is recorded instead. Any request arriving from a | ||
304 | process in that process group is considered to come from the daemon. | ||
305 | If the daemon ever has to be stopped and restarted a new pgid can be | ||
306 | provided through an ioctl as will be described below. | ||
307 | |||
308 | Communicating with autofs: the event pipe | ||
309 | ----------------------------------------- | ||
310 | |||
311 | When an autofs filesystem is mounted, the 'write' end of a pipe must | ||
312 | be passed using the 'fd=' mount option. autofs will write | ||
313 | notification messages to this pipe for the daemon to respond to. | ||
314 | For version 5, the format of the message is: | ||
315 | |||
316 | struct autofs_v5_packet { | ||
317 | int proto_version; /* Protocol version */ | ||
318 | int type; /* Type of packet */ | ||
319 | autofs_wqt_t wait_queue_token; | ||
320 | __u32 dev; | ||
321 | __u64 ino; | ||
322 | __u32 uid; | ||
323 | __u32 gid; | ||
324 | __u32 pid; | ||
325 | __u32 tgid; | ||
326 | __u32 len; | ||
327 | char name[NAME_MAX+1]; | ||
328 | }; | ||
329 | |||
330 | where the type is one of | ||
331 | |||
332 | autofs_ptype_missing_indirect | ||
333 | autofs_ptype_expire_indirect | ||
334 | autofs_ptype_missing_direct | ||
335 | autofs_ptype_expire_direct | ||
336 | |||
337 | so messages can indicate that a name is missing (something tried to | ||
338 | access it but it isn't there) or that it has been selected for expiry. | ||
339 | |||
340 | The pipe will be set to "packet mode" (equivalent to passing | ||
341 | `O_DIRECT`) to _pipe2(2)_ so that a read from the pipe will return at | ||
342 | most one packet, and any unread portion of a packet will be discarded. | ||
343 | |||
344 | The `wait_queue_token` is a unique number which can identify a | ||
345 | particular request to be acknowledged. When a message is sent over | ||
346 | the pipe the affected dentry is marked as either "active" or | ||
347 | "expiring" and other accesses to it block until the message is | ||
348 | acknowledged using one of the ioctls below and the relevant | ||
349 | `wait_queue_token`. | ||
350 | |||
351 | Communicating with autofs: root directory ioctls | ||
352 | ------------------------------------------------ | ||
353 | |||
354 | The root directory of an autofs filesystem will respond to a number of | ||
355 | ioctls. The process issuing the ioctl must have the CAP_SYS_ADMIN | ||
356 | capability, or must be the automount daemon. | ||
357 | |||
358 | The available ioctl commands are: | ||
359 | |||
360 | - **AUTOFS_IOC_READY**: a notification has been handled. The argument | ||
361 | to the ioctl command is the "wait_queue_token" number | ||
362 | corresponding to the notification being acknowledged. | ||
363 | - **AUTOFS_IOC_FAIL**: similar to above, but indicates failure with | ||
364 | the error code `ENOENT`. | ||
365 | - **AUTOFS_IOC_CATATONIC**: Causes the autofs to enter "catatonic" | ||
366 | mode meaning that it stops sending notifications to the daemon. | ||
367 | This mode is also entered if a write to the pipe fails. | ||
368 | - **AUTOFS_IOC_PROTOVER**: This returns the protocol version in use. | ||
369 | - **AUTOFS_IOC_PROTOSUBVER**: Returns the protocol sub-version which | ||
370 | is really a version number for the implementation. It is | ||
371 | currently 2. | ||
372 | - **AUTOFS_IOC_SETTIMEOUT**: This passes a pointer to an unsigned | ||
373 | long. The value is used to set the timeout for expiry, and | ||
374 | the current timeout value is stored back through the pointer. | ||
375 | - **AUTOFS_IOC_ASKUMOUNT**: Returns, in the pointed-to `int`, 1 if | ||
376 | the filesystem could be unmounted. This is only a hint as | ||
377 | the situation could change at any instant. This call can be | ||
378 | use to avoid a more expensive full unmount attempt. | ||
379 | - **AUTOFS_IOC_EXPIRE**: as described above, this asks if there is | ||
380 | anything suitable to expire. A pointer to a packet: | ||
381 | |||
382 | struct autofs_packet_expire_multi { | ||
383 | int proto_version; /* Protocol version */ | ||
384 | int type; /* Type of packet */ | ||
385 | autofs_wqt_t wait_queue_token; | ||
386 | int len; | ||
387 | char name[NAME_MAX+1]; | ||
388 | }; | ||
389 | |||
390 | is required. This is filled in with the name of something | ||
391 | that can be unmounted or removed. If nothing can be expired, | ||
392 | `errno` is set to `EAGAIN`. Even though a `wait_queue_token` | ||
393 | is present in the structure, no "wait queue" is established | ||
394 | and no acknowledgment is needed. | ||
395 | - **AUTOFS_IOC_EXPIRE_MULTI**: This is similar to | ||
396 | **AUTOFS_IOC_EXPIRE** except that it causes notification to be | ||
397 | sent to the daemon, and it blocks until the daemon acknowledges. | ||
398 | The argument is an integer which can contain two different flags. | ||
399 | |||
400 | **AUTOFS_EXP_IMMEDIATE** causes `last_used` time to be ignored | ||
401 | and objects are expired if the are not in use. | ||
402 | |||
403 | **AUTOFS_EXP_LEAVES** will select a leaf rather than a top-level | ||
404 | name to expire. This is only safe when *maxproto* is 4. | ||
405 | |||
406 | Communicating with autofs: char-device ioctls | ||
407 | --------------------------------------------- | ||
408 | |||
409 | It is not always possible to open the root of an autofs filesystem, | ||
410 | particularly a *direct* mounted filesystem. If the automount daemon | ||
411 | is restarted there is no way for it to regain control of existing | ||
412 | mounts using any of the above communication channels. To address this | ||
413 | need there is a "miscellaneous" character device (major 10, minor 235) | ||
414 | which can be used to communicate directly with the autofs filesystem. | ||
415 | It requires CAP_SYS_ADMIN for access. | ||
416 | |||
417 | The `ioctl`s that can be used on this device are described in a separate | ||
418 | document `autofs4-mount-control.txt`, and are summarized briefly here. | ||
419 | Each ioctl is passed a pointer to an `autofs_dev_ioctl` structure: | ||
420 | |||
421 | struct autofs_dev_ioctl { | ||
422 | __u32 ver_major; | ||
423 | __u32 ver_minor; | ||
424 | __u32 size; /* total size of data passed in | ||
425 | * including this struct */ | ||
426 | __s32 ioctlfd; /* automount command fd */ | ||
427 | |||
428 | __u32 arg1; /* Command parameters */ | ||
429 | __u32 arg2; | ||
430 | |||
431 | char path[0]; | ||
432 | }; | ||
433 | |||
434 | For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target | ||
435 | filesystem is identified by the `path`. All other commands identify | ||
436 | the filesystem by the `ioctlfd` which is a file descriptor open on the | ||
437 | root, and which can be returned by **OPEN_MOUNT**. | ||
438 | |||
439 | The `ver_major` and `ver_minor` are in/out parameters which check that | ||
440 | the requested version is supported, and report the maximum version | ||
441 | that the kernel module can support. | ||
442 | |||
443 | Commands are: | ||
444 | |||
445 | - **AUTOFS_DEV_IOCTL_VERSION_CMD**: does nothing, except validate and | ||
446 | set version numbers. | ||
447 | - **AUTOFS_DEV_IOCTL_OPENMOUNT_CMD**: return an open file descriptor | ||
448 | on the root of an autofs filesystem. The filesystem is identified | ||
449 | by name and device number, which is stored in `arg1`. Device | ||
450 | numbers for existing filesystems can be found in | ||
451 | `/proc/self/mountinfo`. | ||
452 | - **AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD**: same as `close(ioctlfd)`. | ||
453 | - **AUTOFS_DEV_IOCTL_SETPIPEFD_CMD**: if the filesystem is in | ||
454 | catatonic mode, this can provide the write end of a new pipe | ||
455 | in `arg1` to re-establish communication with a daemon. The | ||
456 | process group of the calling process is used to identify the | ||
457 | daemon. | ||
458 | - **AUTOFS_DEV_IOCTL_REQUESTER_CMD**: `path` should be a | ||
459 | name within the filesystem that has been auto-mounted on. | ||
460 | arg1 is the dev number of the underlying autofs. On successful | ||
461 | return, `arg1` and `arg2` will be the UID and GID of the process | ||
462 | which triggered that mount. | ||
463 | |||
464 | - **AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD**: Check if path is a | ||
465 | mountpoint of a particular type - see separate documentation for | ||
466 | details. | ||
467 | |||
468 | - **AUTOFS_DEV_IOCTL_PROTOVER_CMD**: | ||
469 | - **AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD**: | ||
470 | - **AUTOFS_DEV_IOCTL_READY_CMD**: | ||
471 | - **AUTOFS_DEV_IOCTL_FAIL_CMD**: | ||
472 | - **AUTOFS_DEV_IOCTL_CATATONIC_CMD**: | ||
473 | - **AUTOFS_DEV_IOCTL_TIMEOUT_CMD**: | ||
474 | - **AUTOFS_DEV_IOCTL_EXPIRE_CMD**: | ||
475 | - **AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD**: These all have the same | ||
476 | function as the similarly named **AUTOFS_IOC** ioctls, except | ||
477 | that **FAIL** can be given an explicit error number in `arg1` | ||
478 | instead of assuming `ENOENT`, and this **EXPIRE** command | ||
479 | corresponds to **AUTOFS_IOC_EXPIRE_MULTI**. | ||
480 | |||
481 | Catatonic mode | ||
482 | -------------- | ||
483 | |||
484 | As mentioned, an autofs mount can enter "catatonic" mode. This | ||
485 | happens if a write to the notification pipe fails, or if it is | ||
486 | explicitly requested by an `ioctl`. | ||
487 | |||
488 | When entering catatonic mode, the pipe is closed and any pending | ||
489 | notifications are acknowledged with the error `ENOENT`. | ||
490 | |||
491 | Once in catatonic mode attempts to access non-existing names will | ||
492 | result in `ENOENT` while attempts to access existing directories will | ||
493 | be treated in the same way as if they came from the daemon, so mount | ||
494 | traps will not fire. | ||
495 | |||
496 | When the filesystem is mounted a _uid_ and _gid_ can be given which | ||
497 | set the ownership of directories and symbolic links. When the | ||
498 | filesystem is in catatonic mode, any process with a matching UID can | ||
499 | create directories or symlinks in the root directory, but not in other | ||
500 | directories. | ||
501 | |||
502 | Catatonic mode can only be left via the | ||
503 | **AUTOFS_DEV_IOCTL_OPENMOUNT_CMD** ioctl on the `/dev/autofs`. | ||
504 | |||
505 | autofs, name spaces, and shared mounts | ||
506 | -------------------------------------- | ||
507 | |||
508 | With bind mounts and name spaces it is possible for an autofs | ||
509 | filesystem to appear at multiple places in one or more filesystem | ||
510 | name spaces. For this to work sensibly, the autofs filesystem should | ||
511 | always be mounted "shared". e.g. | ||
512 | |||
513 | > `mount --make-shared /autofs/mount/point` | ||
514 | |||
515 | The automount daemon is only able to mange a single mount location for | ||
516 | an autofs filesystem and if mounts on that are not 'shared', other | ||
517 | locations will not behave as expected. In particular access to those | ||
518 | other locations will likely result in the `ELOOP` error | ||
519 | |||
520 | > Too many levels of symbolic links | ||
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index b4498218c474..5a615c14f75d 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt | |||
@@ -70,6 +70,38 @@ DMA addresses types dma_addr_t: | |||
70 | For printing a dma_addr_t type which can vary based on build options, | 70 | For printing a dma_addr_t type which can vary based on build options, |
71 | regardless of the width of the CPU data path. Passed by reference. | 71 | regardless of the width of the CPU data path. Passed by reference. |
72 | 72 | ||
73 | Raw buffer as an escaped string: | ||
74 | |||
75 | %*pE[achnops] | ||
76 | |||
77 | For printing raw buffer as an escaped string. For the following buffer | ||
78 | |||
79 | 1b 62 20 5c 43 07 22 90 0d 5d | ||
80 | |||
81 | few examples show how the conversion would be done (the result string | ||
82 | without surrounding quotes): | ||
83 | |||
84 | %*pE "\eb \C\a"\220\r]" | ||
85 | %*pEhp "\x1bb \C\x07"\x90\x0d]" | ||
86 | %*pEa "\e\142\040\\\103\a\042\220\r\135" | ||
87 | |||
88 | The conversion rules are applied according to an optional combination | ||
89 | of flags (see string_escape_mem() kernel documentation for the | ||
90 | details): | ||
91 | a - ESCAPE_ANY | ||
92 | c - ESCAPE_SPECIAL | ||
93 | h - ESCAPE_HEX | ||
94 | n - ESCAPE_NULL | ||
95 | o - ESCAPE_OCTAL | ||
96 | p - ESCAPE_NP | ||
97 | s - ESCAPE_SPACE | ||
98 | By default ESCAPE_ANY_NP is used. | ||
99 | |||
100 | ESCAPE_ANY_NP is the sane choice for many cases, in particularly for | ||
101 | printing SSIDs. | ||
102 | |||
103 | If field width is omitted the 1 byte only will be escaped. | ||
104 | |||
73 | Raw buffer as a hex string: | 105 | Raw buffer as a hex string: |
74 | %*ph 00 01 02 ... 3f | 106 | %*ph 00 01 02 ... 3f |
75 | %*phC 00:01:02: ... :3f | 107 | %*phC 00:01:02: ... :3f |
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index f79eb9666379..57baff5bdb80 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -190,6 +190,8 @@ core_pattern is used to specify a core dumpfile pattern name. | |||
190 | %% output one '%' | 190 | %% output one '%' |
191 | %p pid | 191 | %p pid |
192 | %P global pid (init PID namespace) | 192 | %P global pid (init PID namespace) |
193 | %i tid | ||
194 | %I global tid (init PID namespace) | ||
193 | %u uid | 195 | %u uid |
194 | %g gid | 196 | %g gid |
195 | %d dump mode, matches PR_SET_DUMPABLE and | 197 | %d dump mode, matches PR_SET_DUMPABLE and |
diff --git a/MAINTAINERS b/MAINTAINERS index f413abff3807..c52367997fb5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1338,8 +1338,7 @@ ARM/SAMSUNG MOBILE MACHINE SUPPORT | |||
1338 | M: Kyungmin Park <kyungmin.park@samsung.com> | 1338 | M: Kyungmin Park <kyungmin.park@samsung.com> |
1339 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1339 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1340 | S: Maintained | 1340 | S: Maintained |
1341 | F: arch/arm/mach-s5pv210/mach-aquila.c | 1341 | F: arch/arm/mach-s5pv210/ |
1342 | F: arch/arm/mach-s5pv210/mach-goni.c | ||
1343 | 1342 | ||
1344 | ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT | 1343 | ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT |
1345 | M: Kyungmin Park <kyungmin.park@samsung.com> | 1344 | M: Kyungmin Park <kyungmin.park@samsung.com> |
@@ -1550,6 +1549,7 @@ T: git git://git.xilinx.com/linux-xlnx.git | |||
1550 | S: Supported | 1549 | S: Supported |
1551 | F: arch/arm/mach-zynq/ | 1550 | F: arch/arm/mach-zynq/ |
1552 | F: drivers/cpuidle/cpuidle-zynq.c | 1551 | F: drivers/cpuidle/cpuidle-zynq.c |
1552 | F: drivers/block/xsysace.c | ||
1553 | N: zynq | 1553 | N: zynq |
1554 | N: xilinx | 1554 | N: xilinx |
1555 | F: drivers/clocksource/cadence_ttc_timer.c | 1555 | F: drivers/clocksource/cadence_ttc_timer.c |
@@ -1738,6 +1738,12 @@ M: Nicolas Ferre <nicolas.ferre@atmel.com> | |||
1738 | S: Supported | 1738 | S: Supported |
1739 | F: drivers/net/ethernet/cadence/ | 1739 | F: drivers/net/ethernet/cadence/ |
1740 | 1740 | ||
1741 | ATMEL NAND DRIVER | ||
1742 | M: Josh Wu <josh.wu@atmel.com> | ||
1743 | L: linux-mtd@lists.infradead.org | ||
1744 | S: Supported | ||
1745 | F: drivers/mtd/nand/atmel_nand* | ||
1746 | |||
1741 | ATMEL SPI DRIVER | 1747 | ATMEL SPI DRIVER |
1742 | M: Nicolas Ferre <nicolas.ferre@atmel.com> | 1748 | M: Nicolas Ferre <nicolas.ferre@atmel.com> |
1743 | S: Supported | 1749 | S: Supported |
@@ -3048,7 +3054,7 @@ M: Sumit Semwal <sumit.semwal@linaro.org> | |||
3048 | S: Maintained | 3054 | S: Maintained |
3049 | L: linux-media@vger.kernel.org | 3055 | L: linux-media@vger.kernel.org |
3050 | L: dri-devel@lists.freedesktop.org | 3056 | L: dri-devel@lists.freedesktop.org |
3051 | L: linaro-mm-sig@lists.linaro.org | 3057 | L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers) |
3052 | F: drivers/dma-buf/ | 3058 | F: drivers/dma-buf/ |
3053 | F: include/linux/dma-buf* | 3059 | F: include/linux/dma-buf* |
3054 | F: include/linux/reservation.h | 3060 | F: include/linux/reservation.h |
@@ -4297,9 +4303,8 @@ S: Maintained | |||
4297 | F: drivers/media/dvb-frontends/hd29l2* | 4303 | F: drivers/media/dvb-frontends/hd29l2* |
4298 | 4304 | ||
4299 | HEWLETT-PACKARD SMART2 RAID DRIVER | 4305 | HEWLETT-PACKARD SMART2 RAID DRIVER |
4300 | M: Chirag Kantharia <chirag.kantharia@hp.com> | ||
4301 | L: iss_storagedev@hp.com | 4306 | L: iss_storagedev@hp.com |
4302 | S: Maintained | 4307 | S: Orphan |
4303 | F: Documentation/blockdev/cpqarray.txt | 4308 | F: Documentation/blockdev/cpqarray.txt |
4304 | F: drivers/block/cpqarray.* | 4309 | F: drivers/block/cpqarray.* |
4305 | 4310 | ||
@@ -5300,6 +5305,13 @@ F: include/linux/lockd/ | |||
5300 | F: include/linux/sunrpc/ | 5305 | F: include/linux/sunrpc/ |
5301 | F: include/uapi/linux/sunrpc/ | 5306 | F: include/uapi/linux/sunrpc/ |
5302 | 5307 | ||
5308 | KERNEL SELFTEST FRAMEWORK | ||
5309 | M: Shuah Khan <shuahkh@osg.samsung.com> | ||
5310 | L: linux-api@vger.kernel.org | ||
5311 | T: git git://git.kernel.org/pub/scm/shuah/linux-kselftest | ||
5312 | S: Maintained | ||
5313 | F: tools/testing/selftests | ||
5314 | |||
5303 | KERNEL VIRTUAL MACHINE (KVM) | 5315 | KERNEL VIRTUAL MACHINE (KVM) |
5304 | M: Gleb Natapov <gleb@kernel.org> | 5316 | M: Gleb Natapov <gleb@kernel.org> |
5305 | M: Paolo Bonzini <pbonzini@redhat.com> | 5317 | M: Paolo Bonzini <pbonzini@redhat.com> |
@@ -5746,11 +5758,8 @@ T: git git://github.com/linux-test-project/ltp.git | |||
5746 | S: Maintained | 5758 | S: Maintained |
5747 | 5759 | ||
5748 | M32R ARCHITECTURE | 5760 | M32R ARCHITECTURE |
5749 | M: Hirokazu Takata <takata@linux-m32r.org> | ||
5750 | L: linux-m32r@ml.linux-m32r.org (moderated for non-subscribers) | ||
5751 | L: linux-m32r-ja@ml.linux-m32r.org (in Japanese) | ||
5752 | W: http://www.linux-m32r.org/ | 5761 | W: http://www.linux-m32r.org/ |
5753 | S: Maintained | 5762 | S: Orphan |
5754 | F: arch/m32r/ | 5763 | F: arch/m32r/ |
5755 | 5764 | ||
5756 | M68K ARCHITECTURE | 5765 | M68K ARCHITECTURE |
@@ -7974,7 +7983,6 @@ S: Supported | |||
7974 | F: drivers/mfd/sec*.c | 7983 | F: drivers/mfd/sec*.c |
7975 | F: drivers/regulator/s2m*.c | 7984 | F: drivers/regulator/s2m*.c |
7976 | F: drivers/regulator/s5m*.c | 7985 | F: drivers/regulator/s5m*.c |
7977 | F: drivers/rtc/rtc-sec.c | ||
7978 | F: include/linux/mfd/samsung/ | 7986 | F: include/linux/mfd/samsung/ |
7979 | 7987 | ||
7980 | SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS | 7988 | SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS |
@@ -10315,10 +10323,6 @@ M: John Linn <John.Linn@xilinx.com> | |||
10315 | S: Maintained | 10323 | S: Maintained |
10316 | F: drivers/net/ethernet/xilinx/xilinx_axienet* | 10324 | F: drivers/net/ethernet/xilinx/xilinx_axienet* |
10317 | 10325 | ||
10318 | XILINX SYSTEMACE DRIVER | ||
10319 | S: Orphan | ||
10320 | F: drivers/block/xsysace.c | ||
10321 | |||
10322 | XILINX UARTLITE SERIAL DRIVER | 10326 | XILINX UARTLITE SERIAL DRIVER |
10323 | M: Peter Korsgaard <jacmet@sunsite.dk> | 10327 | M: Peter Korsgaard <jacmet@sunsite.dk> |
10324 | L: linux-serial@vger.kernel.org | 10328 | L: linux-serial@vger.kernel.org |
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index 1d52de6370d5..429a6c6cfcf9 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi | |||
@@ -164,7 +164,7 @@ | |||
164 | }; | 164 | }; |
165 | 165 | ||
166 | rtc: rtc@10070000 { | 166 | rtc: rtc@10070000 { |
167 | compatible = "samsung,s3c6410-rtc"; | 167 | compatible = "samsung,exynos3250-rtc"; |
168 | reg = <0x10070000 0x100>; | 168 | reg = <0x10070000 0x100>; |
169 | interrupts = <0 73 0>, <0 74 0>; | 169 | interrupts = <0 73 0>, <0 74 0>; |
170 | status = "disabled"; | 170 | status = "disabled"; |
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 9f6ec167902a..ad777b353bd5 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c | |||
@@ -416,17 +416,17 @@ static struct pxafb_mach_info *lpd270_lcd_to_use; | |||
416 | 416 | ||
417 | static int __init lpd270_set_lcd(char *str) | 417 | static int __init lpd270_set_lcd(char *str) |
418 | { | 418 | { |
419 | if (!strnicmp(str, "lq057q3dc02", 11)) { | 419 | if (!strncasecmp(str, "lq057q3dc02", 11)) { |
420 | lpd270_lcd_to_use = &sharp_lq057q3dc02; | 420 | lpd270_lcd_to_use = &sharp_lq057q3dc02; |
421 | } else if (!strnicmp(str, "lq121s1dg31", 11)) { | 421 | } else if (!strncasecmp(str, "lq121s1dg31", 11)) { |
422 | lpd270_lcd_to_use = &sharp_lq121s1dg31; | 422 | lpd270_lcd_to_use = &sharp_lq121s1dg31; |
423 | } else if (!strnicmp(str, "lq036q1da01", 11)) { | 423 | } else if (!strncasecmp(str, "lq036q1da01", 11)) { |
424 | lpd270_lcd_to_use = &sharp_lq036q1da01; | 424 | lpd270_lcd_to_use = &sharp_lq036q1da01; |
425 | } else if (!strnicmp(str, "lq64d343", 8)) { | 425 | } else if (!strncasecmp(str, "lq64d343", 8)) { |
426 | lpd270_lcd_to_use = &sharp_lq64d343; | 426 | lpd270_lcd_to_use = &sharp_lq64d343; |
427 | } else if (!strnicmp(str, "lq10d368", 8)) { | 427 | } else if (!strncasecmp(str, "lq10d368", 8)) { |
428 | lpd270_lcd_to_use = &sharp_lq10d368; | 428 | lpd270_lcd_to_use = &sharp_lq10d368; |
429 | } else if (!strnicmp(str, "lq035q7db02-20", 14)) { | 429 | } else if (!strncasecmp(str, "lq035q7db02-20", 14)) { |
430 | lpd270_lcd_to_use = &sharp_lq035q7db02_20; | 430 | lpd270_lcd_to_use = &sharp_lq035q7db02_20; |
431 | } else { | 431 | } else { |
432 | printk(KERN_INFO "lpd270: unknown lcd panel [%s]\n", str); | 432 | printk(KERN_INFO "lpd270: unknown lcd panel [%s]\n", str); |
diff --git a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c index 6aea124f574d..2fb9b3ab57b9 100644 --- a/arch/frv/mm/extable.c +++ b/arch/frv/mm/extable.c | |||
@@ -6,8 +6,6 @@ | |||
6 | #include <linux/spinlock.h> | 6 | #include <linux/spinlock.h> |
7 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
8 | 8 | ||
9 | extern const struct exception_table_entry __attribute__((aligned(8))) __start___ex_table[]; | ||
10 | extern const struct exception_table_entry __attribute__((aligned(8))) __stop___ex_table[]; | ||
11 | extern const void __memset_end, __memset_user_error_lr, __memset_user_error_handler; | 9 | extern const void __memset_end, __memset_user_error_lr, __memset_user_error_handler; |
12 | extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler; | 10 | extern const void __memcpy_end, __memcpy_user_error_lr, __memcpy_user_error_handler; |
13 | extern spinlock_t modlist_lock; | 11 | extern spinlock_t modlist_lock; |
diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h index 1a873b36a4a1..2ab2003698ef 100644 --- a/arch/ia64/include/asm/sections.h +++ b/arch/ia64/include/asm/sections.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/uaccess.h> | 10 | #include <linux/uaccess.h> |
11 | #include <asm-generic/sections.h> | 11 | #include <asm-generic/sections.h> |
12 | 12 | ||
13 | extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[]; | 13 | extern char __phys_per_cpu_start[]; |
14 | #ifdef CONFIG_SMP | 14 | #ifdef CONFIG_SMP |
15 | extern char __cpu0_per_cpu[]; | 15 | extern char __cpu0_per_cpu[]; |
16 | #endif | 16 | #endif |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 700f958652f8..3eff36f719fb 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -964,6 +964,7 @@ static void vgetcpu_set_mode(void) | |||
964 | vgetcpu_mode = VGETCPU_LSL; | 964 | vgetcpu_mode = VGETCPU_LSL; |
965 | } | 965 | } |
966 | 966 | ||
967 | #ifdef CONFIG_IA32_EMULATION | ||
967 | /* May not be __init: called during resume */ | 968 | /* May not be __init: called during resume */ |
968 | static void syscall32_cpu_init(void) | 969 | static void syscall32_cpu_init(void) |
969 | { | 970 | { |
@@ -975,7 +976,8 @@ static void syscall32_cpu_init(void) | |||
975 | 976 | ||
976 | wrmsrl(MSR_CSTAR, ia32_cstar_target); | 977 | wrmsrl(MSR_CSTAR, ia32_cstar_target); |
977 | } | 978 | } |
978 | #endif | 979 | #endif /* CONFIG_IA32_EMULATION */ |
980 | #endif /* CONFIG_X86_64 */ | ||
979 | 981 | ||
980 | #ifdef CONFIG_X86_32 | 982 | #ifdef CONFIG_X86_32 |
981 | void enable_sep_cpu(void) | 983 | void enable_sep_cpu(void) |
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index a618fcd2c07d..f5ab56d14287 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c | |||
@@ -237,7 +237,7 @@ static void fill_up_crash_elf_data(struct crash_elf_data *ced, | |||
237 | ced->max_nr_ranges++; | 237 | ced->max_nr_ranges++; |
238 | 238 | ||
239 | /* If crashk_low_res is not 0, another range split possible */ | 239 | /* If crashk_low_res is not 0, another range split possible */ |
240 | if (crashk_low_res.end != 0) | 240 | if (crashk_low_res.end) |
241 | ced->max_nr_ranges++; | 241 | ced->max_nr_ranges++; |
242 | } | 242 | } |
243 | 243 | ||
@@ -335,9 +335,11 @@ static int elf_header_exclude_ranges(struct crash_elf_data *ced, | |||
335 | if (ret) | 335 | if (ret) |
336 | return ret; | 336 | return ret; |
337 | 337 | ||
338 | ret = exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end); | 338 | if (crashk_low_res.end) { |
339 | if (ret) | 339 | ret = exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end); |
340 | return ret; | 340 | if (ret) |
341 | return ret; | ||
342 | } | ||
341 | 343 | ||
342 | /* Exclude GART region */ | 344 | /* Exclude GART region */ |
343 | if (ced->gart_end) { | 345 | if (ced->gart_end) { |
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index 9642b9b33655..ca05f86481aa 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/setup.h> | 26 | #include <asm/setup.h> |
27 | #include <asm/crash.h> | 27 | #include <asm/crash.h> |
28 | #include <asm/efi.h> | 28 | #include <asm/efi.h> |
29 | #include <asm/kexec-bzimage64.h> | ||
29 | 30 | ||
30 | #define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */ | 31 | #define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */ |
31 | 32 | ||
@@ -267,7 +268,7 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, | |||
267 | return ret; | 268 | return ret; |
268 | } | 269 | } |
269 | 270 | ||
270 | int bzImage64_probe(const char *buf, unsigned long len) | 271 | static int bzImage64_probe(const char *buf, unsigned long len) |
271 | { | 272 | { |
272 | int ret = -ENOEXEC; | 273 | int ret = -ENOEXEC; |
273 | struct setup_header *header; | 274 | struct setup_header *header; |
@@ -325,10 +326,10 @@ int bzImage64_probe(const char *buf, unsigned long len) | |||
325 | return ret; | 326 | return ret; |
326 | } | 327 | } |
327 | 328 | ||
328 | void *bzImage64_load(struct kimage *image, char *kernel, | 329 | static void *bzImage64_load(struct kimage *image, char *kernel, |
329 | unsigned long kernel_len, char *initrd, | 330 | unsigned long kernel_len, char *initrd, |
330 | unsigned long initrd_len, char *cmdline, | 331 | unsigned long initrd_len, char *cmdline, |
331 | unsigned long cmdline_len) | 332 | unsigned long cmdline_len) |
332 | { | 333 | { |
333 | 334 | ||
334 | struct setup_header *header; | 335 | struct setup_header *header; |
@@ -514,7 +515,7 @@ out_free_params: | |||
514 | } | 515 | } |
515 | 516 | ||
516 | /* This cleanup function is called after various segments have been loaded */ | 517 | /* This cleanup function is called after various segments have been loaded */ |
517 | int bzImage64_cleanup(void *loader_data) | 518 | static int bzImage64_cleanup(void *loader_data) |
518 | { | 519 | { |
519 | struct bzimage64_data *ldata = loader_data; | 520 | struct bzimage64_data *ldata = loader_data; |
520 | 521 | ||
@@ -528,7 +529,7 @@ int bzImage64_cleanup(void *loader_data) | |||
528 | } | 529 | } |
529 | 530 | ||
530 | #ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG | 531 | #ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG |
531 | int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len) | 532 | static int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len) |
532 | { | 533 | { |
533 | bool trusted; | 534 | bool trusted; |
534 | int ret; | 535 | int ret; |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 3dd8e2c4d74a..95c3cb16af3e 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/kprobes.h> | 36 | #include <linux/kprobes.h> |
37 | #include <linux/debugfs.h> | 37 | #include <linux/debugfs.h> |
38 | #include <linux/nmi.h> | ||
38 | #include <asm/timer.h> | 39 | #include <asm/timer.h> |
39 | #include <asm/cpu.h> | 40 | #include <asm/cpu.h> |
40 | #include <asm/traps.h> | 41 | #include <asm/traps.h> |
@@ -499,6 +500,13 @@ void __init kvm_guest_init(void) | |||
499 | #else | 500 | #else |
500 | kvm_guest_cpu_init(); | 501 | kvm_guest_cpu_init(); |
501 | #endif | 502 | #endif |
503 | |||
504 | /* | ||
505 | * Hard lockup detection is enabled by default. Disable it, as guests | ||
506 | * can get false positives too easily, for example if the host is | ||
507 | * overcommitted. | ||
508 | */ | ||
509 | watchdog_enable_hardlockup_detector(false); | ||
502 | } | 510 | } |
503 | 511 | ||
504 | static noinline uint32_t __kvm_cpuid_base(void) | 512 | static noinline uint32_t __kvm_cpuid_base(void) |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index baff1da354e0..af78e50ca6ce 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -86,6 +86,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, | |||
86 | pgprot_t prot; | 86 | pgprot_t prot; |
87 | int retval; | 87 | int retval; |
88 | void __iomem *ret_addr; | 88 | void __iomem *ret_addr; |
89 | int ram_region; | ||
89 | 90 | ||
90 | /* Don't allow wraparound or zero size */ | 91 | /* Don't allow wraparound or zero size */ |
91 | last_addr = phys_addr + size - 1; | 92 | last_addr = phys_addr + size - 1; |
@@ -108,12 +109,23 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, | |||
108 | /* | 109 | /* |
109 | * Don't allow anybody to remap normal RAM that we're using.. | 110 | * Don't allow anybody to remap normal RAM that we're using.. |
110 | */ | 111 | */ |
111 | pfn = phys_addr >> PAGE_SHIFT; | 112 | /* First check if whole region can be identified as RAM or not */ |
112 | last_pfn = last_addr >> PAGE_SHIFT; | 113 | ram_region = region_is_ram(phys_addr, size); |
113 | if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL, | 114 | if (ram_region > 0) { |
114 | __ioremap_check_ram) == 1) | 115 | WARN_ONCE(1, "ioremap on RAM at 0x%lx - 0x%lx\n", |
116 | (unsigned long int)phys_addr, | ||
117 | (unsigned long int)last_addr); | ||
115 | return NULL; | 118 | return NULL; |
119 | } | ||
116 | 120 | ||
121 | /* If could not be identified(-1), check page by page */ | ||
122 | if (ram_region < 0) { | ||
123 | pfn = phys_addr >> PAGE_SHIFT; | ||
124 | last_pfn = last_addr >> PAGE_SHIFT; | ||
125 | if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL, | ||
126 | __ioremap_check_ram) == 1) | ||
127 | return NULL; | ||
128 | } | ||
117 | /* | 129 | /* |
118 | * Mappings have to be page-aligned | 130 | * Mappings have to be page-aligned |
119 | */ | 131 | */ |
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index d221374d5ce8..1a883705a12a 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c | |||
@@ -463,6 +463,42 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi) | |||
463 | return true; | 463 | return true; |
464 | } | 464 | } |
465 | 465 | ||
466 | static void __init numa_clear_kernel_node_hotplug(void) | ||
467 | { | ||
468 | int i, nid; | ||
469 | nodemask_t numa_kernel_nodes = NODE_MASK_NONE; | ||
470 | unsigned long start, end; | ||
471 | struct memblock_region *r; | ||
472 | |||
473 | /* | ||
474 | * At this time, all memory regions reserved by memblock are | ||
475 | * used by the kernel. Set the nid in memblock.reserved will | ||
476 | * mark out all the nodes the kernel resides in. | ||
477 | */ | ||
478 | for (i = 0; i < numa_meminfo.nr_blks; i++) { | ||
479 | struct numa_memblk *mb = &numa_meminfo.blk[i]; | ||
480 | |||
481 | memblock_set_node(mb->start, mb->end - mb->start, | ||
482 | &memblock.reserved, mb->nid); | ||
483 | } | ||
484 | |||
485 | /* Mark all kernel nodes. */ | ||
486 | for_each_memblock(reserved, r) | ||
487 | node_set(r->nid, numa_kernel_nodes); | ||
488 | |||
489 | /* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */ | ||
490 | for (i = 0; i < numa_meminfo.nr_blks; i++) { | ||
491 | nid = numa_meminfo.blk[i].nid; | ||
492 | if (!node_isset(nid, numa_kernel_nodes)) | ||
493 | continue; | ||
494 | |||
495 | start = numa_meminfo.blk[i].start; | ||
496 | end = numa_meminfo.blk[i].end; | ||
497 | |||
498 | memblock_clear_hotplug(start, end - start); | ||
499 | } | ||
500 | } | ||
501 | |||
466 | static int __init numa_register_memblks(struct numa_meminfo *mi) | 502 | static int __init numa_register_memblks(struct numa_meminfo *mi) |
467 | { | 503 | { |
468 | unsigned long uninitialized_var(pfn_align); | 504 | unsigned long uninitialized_var(pfn_align); |
@@ -481,6 +517,15 @@ static int __init numa_register_memblks(struct numa_meminfo *mi) | |||
481 | } | 517 | } |
482 | 518 | ||
483 | /* | 519 | /* |
520 | * At very early time, the kernel have to use some memory such as | ||
521 | * loading the kernel image. We cannot prevent this anyway. So any | ||
522 | * node the kernel resides in should be un-hotpluggable. | ||
523 | * | ||
524 | * And when we come here, alloc node data won't fail. | ||
525 | */ | ||
526 | numa_clear_kernel_node_hotplug(); | ||
527 | |||
528 | /* | ||
484 | * If sections array is gonna be used for pfn -> nid mapping, check | 529 | * If sections array is gonna be used for pfn -> nid mapping, check |
485 | * whether its granularity is fine enough. | 530 | * whether its granularity is fine enough. |
486 | */ | 531 | */ |
@@ -548,41 +593,6 @@ static void __init numa_init_array(void) | |||
548 | } | 593 | } |
549 | } | 594 | } |
550 | 595 | ||
551 | static void __init numa_clear_kernel_node_hotplug(void) | ||
552 | { | ||
553 | int i, nid; | ||
554 | nodemask_t numa_kernel_nodes = NODE_MASK_NONE; | ||
555 | unsigned long start, end; | ||
556 | struct memblock_region *r; | ||
557 | |||
558 | /* | ||
559 | * At this time, all memory regions reserved by memblock are | ||
560 | * used by the kernel. Set the nid in memblock.reserved will | ||
561 | * mark out all the nodes the kernel resides in. | ||
562 | */ | ||
563 | for (i = 0; i < numa_meminfo.nr_blks; i++) { | ||
564 | struct numa_memblk *mb = &numa_meminfo.blk[i]; | ||
565 | memblock_set_node(mb->start, mb->end - mb->start, | ||
566 | &memblock.reserved, mb->nid); | ||
567 | } | ||
568 | |||
569 | /* Mark all kernel nodes. */ | ||
570 | for_each_memblock(reserved, r) | ||
571 | node_set(r->nid, numa_kernel_nodes); | ||
572 | |||
573 | /* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */ | ||
574 | for (i = 0; i < numa_meminfo.nr_blks; i++) { | ||
575 | nid = numa_meminfo.blk[i].nid; | ||
576 | if (!node_isset(nid, numa_kernel_nodes)) | ||
577 | continue; | ||
578 | |||
579 | start = numa_meminfo.blk[i].start; | ||
580 | end = numa_meminfo.blk[i].end; | ||
581 | |||
582 | memblock_clear_hotplug(start, end - start); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | static int __init numa_init(int (*init_func)(void)) | 596 | static int __init numa_init(int (*init_func)(void)) |
587 | { | 597 | { |
588 | int i; | 598 | int i; |
@@ -637,15 +647,6 @@ static int __init numa_init(int (*init_func)(void)) | |||
637 | } | 647 | } |
638 | numa_init_array(); | 648 | numa_init_array(); |
639 | 649 | ||
640 | /* | ||
641 | * At very early time, the kernel have to use some memory such as | ||
642 | * loading the kernel image. We cannot prevent this anyway. So any | ||
643 | * node the kernel resides in should be un-hotpluggable. | ||
644 | * | ||
645 | * And when we come here, numa_init() won't fail. | ||
646 | */ | ||
647 | numa_clear_kernel_node_hotplug(); | ||
648 | |||
649 | return 0; | 650 | return 0; |
650 | } | 651 | } |
651 | 652 | ||
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 899dd2454256..f52e033557c9 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile | |||
@@ -18,8 +18,9 @@ $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE | |||
18 | 18 | ||
19 | targets += kexec-purgatory.c | 19 | targets += kexec-purgatory.c |
20 | 20 | ||
21 | CMD_BIN2C = $(objtree)/scripts/basic/bin2c | ||
21 | quiet_cmd_bin2c = BIN2C $@ | 22 | quiet_cmd_bin2c = BIN2C $@ |
22 | cmd_bin2c = cat $(obj)/purgatory.ro | $(objtree)/scripts/basic/bin2c kexec_purgatory > $(obj)/kexec-purgatory.c | 23 | cmd_bin2c = $(CMD_BIN2C) kexec_purgatory < $< > $@ |
23 | 24 | ||
24 | $(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE | 25 | $(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE |
25 | $(call if_changed,bin2c) | 26 | $(call if_changed,bin2c) |
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 7d6e84a51424..55b83983a9c0 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c | |||
@@ -14,11 +14,14 @@ struct dma_coherent_mem { | |||
14 | int size; | 14 | int size; |
15 | int flags; | 15 | int flags; |
16 | unsigned long *bitmap; | 16 | unsigned long *bitmap; |
17 | spinlock_t spinlock; | ||
17 | }; | 18 | }; |
18 | 19 | ||
19 | int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, | 20 | static int dma_init_coherent_memory(phys_addr_t phys_addr, dma_addr_t device_addr, |
20 | dma_addr_t device_addr, size_t size, int flags) | 21 | size_t size, int flags, |
22 | struct dma_coherent_mem **mem) | ||
21 | { | 23 | { |
24 | struct dma_coherent_mem *dma_mem = NULL; | ||
22 | void __iomem *mem_base = NULL; | 25 | void __iomem *mem_base = NULL; |
23 | int pages = size >> PAGE_SHIFT; | 26 | int pages = size >> PAGE_SHIFT; |
24 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); | 27 | int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); |
@@ -27,40 +30,77 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, | |||
27 | goto out; | 30 | goto out; |
28 | if (!size) | 31 | if (!size) |
29 | goto out; | 32 | goto out; |
30 | if (dev->dma_mem) | ||
31 | goto out; | ||
32 | |||
33 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
34 | 33 | ||
35 | mem_base = ioremap(phys_addr, size); | 34 | mem_base = ioremap(phys_addr, size); |
36 | if (!mem_base) | 35 | if (!mem_base) |
37 | goto out; | 36 | goto out; |
38 | 37 | ||
39 | dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); | 38 | dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); |
40 | if (!dev->dma_mem) | 39 | if (!dma_mem) |
41 | goto out; | 40 | goto out; |
42 | dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); | 41 | dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); |
43 | if (!dev->dma_mem->bitmap) | 42 | if (!dma_mem->bitmap) |
44 | goto free1_out; | 43 | goto out; |
44 | |||
45 | dma_mem->virt_base = mem_base; | ||
46 | dma_mem->device_base = device_addr; | ||
47 | dma_mem->pfn_base = PFN_DOWN(phys_addr); | ||
48 | dma_mem->size = pages; | ||
49 | dma_mem->flags = flags; | ||
50 | spin_lock_init(&dma_mem->spinlock); | ||
45 | 51 | ||
46 | dev->dma_mem->virt_base = mem_base; | 52 | *mem = dma_mem; |
47 | dev->dma_mem->device_base = device_addr; | ||
48 | dev->dma_mem->pfn_base = PFN_DOWN(phys_addr); | ||
49 | dev->dma_mem->size = pages; | ||
50 | dev->dma_mem->flags = flags; | ||
51 | 53 | ||
52 | if (flags & DMA_MEMORY_MAP) | 54 | if (flags & DMA_MEMORY_MAP) |
53 | return DMA_MEMORY_MAP; | 55 | return DMA_MEMORY_MAP; |
54 | 56 | ||
55 | return DMA_MEMORY_IO; | 57 | return DMA_MEMORY_IO; |
56 | 58 | ||
57 | free1_out: | 59 | out: |
58 | kfree(dev->dma_mem); | 60 | kfree(dma_mem); |
59 | out: | ||
60 | if (mem_base) | 61 | if (mem_base) |
61 | iounmap(mem_base); | 62 | iounmap(mem_base); |
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
65 | |||
66 | static void dma_release_coherent_memory(struct dma_coherent_mem *mem) | ||
67 | { | ||
68 | if (!mem) | ||
69 | return; | ||
70 | iounmap(mem->virt_base); | ||
71 | kfree(mem->bitmap); | ||
72 | kfree(mem); | ||
73 | } | ||
74 | |||
75 | static int dma_assign_coherent_memory(struct device *dev, | ||
76 | struct dma_coherent_mem *mem) | ||
77 | { | ||
78 | if (dev->dma_mem) | ||
79 | return -EBUSY; | ||
80 | |||
81 | dev->dma_mem = mem; | ||
82 | /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */ | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr, | ||
88 | dma_addr_t device_addr, size_t size, int flags) | ||
89 | { | ||
90 | struct dma_coherent_mem *mem; | ||
91 | int ret; | ||
92 | |||
93 | ret = dma_init_coherent_memory(phys_addr, device_addr, size, flags, | ||
94 | &mem); | ||
95 | if (ret == 0) | ||
96 | return 0; | ||
97 | |||
98 | if (dma_assign_coherent_memory(dev, mem) == 0) | ||
99 | return ret; | ||
100 | |||
101 | dma_release_coherent_memory(mem); | ||
102 | return 0; | ||
103 | } | ||
64 | EXPORT_SYMBOL(dma_declare_coherent_memory); | 104 | EXPORT_SYMBOL(dma_declare_coherent_memory); |
65 | 105 | ||
66 | void dma_release_declared_memory(struct device *dev) | 106 | void dma_release_declared_memory(struct device *dev) |
@@ -69,10 +109,8 @@ void dma_release_declared_memory(struct device *dev) | |||
69 | 109 | ||
70 | if (!mem) | 110 | if (!mem) |
71 | return; | 111 | return; |
112 | dma_release_coherent_memory(mem); | ||
72 | dev->dma_mem = NULL; | 113 | dev->dma_mem = NULL; |
73 | iounmap(mem->virt_base); | ||
74 | kfree(mem->bitmap); | ||
75 | kfree(mem); | ||
76 | } | 114 | } |
77 | EXPORT_SYMBOL(dma_release_declared_memory); | 115 | EXPORT_SYMBOL(dma_release_declared_memory); |
78 | 116 | ||
@@ -80,6 +118,7 @@ void *dma_mark_declared_memory_occupied(struct device *dev, | |||
80 | dma_addr_t device_addr, size_t size) | 118 | dma_addr_t device_addr, size_t size) |
81 | { | 119 | { |
82 | struct dma_coherent_mem *mem = dev->dma_mem; | 120 | struct dma_coherent_mem *mem = dev->dma_mem; |
121 | unsigned long flags; | ||
83 | int pos, err; | 122 | int pos, err; |
84 | 123 | ||
85 | size += device_addr & ~PAGE_MASK; | 124 | size += device_addr & ~PAGE_MASK; |
@@ -87,8 +126,11 @@ void *dma_mark_declared_memory_occupied(struct device *dev, | |||
87 | if (!mem) | 126 | if (!mem) |
88 | return ERR_PTR(-EINVAL); | 127 | return ERR_PTR(-EINVAL); |
89 | 128 | ||
129 | spin_lock_irqsave(&mem->spinlock, flags); | ||
90 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; | 130 | pos = (device_addr - mem->device_base) >> PAGE_SHIFT; |
91 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(size)); | 131 | err = bitmap_allocate_region(mem->bitmap, pos, get_order(size)); |
132 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
133 | |||
92 | if (err != 0) | 134 | if (err != 0) |
93 | return ERR_PTR(err); | 135 | return ERR_PTR(err); |
94 | return mem->virt_base + (pos << PAGE_SHIFT); | 136 | return mem->virt_base + (pos << PAGE_SHIFT); |
@@ -115,6 +157,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, | |||
115 | { | 157 | { |
116 | struct dma_coherent_mem *mem; | 158 | struct dma_coherent_mem *mem; |
117 | int order = get_order(size); | 159 | int order = get_order(size); |
160 | unsigned long flags; | ||
118 | int pageno; | 161 | int pageno; |
119 | 162 | ||
120 | if (!dev) | 163 | if (!dev) |
@@ -124,6 +167,7 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, | |||
124 | return 0; | 167 | return 0; |
125 | 168 | ||
126 | *ret = NULL; | 169 | *ret = NULL; |
170 | spin_lock_irqsave(&mem->spinlock, flags); | ||
127 | 171 | ||
128 | if (unlikely(size > (mem->size << PAGE_SHIFT))) | 172 | if (unlikely(size > (mem->size << PAGE_SHIFT))) |
129 | goto err; | 173 | goto err; |
@@ -138,10 +182,12 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, | |||
138 | *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); | 182 | *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); |
139 | *ret = mem->virt_base + (pageno << PAGE_SHIFT); | 183 | *ret = mem->virt_base + (pageno << PAGE_SHIFT); |
140 | memset(*ret, 0, size); | 184 | memset(*ret, 0, size); |
185 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
141 | 186 | ||
142 | return 1; | 187 | return 1; |
143 | 188 | ||
144 | err: | 189 | err: |
190 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
145 | /* | 191 | /* |
146 | * In the case where the allocation can not be satisfied from the | 192 | * In the case where the allocation can not be satisfied from the |
147 | * per-device area, try to fall back to generic memory if the | 193 | * per-device area, try to fall back to generic memory if the |
@@ -171,8 +217,11 @@ int dma_release_from_coherent(struct device *dev, int order, void *vaddr) | |||
171 | if (mem && vaddr >= mem->virt_base && vaddr < | 217 | if (mem && vaddr >= mem->virt_base && vaddr < |
172 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { | 218 | (mem->virt_base + (mem->size << PAGE_SHIFT))) { |
173 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; | 219 | int page = (vaddr - mem->virt_base) >> PAGE_SHIFT; |
220 | unsigned long flags; | ||
174 | 221 | ||
222 | spin_lock_irqsave(&mem->spinlock, flags); | ||
175 | bitmap_release_region(mem->bitmap, page, order); | 223 | bitmap_release_region(mem->bitmap, page, order); |
224 | spin_unlock_irqrestore(&mem->spinlock, flags); | ||
176 | return 1; | 225 | return 1; |
177 | } | 226 | } |
178 | return 0; | 227 | return 0; |
@@ -218,3 +267,61 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, | |||
218 | return 0; | 267 | return 0; |
219 | } | 268 | } |
220 | EXPORT_SYMBOL(dma_mmap_from_coherent); | 269 | EXPORT_SYMBOL(dma_mmap_from_coherent); |
270 | |||
271 | /* | ||
272 | * Support for reserved memory regions defined in device tree | ||
273 | */ | ||
274 | #ifdef CONFIG_OF_RESERVED_MEM | ||
275 | #include <linux/of.h> | ||
276 | #include <linux/of_fdt.h> | ||
277 | #include <linux/of_reserved_mem.h> | ||
278 | |||
279 | static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev) | ||
280 | { | ||
281 | struct dma_coherent_mem *mem = rmem->priv; | ||
282 | |||
283 | if (!mem && | ||
284 | dma_init_coherent_memory(rmem->base, rmem->base, rmem->size, | ||
285 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE, | ||
286 | &mem) != DMA_MEMORY_MAP) { | ||
287 | pr_err("Reserved memory: failed to init DMA memory pool at %pa, size %ld MiB\n", | ||
288 | &rmem->base, (unsigned long)rmem->size / SZ_1M); | ||
289 | return -ENODEV; | ||
290 | } | ||
291 | rmem->priv = mem; | ||
292 | dma_assign_coherent_memory(dev, mem); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static void rmem_dma_device_release(struct reserved_mem *rmem, | ||
297 | struct device *dev) | ||
298 | { | ||
299 | dev->dma_mem = NULL; | ||
300 | } | ||
301 | |||
302 | static const struct reserved_mem_ops rmem_dma_ops = { | ||
303 | .device_init = rmem_dma_device_init, | ||
304 | .device_release = rmem_dma_device_release, | ||
305 | }; | ||
306 | |||
307 | static int __init rmem_dma_setup(struct reserved_mem *rmem) | ||
308 | { | ||
309 | unsigned long node = rmem->fdt_node; | ||
310 | |||
311 | if (of_get_flat_dt_prop(node, "reusable", NULL)) | ||
312 | return -EINVAL; | ||
313 | |||
314 | #ifdef CONFIG_ARM | ||
315 | if (!of_get_flat_dt_prop(node, "no-map", NULL)) { | ||
316 | pr_err("Reserved memory: regions without no-map are not yet supported\n"); | ||
317 | return -EINVAL; | ||
318 | } | ||
319 | #endif | ||
320 | |||
321 | rmem->ops = &rmem_dma_ops; | ||
322 | pr_info("Reserved memory: created DMA memory pool at %pa, size %ld MiB\n", | ||
323 | &rmem->base, (unsigned long)rmem->size / SZ_1M); | ||
324 | return 0; | ||
325 | } | ||
326 | RESERVEDMEM_OF_DECLARE(dma, "shared-dma-pool", rmem_dma_setup); | ||
327 | #endif | ||
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 6606abdf880c..473ff4892401 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c | |||
@@ -211,3 +211,69 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages, | |||
211 | { | 211 | { |
212 | return cma_release(dev_get_cma_area(dev), pages, count); | 212 | return cma_release(dev_get_cma_area(dev), pages, count); |
213 | } | 213 | } |
214 | |||
215 | /* | ||
216 | * Support for reserved memory regions defined in device tree | ||
217 | */ | ||
218 | #ifdef CONFIG_OF_RESERVED_MEM | ||
219 | #include <linux/of.h> | ||
220 | #include <linux/of_fdt.h> | ||
221 | #include <linux/of_reserved_mem.h> | ||
222 | |||
223 | #undef pr_fmt | ||
224 | #define pr_fmt(fmt) fmt | ||
225 | |||
226 | static void rmem_cma_device_init(struct reserved_mem *rmem, struct device *dev) | ||
227 | { | ||
228 | dev_set_cma_area(dev, rmem->priv); | ||
229 | } | ||
230 | |||
231 | static void rmem_cma_device_release(struct reserved_mem *rmem, | ||
232 | struct device *dev) | ||
233 | { | ||
234 | dev_set_cma_area(dev, NULL); | ||
235 | } | ||
236 | |||
237 | static const struct reserved_mem_ops rmem_cma_ops = { | ||
238 | .device_init = rmem_cma_device_init, | ||
239 | .device_release = rmem_cma_device_release, | ||
240 | }; | ||
241 | |||
242 | static int __init rmem_cma_setup(struct reserved_mem *rmem) | ||
243 | { | ||
244 | phys_addr_t align = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); | ||
245 | phys_addr_t mask = align - 1; | ||
246 | unsigned long node = rmem->fdt_node; | ||
247 | struct cma *cma; | ||
248 | int err; | ||
249 | |||
250 | if (!of_get_flat_dt_prop(node, "reusable", NULL) || | ||
251 | of_get_flat_dt_prop(node, "no-map", NULL)) | ||
252 | return -EINVAL; | ||
253 | |||
254 | if ((rmem->base & mask) || (rmem->size & mask)) { | ||
255 | pr_err("Reserved memory: incorrect alignment of CMA region\n"); | ||
256 | return -EINVAL; | ||
257 | } | ||
258 | |||
259 | err = cma_init_reserved_mem(rmem->base, rmem->size, 0, &cma); | ||
260 | if (err) { | ||
261 | pr_err("Reserved memory: unable to setup CMA region\n"); | ||
262 | return err; | ||
263 | } | ||
264 | /* Architecture specific contiguous memory fixup. */ | ||
265 | dma_contiguous_early_fixup(rmem->base, rmem->size); | ||
266 | |||
267 | if (of_get_flat_dt_prop(node, "linux,cma-default", NULL)) | ||
268 | dma_contiguous_set_default(cma); | ||
269 | |||
270 | rmem->ops = &rmem_cma_ops; | ||
271 | rmem->priv = cma; | ||
272 | |||
273 | pr_info("Reserved memory: created CMA memory pool at %pa, size %ld MiB\n", | ||
274 | &rmem->base, (unsigned long)rmem->size / SZ_1M); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | RESERVEDMEM_OF_DECLARE(cma, "shared-dma-pool", rmem_cma_setup); | ||
279 | #endif | ||
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index cfd3af7b2cbd..84e0590e31dc 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -38,6 +38,15 @@ config COMMON_CLK_MAX77686 | |||
38 | ---help--- | 38 | ---help--- |
39 | This driver supports Maxim 77686 crystal oscillator clock. | 39 | This driver supports Maxim 77686 crystal oscillator clock. |
40 | 40 | ||
41 | config COMMON_CLK_RK808 | ||
42 | tristate "Clock driver for RK808" | ||
43 | depends on MFD_RK808 | ||
44 | ---help--- | ||
45 | This driver supports RK808 crystal oscillator clock. These | ||
46 | multi-function devices have two fixed-rate oscillators, | ||
47 | clocked at 32KHz each. Clkout1 is always on, Clkout2 can off | ||
48 | by control register. | ||
49 | |||
41 | config COMMON_CLK_SI5351 | 50 | config COMMON_CLK_SI5351 |
42 | tristate "Clock driver for SiLabs 5351A/B/C" | 51 | tristate "Clock driver for SiLabs 5351A/B/C" |
43 | depends on I2C | 52 | depends on I2C |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f537a0b1f798..99f53d5f8766 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o | |||
28 | obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o | 28 | obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o |
29 | obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o | 29 | obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o |
30 | obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o | 30 | obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o |
31 | obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o | ||
31 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o | 32 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o |
32 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | 33 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o |
33 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o | 34 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o |
diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c new file mode 100644 index 000000000000..83902b9cd49e --- /dev/null +++ b/drivers/clk/clk-rk808.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | * Clkout driver for Rockchip RK808 | ||
3 | * | ||
4 | * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd | ||
5 | * | ||
6 | * Author:Chris Zhong <zyw@rock-chips.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/clk.h> | ||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mfd/rk808.h> | ||
24 | #include <linux/i2c.h> | ||
25 | |||
26 | #define RK808_NR_OUTPUT 2 | ||
27 | |||
28 | struct rk808_clkout { | ||
29 | struct rk808 *rk808; | ||
30 | struct clk_onecell_data clk_data; | ||
31 | struct clk_hw clkout1_hw; | ||
32 | struct clk_hw clkout2_hw; | ||
33 | }; | ||
34 | |||
35 | static unsigned long rk808_clkout_recalc_rate(struct clk_hw *hw, | ||
36 | unsigned long parent_rate) | ||
37 | { | ||
38 | return 32768; | ||
39 | } | ||
40 | |||
41 | static int rk808_clkout2_enable(struct clk_hw *hw, bool enable) | ||
42 | { | ||
43 | struct rk808_clkout *rk808_clkout = container_of(hw, | ||
44 | struct rk808_clkout, | ||
45 | clkout2_hw); | ||
46 | struct rk808 *rk808 = rk808_clkout->rk808; | ||
47 | |||
48 | return regmap_update_bits(rk808->regmap, RK808_CLK32OUT_REG, | ||
49 | CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0); | ||
50 | } | ||
51 | |||
52 | static int rk808_clkout2_prepare(struct clk_hw *hw) | ||
53 | { | ||
54 | return rk808_clkout2_enable(hw, true); | ||
55 | } | ||
56 | |||
57 | static void rk808_clkout2_unprepare(struct clk_hw *hw) | ||
58 | { | ||
59 | rk808_clkout2_enable(hw, false); | ||
60 | } | ||
61 | |||
62 | static int rk808_clkout2_is_prepared(struct clk_hw *hw) | ||
63 | { | ||
64 | struct rk808_clkout *rk808_clkout = container_of(hw, | ||
65 | struct rk808_clkout, | ||
66 | clkout2_hw); | ||
67 | struct rk808 *rk808 = rk808_clkout->rk808; | ||
68 | uint32_t val; | ||
69 | |||
70 | int ret = regmap_read(rk808->regmap, RK808_CLK32OUT_REG, &val); | ||
71 | |||
72 | if (ret < 0) | ||
73 | return ret; | ||
74 | |||
75 | return (val & CLK32KOUT2_EN) ? 1 : 0; | ||
76 | } | ||
77 | |||
78 | static const struct clk_ops rk808_clkout1_ops = { | ||
79 | .recalc_rate = rk808_clkout_recalc_rate, | ||
80 | }; | ||
81 | |||
82 | static const struct clk_ops rk808_clkout2_ops = { | ||
83 | .prepare = rk808_clkout2_prepare, | ||
84 | .unprepare = rk808_clkout2_unprepare, | ||
85 | .is_prepared = rk808_clkout2_is_prepared, | ||
86 | .recalc_rate = rk808_clkout_recalc_rate, | ||
87 | }; | ||
88 | |||
89 | static int rk808_clkout_probe(struct platform_device *pdev) | ||
90 | { | ||
91 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | ||
92 | struct i2c_client *client = rk808->i2c; | ||
93 | struct device_node *node = client->dev.of_node; | ||
94 | struct clk_init_data init = {}; | ||
95 | struct clk **clk_table; | ||
96 | struct rk808_clkout *rk808_clkout; | ||
97 | |||
98 | rk808_clkout = devm_kzalloc(&client->dev, | ||
99 | sizeof(*rk808_clkout), GFP_KERNEL); | ||
100 | if (!rk808_clkout) | ||
101 | return -ENOMEM; | ||
102 | |||
103 | rk808_clkout->rk808 = rk808; | ||
104 | |||
105 | clk_table = devm_kcalloc(&client->dev, RK808_NR_OUTPUT, | ||
106 | sizeof(struct clk *), GFP_KERNEL); | ||
107 | if (!clk_table) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | init.flags = CLK_IS_ROOT; | ||
111 | init.parent_names = NULL; | ||
112 | init.num_parents = 0; | ||
113 | init.name = "rk808-clkout1"; | ||
114 | init.ops = &rk808_clkout1_ops; | ||
115 | rk808_clkout->clkout1_hw.init = &init; | ||
116 | |||
117 | /* optional override of the clockname */ | ||
118 | of_property_read_string_index(node, "clock-output-names", | ||
119 | 0, &init.name); | ||
120 | |||
121 | clk_table[0] = devm_clk_register(&client->dev, | ||
122 | &rk808_clkout->clkout1_hw); | ||
123 | if (IS_ERR(clk_table[0])) | ||
124 | return PTR_ERR(clk_table[0]); | ||
125 | |||
126 | init.name = "rk808-clkout2"; | ||
127 | init.ops = &rk808_clkout2_ops; | ||
128 | rk808_clkout->clkout2_hw.init = &init; | ||
129 | |||
130 | /* optional override of the clockname */ | ||
131 | of_property_read_string_index(node, "clock-output-names", | ||
132 | 1, &init.name); | ||
133 | |||
134 | clk_table[1] = devm_clk_register(&client->dev, | ||
135 | &rk808_clkout->clkout2_hw); | ||
136 | if (IS_ERR(clk_table[1])) | ||
137 | return PTR_ERR(clk_table[1]); | ||
138 | |||
139 | rk808_clkout->clk_data.clks = clk_table; | ||
140 | rk808_clkout->clk_data.clk_num = RK808_NR_OUTPUT; | ||
141 | |||
142 | return of_clk_add_provider(node, of_clk_src_onecell_get, | ||
143 | &rk808_clkout->clk_data); | ||
144 | } | ||
145 | |||
146 | static int rk808_clkout_remove(struct platform_device *pdev) | ||
147 | { | ||
148 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | ||
149 | struct i2c_client *client = rk808->i2c; | ||
150 | struct device_node *node = client->dev.of_node; | ||
151 | |||
152 | of_clk_del_provider(node); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static struct platform_driver rk808_clkout_driver = { | ||
158 | .probe = rk808_clkout_probe, | ||
159 | .remove = rk808_clkout_remove, | ||
160 | .driver = { | ||
161 | .name = "rk808-clkout", | ||
162 | }, | ||
163 | }; | ||
164 | |||
165 | module_platform_driver(rk808_clkout_driver); | ||
166 | |||
167 | MODULE_DESCRIPTION("Clkout driver for the rk808 series PMICs"); | ||
168 | MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); | ||
169 | MODULE_LICENSE("GPL"); | ||
170 | MODULE_ALIAS("platform:rk808-clkout"); | ||
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index d28a8c284da9..7206547c13ce 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -3574,7 +3574,7 @@ static int srpt_parse_i_port_id(u8 i_port_id[16], const char *name) | |||
3574 | int ret, rc; | 3574 | int ret, rc; |
3575 | 3575 | ||
3576 | p = name; | 3576 | p = name; |
3577 | if (strnicmp(p, "0x", 2) == 0) | 3577 | if (strncasecmp(p, "0x", 2) == 0) |
3578 | p += 2; | 3578 | p += 2; |
3579 | ret = -EINVAL; | 3579 | ret = -EINVAL; |
3580 | len = strlen(p); | 3580 | len = strlen(p); |
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 8857d5b9be71..ee3434f1e949 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -812,7 +812,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, | |||
812 | /* if we find something consistent, stay with that assumption | 812 | /* if we find something consistent, stay with that assumption |
813 | * at least M09 won't send 3 bytes here | 813 | * at least M09 won't send 3 bytes here |
814 | */ | 814 | */ |
815 | if (!(strnicmp(rdbuf + 1, "EP0", 3))) { | 815 | if (!(strncasecmp(rdbuf + 1, "EP0", 3))) { |
816 | tsdata->version = M06; | 816 | tsdata->version = M06; |
817 | 817 | ||
818 | /* remove last '$' end marker */ | 818 | /* remove last '$' end marker */ |
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 31727bf285d0..e2a4f5f415b2 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c | |||
@@ -188,6 +188,7 @@ static void r592_host_reset(struct r592_device *dev) | |||
188 | r592_set_mode(dev, dev->parallel_mode); | 188 | r592_set_mode(dev, dev->parallel_mode); |
189 | } | 189 | } |
190 | 190 | ||
191 | #ifdef CONFIG_PM_SLEEP | ||
191 | /* Disable all hardware interrupts */ | 192 | /* Disable all hardware interrupts */ |
192 | static void r592_clear_interrupts(struct r592_device *dev) | 193 | static void r592_clear_interrupts(struct r592_device *dev) |
193 | { | 194 | { |
@@ -195,6 +196,7 @@ static void r592_clear_interrupts(struct r592_device *dev) | |||
195 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_ACK_MASK); | 196 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_ACK_MASK); |
196 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_EN_MASK); | 197 | r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_EN_MASK); |
197 | } | 198 | } |
199 | #endif | ||
198 | 200 | ||
199 | /* Tests if there is an CRC error */ | 201 | /* Tests if there is an CRC error */ |
200 | static int r592_test_io_error(struct r592_device *dev) | 202 | static int r592_test_io_error(struct r592_device *dev) |
diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index 24272e022bec..bca2630d006f 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c | |||
@@ -454,7 +454,7 @@ exit_done: | |||
454 | 454 | ||
455 | name = &p[str_table + name_id]; | 455 | name = &p[str_table + name_id]; |
456 | 456 | ||
457 | if (strnicmp(aconf->action, name, strlen(name)) == 0) { | 457 | if (strncasecmp(aconf->action, name, strlen(name)) == 0) { |
458 | action_found = 1; | 458 | action_found = 1; |
459 | current_proc = | 459 | current_proc = |
460 | get_unaligned_be32(&p[action_table + | 460 | get_unaligned_be32(&p[action_table + |
@@ -2176,7 +2176,7 @@ static int altera_get_note(u8 *p, s32 program_size, | |||
2176 | key_ptr = &p[note_strings + | 2176 | key_ptr = &p[note_strings + |
2177 | get_unaligned_be32( | 2177 | get_unaligned_be32( |
2178 | &p[note_table + (8 * i)])]; | 2178 | &p[note_table + (8 * i)])]; |
2179 | if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) && | 2179 | if ((strncasecmp(key, key_ptr, strlen(key_ptr)) == 0) && |
2180 | (key != NULL)) { | 2180 | (key != NULL)) { |
2181 | status = 0; | 2181 | status = 0; |
2182 | 2182 | ||
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index 8efd17c52f65..dd84557cf957 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
@@ -168,7 +168,6 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v) | |||
168 | local_info_t *local = m->private; | 168 | local_info_t *local = m->private; |
169 | struct list_head *ptr = v; | 169 | struct list_head *ptr = v; |
170 | struct hostap_bss_info *bss; | 170 | struct hostap_bss_info *bss; |
171 | int i; | ||
172 | 171 | ||
173 | if (ptr == &local->bss_list) { | 172 | if (ptr == &local->bss_list) { |
174 | seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" | 173 | seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" |
@@ -181,9 +180,7 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v) | |||
181 | bss->bssid, bss->last_update, | 180 | bss->bssid, bss->last_update, |
182 | bss->count, bss->capab_info); | 181 | bss->count, bss->capab_info); |
183 | 182 | ||
184 | for (i = 0; i < bss->ssid_len; i++) | 183 | seq_printf(m, "%*pE", (int)bss->ssid_len, bss->ssid); |
185 | seq_putc(m,bss->ssid[i] >= 32 && bss->ssid[i] < 127 ? | ||
186 | bss->ssid[i] : '_'); | ||
187 | 184 | ||
188 | seq_putc(m, '\t'); | 185 | seq_putc(m, '\t'); |
189 | seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid); | 186 | seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid); |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index c3d726f334e3..6fabea0309dd 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -2005,7 +2005,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) | |||
2005 | u32 chan; | 2005 | u32 chan; |
2006 | char *txratename; | 2006 | char *txratename; |
2007 | u8 bssid[ETH_ALEN]; | 2007 | u8 bssid[ETH_ALEN]; |
2008 | DECLARE_SSID_BUF(ssid); | ||
2009 | 2008 | ||
2010 | /* | 2009 | /* |
2011 | * TBD: BSSID is usually 00:00:00:00:00:00 here and not | 2010 | * TBD: BSSID is usually 00:00:00:00:00:00 here and not |
@@ -2067,8 +2066,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) | |||
2067 | break; | 2066 | break; |
2068 | } | 2067 | } |
2069 | 2068 | ||
2070 | IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID=%pM)\n", | 2069 | IPW_DEBUG_INFO("%s: Associated with '%*pE' at %s, channel %d (BSSID=%pM)\n", |
2071 | priv->net_dev->name, print_ssid(ssid, essid, essid_len), | 2070 | priv->net_dev->name, essid_len, essid, |
2072 | txratename, chan, bssid); | 2071 | txratename, chan, bssid); |
2073 | 2072 | ||
2074 | /* now we copy read ssid into dev */ | 2073 | /* now we copy read ssid into dev */ |
@@ -2095,9 +2094,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, | |||
2095 | .host_command_length = ssid_len | 2094 | .host_command_length = ssid_len |
2096 | }; | 2095 | }; |
2097 | int err; | 2096 | int err; |
2098 | DECLARE_SSID_BUF(ssid); | ||
2099 | 2097 | ||
2100 | IPW_DEBUG_HC("SSID: '%s'\n", print_ssid(ssid, essid, ssid_len)); | 2098 | IPW_DEBUG_HC("SSID: '%*pE'\n", ssid_len, essid); |
2101 | 2099 | ||
2102 | if (ssid_len) | 2100 | if (ssid_len) |
2103 | memcpy(cmd.host_command_parameters, essid, ssid_len); | 2101 | memcpy(cmd.host_command_parameters, essid, ssid_len); |
@@ -2138,11 +2136,8 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, | |||
2138 | 2136 | ||
2139 | static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) | 2137 | static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) |
2140 | { | 2138 | { |
2141 | DECLARE_SSID_BUF(ssid); | ||
2142 | |||
2143 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, | 2139 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC, |
2144 | "disassociated: '%s' %pM\n", | 2140 | "disassociated: '%*pE' %pM\n", priv->essid_len, priv->essid, |
2145 | print_ssid(ssid, priv->essid, priv->essid_len), | ||
2146 | priv->bssid); | 2141 | priv->bssid); |
2147 | 2142 | ||
2148 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); | 2143 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); |
@@ -6975,7 +6970,6 @@ static int ipw2100_wx_set_essid(struct net_device *dev, | |||
6975 | char *essid = ""; /* ANY */ | 6970 | char *essid = ""; /* ANY */ |
6976 | int length = 0; | 6971 | int length = 0; |
6977 | int err = 0; | 6972 | int err = 0; |
6978 | DECLARE_SSID_BUF(ssid); | ||
6979 | 6973 | ||
6980 | mutex_lock(&priv->action_mutex); | 6974 | mutex_lock(&priv->action_mutex); |
6981 | if (!(priv->status & STATUS_INITIALIZED)) { | 6975 | if (!(priv->status & STATUS_INITIALIZED)) { |
@@ -7005,8 +6999,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, | |||
7005 | goto done; | 6999 | goto done; |
7006 | } | 7000 | } |
7007 | 7001 | ||
7008 | IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", | 7002 | IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, essid, length); |
7009 | print_ssid(ssid, essid, length), length); | ||
7010 | 7003 | ||
7011 | priv->essid_len = length; | 7004 | priv->essid_len = length; |
7012 | memcpy(priv->essid, essid, priv->essid_len); | 7005 | memcpy(priv->essid, essid, priv->essid_len); |
@@ -7027,13 +7020,12 @@ static int ipw2100_wx_get_essid(struct net_device *dev, | |||
7027 | */ | 7020 | */ |
7028 | 7021 | ||
7029 | struct ipw2100_priv *priv = libipw_priv(dev); | 7022 | struct ipw2100_priv *priv = libipw_priv(dev); |
7030 | DECLARE_SSID_BUF(ssid); | ||
7031 | 7023 | ||
7032 | /* If we are associated, trying to associate, or have a statically | 7024 | /* If we are associated, trying to associate, or have a statically |
7033 | * configured ESSID then return that; otherwise return ANY */ | 7025 | * configured ESSID then return that; otherwise return ANY */ |
7034 | if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) { | 7026 | if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) { |
7035 | IPW_DEBUG_WX("Getting essid: '%s'\n", | 7027 | IPW_DEBUG_WX("Getting essid: '%*pE'\n", |
7036 | print_ssid(ssid, priv->essid, priv->essid_len)); | 7028 | priv->essid_len, priv->essid); |
7037 | memcpy(extra, priv->essid, priv->essid_len); | 7029 | memcpy(extra, priv->essid, priv->essid_len); |
7038 | wrqu->essid.length = priv->essid_len; | 7030 | wrqu->essid.length = priv->essid_len; |
7039 | wrqu->essid.flags = 1; /* active */ | 7031 | wrqu->essid.flags = 1; /* active */ |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index f0c3c77a48d3..edc344334a75 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -4496,7 +4496,6 @@ static void handle_scan_event(struct ipw_priv *priv) | |||
4496 | static void ipw_rx_notification(struct ipw_priv *priv, | 4496 | static void ipw_rx_notification(struct ipw_priv *priv, |
4497 | struct ipw_rx_notification *notif) | 4497 | struct ipw_rx_notification *notif) |
4498 | { | 4498 | { |
4499 | DECLARE_SSID_BUF(ssid); | ||
4500 | u16 size = le16_to_cpu(notif->size); | 4499 | u16 size = le16_to_cpu(notif->size); |
4501 | 4500 | ||
4502 | IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size); | 4501 | IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size); |
@@ -4509,9 +4508,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4509 | case CMAS_ASSOCIATED:{ | 4508 | case CMAS_ASSOCIATED:{ |
4510 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4509 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4511 | IPW_DL_ASSOC, | 4510 | IPW_DL_ASSOC, |
4512 | "associated: '%s' %pM\n", | 4511 | "associated: '%*pE' %pM\n", |
4513 | print_ssid(ssid, priv->essid, | 4512 | priv->essid_len, priv->essid, |
4514 | priv->essid_len), | ||
4515 | priv->bssid); | 4513 | priv->bssid); |
4516 | 4514 | ||
4517 | switch (priv->ieee->iw_mode) { | 4515 | switch (priv->ieee->iw_mode) { |
@@ -4585,14 +4583,9 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4585 | IPW_DEBUG(IPW_DL_NOTIF | | 4583 | IPW_DEBUG(IPW_DL_NOTIF | |
4586 | IPW_DL_STATE | | 4584 | IPW_DL_STATE | |
4587 | IPW_DL_ASSOC, | 4585 | IPW_DL_ASSOC, |
4588 | "deauthenticated: '%s' " | 4586 | "deauthenticated: '%*pE' %pM: (0x%04X) - %s\n", |
4589 | "%pM" | 4587 | priv->essid_len, |
4590 | ": (0x%04X) - %s\n", | 4588 | priv->essid, |
4591 | print_ssid(ssid, | ||
4592 | priv-> | ||
4593 | essid, | ||
4594 | priv-> | ||
4595 | essid_len), | ||
4596 | priv->bssid, | 4589 | priv->bssid, |
4597 | le16_to_cpu(auth->status), | 4590 | le16_to_cpu(auth->status), |
4598 | ipw_get_status_code | 4591 | ipw_get_status_code |
@@ -4610,9 +4603,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4610 | 4603 | ||
4611 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4604 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4612 | IPW_DL_ASSOC, | 4605 | IPW_DL_ASSOC, |
4613 | "authenticated: '%s' %pM\n", | 4606 | "authenticated: '%*pE' %pM\n", |
4614 | print_ssid(ssid, priv->essid, | 4607 | priv->essid_len, priv->essid, |
4615 | priv->essid_len), | ||
4616 | priv->bssid); | 4608 | priv->bssid); |
4617 | break; | 4609 | break; |
4618 | } | 4610 | } |
@@ -4638,9 +4630,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4638 | 4630 | ||
4639 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4631 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4640 | IPW_DL_ASSOC, | 4632 | IPW_DL_ASSOC, |
4641 | "disassociated: '%s' %pM\n", | 4633 | "disassociated: '%*pE' %pM\n", |
4642 | print_ssid(ssid, priv->essid, | 4634 | priv->essid_len, priv->essid, |
4643 | priv->essid_len), | ||
4644 | priv->bssid); | 4635 | priv->bssid); |
4645 | 4636 | ||
4646 | priv->status &= | 4637 | priv->status &= |
@@ -4676,9 +4667,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4676 | switch (auth->state) { | 4667 | switch (auth->state) { |
4677 | case CMAS_AUTHENTICATED: | 4668 | case CMAS_AUTHENTICATED: |
4678 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, | 4669 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, |
4679 | "authenticated: '%s' %pM\n", | 4670 | "authenticated: '%*pE' %pM\n", |
4680 | print_ssid(ssid, priv->essid, | 4671 | priv->essid_len, priv->essid, |
4681 | priv->essid_len), | ||
4682 | priv->bssid); | 4672 | priv->bssid); |
4683 | priv->status |= STATUS_AUTH; | 4673 | priv->status |= STATUS_AUTH; |
4684 | break; | 4674 | break; |
@@ -4695,9 +4685,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4695 | } | 4685 | } |
4696 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | | 4686 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | |
4697 | IPW_DL_ASSOC, | 4687 | IPW_DL_ASSOC, |
4698 | "deauthenticated: '%s' %pM\n", | 4688 | "deauthenticated: '%*pE' %pM\n", |
4699 | print_ssid(ssid, priv->essid, | 4689 | priv->essid_len, priv->essid, |
4700 | priv->essid_len), | ||
4701 | priv->bssid); | 4690 | priv->bssid); |
4702 | 4691 | ||
4703 | priv->status &= ~(STATUS_ASSOCIATING | | 4692 | priv->status &= ~(STATUS_ASSOCIATING | |
@@ -5516,16 +5505,13 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5516 | int roaming) | 5505 | int roaming) |
5517 | { | 5506 | { |
5518 | struct ipw_supported_rates rates; | 5507 | struct ipw_supported_rates rates; |
5519 | DECLARE_SSID_BUF(ssid); | ||
5520 | 5508 | ||
5521 | /* Verify that this network's capability is compatible with the | 5509 | /* Verify that this network's capability is compatible with the |
5522 | * current mode (AdHoc or Infrastructure) */ | 5510 | * current mode (AdHoc or Infrastructure) */ |
5523 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC && | 5511 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC && |
5524 | !(network->capability & WLAN_CAPABILITY_IBSS))) { | 5512 | !(network->capability & WLAN_CAPABILITY_IBSS))) { |
5525 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to " | 5513 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded due to capability mismatch.\n", |
5526 | "capability mismatch.\n", | 5514 | network->ssid_len, network->ssid, |
5527 | print_ssid(ssid, network->ssid, | ||
5528 | network->ssid_len), | ||
5529 | network->bssid); | 5515 | network->bssid); |
5530 | return 0; | 5516 | return 0; |
5531 | } | 5517 | } |
@@ -5536,10 +5522,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5536 | if ((network->ssid_len != match->network->ssid_len) || | 5522 | if ((network->ssid_len != match->network->ssid_len) || |
5537 | memcmp(network->ssid, match->network->ssid, | 5523 | memcmp(network->ssid, match->network->ssid, |
5538 | network->ssid_len)) { | 5524 | network->ssid_len)) { |
5539 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5525 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of non-network ESSID.\n", |
5540 | "because of non-network ESSID.\n", | 5526 | network->ssid_len, network->ssid, |
5541 | print_ssid(ssid, network->ssid, | ||
5542 | network->ssid_len), | ||
5543 | network->bssid); | 5527 | network->bssid); |
5544 | return 0; | 5528 | return 0; |
5545 | } | 5529 | } |
@@ -5550,17 +5534,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5550 | ((network->ssid_len != priv->essid_len) || | 5534 | ((network->ssid_len != priv->essid_len) || |
5551 | memcmp(network->ssid, priv->essid, | 5535 | memcmp(network->ssid, priv->essid, |
5552 | min(network->ssid_len, priv->essid_len)))) { | 5536 | min(network->ssid_len, priv->essid_len)))) { |
5553 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5537 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n", |
5554 | 5538 | network->ssid_len, network->ssid, | |
5555 | strlcpy(escaped, | 5539 | network->bssid, priv->essid_len, |
5556 | print_ssid(ssid, network->ssid, | 5540 | priv->essid); |
5557 | network->ssid_len), | ||
5558 | sizeof(escaped)); | ||
5559 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | ||
5560 | "because of ESSID mismatch: '%s'.\n", | ||
5561 | escaped, network->bssid, | ||
5562 | print_ssid(ssid, priv->essid, | ||
5563 | priv->essid_len)); | ||
5564 | return 0; | 5541 | return 0; |
5565 | } | 5542 | } |
5566 | } | 5543 | } |
@@ -5569,26 +5546,20 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5569 | * testing everything else. */ | 5546 | * testing everything else. */ |
5570 | 5547 | ||
5571 | if (network->time_stamp[0] < match->network->time_stamp[0]) { | 5548 | if (network->time_stamp[0] < match->network->time_stamp[0]) { |
5572 | IPW_DEBUG_MERGE("Network '%s excluded because newer than " | 5549 | IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n", |
5573 | "current network.\n", | 5550 | match->network->ssid_len, match->network->ssid); |
5574 | print_ssid(ssid, match->network->ssid, | ||
5575 | match->network->ssid_len)); | ||
5576 | return 0; | 5551 | return 0; |
5577 | } else if (network->time_stamp[1] < match->network->time_stamp[1]) { | 5552 | } else if (network->time_stamp[1] < match->network->time_stamp[1]) { |
5578 | IPW_DEBUG_MERGE("Network '%s excluded because newer than " | 5553 | IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n", |
5579 | "current network.\n", | 5554 | match->network->ssid_len, match->network->ssid); |
5580 | print_ssid(ssid, match->network->ssid, | ||
5581 | match->network->ssid_len)); | ||
5582 | return 0; | 5555 | return 0; |
5583 | } | 5556 | } |
5584 | 5557 | ||
5585 | /* Now go through and see if the requested network is valid... */ | 5558 | /* Now go through and see if the requested network is valid... */ |
5586 | if (priv->ieee->scan_age != 0 && | 5559 | if (priv->ieee->scan_age != 0 && |
5587 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { | 5560 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { |
5588 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5561 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of age: %ums.\n", |
5589 | "because of age: %ums.\n", | 5562 | network->ssid_len, network->ssid, |
5590 | print_ssid(ssid, network->ssid, | ||
5591 | network->ssid_len), | ||
5592 | network->bssid, | 5563 | network->bssid, |
5593 | jiffies_to_msecs(jiffies - | 5564 | jiffies_to_msecs(jiffies - |
5594 | network->last_scanned)); | 5565 | network->last_scanned)); |
@@ -5597,10 +5568,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5597 | 5568 | ||
5598 | if ((priv->config & CFG_STATIC_CHANNEL) && | 5569 | if ((priv->config & CFG_STATIC_CHANNEL) && |
5599 | (network->channel != priv->channel)) { | 5570 | (network->channel != priv->channel)) { |
5600 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5571 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n", |
5601 | "because of channel mismatch: %d != %d.\n", | 5572 | network->ssid_len, network->ssid, |
5602 | print_ssid(ssid, network->ssid, | ||
5603 | network->ssid_len), | ||
5604 | network->bssid, | 5573 | network->bssid, |
5605 | network->channel, priv->channel); | 5574 | network->channel, priv->channel); |
5606 | return 0; | 5575 | return 0; |
@@ -5609,10 +5578,8 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5609 | /* Verify privacy compatibility */ | 5578 | /* Verify privacy compatibility */ |
5610 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != | 5579 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != |
5611 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { | 5580 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { |
5612 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5581 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n", |
5613 | "because of privacy mismatch: %s != %s.\n", | 5582 | network->ssid_len, network->ssid, |
5614 | print_ssid(ssid, network->ssid, | ||
5615 | network->ssid_len), | ||
5616 | network->bssid, | 5583 | network->bssid, |
5617 | priv-> | 5584 | priv-> |
5618 | capability & CAP_PRIVACY_ON ? "on" : "off", | 5585 | capability & CAP_PRIVACY_ON ? "on" : "off", |
@@ -5623,22 +5590,16 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5623 | } | 5590 | } |
5624 | 5591 | ||
5625 | if (ether_addr_equal(network->bssid, priv->bssid)) { | 5592 | if (ether_addr_equal(network->bssid, priv->bssid)) { |
5626 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5593 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of the same BSSID match: %pM.\n", |
5627 | "because of the same BSSID match: %pM" | 5594 | network->ssid_len, network->ssid, |
5628 | ".\n", print_ssid(ssid, network->ssid, | 5595 | network->bssid, priv->bssid); |
5629 | network->ssid_len), | ||
5630 | network->bssid, | ||
5631 | priv->bssid); | ||
5632 | return 0; | 5596 | return 0; |
5633 | } | 5597 | } |
5634 | 5598 | ||
5635 | /* Filter out any incompatible freq / mode combinations */ | 5599 | /* Filter out any incompatible freq / mode combinations */ |
5636 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { | 5600 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { |
5637 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5601 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n", |
5638 | "because of invalid frequency/mode " | 5602 | network->ssid_len, network->ssid, |
5639 | "combination.\n", | ||
5640 | print_ssid(ssid, network->ssid, | ||
5641 | network->ssid_len), | ||
5642 | network->bssid); | 5603 | network->bssid); |
5643 | return 0; | 5604 | return 0; |
5644 | } | 5605 | } |
@@ -5646,20 +5607,15 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5646 | /* Ensure that the rates supported by the driver are compatible with | 5607 | /* Ensure that the rates supported by the driver are compatible with |
5647 | * this AP, including verification of basic rates (mandatory) */ | 5608 | * this AP, including verification of basic rates (mandatory) */ |
5648 | if (!ipw_compatible_rates(priv, network, &rates)) { | 5609 | if (!ipw_compatible_rates(priv, network, &rates)) { |
5649 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5610 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n", |
5650 | "because configured rate mask excludes " | 5611 | network->ssid_len, network->ssid, |
5651 | "AP mandatory rate.\n", | ||
5652 | print_ssid(ssid, network->ssid, | ||
5653 | network->ssid_len), | ||
5654 | network->bssid); | 5612 | network->bssid); |
5655 | return 0; | 5613 | return 0; |
5656 | } | 5614 | } |
5657 | 5615 | ||
5658 | if (rates.num_rates == 0) { | 5616 | if (rates.num_rates == 0) { |
5659 | IPW_DEBUG_MERGE("Network '%s (%pM)' excluded " | 5617 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of no compatible rates.\n", |
5660 | "because of no compatible rates.\n", | 5618 | network->ssid_len, network->ssid, |
5661 | print_ssid(ssid, network->ssid, | ||
5662 | network->ssid_len), | ||
5663 | network->bssid); | 5619 | network->bssid); |
5664 | return 0; | 5620 | return 0; |
5665 | } | 5621 | } |
@@ -5671,16 +5627,14 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5671 | /* Set up 'new' AP to this network */ | 5627 | /* Set up 'new' AP to this network */ |
5672 | ipw_copy_rates(&match->rates, &rates); | 5628 | ipw_copy_rates(&match->rates, &rates); |
5673 | match->network = network; | 5629 | match->network = network; |
5674 | IPW_DEBUG_MERGE("Network '%s (%pM)' is a viable match.\n", | 5630 | IPW_DEBUG_MERGE("Network '%*pE (%pM)' is a viable match.\n", |
5675 | print_ssid(ssid, network->ssid, network->ssid_len), | 5631 | network->ssid_len, network->ssid, network->bssid); |
5676 | network->bssid); | ||
5677 | 5632 | ||
5678 | return 1; | 5633 | return 1; |
5679 | } | 5634 | } |
5680 | 5635 | ||
5681 | static void ipw_merge_adhoc_network(struct work_struct *work) | 5636 | static void ipw_merge_adhoc_network(struct work_struct *work) |
5682 | { | 5637 | { |
5683 | DECLARE_SSID_BUF(ssid); | ||
5684 | struct ipw_priv *priv = | 5638 | struct ipw_priv *priv = |
5685 | container_of(work, struct ipw_priv, merge_networks); | 5639 | container_of(work, struct ipw_priv, merge_networks); |
5686 | struct libipw_network *network = NULL; | 5640 | struct libipw_network *network = NULL; |
@@ -5710,9 +5664,8 @@ static void ipw_merge_adhoc_network(struct work_struct *work) | |||
5710 | 5664 | ||
5711 | mutex_lock(&priv->mutex); | 5665 | mutex_lock(&priv->mutex); |
5712 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { | 5666 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) { |
5713 | IPW_DEBUG_MERGE("remove network %s\n", | 5667 | IPW_DEBUG_MERGE("remove network %*pE\n", |
5714 | print_ssid(ssid, priv->essid, | 5668 | priv->essid_len, priv->essid); |
5715 | priv->essid_len)); | ||
5716 | ipw_remove_current_network(priv); | 5669 | ipw_remove_current_network(priv); |
5717 | } | 5670 | } |
5718 | 5671 | ||
@@ -5728,7 +5681,6 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5728 | struct libipw_network *network, int roaming) | 5681 | struct libipw_network *network, int roaming) |
5729 | { | 5682 | { |
5730 | struct ipw_supported_rates rates; | 5683 | struct ipw_supported_rates rates; |
5731 | DECLARE_SSID_BUF(ssid); | ||
5732 | 5684 | ||
5733 | /* Verify that this network's capability is compatible with the | 5685 | /* Verify that this network's capability is compatible with the |
5734 | * current mode (AdHoc or Infrastructure) */ | 5686 | * current mode (AdHoc or Infrastructure) */ |
@@ -5736,10 +5688,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5736 | !(network->capability & WLAN_CAPABILITY_ESS)) || | 5688 | !(network->capability & WLAN_CAPABILITY_ESS)) || |
5737 | (priv->ieee->iw_mode == IW_MODE_ADHOC && | 5689 | (priv->ieee->iw_mode == IW_MODE_ADHOC && |
5738 | !(network->capability & WLAN_CAPABILITY_IBSS))) { | 5690 | !(network->capability & WLAN_CAPABILITY_IBSS))) { |
5739 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to " | 5691 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded due to capability mismatch.\n", |
5740 | "capability mismatch.\n", | 5692 | network->ssid_len, network->ssid, |
5741 | print_ssid(ssid, network->ssid, | ||
5742 | network->ssid_len), | ||
5743 | network->bssid); | 5693 | network->bssid); |
5744 | return 0; | 5694 | return 0; |
5745 | } | 5695 | } |
@@ -5750,10 +5700,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5750 | if ((network->ssid_len != match->network->ssid_len) || | 5700 | if ((network->ssid_len != match->network->ssid_len) || |
5751 | memcmp(network->ssid, match->network->ssid, | 5701 | memcmp(network->ssid, match->network->ssid, |
5752 | network->ssid_len)) { | 5702 | network->ssid_len)) { |
5753 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5703 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of non-network ESSID.\n", |
5754 | "because of non-network ESSID.\n", | 5704 | network->ssid_len, network->ssid, |
5755 | print_ssid(ssid, network->ssid, | ||
5756 | network->ssid_len), | ||
5757 | network->bssid); | 5705 | network->bssid); |
5758 | return 0; | 5706 | return 0; |
5759 | } | 5707 | } |
@@ -5764,16 +5712,10 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5764 | ((network->ssid_len != priv->essid_len) || | 5712 | ((network->ssid_len != priv->essid_len) || |
5765 | memcmp(network->ssid, priv->essid, | 5713 | memcmp(network->ssid, priv->essid, |
5766 | min(network->ssid_len, priv->essid_len)))) { | 5714 | min(network->ssid_len, priv->essid_len)))) { |
5767 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5715 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n", |
5768 | strlcpy(escaped, | 5716 | network->ssid_len, network->ssid, |
5769 | print_ssid(ssid, network->ssid, | 5717 | network->bssid, priv->essid_len, |
5770 | network->ssid_len), | 5718 | priv->essid); |
5771 | sizeof(escaped)); | ||
5772 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | ||
5773 | "because of ESSID mismatch: '%s'.\n", | ||
5774 | escaped, network->bssid, | ||
5775 | print_ssid(ssid, priv->essid, | ||
5776 | priv->essid_len)); | ||
5777 | return 0; | 5719 | return 0; |
5778 | } | 5720 | } |
5779 | } | 5721 | } |
@@ -5781,16 +5723,10 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5781 | /* If the old network rate is better than this one, don't bother | 5723 | /* If the old network rate is better than this one, don't bother |
5782 | * testing everything else. */ | 5724 | * testing everything else. */ |
5783 | if (match->network && match->network->stats.rssi > network->stats.rssi) { | 5725 | if (match->network && match->network->stats.rssi > network->stats.rssi) { |
5784 | char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 5726 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because '%*pE (%pM)' has a stronger signal.\n", |
5785 | strlcpy(escaped, | 5727 | network->ssid_len, network->ssid, |
5786 | print_ssid(ssid, network->ssid, network->ssid_len), | 5728 | network->bssid, match->network->ssid_len, |
5787 | sizeof(escaped)); | 5729 | match->network->ssid, match->network->bssid); |
5788 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because " | ||
5789 | "'%s (%pM)' has a stronger signal.\n", | ||
5790 | escaped, network->bssid, | ||
5791 | print_ssid(ssid, match->network->ssid, | ||
5792 | match->network->ssid_len), | ||
5793 | match->network->bssid); | ||
5794 | return 0; | 5730 | return 0; |
5795 | } | 5731 | } |
5796 | 5732 | ||
@@ -5798,11 +5734,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5798 | * last 3 seconds, do not try and associate again... */ | 5734 | * last 3 seconds, do not try and associate again... */ |
5799 | if (network->last_associate && | 5735 | if (network->last_associate && |
5800 | time_after(network->last_associate + (HZ * 3UL), jiffies)) { | 5736 | time_after(network->last_associate + (HZ * 3UL), jiffies)) { |
5801 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5737 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of storming (%ums since last assoc attempt).\n", |
5802 | "because of storming (%ums since last " | 5738 | network->ssid_len, network->ssid, |
5803 | "assoc attempt).\n", | ||
5804 | print_ssid(ssid, network->ssid, | ||
5805 | network->ssid_len), | ||
5806 | network->bssid, | 5739 | network->bssid, |
5807 | jiffies_to_msecs(jiffies - | 5740 | jiffies_to_msecs(jiffies - |
5808 | network->last_associate)); | 5741 | network->last_associate)); |
@@ -5812,10 +5745,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5812 | /* Now go through and see if the requested network is valid... */ | 5745 | /* Now go through and see if the requested network is valid... */ |
5813 | if (priv->ieee->scan_age != 0 && | 5746 | if (priv->ieee->scan_age != 0 && |
5814 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { | 5747 | time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) { |
5815 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5748 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of age: %ums.\n", |
5816 | "because of age: %ums.\n", | 5749 | network->ssid_len, network->ssid, |
5817 | print_ssid(ssid, network->ssid, | ||
5818 | network->ssid_len), | ||
5819 | network->bssid, | 5750 | network->bssid, |
5820 | jiffies_to_msecs(jiffies - | 5751 | jiffies_to_msecs(jiffies - |
5821 | network->last_scanned)); | 5752 | network->last_scanned)); |
@@ -5824,10 +5755,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5824 | 5755 | ||
5825 | if ((priv->config & CFG_STATIC_CHANNEL) && | 5756 | if ((priv->config & CFG_STATIC_CHANNEL) && |
5826 | (network->channel != priv->channel)) { | 5757 | (network->channel != priv->channel)) { |
5827 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5758 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n", |
5828 | "because of channel mismatch: %d != %d.\n", | 5759 | network->ssid_len, network->ssid, |
5829 | print_ssid(ssid, network->ssid, | ||
5830 | network->ssid_len), | ||
5831 | network->bssid, | 5760 | network->bssid, |
5832 | network->channel, priv->channel); | 5761 | network->channel, priv->channel); |
5833 | return 0; | 5762 | return 0; |
@@ -5836,10 +5765,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5836 | /* Verify privacy compatibility */ | 5765 | /* Verify privacy compatibility */ |
5837 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != | 5766 | if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) != |
5838 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { | 5767 | ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) { |
5839 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5768 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n", |
5840 | "because of privacy mismatch: %s != %s.\n", | 5769 | network->ssid_len, network->ssid, |
5841 | print_ssid(ssid, network->ssid, | ||
5842 | network->ssid_len), | ||
5843 | network->bssid, | 5770 | network->bssid, |
5844 | priv->capability & CAP_PRIVACY_ON ? "on" : | 5771 | priv->capability & CAP_PRIVACY_ON ? "on" : |
5845 | "off", | 5772 | "off", |
@@ -5850,31 +5777,24 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5850 | 5777 | ||
5851 | if ((priv->config & CFG_STATIC_BSSID) && | 5778 | if ((priv->config & CFG_STATIC_BSSID) && |
5852 | !ether_addr_equal(network->bssid, priv->bssid)) { | 5779 | !ether_addr_equal(network->bssid, priv->bssid)) { |
5853 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5780 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of BSSID mismatch: %pM.\n", |
5854 | "because of BSSID mismatch: %pM.\n", | 5781 | network->ssid_len, network->ssid, |
5855 | print_ssid(ssid, network->ssid, | ||
5856 | network->ssid_len), | ||
5857 | network->bssid, priv->bssid); | 5782 | network->bssid, priv->bssid); |
5858 | return 0; | 5783 | return 0; |
5859 | } | 5784 | } |
5860 | 5785 | ||
5861 | /* Filter out any incompatible freq / mode combinations */ | 5786 | /* Filter out any incompatible freq / mode combinations */ |
5862 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { | 5787 | if (!libipw_is_valid_mode(priv->ieee, network->mode)) { |
5863 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5788 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n", |
5864 | "because of invalid frequency/mode " | 5789 | network->ssid_len, network->ssid, |
5865 | "combination.\n", | ||
5866 | print_ssid(ssid, network->ssid, | ||
5867 | network->ssid_len), | ||
5868 | network->bssid); | 5790 | network->bssid); |
5869 | return 0; | 5791 | return 0; |
5870 | } | 5792 | } |
5871 | 5793 | ||
5872 | /* Filter out invalid channel in current GEO */ | 5794 | /* Filter out invalid channel in current GEO */ |
5873 | if (!libipw_is_valid_channel(priv->ieee, network->channel)) { | 5795 | if (!libipw_is_valid_channel(priv->ieee, network->channel)) { |
5874 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5796 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid channel in current GEO\n", |
5875 | "because of invalid channel in current GEO\n", | 5797 | network->ssid_len, network->ssid, |
5876 | print_ssid(ssid, network->ssid, | ||
5877 | network->ssid_len), | ||
5878 | network->bssid); | 5798 | network->bssid); |
5879 | return 0; | 5799 | return 0; |
5880 | } | 5800 | } |
@@ -5882,20 +5802,15 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5882 | /* Ensure that the rates supported by the driver are compatible with | 5802 | /* Ensure that the rates supported by the driver are compatible with |
5883 | * this AP, including verification of basic rates (mandatory) */ | 5803 | * this AP, including verification of basic rates (mandatory) */ |
5884 | if (!ipw_compatible_rates(priv, network, &rates)) { | 5804 | if (!ipw_compatible_rates(priv, network, &rates)) { |
5885 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5805 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n", |
5886 | "because configured rate mask excludes " | 5806 | network->ssid_len, network->ssid, |
5887 | "AP mandatory rate.\n", | ||
5888 | print_ssid(ssid, network->ssid, | ||
5889 | network->ssid_len), | ||
5890 | network->bssid); | 5807 | network->bssid); |
5891 | return 0; | 5808 | return 0; |
5892 | } | 5809 | } |
5893 | 5810 | ||
5894 | if (rates.num_rates == 0) { | 5811 | if (rates.num_rates == 0) { |
5895 | IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded " | 5812 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of no compatible rates.\n", |
5896 | "because of no compatible rates.\n", | 5813 | network->ssid_len, network->ssid, |
5897 | print_ssid(ssid, network->ssid, | ||
5898 | network->ssid_len), | ||
5899 | network->bssid); | 5814 | network->bssid); |
5900 | return 0; | 5815 | return 0; |
5901 | } | 5816 | } |
@@ -5908,9 +5823,8 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5908 | ipw_copy_rates(&match->rates, &rates); | 5823 | ipw_copy_rates(&match->rates, &rates); |
5909 | match->network = network; | 5824 | match->network = network; |
5910 | 5825 | ||
5911 | IPW_DEBUG_ASSOC("Network '%s (%pM)' is a viable match.\n", | 5826 | IPW_DEBUG_ASSOC("Network '%*pE (%pM)' is a viable match.\n", |
5912 | print_ssid(ssid, network->ssid, network->ssid_len), | 5827 | network->ssid_len, network->ssid, network->bssid); |
5913 | network->bssid); | ||
5914 | 5828 | ||
5915 | return 1; | 5829 | return 1; |
5916 | } | 5830 | } |
@@ -6152,7 +6066,6 @@ static void ipw_bg_adhoc_check(struct work_struct *work) | |||
6152 | 6066 | ||
6153 | static void ipw_debug_config(struct ipw_priv *priv) | 6067 | static void ipw_debug_config(struct ipw_priv *priv) |
6154 | { | 6068 | { |
6155 | DECLARE_SSID_BUF(ssid); | ||
6156 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " | 6069 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " |
6157 | "[CFG 0x%08X]\n", priv->config); | 6070 | "[CFG 0x%08X]\n", priv->config); |
6158 | if (priv->config & CFG_STATIC_CHANNEL) | 6071 | if (priv->config & CFG_STATIC_CHANNEL) |
@@ -6160,8 +6073,8 @@ static void ipw_debug_config(struct ipw_priv *priv) | |||
6160 | else | 6073 | else |
6161 | IPW_DEBUG_INFO("Channel unlocked.\n"); | 6074 | IPW_DEBUG_INFO("Channel unlocked.\n"); |
6162 | if (priv->config & CFG_STATIC_ESSID) | 6075 | if (priv->config & CFG_STATIC_ESSID) |
6163 | IPW_DEBUG_INFO("ESSID locked to '%s'\n", | 6076 | IPW_DEBUG_INFO("ESSID locked to '%*pE'\n", |
6164 | print_ssid(ssid, priv->essid, priv->essid_len)); | 6077 | priv->essid_len, priv->essid); |
6165 | else | 6078 | else |
6166 | IPW_DEBUG_INFO("ESSID unlocked.\n"); | 6079 | IPW_DEBUG_INFO("ESSID unlocked.\n"); |
6167 | if (priv->config & CFG_STATIC_BSSID) | 6080 | if (priv->config & CFG_STATIC_BSSID) |
@@ -7385,7 +7298,6 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
7385 | struct ipw_supported_rates *rates, int roaming) | 7298 | struct ipw_supported_rates *rates, int roaming) |
7386 | { | 7299 | { |
7387 | int err; | 7300 | int err; |
7388 | DECLARE_SSID_BUF(ssid); | ||
7389 | 7301 | ||
7390 | if (priv->config & CFG_FIXED_RATE) | 7302 | if (priv->config & CFG_FIXED_RATE) |
7391 | ipw_set_fixed_rate(priv, network->mode); | 7303 | ipw_set_fixed_rate(priv, network->mode); |
@@ -7451,10 +7363,9 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
7451 | priv->assoc_request.capability &= | 7363 | priv->assoc_request.capability &= |
7452 | ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); | 7364 | ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); |
7453 | 7365 | ||
7454 | IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, " | 7366 | IPW_DEBUG_ASSOC("%ssociation attempt: '%*pE', channel %d, 802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n", |
7455 | "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n", | ||
7456 | roaming ? "Rea" : "A", | 7367 | roaming ? "Rea" : "A", |
7457 | print_ssid(ssid, priv->essid, priv->essid_len), | 7368 | priv->essid_len, priv->essid, |
7458 | network->channel, | 7369 | network->channel, |
7459 | ipw_modes[priv->assoc_request.ieee_mode], | 7370 | ipw_modes[priv->assoc_request.ieee_mode], |
7460 | rates->num_rates, | 7371 | rates->num_rates, |
@@ -7553,9 +7464,8 @@ static int ipw_associate_network(struct ipw_priv *priv, | |||
7553 | return err; | 7464 | return err; |
7554 | } | 7465 | } |
7555 | 7466 | ||
7556 | IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM\n", | 7467 | IPW_DEBUG(IPW_DL_STATE, "associating: '%*pE' %pM\n", |
7557 | print_ssid(ssid, priv->essid, priv->essid_len), | 7468 | priv->essid_len, priv->essid, priv->bssid); |
7558 | priv->bssid); | ||
7559 | 7469 | ||
7560 | return 0; | 7470 | return 0; |
7561 | } | 7471 | } |
@@ -7645,7 +7555,6 @@ static int ipw_associate(void *data) | |||
7645 | struct ipw_supported_rates *rates; | 7555 | struct ipw_supported_rates *rates; |
7646 | struct list_head *element; | 7556 | struct list_head *element; |
7647 | unsigned long flags; | 7557 | unsigned long flags; |
7648 | DECLARE_SSID_BUF(ssid); | ||
7649 | 7558 | ||
7650 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 7559 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
7651 | IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n"); | 7560 | IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n"); |
@@ -7704,10 +7613,8 @@ static int ipw_associate(void *data) | |||
7704 | /* If there are no more slots, expire the oldest */ | 7613 | /* If there are no more slots, expire the oldest */ |
7705 | list_del(&oldest->list); | 7614 | list_del(&oldest->list); |
7706 | target = oldest; | 7615 | target = oldest; |
7707 | IPW_DEBUG_ASSOC("Expired '%s' (%pM) from " | 7616 | IPW_DEBUG_ASSOC("Expired '%*pE' (%pM) from network list.\n", |
7708 | "network list.\n", | 7617 | target->ssid_len, target->ssid, |
7709 | print_ssid(ssid, target->ssid, | ||
7710 | target->ssid_len), | ||
7711 | target->bssid); | 7618 | target->bssid); |
7712 | list_add_tail(&target->list, | 7619 | list_add_tail(&target->list, |
7713 | &priv->ieee->network_free_list); | 7620 | &priv->ieee->network_free_list); |
@@ -9093,7 +9000,6 @@ static int ipw_wx_set_essid(struct net_device *dev, | |||
9093 | { | 9000 | { |
9094 | struct ipw_priv *priv = libipw_priv(dev); | 9001 | struct ipw_priv *priv = libipw_priv(dev); |
9095 | int length; | 9002 | int length; |
9096 | DECLARE_SSID_BUF(ssid); | ||
9097 | 9003 | ||
9098 | mutex_lock(&priv->mutex); | 9004 | mutex_lock(&priv->mutex); |
9099 | 9005 | ||
@@ -9118,8 +9024,7 @@ static int ipw_wx_set_essid(struct net_device *dev, | |||
9118 | return 0; | 9024 | return 0; |
9119 | } | 9025 | } |
9120 | 9026 | ||
9121 | IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", | 9027 | IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, extra, length); |
9122 | print_ssid(ssid, extra, length), length); | ||
9123 | 9028 | ||
9124 | priv->essid_len = length; | 9029 | priv->essid_len = length; |
9125 | memcpy(priv->essid, extra, priv->essid_len); | 9030 | memcpy(priv->essid, extra, priv->essid_len); |
@@ -9138,15 +9043,14 @@ static int ipw_wx_get_essid(struct net_device *dev, | |||
9138 | union iwreq_data *wrqu, char *extra) | 9043 | union iwreq_data *wrqu, char *extra) |
9139 | { | 9044 | { |
9140 | struct ipw_priv *priv = libipw_priv(dev); | 9045 | struct ipw_priv *priv = libipw_priv(dev); |
9141 | DECLARE_SSID_BUF(ssid); | ||
9142 | 9046 | ||
9143 | /* If we are associated, trying to associate, or have a statically | 9047 | /* If we are associated, trying to associate, or have a statically |
9144 | * configured ESSID then return that; otherwise return ANY */ | 9048 | * configured ESSID then return that; otherwise return ANY */ |
9145 | mutex_lock(&priv->mutex); | 9049 | mutex_lock(&priv->mutex); |
9146 | if (priv->config & CFG_STATIC_ESSID || | 9050 | if (priv->config & CFG_STATIC_ESSID || |
9147 | priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { | 9051 | priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { |
9148 | IPW_DEBUG_WX("Getting essid: '%s'\n", | 9052 | IPW_DEBUG_WX("Getting essid: '%*pE'\n", |
9149 | print_ssid(ssid, priv->essid, priv->essid_len)); | 9053 | priv->essid_len, priv->essid); |
9150 | memcpy(extra, priv->essid, priv->essid_len); | 9054 | memcpy(extra, priv->essid, priv->essid_len); |
9151 | wrqu->essid.length = priv->essid_len; | 9055 | wrqu->essid.length = priv->essid_len; |
9152 | wrqu->essid.flags = 1; /* active */ | 9056 | wrqu->essid.flags = 1; /* active */ |
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index a586a85bfcfe..2d66984079bb 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c | |||
@@ -1120,7 +1120,6 @@ static int libipw_parse_info_param(struct libipw_info_element | |||
1120 | *info_element, u16 length, | 1120 | *info_element, u16 length, |
1121 | struct libipw_network *network) | 1121 | struct libipw_network *network) |
1122 | { | 1122 | { |
1123 | DECLARE_SSID_BUF(ssid); | ||
1124 | u8 i; | 1123 | u8 i; |
1125 | #ifdef CONFIG_LIBIPW_DEBUG | 1124 | #ifdef CONFIG_LIBIPW_DEBUG |
1126 | char rates_str[64]; | 1125 | char rates_str[64]; |
@@ -1151,10 +1150,9 @@ static int libipw_parse_info_param(struct libipw_info_element | |||
1151 | memset(network->ssid + network->ssid_len, 0, | 1150 | memset(network->ssid + network->ssid_len, 0, |
1152 | IW_ESSID_MAX_SIZE - network->ssid_len); | 1151 | IW_ESSID_MAX_SIZE - network->ssid_len); |
1153 | 1152 | ||
1154 | LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n", | 1153 | LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%*pE' len=%d.\n", |
1155 | print_ssid(ssid, network->ssid, | 1154 | network->ssid_len, network->ssid, |
1156 | network->ssid_len), | 1155 | network->ssid_len); |
1157 | network->ssid_len); | ||
1158 | break; | 1156 | break; |
1159 | 1157 | ||
1160 | case WLAN_EID_SUPP_RATES: | 1158 | case WLAN_EID_SUPP_RATES: |
@@ -1399,8 +1397,6 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r | |||
1399 | struct libipw_network *network, | 1397 | struct libipw_network *network, |
1400 | struct libipw_rx_stats *stats) | 1398 | struct libipw_rx_stats *stats) |
1401 | { | 1399 | { |
1402 | DECLARE_SSID_BUF(ssid); | ||
1403 | |||
1404 | network->qos_data.active = 0; | 1400 | network->qos_data.active = 0; |
1405 | network->qos_data.supported = 0; | 1401 | network->qos_data.supported = 0; |
1406 | network->qos_data.param_count = 0; | 1402 | network->qos_data.param_count = 0; |
@@ -1447,11 +1443,9 @@ static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_r | |||
1447 | } | 1443 | } |
1448 | 1444 | ||
1449 | if (network->mode == 0) { | 1445 | if (network->mode == 0) { |
1450 | LIBIPW_DEBUG_SCAN("Filtered out '%s (%pM)' " | 1446 | LIBIPW_DEBUG_SCAN("Filtered out '%*pE (%pM)' network.\n", |
1451 | "network.\n", | 1447 | network->ssid_len, network->ssid, |
1452 | print_ssid(ssid, network->ssid, | 1448 | network->bssid); |
1453 | network->ssid_len), | ||
1454 | network->bssid); | ||
1455 | return 1; | 1449 | return 1; |
1456 | } | 1450 | } |
1457 | 1451 | ||
@@ -1563,11 +1557,9 @@ static void libipw_process_probe_response(struct libipw_device | |||
1563 | struct libipw_info_element *info_element = beacon->info_element; | 1557 | struct libipw_info_element *info_element = beacon->info_element; |
1564 | #endif | 1558 | #endif |
1565 | unsigned long flags; | 1559 | unsigned long flags; |
1566 | DECLARE_SSID_BUF(ssid); | ||
1567 | 1560 | ||
1568 | LIBIPW_DEBUG_SCAN("'%s' (%pM" | 1561 | LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", |
1569 | "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", | 1562 | info_element->len, info_element->data, |
1570 | print_ssid(ssid, info_element->data, info_element->len), | ||
1571 | beacon->header.addr3, | 1563 | beacon->header.addr3, |
1572 | (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0', | 1564 | (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0', |
1573 | (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0', | 1565 | (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0', |
@@ -1587,12 +1579,11 @@ static void libipw_process_probe_response(struct libipw_device | |||
1587 | (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0'); | 1579 | (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0'); |
1588 | 1580 | ||
1589 | if (libipw_network_init(ieee, beacon, &network, stats)) { | 1581 | if (libipw_network_init(ieee, beacon, &network, stats)) { |
1590 | LIBIPW_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", | 1582 | LIBIPW_DEBUG_SCAN("Dropped '%*pE' (%pM) via %s.\n", |
1591 | print_ssid(ssid, info_element->data, | 1583 | info_element->len, info_element->data, |
1592 | info_element->len), | 1584 | beacon->header.addr3, |
1593 | beacon->header.addr3, | 1585 | is_beacon(beacon->header.frame_ctl) ? |
1594 | is_beacon(beacon->header.frame_ctl) ? | 1586 | "BEACON" : "PROBE RESPONSE"); |
1595 | "BEACON" : "PROBE RESPONSE"); | ||
1596 | return; | 1587 | return; |
1597 | } | 1588 | } |
1598 | 1589 | ||
@@ -1624,11 +1615,9 @@ static void libipw_process_probe_response(struct libipw_device | |||
1624 | /* If there are no more slots, expire the oldest */ | 1615 | /* If there are no more slots, expire the oldest */ |
1625 | list_del(&oldest->list); | 1616 | list_del(&oldest->list); |
1626 | target = oldest; | 1617 | target = oldest; |
1627 | LIBIPW_DEBUG_SCAN("Expired '%s' (%pM) from " | 1618 | LIBIPW_DEBUG_SCAN("Expired '%*pE' (%pM) from network list.\n", |
1628 | "network list.\n", | 1619 | target->ssid_len, target->ssid, |
1629 | print_ssid(ssid, target->ssid, | 1620 | target->bssid); |
1630 | target->ssid_len), | ||
1631 | target->bssid); | ||
1632 | libipw_network_reset(target); | 1621 | libipw_network_reset(target); |
1633 | } else { | 1622 | } else { |
1634 | /* Otherwise just pull from the free list */ | 1623 | /* Otherwise just pull from the free list */ |
@@ -1638,23 +1627,21 @@ static void libipw_process_probe_response(struct libipw_device | |||
1638 | } | 1627 | } |
1639 | 1628 | ||
1640 | #ifdef CONFIG_LIBIPW_DEBUG | 1629 | #ifdef CONFIG_LIBIPW_DEBUG |
1641 | LIBIPW_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", | 1630 | LIBIPW_DEBUG_SCAN("Adding '%*pE' (%pM) via %s.\n", |
1642 | print_ssid(ssid, network.ssid, | 1631 | network.ssid_len, network.ssid, |
1643 | network.ssid_len), | 1632 | network.bssid, |
1644 | network.bssid, | 1633 | is_beacon(beacon->header.frame_ctl) ? |
1645 | is_beacon(beacon->header.frame_ctl) ? | 1634 | "BEACON" : "PROBE RESPONSE"); |
1646 | "BEACON" : "PROBE RESPONSE"); | ||
1647 | #endif | 1635 | #endif |
1648 | memcpy(target, &network, sizeof(*target)); | 1636 | memcpy(target, &network, sizeof(*target)); |
1649 | network.ibss_dfs = NULL; | 1637 | network.ibss_dfs = NULL; |
1650 | list_add_tail(&target->list, &ieee->network_list); | 1638 | list_add_tail(&target->list, &ieee->network_list); |
1651 | } else { | 1639 | } else { |
1652 | LIBIPW_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", | 1640 | LIBIPW_DEBUG_SCAN("Updating '%*pE' (%pM) via %s.\n", |
1653 | print_ssid(ssid, target->ssid, | 1641 | target->ssid_len, target->ssid, |
1654 | target->ssid_len), | 1642 | target->bssid, |
1655 | target->bssid, | 1643 | is_beacon(beacon->header.frame_ctl) ? |
1656 | is_beacon(beacon->header.frame_ctl) ? | 1644 | "BEACON" : "PROBE RESPONSE"); |
1657 | "BEACON" : "PROBE RESPONSE"); | ||
1658 | update_network(target, &network); | 1645 | update_network(target, &network); |
1659 | network.ibss_dfs = NULL; | 1646 | network.ibss_dfs = NULL; |
1660 | } | 1647 | } |
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index 54aba4744438..dd29f46d086b 100644 --- a/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/ipw2x00/libipw_wx.c | |||
@@ -272,7 +272,6 @@ int libipw_wx_get_scan(struct libipw_device *ieee, | |||
272 | char *ev = extra; | 272 | char *ev = extra; |
273 | char *stop = ev + wrqu->data.length; | 273 | char *stop = ev + wrqu->data.length; |
274 | int i = 0; | 274 | int i = 0; |
275 | DECLARE_SSID_BUF(ssid); | ||
276 | 275 | ||
277 | LIBIPW_DEBUG_WX("Getting scan\n"); | 276 | LIBIPW_DEBUG_WX("Getting scan\n"); |
278 | 277 | ||
@@ -290,12 +289,10 @@ int libipw_wx_get_scan(struct libipw_device *ieee, | |||
290 | ev = libipw_translate_scan(ieee, ev, stop, network, | 289 | ev = libipw_translate_scan(ieee, ev, stop, network, |
291 | info); | 290 | info); |
292 | else { | 291 | else { |
293 | LIBIPW_DEBUG_SCAN("Not showing network '%s (" | 292 | LIBIPW_DEBUG_SCAN("Not showing network '%*pE (%pM)' due to age (%ums).\n", |
294 | "%pM)' due to age (%ums).\n", | 293 | network->ssid_len, network->ssid, |
295 | print_ssid(ssid, network->ssid, | 294 | network->bssid, |
296 | network->ssid_len), | 295 | elapsed_jiffies_msecs( |
297 | network->bssid, | ||
298 | elapsed_jiffies_msecs( | ||
299 | network->last_scanned)); | 296 | network->last_scanned)); |
300 | } | 297 | } |
301 | } | 298 | } |
@@ -322,7 +319,6 @@ int libipw_wx_set_encode(struct libipw_device *ieee, | |||
322 | int i, key, key_provided, len; | 319 | int i, key, key_provided, len; |
323 | struct lib80211_crypt_data **crypt; | 320 | struct lib80211_crypt_data **crypt; |
324 | int host_crypto = ieee->host_encrypt || ieee->host_decrypt; | 321 | int host_crypto = ieee->host_encrypt || ieee->host_decrypt; |
325 | DECLARE_SSID_BUF(ssid); | ||
326 | 322 | ||
327 | LIBIPW_DEBUG_WX("SET_ENCODE\n"); | 323 | LIBIPW_DEBUG_WX("SET_ENCODE\n"); |
328 | 324 | ||
@@ -417,8 +413,8 @@ int libipw_wx_set_encode(struct libipw_device *ieee, | |||
417 | if (len > erq->length) | 413 | if (len > erq->length) |
418 | memset(sec.keys[key] + erq->length, 0, | 414 | memset(sec.keys[key] + erq->length, 0, |
419 | len - erq->length); | 415 | len - erq->length); |
420 | LIBIPW_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", | 416 | LIBIPW_DEBUG_WX("Setting key %d to '%*pE' (%d:%d bytes)\n", |
421 | key, print_ssid(ssid, sec.keys[key], len), | 417 | key, len, sec.keys[key], |
422 | erq->length, len); | 418 | erq->length, len); |
423 | sec.key_sizes[key] = len; | 419 | sec.key_sizes[key] = len; |
424 | if (*crypt) | 420 | if (*crypt) |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 818b1edaaa9a..34f09ef90bb3 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -590,7 +590,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
590 | int chan_no = -1; | 590 | int chan_no = -1; |
591 | const u8 *ssid = NULL; | 591 | const u8 *ssid = NULL; |
592 | u8 ssid_len = 0; | 592 | u8 ssid_len = 0; |
593 | DECLARE_SSID_BUF(ssid_buf); | ||
594 | 593 | ||
595 | int len = get_unaligned_le16(pos); | 594 | int len = get_unaligned_le16(pos); |
596 | pos += 2; | 595 | pos += 2; |
@@ -644,10 +643,8 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
644 | struct ieee80211_channel *channel = | 643 | struct ieee80211_channel *channel = |
645 | ieee80211_get_channel(wiphy, freq); | 644 | ieee80211_get_channel(wiphy, freq); |
646 | 645 | ||
647 | lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, " | 646 | lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %*pE, %d dBm\n", |
648 | "%d dBm\n", | 647 | bssid, capa, chan_no, ssid_len, ssid, |
649 | bssid, capa, chan_no, | ||
650 | print_ssid(ssid_buf, ssid, ssid_len), | ||
651 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); | 648 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); |
652 | 649 | ||
653 | if (channel && | 650 | if (channel && |
@@ -1984,7 +1981,6 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
1984 | struct lbs_private *priv = wiphy_priv(wiphy); | 1981 | struct lbs_private *priv = wiphy_priv(wiphy); |
1985 | int ret = 0; | 1982 | int ret = 0; |
1986 | struct cfg80211_bss *bss; | 1983 | struct cfg80211_bss *bss; |
1987 | DECLARE_SSID_BUF(ssid_buf); | ||
1988 | 1984 | ||
1989 | if (dev == priv->mesh_dev) | 1985 | if (dev == priv->mesh_dev) |
1990 | return -EOPNOTSUPP; | 1986 | return -EOPNOTSUPP; |
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 01a67f62696f..d0c881dd5846 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c | |||
@@ -93,7 +93,6 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, | |||
93 | { | 93 | { |
94 | struct cmd_ds_mesh_config cmd; | 94 | struct cmd_ds_mesh_config cmd; |
95 | struct mrvl_meshie *ie; | 95 | struct mrvl_meshie *ie; |
96 | DECLARE_SSID_BUF(ssid); | ||
97 | 96 | ||
98 | memset(&cmd, 0, sizeof(cmd)); | 97 | memset(&cmd, 0, sizeof(cmd)); |
99 | cmd.channel = cpu_to_le16(chan); | 98 | cmd.channel = cpu_to_le16(chan); |
@@ -122,9 +121,9 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, | |||
122 | default: | 121 | default: |
123 | return -1; | 122 | return -1; |
124 | } | 123 | } |
125 | lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n", | 124 | lbs_deb_cmd("mesh config action %d type %x channel %d SSID %*pE\n", |
126 | action, priv->mesh_tlv, chan, | 125 | action, priv->mesh_tlv, chan, priv->mesh_ssid_len, |
127 | print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len)); | 126 | priv->mesh_ssid); |
128 | 127 | ||
129 | return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); | 128 | return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); |
130 | } | 129 | } |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index f959978c7aac..cf0f89364d44 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -8878,13 +8878,13 @@ static int __must_check __init get_thinkpad_model_data( | |||
8878 | } | 8878 | } |
8879 | 8879 | ||
8880 | s = dmi_get_system_info(DMI_PRODUCT_VERSION); | 8880 | s = dmi_get_system_info(DMI_PRODUCT_VERSION); |
8881 | if (s && !(strnicmp(s, "ThinkPad", 8) && strnicmp(s, "Lenovo", 6))) { | 8881 | if (s && !(strncasecmp(s, "ThinkPad", 8) && strncasecmp(s, "Lenovo", 6))) { |
8882 | tp->model_str = kstrdup(s, GFP_KERNEL); | 8882 | tp->model_str = kstrdup(s, GFP_KERNEL); |
8883 | if (!tp->model_str) | 8883 | if (!tp->model_str) |
8884 | return -ENOMEM; | 8884 | return -ENOMEM; |
8885 | } else { | 8885 | } else { |
8886 | s = dmi_get_system_info(DMI_BIOS_VENDOR); | 8886 | s = dmi_get_system_info(DMI_BIOS_VENDOR); |
8887 | if (s && !(strnicmp(s, "Lenovo", 6))) { | 8887 | if (s && !(strncasecmp(s, "Lenovo", 6))) { |
8888 | tp->model_str = kstrdup(s, GFP_KERNEL); | 8888 | tp->model_str = kstrdup(s, GFP_KERNEL); |
8889 | if (!tp->model_str) | 8889 | if (!tp->model_str) |
8890 | return -ENOMEM; | 8890 | return -ENOMEM; |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index e6c403be09a9..4b6808ff0e5d 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -346,41 +346,41 @@ static ssize_t resources_store(struct device *dmdev, | |||
346 | } | 346 | } |
347 | 347 | ||
348 | buf = skip_spaces(buf); | 348 | buf = skip_spaces(buf); |
349 | if (!strnicmp(buf, "disable", 7)) { | 349 | if (!strncasecmp(buf, "disable", 7)) { |
350 | retval = pnp_disable_dev(dev); | 350 | retval = pnp_disable_dev(dev); |
351 | goto done; | 351 | goto done; |
352 | } | 352 | } |
353 | if (!strnicmp(buf, "activate", 8)) { | 353 | if (!strncasecmp(buf, "activate", 8)) { |
354 | retval = pnp_activate_dev(dev); | 354 | retval = pnp_activate_dev(dev); |
355 | goto done; | 355 | goto done; |
356 | } | 356 | } |
357 | if (!strnicmp(buf, "fill", 4)) { | 357 | if (!strncasecmp(buf, "fill", 4)) { |
358 | if (dev->active) | 358 | if (dev->active) |
359 | goto done; | 359 | goto done; |
360 | retval = pnp_auto_config_dev(dev); | 360 | retval = pnp_auto_config_dev(dev); |
361 | goto done; | 361 | goto done; |
362 | } | 362 | } |
363 | if (!strnicmp(buf, "auto", 4)) { | 363 | if (!strncasecmp(buf, "auto", 4)) { |
364 | if (dev->active) | 364 | if (dev->active) |
365 | goto done; | 365 | goto done; |
366 | pnp_init_resources(dev); | 366 | pnp_init_resources(dev); |
367 | retval = pnp_auto_config_dev(dev); | 367 | retval = pnp_auto_config_dev(dev); |
368 | goto done; | 368 | goto done; |
369 | } | 369 | } |
370 | if (!strnicmp(buf, "clear", 5)) { | 370 | if (!strncasecmp(buf, "clear", 5)) { |
371 | if (dev->active) | 371 | if (dev->active) |
372 | goto done; | 372 | goto done; |
373 | pnp_init_resources(dev); | 373 | pnp_init_resources(dev); |
374 | goto done; | 374 | goto done; |
375 | } | 375 | } |
376 | if (!strnicmp(buf, "get", 3)) { | 376 | if (!strncasecmp(buf, "get", 3)) { |
377 | mutex_lock(&pnp_res_mutex); | 377 | mutex_lock(&pnp_res_mutex); |
378 | if (pnp_can_read(dev)) | 378 | if (pnp_can_read(dev)) |
379 | dev->protocol->get(dev); | 379 | dev->protocol->get(dev); |
380 | mutex_unlock(&pnp_res_mutex); | 380 | mutex_unlock(&pnp_res_mutex); |
381 | goto done; | 381 | goto done; |
382 | } | 382 | } |
383 | if (!strnicmp(buf, "set", 3)) { | 383 | if (!strncasecmp(buf, "set", 3)) { |
384 | resource_size_t start; | 384 | resource_size_t start; |
385 | resource_size_t end; | 385 | resource_size_t end; |
386 | unsigned long flags; | 386 | unsigned long flags; |
@@ -392,31 +392,31 @@ static ssize_t resources_store(struct device *dmdev, | |||
392 | mutex_lock(&pnp_res_mutex); | 392 | mutex_lock(&pnp_res_mutex); |
393 | while (1) { | 393 | while (1) { |
394 | buf = skip_spaces(buf); | 394 | buf = skip_spaces(buf); |
395 | if (!strnicmp(buf, "io", 2)) { | 395 | if (!strncasecmp(buf, "io", 2)) { |
396 | buf = pnp_get_resource_value(buf + 2, | 396 | buf = pnp_get_resource_value(buf + 2, |
397 | IORESOURCE_IO, | 397 | IORESOURCE_IO, |
398 | &start, &end, | 398 | &start, &end, |
399 | &flags); | 399 | &flags); |
400 | pnp_add_io_resource(dev, start, end, flags); | 400 | pnp_add_io_resource(dev, start, end, flags); |
401 | } else if (!strnicmp(buf, "mem", 3)) { | 401 | } else if (!strncasecmp(buf, "mem", 3)) { |
402 | buf = pnp_get_resource_value(buf + 3, | 402 | buf = pnp_get_resource_value(buf + 3, |
403 | IORESOURCE_MEM, | 403 | IORESOURCE_MEM, |
404 | &start, &end, | 404 | &start, &end, |
405 | &flags); | 405 | &flags); |
406 | pnp_add_mem_resource(dev, start, end, flags); | 406 | pnp_add_mem_resource(dev, start, end, flags); |
407 | } else if (!strnicmp(buf, "irq", 3)) { | 407 | } else if (!strncasecmp(buf, "irq", 3)) { |
408 | buf = pnp_get_resource_value(buf + 3, | 408 | buf = pnp_get_resource_value(buf + 3, |
409 | IORESOURCE_IRQ, | 409 | IORESOURCE_IRQ, |
410 | &start, NULL, | 410 | &start, NULL, |
411 | &flags); | 411 | &flags); |
412 | pnp_add_irq_resource(dev, start, flags); | 412 | pnp_add_irq_resource(dev, start, flags); |
413 | } else if (!strnicmp(buf, "dma", 3)) { | 413 | } else if (!strncasecmp(buf, "dma", 3)) { |
414 | buf = pnp_get_resource_value(buf + 3, | 414 | buf = pnp_get_resource_value(buf + 3, |
415 | IORESOURCE_DMA, | 415 | IORESOURCE_DMA, |
416 | &start, NULL, | 416 | &start, NULL, |
417 | &flags); | 417 | &flags); |
418 | pnp_add_dma_resource(dev, start, flags); | 418 | pnp_add_dma_resource(dev, start, flags); |
419 | } else if (!strnicmp(buf, "bus", 3)) { | 419 | } else if (!strncasecmp(buf, "bus", 3)) { |
420 | buf = pnp_get_resource_value(buf + 3, | 420 | buf = pnp_get_resource_value(buf + 3, |
421 | IORESOURCE_BUS, | 421 | IORESOURCE_BUS, |
422 | &start, &end, | 422 | &start, &end, |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 1bea0fc43464..8cd0beebdc3f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -288,6 +288,26 @@ config RTC_DRV_MAX77686 | |||
288 | This driver can also be built as a module. If so, the module | 288 | This driver can also be built as a module. If so, the module |
289 | will be called rtc-max77686. | 289 | will be called rtc-max77686. |
290 | 290 | ||
291 | config RTC_DRV_RK808 | ||
292 | tristate "Rockchip RK808 RTC" | ||
293 | depends on MFD_RK808 | ||
294 | help | ||
295 | If you say yes here you will get support for the | ||
296 | RTC of RK808 PMIC. | ||
297 | |||
298 | This driver can also be built as a module. If so, the module | ||
299 | will be called rk808-rtc. | ||
300 | |||
301 | config RTC_DRV_MAX77802 | ||
302 | tristate "Maxim 77802 RTC" | ||
303 | depends on MFD_MAX77686 | ||
304 | help | ||
305 | If you say yes here you will get support for the | ||
306 | RTC of Maxim MAX77802 PMIC. | ||
307 | |||
308 | This driver can also be built as a module. If so, the module | ||
309 | will be called rtc-max77802. | ||
310 | |||
291 | config RTC_DRV_RS5C372 | 311 | config RTC_DRV_RS5C372 |
292 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" | 312 | tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" |
293 | help | 313 | help |
@@ -732,6 +752,7 @@ config RTC_DRV_DS1216 | |||
732 | 752 | ||
733 | config RTC_DRV_DS1286 | 753 | config RTC_DRV_DS1286 |
734 | tristate "Dallas DS1286" | 754 | tristate "Dallas DS1286" |
755 | depends on HAS_IOMEM | ||
735 | help | 756 | help |
736 | If you say yes here you get support for the Dallas DS1286 RTC chips. | 757 | If you say yes here you get support for the Dallas DS1286 RTC chips. |
737 | 758 | ||
@@ -743,6 +764,7 @@ config RTC_DRV_DS1302 | |||
743 | 764 | ||
744 | config RTC_DRV_DS1511 | 765 | config RTC_DRV_DS1511 |
745 | tristate "Dallas DS1511" | 766 | tristate "Dallas DS1511" |
767 | depends on HAS_IOMEM | ||
746 | help | 768 | help |
747 | If you say yes here you get support for the | 769 | If you say yes here you get support for the |
748 | Dallas DS1511 timekeeping/watchdog chip. | 770 | Dallas DS1511 timekeeping/watchdog chip. |
@@ -752,6 +774,7 @@ config RTC_DRV_DS1511 | |||
752 | 774 | ||
753 | config RTC_DRV_DS1553 | 775 | config RTC_DRV_DS1553 |
754 | tristate "Maxim/Dallas DS1553" | 776 | tristate "Maxim/Dallas DS1553" |
777 | depends on HAS_IOMEM | ||
755 | help | 778 | help |
756 | If you say yes here you get support for the | 779 | If you say yes here you get support for the |
757 | Maxim/Dallas DS1553 timekeeping chip. | 780 | Maxim/Dallas DS1553 timekeeping chip. |
@@ -761,6 +784,7 @@ config RTC_DRV_DS1553 | |||
761 | 784 | ||
762 | config RTC_DRV_DS1742 | 785 | config RTC_DRV_DS1742 |
763 | tristate "Maxim/Dallas DS1742/1743" | 786 | tristate "Maxim/Dallas DS1742/1743" |
787 | depends on HAS_IOMEM | ||
764 | help | 788 | help |
765 | If you say yes here you get support for the | 789 | If you say yes here you get support for the |
766 | Maxim/Dallas DS1742/1743 timekeeping chip. | 790 | Maxim/Dallas DS1742/1743 timekeeping chip. |
@@ -816,6 +840,7 @@ config RTC_DRV_EFI | |||
816 | 840 | ||
817 | config RTC_DRV_STK17TA8 | 841 | config RTC_DRV_STK17TA8 |
818 | tristate "Simtek STK17TA8" | 842 | tristate "Simtek STK17TA8" |
843 | depends on HAS_IOMEM | ||
819 | help | 844 | help |
820 | If you say yes here you get support for the | 845 | If you say yes here you get support for the |
821 | Simtek STK17TA8 timekeeping chip. | 846 | Simtek STK17TA8 timekeeping chip. |
@@ -834,6 +859,7 @@ config RTC_DRV_M48T86 | |||
834 | 859 | ||
835 | config RTC_DRV_M48T35 | 860 | config RTC_DRV_M48T35 |
836 | tristate "ST M48T35" | 861 | tristate "ST M48T35" |
862 | depends on HAS_IOMEM | ||
837 | help | 863 | help |
838 | If you say Y here you will get support for the | 864 | If you say Y here you will get support for the |
839 | ST M48T35 RTC chip. | 865 | ST M48T35 RTC chip. |
@@ -843,6 +869,7 @@ config RTC_DRV_M48T35 | |||
843 | 869 | ||
844 | config RTC_DRV_M48T59 | 870 | config RTC_DRV_M48T59 |
845 | tristate "ST M48T59/M48T08/M48T02" | 871 | tristate "ST M48T59/M48T08/M48T02" |
872 | depends on HAS_IOMEM | ||
846 | help | 873 | help |
847 | If you say Y here you will get support for the | 874 | If you say Y here you will get support for the |
848 | ST M48T59 RTC chip and compatible ST M48T08 and M48T02. | 875 | ST M48T59 RTC chip and compatible ST M48T08 and M48T02. |
@@ -855,6 +882,7 @@ config RTC_DRV_M48T59 | |||
855 | 882 | ||
856 | config RTC_DRV_MSM6242 | 883 | config RTC_DRV_MSM6242 |
857 | tristate "Oki MSM6242" | 884 | tristate "Oki MSM6242" |
885 | depends on HAS_IOMEM | ||
858 | help | 886 | help |
859 | If you say yes here you get support for the Oki MSM6242 | 887 | If you say yes here you get support for the Oki MSM6242 |
860 | timekeeping chip. It is used in some Amiga models (e.g. A2000). | 888 | timekeeping chip. It is used in some Amiga models (e.g. A2000). |
@@ -864,6 +892,7 @@ config RTC_DRV_MSM6242 | |||
864 | 892 | ||
865 | config RTC_DRV_BQ4802 | 893 | config RTC_DRV_BQ4802 |
866 | tristate "TI BQ4802" | 894 | tristate "TI BQ4802" |
895 | depends on HAS_IOMEM | ||
867 | help | 896 | help |
868 | If you say Y here you will get support for the TI | 897 | If you say Y here you will get support for the TI |
869 | BQ4802 RTC chip. | 898 | BQ4802 RTC chip. |
@@ -873,6 +902,7 @@ config RTC_DRV_BQ4802 | |||
873 | 902 | ||
874 | config RTC_DRV_RP5C01 | 903 | config RTC_DRV_RP5C01 |
875 | tristate "Ricoh RP5C01" | 904 | tristate "Ricoh RP5C01" |
905 | depends on HAS_IOMEM | ||
876 | help | 906 | help |
877 | If you say yes here you get support for the Ricoh RP5C01 | 907 | If you say yes here you get support for the Ricoh RP5C01 |
878 | timekeeping chip. It is used in some Amiga models (e.g. A3000 | 908 | timekeeping chip. It is used in some Amiga models (e.g. A3000 |
@@ -1374,6 +1404,7 @@ config RTC_DRV_MOXART | |||
1374 | 1404 | ||
1375 | config RTC_DRV_XGENE | 1405 | config RTC_DRV_XGENE |
1376 | tristate "APM X-Gene RTC" | 1406 | tristate "APM X-Gene RTC" |
1407 | depends on HAS_IOMEM | ||
1377 | help | 1408 | help |
1378 | If you say yes here you get support for the APM X-Gene SoC real time | 1409 | If you say yes here you get support for the APM X-Gene SoC real time |
1379 | clock. | 1410 | clock. |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9055b7dd3dc5..b188323c096a 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -85,6 +85,7 @@ obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | |||
85 | obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o | 85 | obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o |
86 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 86 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
87 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o | 87 | obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o |
88 | obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o | ||
88 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o | 89 | obj-$(CONFIG_RTC_DRV_MC13XXX) += rtc-mc13xxx.o |
89 | obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o | 90 | obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o |
90 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o | 91 | obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o |
@@ -109,6 +110,7 @@ obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o | |||
109 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o | 110 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o |
110 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 111 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
111 | obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o | 112 | obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o |
113 | obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o | ||
112 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o | 114 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o |
113 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 115 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
114 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 116 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index c74bf0dc52cc..314129e66d6e 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c | |||
@@ -2,10 +2,14 @@ | |||
2 | * Driver for TI BQ32000 RTC. | 2 | * Driver for TI BQ32000 RTC. |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Semihalf. | 4 | * Copyright (C) 2009 Semihalf. |
5 | * Copyright (C) 2014 Pavel Machek <pavel@denx.de> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | ||
11 | * You can get hardware description at | ||
12 | * http://www.ti.com/lit/ds/symlink/bq32000.pdf | ||
9 | */ | 13 | */ |
10 | 14 | ||
11 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -27,6 +31,10 @@ | |||
27 | #define BQ32K_CENT 0x40 /* Century flag */ | 31 | #define BQ32K_CENT 0x40 /* Century flag */ |
28 | #define BQ32K_CENT_EN 0x80 /* Century flag enable bit */ | 32 | #define BQ32K_CENT_EN 0x80 /* Century flag enable bit */ |
29 | 33 | ||
34 | #define BQ32K_CALIBRATION 0x07 /* CAL_CFG1, calibration and control */ | ||
35 | #define BQ32K_TCH2 0x08 /* Trickle charge enable */ | ||
36 | #define BQ32K_CFG2 0x09 /* Trickle charger control */ | ||
37 | |||
30 | struct bq32k_regs { | 38 | struct bq32k_regs { |
31 | uint8_t seconds; | 39 | uint8_t seconds; |
32 | uint8_t minutes; | 40 | uint8_t minutes; |
@@ -122,6 +130,57 @@ static const struct rtc_class_ops bq32k_rtc_ops = { | |||
122 | .set_time = bq32k_rtc_set_time, | 130 | .set_time = bq32k_rtc_set_time, |
123 | }; | 131 | }; |
124 | 132 | ||
133 | static int trickle_charger_of_init(struct device *dev, struct device_node *node) | ||
134 | { | ||
135 | unsigned char reg; | ||
136 | int error; | ||
137 | u32 ohms = 0; | ||
138 | |||
139 | if (of_property_read_u32(node, "trickle-resistor-ohms" , &ohms)) | ||
140 | return 0; | ||
141 | |||
142 | switch (ohms) { | ||
143 | case 180+940: | ||
144 | /* | ||
145 | * TCHE[3:0] == 0x05, TCH2 == 1, TCFE == 0 (charging | ||
146 | * over diode and 940ohm resistor) | ||
147 | */ | ||
148 | |||
149 | if (of_property_read_bool(node, "trickle-diode-disable")) { | ||
150 | dev_err(dev, "diode and resistor mismatch\n"); | ||
151 | return -EINVAL; | ||
152 | } | ||
153 | reg = 0x05; | ||
154 | break; | ||
155 | |||
156 | case 180+20000: | ||
157 | /* diode disabled */ | ||
158 | |||
159 | if (!of_property_read_bool(node, "trickle-diode-disable")) { | ||
160 | dev_err(dev, "bq32k: diode and resistor mismatch\n"); | ||
161 | return -EINVAL; | ||
162 | } | ||
163 | reg = 0x25; | ||
164 | break; | ||
165 | |||
166 | default: | ||
167 | dev_err(dev, "invalid resistor value (%d)\n", ohms); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | error = bq32k_write(dev, ®, BQ32K_CFG2, 1); | ||
172 | if (error) | ||
173 | return error; | ||
174 | |||
175 | reg = 0x20; | ||
176 | error = bq32k_write(dev, ®, BQ32K_TCH2, 1); | ||
177 | if (error) | ||
178 | return error; | ||
179 | |||
180 | dev_info(dev, "Enabled trickle RTC battery charge.\n"); | ||
181 | return 0; | ||
182 | } | ||
183 | |||
125 | static int bq32k_probe(struct i2c_client *client, | 184 | static int bq32k_probe(struct i2c_client *client, |
126 | const struct i2c_device_id *id) | 185 | const struct i2c_device_id *id) |
127 | { | 186 | { |
@@ -153,6 +212,9 @@ static int bq32k_probe(struct i2c_client *client, | |||
153 | if (error) | 212 | if (error) |
154 | return error; | 213 | return error; |
155 | 214 | ||
215 | if (client && client->dev.of_node) | ||
216 | trickle_charger_of_init(dev, client->dev.of_node); | ||
217 | |||
156 | rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name, | 218 | rtc = devm_rtc_device_register(&client->dev, bq32k_driver.driver.name, |
157 | &bq32k_rtc_ops, THIS_MODULE); | 219 | &bq32k_rtc_ops, THIS_MODULE); |
158 | if (IS_ERR(rtc)) | 220 | if (IS_ERR(rtc)) |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index b0e4a3eb33c7..5b2e76159b41 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -856,7 +856,7 @@ static void __exit cmos_do_remove(struct device *dev) | |||
856 | cmos->dev = NULL; | 856 | cmos->dev = NULL; |
857 | } | 857 | } |
858 | 858 | ||
859 | #ifdef CONFIG_PM_SLEEP | 859 | #ifdef CONFIG_PM |
860 | 860 | ||
861 | static int cmos_suspend(struct device *dev) | 861 | static int cmos_suspend(struct device *dev) |
862 | { | 862 | { |
@@ -907,6 +907,8 @@ static inline int cmos_poweroff(struct device *dev) | |||
907 | return cmos_suspend(dev); | 907 | return cmos_suspend(dev); |
908 | } | 908 | } |
909 | 909 | ||
910 | #ifdef CONFIG_PM_SLEEP | ||
911 | |||
910 | static int cmos_resume(struct device *dev) | 912 | static int cmos_resume(struct device *dev) |
911 | { | 913 | { |
912 | struct cmos_rtc *cmos = dev_get_drvdata(dev); | 914 | struct cmos_rtc *cmos = dev_get_drvdata(dev); |
@@ -954,6 +956,7 @@ static int cmos_resume(struct device *dev) | |||
954 | return 0; | 956 | return 0; |
955 | } | 957 | } |
956 | 958 | ||
959 | #endif | ||
957 | #else | 960 | #else |
958 | 961 | ||
959 | static inline int cmos_poweroff(struct device *dev) | 962 | static inline int cmos_poweroff(struct device *dev) |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f03d5ba96db1..bb43cf703efc 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -126,9 +126,14 @@ struct chip_desc { | |||
126 | u16 nvram_offset; | 126 | u16 nvram_offset; |
127 | u16 nvram_size; | 127 | u16 nvram_size; |
128 | u16 trickle_charger_reg; | 128 | u16 trickle_charger_reg; |
129 | u8 trickle_charger_setup; | ||
130 | u8 (*do_trickle_setup)(struct i2c_client *, uint32_t, bool); | ||
129 | }; | 131 | }; |
130 | 132 | ||
131 | static const struct chip_desc chips[last_ds_type] = { | 133 | static u8 do_trickle_setup_ds1339(struct i2c_client *, |
134 | uint32_t ohms, bool diode); | ||
135 | |||
136 | static struct chip_desc chips[last_ds_type] = { | ||
132 | [ds_1307] = { | 137 | [ds_1307] = { |
133 | .nvram_offset = 8, | 138 | .nvram_offset = 8, |
134 | .nvram_size = 56, | 139 | .nvram_size = 56, |
@@ -143,6 +148,7 @@ static const struct chip_desc chips[last_ds_type] = { | |||
143 | [ds_1339] = { | 148 | [ds_1339] = { |
144 | .alarm = 1, | 149 | .alarm = 1, |
145 | .trickle_charger_reg = 0x10, | 150 | .trickle_charger_reg = 0x10, |
151 | .do_trickle_setup = &do_trickle_setup_ds1339, | ||
146 | }, | 152 | }, |
147 | [ds_1340] = { | 153 | [ds_1340] = { |
148 | .trickle_charger_reg = 0x08, | 154 | .trickle_charger_reg = 0x08, |
@@ -833,15 +839,58 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, | |||
833 | return count; | 839 | return count; |
834 | } | 840 | } |
835 | 841 | ||
842 | |||
836 | /*----------------------------------------------------------------------*/ | 843 | /*----------------------------------------------------------------------*/ |
837 | 844 | ||
845 | static u8 do_trickle_setup_ds1339(struct i2c_client *client, | ||
846 | uint32_t ohms, bool diode) | ||
847 | { | ||
848 | u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE : | ||
849 | DS1307_TRICKLE_CHARGER_NO_DIODE; | ||
850 | |||
851 | switch (ohms) { | ||
852 | case 250: | ||
853 | setup |= DS1307_TRICKLE_CHARGER_250_OHM; | ||
854 | break; | ||
855 | case 2000: | ||
856 | setup |= DS1307_TRICKLE_CHARGER_2K_OHM; | ||
857 | break; | ||
858 | case 4000: | ||
859 | setup |= DS1307_TRICKLE_CHARGER_4K_OHM; | ||
860 | break; | ||
861 | default: | ||
862 | dev_warn(&client->dev, | ||
863 | "Unsupported ohm value %u in dt\n", ohms); | ||
864 | return 0; | ||
865 | } | ||
866 | return setup; | ||
867 | } | ||
868 | |||
869 | static void ds1307_trickle_of_init(struct i2c_client *client, | ||
870 | struct chip_desc *chip) | ||
871 | { | ||
872 | uint32_t ohms = 0; | ||
873 | bool diode = true; | ||
874 | |||
875 | if (!chip->do_trickle_setup) | ||
876 | goto out; | ||
877 | if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms" , &ohms)) | ||
878 | goto out; | ||
879 | if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable")) | ||
880 | diode = false; | ||
881 | chip->trickle_charger_setup = chip->do_trickle_setup(client, | ||
882 | ohms, diode); | ||
883 | out: | ||
884 | return; | ||
885 | } | ||
886 | |||
838 | static int ds1307_probe(struct i2c_client *client, | 887 | static int ds1307_probe(struct i2c_client *client, |
839 | const struct i2c_device_id *id) | 888 | const struct i2c_device_id *id) |
840 | { | 889 | { |
841 | struct ds1307 *ds1307; | 890 | struct ds1307 *ds1307; |
842 | int err = -ENODEV; | 891 | int err = -ENODEV; |
843 | int tmp; | 892 | int tmp; |
844 | const struct chip_desc *chip = &chips[id->driver_data]; | 893 | struct chip_desc *chip = &chips[id->driver_data]; |
845 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 894 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
846 | bool want_irq = false; | 895 | bool want_irq = false; |
847 | unsigned char *buf; | 896 | unsigned char *buf; |
@@ -866,9 +915,19 @@ static int ds1307_probe(struct i2c_client *client, | |||
866 | ds1307->client = client; | 915 | ds1307->client = client; |
867 | ds1307->type = id->driver_data; | 916 | ds1307->type = id->driver_data; |
868 | 917 | ||
869 | if (pdata && pdata->trickle_charger_setup && chip->trickle_charger_reg) | 918 | if (!pdata && client->dev.of_node) |
919 | ds1307_trickle_of_init(client, chip); | ||
920 | else if (pdata && pdata->trickle_charger_setup) | ||
921 | chip->trickle_charger_setup = pdata->trickle_charger_setup; | ||
922 | |||
923 | if (chip->trickle_charger_setup && chip->trickle_charger_reg) { | ||
924 | dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n", | ||
925 | DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup, | ||
926 | chip->trickle_charger_reg); | ||
870 | i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, | 927 | i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, |
871 | DS13XX_TRICKLE_CHARGER_MAGIC | pdata->trickle_charger_setup); | 928 | DS13XX_TRICKLE_CHARGER_MAGIC | |
929 | chip->trickle_charger_setup); | ||
930 | } | ||
872 | 931 | ||
873 | buf = ds1307->regs; | 932 | buf = ds1307->regs; |
874 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { | 933 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { |
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index aa55f081c505..ee3ba7e6b45e 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c | |||
@@ -274,7 +274,7 @@ static int isl12022_probe(struct i2c_client *client, | |||
274 | } | 274 | } |
275 | 275 | ||
276 | #ifdef CONFIG_OF | 276 | #ifdef CONFIG_OF |
277 | static struct of_device_id isl12022_dt_match[] = { | 277 | static const struct of_device_id isl12022_dt_match[] = { |
278 | { .compatible = "isl,isl12022" }, | 278 | { .compatible = "isl,isl12022" }, |
279 | { }, | 279 | { }, |
280 | }; | 280 | }; |
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index d20a7f0786eb..cf73e969c8cc 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c | |||
@@ -32,15 +32,6 @@ | |||
32 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | 32 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) |
33 | #define RTC_RBUDR_SHIFT 4 | 33 | #define RTC_RBUDR_SHIFT 4 |
34 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) | 34 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) |
35 | /* WTSR and SMPL Register */ | ||
36 | #define WTSRT_SHIFT 0 | ||
37 | #define SMPLT_SHIFT 2 | ||
38 | #define WTSR_EN_SHIFT 6 | ||
39 | #define SMPL_EN_SHIFT 7 | ||
40 | #define WTSRT_MASK (3 << WTSRT_SHIFT) | ||
41 | #define SMPLT_MASK (3 << SMPLT_SHIFT) | ||
42 | #define WTSR_EN_MASK (1 << WTSR_EN_SHIFT) | ||
43 | #define SMPL_EN_MASK (1 << SMPL_EN_SHIFT) | ||
44 | /* RTC Hour register */ | 35 | /* RTC Hour register */ |
45 | #define HOUR_PM_SHIFT 6 | 36 | #define HOUR_PM_SHIFT 6 |
46 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | 37 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) |
@@ -49,7 +40,6 @@ | |||
49 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | 40 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) |
50 | 41 | ||
51 | #define MAX77686_RTC_UPDATE_DELAY 16 | 42 | #define MAX77686_RTC_UPDATE_DELAY 16 |
52 | #undef MAX77686_RTC_WTSR_SMPL | ||
53 | 43 | ||
54 | enum { | 44 | enum { |
55 | RTC_SEC = 0, | 45 | RTC_SEC = 0, |
@@ -80,16 +70,6 @@ enum MAX77686_RTC_OP { | |||
80 | MAX77686_RTC_READ, | 70 | MAX77686_RTC_READ, |
81 | }; | 71 | }; |
82 | 72 | ||
83 | static inline int max77686_rtc_calculate_wday(u8 shifted) | ||
84 | { | ||
85 | int counter = -1; | ||
86 | while (shifted) { | ||
87 | shifted >>= 1; | ||
88 | counter++; | ||
89 | } | ||
90 | return counter; | ||
91 | } | ||
92 | |||
93 | static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | 73 | static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, |
94 | int rtc_24hr_mode) | 74 | int rtc_24hr_mode) |
95 | { | 75 | { |
@@ -103,7 +83,8 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | |||
103 | tm->tm_hour += 12; | 83 | tm->tm_hour += 12; |
104 | } | 84 | } |
105 | 85 | ||
106 | tm->tm_wday = max77686_rtc_calculate_wday(data[RTC_WEEKDAY] & 0x7f); | 86 | /* Only a single bit is set in data[], so fls() would be equivalent */ |
87 | tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f) - 1; | ||
107 | tm->tm_mday = data[RTC_DATE] & 0x1f; | 88 | tm->tm_mday = data[RTC_DATE] & 0x1f; |
108 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | 89 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; |
109 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; | 90 | tm->tm_year = (data[RTC_YEAR] & 0x7f) + 100; |
@@ -412,64 +393,6 @@ static const struct rtc_class_ops max77686_rtc_ops = { | |||
412 | .alarm_irq_enable = max77686_rtc_alarm_irq_enable, | 393 | .alarm_irq_enable = max77686_rtc_alarm_irq_enable, |
413 | }; | 394 | }; |
414 | 395 | ||
415 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
416 | static void max77686_rtc_enable_wtsr(struct max77686_rtc_info *info, bool enable) | ||
417 | { | ||
418 | int ret; | ||
419 | unsigned int val, mask; | ||
420 | |||
421 | if (enable) | ||
422 | val = (1 << WTSR_EN_SHIFT) | (3 << WTSRT_SHIFT); | ||
423 | else | ||
424 | val = 0; | ||
425 | |||
426 | mask = WTSR_EN_MASK | WTSRT_MASK; | ||
427 | |||
428 | dev_info(info->dev, "%s: %s WTSR\n", __func__, | ||
429 | enable ? "enable" : "disable"); | ||
430 | |||
431 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
432 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
433 | if (ret < 0) { | ||
434 | dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", | ||
435 | __func__, ret); | ||
436 | return; | ||
437 | } | ||
438 | |||
439 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
440 | } | ||
441 | |||
442 | static void max77686_rtc_enable_smpl(struct max77686_rtc_info *info, bool enable) | ||
443 | { | ||
444 | int ret; | ||
445 | unsigned int val, mask; | ||
446 | |||
447 | if (enable) | ||
448 | val = (1 << SMPL_EN_SHIFT) | (0 << SMPLT_SHIFT); | ||
449 | else | ||
450 | val = 0; | ||
451 | |||
452 | mask = SMPL_EN_MASK | SMPLT_MASK; | ||
453 | |||
454 | dev_info(info->dev, "%s: %s SMPL\n", __func__, | ||
455 | enable ? "enable" : "disable"); | ||
456 | |||
457 | ret = regmap_update_bits(info->max77686->rtc_regmap, | ||
458 | MAX77686_WTSR_SMPL_CNTL, mask, val); | ||
459 | if (ret < 0) { | ||
460 | dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", | ||
461 | __func__, ret); | ||
462 | return; | ||
463 | } | ||
464 | |||
465 | max77686_rtc_update(info, MAX77686_RTC_WRITE); | ||
466 | |||
467 | val = 0; | ||
468 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
469 | dev_info(info->dev, "%s: WTSR_SMPL(0x%02x)\n", __func__, val); | ||
470 | } | ||
471 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
472 | |||
473 | static int max77686_rtc_init_reg(struct max77686_rtc_info *info) | 396 | static int max77686_rtc_init_reg(struct max77686_rtc_info *info) |
474 | { | 397 | { |
475 | u8 data[2]; | 398 | u8 data[2]; |
@@ -519,19 +442,12 @@ static int max77686_rtc_probe(struct platform_device *pdev) | |||
519 | goto err_rtc; | 442 | goto err_rtc; |
520 | } | 443 | } |
521 | 444 | ||
522 | #ifdef MAX77686_RTC_WTSR_SMPL | ||
523 | max77686_rtc_enable_wtsr(info, true); | ||
524 | max77686_rtc_enable_smpl(info, true); | ||
525 | #endif | ||
526 | |||
527 | device_init_wakeup(&pdev->dev, 1); | 445 | device_init_wakeup(&pdev->dev, 1); |
528 | 446 | ||
529 | info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc", | 447 | info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77686-rtc", |
530 | &max77686_rtc_ops, THIS_MODULE); | 448 | &max77686_rtc_ops, THIS_MODULE); |
531 | 449 | ||
532 | if (IS_ERR(info->rtc_dev)) { | 450 | if (IS_ERR(info->rtc_dev)) { |
533 | dev_info(&pdev->dev, "%s: fail\n", __func__); | ||
534 | |||
535 | ret = PTR_ERR(info->rtc_dev); | 451 | ret = PTR_ERR(info->rtc_dev); |
536 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | 452 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); |
537 | if (ret == 0) | 453 | if (ret == 0) |
@@ -539,6 +455,12 @@ static int max77686_rtc_probe(struct platform_device *pdev) | |||
539 | goto err_rtc; | 455 | goto err_rtc; |
540 | } | 456 | } |
541 | 457 | ||
458 | if (!max77686->rtc_irq_data) { | ||
459 | ret = -EINVAL; | ||
460 | dev_err(&pdev->dev, "%s: no RTC regmap IRQ chip\n", __func__); | ||
461 | goto err_rtc; | ||
462 | } | ||
463 | |||
542 | info->virq = regmap_irq_get_virq(max77686->rtc_irq_data, | 464 | info->virq = regmap_irq_get_virq(max77686->rtc_irq_data, |
543 | MAX77686_RTCIRQ_RTCA1); | 465 | MAX77686_RTCIRQ_RTCA1); |
544 | if (!info->virq) { | 466 | if (!info->virq) { |
@@ -556,33 +478,33 @@ err_rtc: | |||
556 | return ret; | 478 | return ret; |
557 | } | 479 | } |
558 | 480 | ||
559 | static void max77686_rtc_shutdown(struct platform_device *pdev) | 481 | #ifdef CONFIG_PM_SLEEP |
482 | static int max77686_rtc_suspend(struct device *dev) | ||
560 | { | 483 | { |
561 | #ifdef MAX77686_RTC_WTSR_SMPL | 484 | if (device_may_wakeup(dev)) { |
562 | struct max77686_rtc_info *info = platform_get_drvdata(pdev); | 485 | struct max77686_rtc_info *info = dev_get_drvdata(dev); |
563 | int i; | 486 | |
564 | u8 val = 0; | 487 | return enable_irq_wake(info->virq); |
565 | |||
566 | for (i = 0; i < 3; i++) { | ||
567 | max77686_rtc_enable_wtsr(info, false); | ||
568 | regmap_read(info->max77686->rtc_regmap, MAX77686_WTSR_SMPL_CNTL, &val); | ||
569 | dev_info(info->dev, "%s: WTSR_SMPL reg(0x%02x)\n", __func__, | ||
570 | val); | ||
571 | if (val & WTSR_EN_MASK) { | ||
572 | dev_emerg(info->dev, "%s: fail to disable WTSR\n", | ||
573 | __func__); | ||
574 | } else { | ||
575 | dev_info(info->dev, "%s: success to disable WTSR\n", | ||
576 | __func__); | ||
577 | break; | ||
578 | } | ||
579 | } | 488 | } |
580 | 489 | ||
581 | /* Disable SMPL when power off */ | 490 | return 0; |
582 | max77686_rtc_enable_smpl(info, false); | ||
583 | #endif /* MAX77686_RTC_WTSR_SMPL */ | ||
584 | } | 491 | } |
585 | 492 | ||
493 | static int max77686_rtc_resume(struct device *dev) | ||
494 | { | ||
495 | if (device_may_wakeup(dev)) { | ||
496 | struct max77686_rtc_info *info = dev_get_drvdata(dev); | ||
497 | |||
498 | return disable_irq_wake(info->virq); | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | #endif | ||
504 | |||
505 | static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops, | ||
506 | max77686_rtc_suspend, max77686_rtc_resume); | ||
507 | |||
586 | static const struct platform_device_id rtc_id[] = { | 508 | static const struct platform_device_id rtc_id[] = { |
587 | { "max77686-rtc", 0 }, | 509 | { "max77686-rtc", 0 }, |
588 | {}, | 510 | {}, |
@@ -592,9 +514,9 @@ static struct platform_driver max77686_rtc_driver = { | |||
592 | .driver = { | 514 | .driver = { |
593 | .name = "max77686-rtc", | 515 | .name = "max77686-rtc", |
594 | .owner = THIS_MODULE, | 516 | .owner = THIS_MODULE, |
517 | .pm = &max77686_rtc_pm_ops, | ||
595 | }, | 518 | }, |
596 | .probe = max77686_rtc_probe, | 519 | .probe = max77686_rtc_probe, |
597 | .shutdown = max77686_rtc_shutdown, | ||
598 | .id_table = rtc_id, | 520 | .id_table = rtc_id, |
599 | }; | 521 | }; |
600 | 522 | ||
diff --git a/drivers/rtc/rtc-max77802.c b/drivers/rtc/rtc-max77802.c new file mode 100644 index 000000000000..566471335b33 --- /dev/null +++ b/drivers/rtc/rtc-max77802.c | |||
@@ -0,0 +1,502 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX77802 | ||
3 | * | ||
4 | * Copyright (C) 2013 Google, Inc | ||
5 | * | ||
6 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
7 | * | ||
8 | * based on rtc-max8997.c | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/slab.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/mutex.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mfd/max77686-private.h> | ||
24 | #include <linux/irqdomain.h> | ||
25 | #include <linux/regmap.h> | ||
26 | |||
27 | /* RTC Control Register */ | ||
28 | #define BCD_EN_SHIFT 0 | ||
29 | #define BCD_EN_MASK (1 << BCD_EN_SHIFT) | ||
30 | #define MODEL24_SHIFT 1 | ||
31 | #define MODEL24_MASK (1 << MODEL24_SHIFT) | ||
32 | /* RTC Update Register1 */ | ||
33 | #define RTC_UDR_SHIFT 0 | ||
34 | #define RTC_UDR_MASK (1 << RTC_UDR_SHIFT) | ||
35 | #define RTC_RBUDR_SHIFT 4 | ||
36 | #define RTC_RBUDR_MASK (1 << RTC_RBUDR_SHIFT) | ||
37 | /* RTC Hour register */ | ||
38 | #define HOUR_PM_SHIFT 6 | ||
39 | #define HOUR_PM_MASK (1 << HOUR_PM_SHIFT) | ||
40 | /* RTC Alarm Enable */ | ||
41 | #define ALARM_ENABLE_SHIFT 7 | ||
42 | #define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT) | ||
43 | |||
44 | /* For the RTCAE1 register, we write this value to enable the alarm */ | ||
45 | #define ALARM_ENABLE_VALUE 0x77 | ||
46 | |||
47 | #define MAX77802_RTC_UPDATE_DELAY_US 200 | ||
48 | |||
49 | enum { | ||
50 | RTC_SEC = 0, | ||
51 | RTC_MIN, | ||
52 | RTC_HOUR, | ||
53 | RTC_WEEKDAY, | ||
54 | RTC_MONTH, | ||
55 | RTC_YEAR, | ||
56 | RTC_DATE, | ||
57 | RTC_NR_TIME | ||
58 | }; | ||
59 | |||
60 | struct max77802_rtc_info { | ||
61 | struct device *dev; | ||
62 | struct max77686_dev *max77802; | ||
63 | struct i2c_client *rtc; | ||
64 | struct rtc_device *rtc_dev; | ||
65 | struct mutex lock; | ||
66 | |||
67 | struct regmap *regmap; | ||
68 | |||
69 | int virq; | ||
70 | int rtc_24hr_mode; | ||
71 | }; | ||
72 | |||
73 | enum MAX77802_RTC_OP { | ||
74 | MAX77802_RTC_WRITE, | ||
75 | MAX77802_RTC_READ, | ||
76 | }; | ||
77 | |||
78 | static void max77802_rtc_data_to_tm(u8 *data, struct rtc_time *tm, | ||
79 | int rtc_24hr_mode) | ||
80 | { | ||
81 | tm->tm_sec = data[RTC_SEC] & 0xff; | ||
82 | tm->tm_min = data[RTC_MIN] & 0xff; | ||
83 | if (rtc_24hr_mode) | ||
84 | tm->tm_hour = data[RTC_HOUR] & 0x1f; | ||
85 | else { | ||
86 | tm->tm_hour = data[RTC_HOUR] & 0x0f; | ||
87 | if (data[RTC_HOUR] & HOUR_PM_MASK) | ||
88 | tm->tm_hour += 12; | ||
89 | } | ||
90 | |||
91 | /* Only a single bit is set in data[], so fls() would be equivalent */ | ||
92 | tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0xff) - 1; | ||
93 | tm->tm_mday = data[RTC_DATE] & 0x1f; | ||
94 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | ||
95 | |||
96 | tm->tm_year = data[RTC_YEAR] & 0xff; | ||
97 | tm->tm_yday = 0; | ||
98 | tm->tm_isdst = 0; | ||
99 | } | ||
100 | |||
101 | static int max77802_rtc_tm_to_data(struct rtc_time *tm, u8 *data) | ||
102 | { | ||
103 | data[RTC_SEC] = tm->tm_sec; | ||
104 | data[RTC_MIN] = tm->tm_min; | ||
105 | data[RTC_HOUR] = tm->tm_hour; | ||
106 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; | ||
107 | data[RTC_DATE] = tm->tm_mday; | ||
108 | data[RTC_MONTH] = tm->tm_mon + 1; | ||
109 | data[RTC_YEAR] = tm->tm_year; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int max77802_rtc_update(struct max77802_rtc_info *info, | ||
115 | enum MAX77802_RTC_OP op) | ||
116 | { | ||
117 | int ret; | ||
118 | unsigned int data; | ||
119 | |||
120 | if (op == MAX77802_RTC_WRITE) | ||
121 | data = 1 << RTC_UDR_SHIFT; | ||
122 | else | ||
123 | data = 1 << RTC_RBUDR_SHIFT; | ||
124 | |||
125 | ret = regmap_update_bits(info->max77802->regmap, | ||
126 | MAX77802_RTC_UPDATE0, data, data); | ||
127 | if (ret < 0) | ||
128 | dev_err(info->dev, "%s: fail to write update reg(ret=%d, data=0x%x)\n", | ||
129 | __func__, ret, data); | ||
130 | else { | ||
131 | /* Minimum delay required before RTC update. */ | ||
132 | usleep_range(MAX77802_RTC_UPDATE_DELAY_US, | ||
133 | MAX77802_RTC_UPDATE_DELAY_US * 2); | ||
134 | } | ||
135 | |||
136 | return ret; | ||
137 | } | ||
138 | |||
139 | static int max77802_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
140 | { | ||
141 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
142 | u8 data[RTC_NR_TIME]; | ||
143 | int ret; | ||
144 | |||
145 | mutex_lock(&info->lock); | ||
146 | |||
147 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
148 | if (ret < 0) | ||
149 | goto out; | ||
150 | |||
151 | ret = regmap_bulk_read(info->max77802->regmap, | ||
152 | MAX77802_RTC_SEC, data, RTC_NR_TIME); | ||
153 | if (ret < 0) { | ||
154 | dev_err(info->dev, "%s: fail to read time reg(%d)\n", __func__, | ||
155 | ret); | ||
156 | goto out; | ||
157 | } | ||
158 | |||
159 | max77802_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); | ||
160 | |||
161 | ret = rtc_valid_tm(tm); | ||
162 | |||
163 | out: | ||
164 | mutex_unlock(&info->lock); | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | static int max77802_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
169 | { | ||
170 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
171 | u8 data[RTC_NR_TIME]; | ||
172 | int ret; | ||
173 | |||
174 | ret = max77802_rtc_tm_to_data(tm, data); | ||
175 | if (ret < 0) | ||
176 | return ret; | ||
177 | |||
178 | mutex_lock(&info->lock); | ||
179 | |||
180 | ret = regmap_bulk_write(info->max77802->regmap, | ||
181 | MAX77802_RTC_SEC, data, RTC_NR_TIME); | ||
182 | if (ret < 0) { | ||
183 | dev_err(info->dev, "%s: fail to write time reg(%d)\n", __func__, | ||
184 | ret); | ||
185 | goto out; | ||
186 | } | ||
187 | |||
188 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
189 | |||
190 | out: | ||
191 | mutex_unlock(&info->lock); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int max77802_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
196 | { | ||
197 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
198 | u8 data[RTC_NR_TIME]; | ||
199 | unsigned int val; | ||
200 | int ret; | ||
201 | |||
202 | mutex_lock(&info->lock); | ||
203 | |||
204 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
205 | if (ret < 0) | ||
206 | goto out; | ||
207 | |||
208 | ret = regmap_bulk_read(info->max77802->regmap, | ||
209 | MAX77802_ALARM1_SEC, data, RTC_NR_TIME); | ||
210 | if (ret < 0) { | ||
211 | dev_err(info->dev, "%s:%d fail to read alarm reg(%d)\n", | ||
212 | __func__, __LINE__, ret); | ||
213 | goto out; | ||
214 | } | ||
215 | |||
216 | max77802_rtc_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); | ||
217 | |||
218 | alrm->enabled = 0; | ||
219 | ret = regmap_read(info->max77802->regmap, | ||
220 | MAX77802_RTC_AE1, &val); | ||
221 | if (ret < 0) { | ||
222 | dev_err(info->dev, "%s:%d fail to read alarm enable(%d)\n", | ||
223 | __func__, __LINE__, ret); | ||
224 | goto out; | ||
225 | } | ||
226 | if (val) | ||
227 | alrm->enabled = 1; | ||
228 | |||
229 | alrm->pending = 0; | ||
230 | ret = regmap_read(info->max77802->regmap, MAX77802_REG_STATUS2, &val); | ||
231 | if (ret < 0) { | ||
232 | dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n", | ||
233 | __func__, __LINE__, ret); | ||
234 | goto out; | ||
235 | } | ||
236 | |||
237 | if (val & (1 << 2)) /* RTCA1 */ | ||
238 | alrm->pending = 1; | ||
239 | |||
240 | out: | ||
241 | mutex_unlock(&info->lock); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static int max77802_rtc_stop_alarm(struct max77802_rtc_info *info) | ||
246 | { | ||
247 | int ret; | ||
248 | |||
249 | if (!mutex_is_locked(&info->lock)) | ||
250 | dev_warn(info->dev, "%s: should have mutex locked\n", __func__); | ||
251 | |||
252 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
253 | if (ret < 0) | ||
254 | goto out; | ||
255 | |||
256 | ret = regmap_write(info->max77802->regmap, | ||
257 | MAX77802_RTC_AE1, 0); | ||
258 | if (ret < 0) { | ||
259 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
260 | __func__, ret); | ||
261 | goto out; | ||
262 | } | ||
263 | |||
264 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
265 | out: | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | static int max77802_rtc_start_alarm(struct max77802_rtc_info *info) | ||
270 | { | ||
271 | int ret; | ||
272 | |||
273 | if (!mutex_is_locked(&info->lock)) | ||
274 | dev_warn(info->dev, "%s: should have mutex locked\n", | ||
275 | __func__); | ||
276 | |||
277 | ret = max77802_rtc_update(info, MAX77802_RTC_READ); | ||
278 | if (ret < 0) | ||
279 | goto out; | ||
280 | |||
281 | ret = regmap_write(info->max77802->regmap, | ||
282 | MAX77802_RTC_AE1, | ||
283 | ALARM_ENABLE_VALUE); | ||
284 | |||
285 | if (ret < 0) { | ||
286 | dev_err(info->dev, "%s: fail to read alarm reg(%d)\n", | ||
287 | __func__, ret); | ||
288 | goto out; | ||
289 | } | ||
290 | |||
291 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
292 | out: | ||
293 | return ret; | ||
294 | } | ||
295 | |||
296 | static int max77802_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
297 | { | ||
298 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
299 | u8 data[RTC_NR_TIME]; | ||
300 | int ret; | ||
301 | |||
302 | ret = max77802_rtc_tm_to_data(&alrm->time, data); | ||
303 | if (ret < 0) | ||
304 | return ret; | ||
305 | |||
306 | mutex_lock(&info->lock); | ||
307 | |||
308 | ret = max77802_rtc_stop_alarm(info); | ||
309 | if (ret < 0) | ||
310 | goto out; | ||
311 | |||
312 | ret = regmap_bulk_write(info->max77802->regmap, | ||
313 | MAX77802_ALARM1_SEC, data, RTC_NR_TIME); | ||
314 | |||
315 | if (ret < 0) { | ||
316 | dev_err(info->dev, "%s: fail to write alarm reg(%d)\n", | ||
317 | __func__, ret); | ||
318 | goto out; | ||
319 | } | ||
320 | |||
321 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
322 | if (ret < 0) | ||
323 | goto out; | ||
324 | |||
325 | if (alrm->enabled) | ||
326 | ret = max77802_rtc_start_alarm(info); | ||
327 | out: | ||
328 | mutex_unlock(&info->lock); | ||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | static int max77802_rtc_alarm_irq_enable(struct device *dev, | ||
333 | unsigned int enabled) | ||
334 | { | ||
335 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
336 | int ret; | ||
337 | |||
338 | mutex_lock(&info->lock); | ||
339 | if (enabled) | ||
340 | ret = max77802_rtc_start_alarm(info); | ||
341 | else | ||
342 | ret = max77802_rtc_stop_alarm(info); | ||
343 | mutex_unlock(&info->lock); | ||
344 | |||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | static irqreturn_t max77802_rtc_alarm_irq(int irq, void *data) | ||
349 | { | ||
350 | struct max77802_rtc_info *info = data; | ||
351 | |||
352 | dev_dbg(info->dev, "%s:irq(%d)\n", __func__, irq); | ||
353 | |||
354 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
355 | |||
356 | return IRQ_HANDLED; | ||
357 | } | ||
358 | |||
359 | static const struct rtc_class_ops max77802_rtc_ops = { | ||
360 | .read_time = max77802_rtc_read_time, | ||
361 | .set_time = max77802_rtc_set_time, | ||
362 | .read_alarm = max77802_rtc_read_alarm, | ||
363 | .set_alarm = max77802_rtc_set_alarm, | ||
364 | .alarm_irq_enable = max77802_rtc_alarm_irq_enable, | ||
365 | }; | ||
366 | |||
367 | static int max77802_rtc_init_reg(struct max77802_rtc_info *info) | ||
368 | { | ||
369 | u8 data[2]; | ||
370 | int ret; | ||
371 | |||
372 | max77802_rtc_update(info, MAX77802_RTC_READ); | ||
373 | |||
374 | /* Set RTC control register : Binary mode, 24hour mdoe */ | ||
375 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
376 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | ||
377 | |||
378 | info->rtc_24hr_mode = 1; | ||
379 | |||
380 | ret = regmap_bulk_write(info->max77802->regmap, | ||
381 | MAX77802_RTC_CONTROLM, data, ARRAY_SIZE(data)); | ||
382 | if (ret < 0) { | ||
383 | dev_err(info->dev, "%s: fail to write controlm reg(%d)\n", | ||
384 | __func__, ret); | ||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | ret = max77802_rtc_update(info, MAX77802_RTC_WRITE); | ||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | static int max77802_rtc_probe(struct platform_device *pdev) | ||
393 | { | ||
394 | struct max77686_dev *max77802 = dev_get_drvdata(pdev->dev.parent); | ||
395 | struct max77802_rtc_info *info; | ||
396 | int ret; | ||
397 | |||
398 | dev_dbg(&pdev->dev, "%s\n", __func__); | ||
399 | |||
400 | info = devm_kzalloc(&pdev->dev, sizeof(struct max77802_rtc_info), | ||
401 | GFP_KERNEL); | ||
402 | if (!info) | ||
403 | return -ENOMEM; | ||
404 | |||
405 | mutex_init(&info->lock); | ||
406 | info->dev = &pdev->dev; | ||
407 | info->max77802 = max77802; | ||
408 | info->rtc = max77802->i2c; | ||
409 | |||
410 | platform_set_drvdata(pdev, info); | ||
411 | |||
412 | ret = max77802_rtc_init_reg(info); | ||
413 | |||
414 | if (ret < 0) { | ||
415 | dev_err(&pdev->dev, "Failed to initialize RTC reg:%d\n", ret); | ||
416 | return ret; | ||
417 | } | ||
418 | |||
419 | device_init_wakeup(&pdev->dev, 1); | ||
420 | |||
421 | info->rtc_dev = devm_rtc_device_register(&pdev->dev, "max77802-rtc", | ||
422 | &max77802_rtc_ops, THIS_MODULE); | ||
423 | |||
424 | if (IS_ERR(info->rtc_dev)) { | ||
425 | ret = PTR_ERR(info->rtc_dev); | ||
426 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
427 | if (ret == 0) | ||
428 | ret = -EINVAL; | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | if (!max77802->rtc_irq_data) { | ||
433 | dev_err(&pdev->dev, "No RTC regmap IRQ chip\n"); | ||
434 | return -EINVAL; | ||
435 | } | ||
436 | |||
437 | info->virq = regmap_irq_get_virq(max77802->rtc_irq_data, | ||
438 | MAX77686_RTCIRQ_RTCA1); | ||
439 | |||
440 | if (info->virq <= 0) { | ||
441 | dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n", | ||
442 | MAX77686_RTCIRQ_RTCA1); | ||
443 | return -EINVAL; | ||
444 | } | ||
445 | |||
446 | ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL, | ||
447 | max77802_rtc_alarm_irq, 0, "rtc-alarm1", | ||
448 | info); | ||
449 | if (ret < 0) | ||
450 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | ||
451 | info->virq, ret); | ||
452 | |||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | #ifdef CONFIG_PM_SLEEP | ||
457 | static int max77802_rtc_suspend(struct device *dev) | ||
458 | { | ||
459 | if (device_may_wakeup(dev)) { | ||
460 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
461 | |||
462 | return enable_irq_wake(info->virq); | ||
463 | } | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static int max77802_rtc_resume(struct device *dev) | ||
469 | { | ||
470 | if (device_may_wakeup(dev)) { | ||
471 | struct max77802_rtc_info *info = dev_get_drvdata(dev); | ||
472 | |||
473 | return disable_irq_wake(info->virq); | ||
474 | } | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | #endif | ||
479 | |||
480 | static SIMPLE_DEV_PM_OPS(max77802_rtc_pm_ops, | ||
481 | max77802_rtc_suspend, max77802_rtc_resume); | ||
482 | |||
483 | static const struct platform_device_id rtc_id[] = { | ||
484 | { "max77802-rtc", 0 }, | ||
485 | {}, | ||
486 | }; | ||
487 | |||
488 | static struct platform_driver max77802_rtc_driver = { | ||
489 | .driver = { | ||
490 | .name = "max77802-rtc", | ||
491 | .owner = THIS_MODULE, | ||
492 | .pm = &max77802_rtc_pm_ops, | ||
493 | }, | ||
494 | .probe = max77802_rtc_probe, | ||
495 | .id_table = rtc_id, | ||
496 | }; | ||
497 | |||
498 | module_platform_driver(max77802_rtc_driver); | ||
499 | |||
500 | MODULE_DESCRIPTION("Maxim MAX77802 RTC driver"); | ||
501 | MODULE_AUTHOR("Simon Glass <sjg@chromium.org>"); | ||
502 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index dc4f14255cc3..3b965ad6f4d5 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c | |||
@@ -401,7 +401,7 @@ static int mpc5121_rtc_remove(struct platform_device *op) | |||
401 | } | 401 | } |
402 | 402 | ||
403 | #ifdef CONFIG_OF | 403 | #ifdef CONFIG_OF |
404 | static struct of_device_id mpc5121_rtc_match[] = { | 404 | static const struct of_device_id mpc5121_rtc_match[] = { |
405 | { .compatible = "fsl,mpc5121-rtc", }, | 405 | { .compatible = "fsl,mpc5121-rtc", }, |
406 | { .compatible = "fsl,mpc5200-rtc", }, | 406 | { .compatible = "fsl,mpc5200-rtc", }, |
407 | {}, | 407 | {}, |
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 5a197d9dc7e7..c2ef0a22ee94 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -167,8 +167,8 @@ static irqreturn_t pcf8563_irq(int irq, void *dev_id) | |||
167 | char pending; | 167 | char pending; |
168 | 168 | ||
169 | err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending); | 169 | err = pcf8563_get_alarm_mode(pcf8563->client, NULL, &pending); |
170 | if (err < 0) | 170 | if (err) |
171 | return err; | 171 | return IRQ_NONE; |
172 | 172 | ||
173 | if (pending) { | 173 | if (pending) { |
174 | rtc_update_irq(pcf8563->rtc, 1, RTC_IRQF | RTC_AF); | 174 | rtc_update_irq(pcf8563->rtc, 1, RTC_IRQF | RTC_AF); |
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index c2639845186b..5911a6dca291 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -176,7 +176,11 @@ static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
176 | { | 176 | { |
177 | struct i2c_client *client = to_i2c_client(dev); | 177 | struct i2c_client *client = to_i2c_client(dev); |
178 | unsigned char ctrl, year[2]; | 178 | unsigned char ctrl, year[2]; |
179 | struct rtc_mem mem = { CMOS_YEAR, sizeof(year), year }; | 179 | struct rtc_mem mem = { |
180 | .loc = CMOS_YEAR, | ||
181 | .nr = sizeof(year), | ||
182 | .data = year | ||
183 | }; | ||
180 | int real_year, year_offset, err; | 184 | int real_year, year_offset, err; |
181 | 185 | ||
182 | /* | 186 | /* |
@@ -222,8 +226,16 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
222 | { | 226 | { |
223 | struct i2c_client *client = to_i2c_client(dev); | 227 | struct i2c_client *client = to_i2c_client(dev); |
224 | unsigned char year[2], chk; | 228 | unsigned char year[2], chk; |
225 | struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year }; | 229 | struct rtc_mem cmos_year = { |
226 | struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; | 230 | .loc = CMOS_YEAR, |
231 | .nr = sizeof(year), | ||
232 | .data = year | ||
233 | }; | ||
234 | struct rtc_mem cmos_check = { | ||
235 | .loc = CMOS_CHECKSUM, | ||
236 | .nr = 1, | ||
237 | .data = &chk | ||
238 | }; | ||
227 | unsigned int proper_year = tm->tm_year + 1900; | 239 | unsigned int proper_year = tm->tm_year + 1900; |
228 | int ret; | 240 | int ret; |
229 | 241 | ||
diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c new file mode 100644 index 000000000000..df42257668ac --- /dev/null +++ b/drivers/rtc/rtc-rk808.c | |||
@@ -0,0 +1,414 @@ | |||
1 | /* | ||
2 | * RTC driver for Rockchip RK808 | ||
3 | * | ||
4 | * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd | ||
5 | * | ||
6 | * Author: Chris Zhong <zyw@rock-chips.com> | ||
7 | * Author: Zhang Qing <zhangqing@rock-chips.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms and conditions of the GNU General Public License, | ||
11 | * version 2, as published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/rtc.h> | ||
22 | #include <linux/bcd.h> | ||
23 | #include <linux/mfd/rk808.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/i2c.h> | ||
26 | |||
27 | /* RTC_CTRL_REG bitfields */ | ||
28 | #define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0) | ||
29 | |||
30 | /* RK808 has a shadowed register for saving a "frozen" RTC time. | ||
31 | * When user setting "GET_TIME" to 1, the time will save in this shadowed | ||
32 | * register. If set "READSEL" to 1, user read rtc time register, actually | ||
33 | * get the time of that moment. If we need the real time, clr this bit. | ||
34 | */ | ||
35 | #define BIT_RTC_CTRL_REG_RTC_GET_TIME BIT(6) | ||
36 | #define BIT_RTC_CTRL_REG_RTC_READSEL_M BIT(7) | ||
37 | #define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M BIT(3) | ||
38 | #define RTC_STATUS_MASK 0xFE | ||
39 | |||
40 | #define SECONDS_REG_MSK 0x7F | ||
41 | #define MINUTES_REG_MAK 0x7F | ||
42 | #define HOURS_REG_MSK 0x3F | ||
43 | #define DAYS_REG_MSK 0x3F | ||
44 | #define MONTHS_REG_MSK 0x1F | ||
45 | #define YEARS_REG_MSK 0xFF | ||
46 | #define WEEKS_REG_MSK 0x7 | ||
47 | |||
48 | /* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */ | ||
49 | |||
50 | #define NUM_TIME_REGS (RK808_WEEKS_REG - RK808_SECONDS_REG + 1) | ||
51 | #define NUM_ALARM_REGS (RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1) | ||
52 | |||
53 | struct rk808_rtc { | ||
54 | struct rk808 *rk808; | ||
55 | struct rtc_device *rtc; | ||
56 | int irq; | ||
57 | }; | ||
58 | |||
59 | /* Read current time and date in RTC */ | ||
60 | static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) | ||
61 | { | ||
62 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
63 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
64 | u8 rtc_data[NUM_TIME_REGS]; | ||
65 | int ret; | ||
66 | |||
67 | /* Force an update of the shadowed registers right now */ | ||
68 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
69 | BIT_RTC_CTRL_REG_RTC_GET_TIME, | ||
70 | 0); | ||
71 | if (ret) { | ||
72 | dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
77 | BIT_RTC_CTRL_REG_RTC_GET_TIME, | ||
78 | BIT_RTC_CTRL_REG_RTC_GET_TIME); | ||
79 | if (ret) { | ||
80 | dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG, | ||
85 | rtc_data, NUM_TIME_REGS); | ||
86 | if (ret) { | ||
87 | dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret); | ||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK); | ||
92 | tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK); | ||
93 | tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK); | ||
94 | tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK); | ||
95 | tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1; | ||
96 | tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100; | ||
97 | tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK); | ||
98 | dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
99 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | ||
100 | tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); | ||
101 | |||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | /* Set current time and date in RTC */ | ||
106 | static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
107 | { | ||
108 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
109 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
110 | u8 rtc_data[NUM_TIME_REGS]; | ||
111 | int ret; | ||
112 | |||
113 | rtc_data[0] = bin2bcd(tm->tm_sec); | ||
114 | rtc_data[1] = bin2bcd(tm->tm_min); | ||
115 | rtc_data[2] = bin2bcd(tm->tm_hour); | ||
116 | rtc_data[3] = bin2bcd(tm->tm_mday); | ||
117 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); | ||
118 | rtc_data[5] = bin2bcd(tm->tm_year - 100); | ||
119 | rtc_data[6] = bin2bcd(tm->tm_wday); | ||
120 | dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
121 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | ||
122 | tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); | ||
123 | |||
124 | /* Stop RTC while updating the RTC registers */ | ||
125 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
126 | BIT_RTC_CTRL_REG_STOP_RTC_M, | ||
127 | BIT_RTC_CTRL_REG_STOP_RTC_M); | ||
128 | if (ret) { | ||
129 | dev_err(dev, "Failed to update RTC control: %d\n", ret); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG, | ||
134 | rtc_data, NUM_TIME_REGS); | ||
135 | if (ret) { | ||
136 | dev_err(dev, "Failed to bull write rtc_data: %d\n", ret); | ||
137 | return ret; | ||
138 | } | ||
139 | /* Start RTC again */ | ||
140 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
141 | BIT_RTC_CTRL_REG_STOP_RTC_M, 0); | ||
142 | if (ret) { | ||
143 | dev_err(dev, "Failed to update RTC control: %d\n", ret); | ||
144 | return ret; | ||
145 | } | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /* Read alarm time and date in RTC */ | ||
150 | static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
151 | { | ||
152 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
153 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
154 | u8 alrm_data[NUM_ALARM_REGS]; | ||
155 | uint32_t int_reg; | ||
156 | int ret; | ||
157 | |||
158 | ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG, | ||
159 | alrm_data, NUM_ALARM_REGS); | ||
160 | |||
161 | alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK); | ||
162 | alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK); | ||
163 | alrm->time.tm_hour = bcd2bin(alrm_data[2] & HOURS_REG_MSK); | ||
164 | alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK); | ||
165 | alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1; | ||
166 | alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100; | ||
167 | |||
168 | ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg); | ||
169 | if (ret) { | ||
170 | dev_err(dev, "Failed to read RTC INT REG: %d\n", ret); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
175 | 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, | ||
176 | alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, | ||
177 | alrm->time.tm_min, alrm->time.tm_sec); | ||
178 | |||
179 | alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0; | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc) | ||
185 | { | ||
186 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
187 | int ret; | ||
188 | |||
189 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, | ||
190 | BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0); | ||
191 | |||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc) | ||
196 | { | ||
197 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
198 | int ret; | ||
199 | |||
200 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, | ||
201 | BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, | ||
202 | BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); | ||
203 | |||
204 | return ret; | ||
205 | } | ||
206 | |||
207 | static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
208 | { | ||
209 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
210 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
211 | u8 alrm_data[NUM_ALARM_REGS]; | ||
212 | int ret; | ||
213 | |||
214 | ret = rk808_rtc_stop_alarm(rk808_rtc); | ||
215 | if (ret) { | ||
216 | dev_err(dev, "Failed to stop alarm: %d\n", ret); | ||
217 | return ret; | ||
218 | } | ||
219 | dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", | ||
220 | 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, | ||
221 | alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, | ||
222 | alrm->time.tm_min, alrm->time.tm_sec); | ||
223 | |||
224 | alrm_data[0] = bin2bcd(alrm->time.tm_sec); | ||
225 | alrm_data[1] = bin2bcd(alrm->time.tm_min); | ||
226 | alrm_data[2] = bin2bcd(alrm->time.tm_hour); | ||
227 | alrm_data[3] = bin2bcd(alrm->time.tm_mday); | ||
228 | alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1); | ||
229 | alrm_data[5] = bin2bcd(alrm->time.tm_year - 100); | ||
230 | |||
231 | ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG, | ||
232 | alrm_data, NUM_ALARM_REGS); | ||
233 | if (ret) { | ||
234 | dev_err(dev, "Failed to bulk write: %d\n", ret); | ||
235 | return ret; | ||
236 | } | ||
237 | if (alrm->enabled) { | ||
238 | ret = rk808_rtc_start_alarm(rk808_rtc); | ||
239 | if (ret) { | ||
240 | dev_err(dev, "Failed to start alarm: %d\n", ret); | ||
241 | return ret; | ||
242 | } | ||
243 | } | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int rk808_rtc_alarm_irq_enable(struct device *dev, | ||
248 | unsigned int enabled) | ||
249 | { | ||
250 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); | ||
251 | |||
252 | if (enabled) | ||
253 | return rk808_rtc_start_alarm(rk808_rtc); | ||
254 | |||
255 | return rk808_rtc_stop_alarm(rk808_rtc); | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * We will just handle setting the frequency and make use the framework for | ||
260 | * reading the periodic interupts. | ||
261 | * | ||
262 | * @freq: Current periodic IRQ freq: | ||
263 | * bit 0: every second | ||
264 | * bit 1: every minute | ||
265 | * bit 2: every hour | ||
266 | * bit 3: every day | ||
267 | */ | ||
268 | static irqreturn_t rk808_alarm_irq(int irq, void *data) | ||
269 | { | ||
270 | struct rk808_rtc *rk808_rtc = data; | ||
271 | struct rk808 *rk808 = rk808_rtc->rk808; | ||
272 | struct i2c_client *client = rk808->i2c; | ||
273 | int ret; | ||
274 | |||
275 | ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, | ||
276 | RTC_STATUS_MASK); | ||
277 | if (ret) { | ||
278 | dev_err(&client->dev, | ||
279 | "%s:Failed to update RTC status: %d\n", __func__, ret); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
284 | dev_dbg(&client->dev, | ||
285 | "%s:irq=%d\n", __func__, irq); | ||
286 | return IRQ_HANDLED; | ||
287 | } | ||
288 | |||
289 | static const struct rtc_class_ops rk808_rtc_ops = { | ||
290 | .read_time = rk808_rtc_readtime, | ||
291 | .set_time = rk808_rtc_set_time, | ||
292 | .read_alarm = rk808_rtc_readalarm, | ||
293 | .set_alarm = rk808_rtc_setalarm, | ||
294 | .alarm_irq_enable = rk808_rtc_alarm_irq_enable, | ||
295 | }; | ||
296 | |||
297 | #ifdef CONFIG_PM_SLEEP | ||
298 | /* Turn off the alarm if it should not be a wake source. */ | ||
299 | static int rk808_rtc_suspend(struct device *dev) | ||
300 | { | ||
301 | struct platform_device *pdev = to_platform_device(dev); | ||
302 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); | ||
303 | |||
304 | if (device_may_wakeup(dev)) | ||
305 | enable_irq_wake(rk808_rtc->irq); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | /* Enable the alarm if it should be enabled (in case it was disabled to | ||
311 | * prevent use as a wake source). | ||
312 | */ | ||
313 | static int rk808_rtc_resume(struct device *dev) | ||
314 | { | ||
315 | struct platform_device *pdev = to_platform_device(dev); | ||
316 | struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); | ||
317 | |||
318 | if (device_may_wakeup(dev)) | ||
319 | disable_irq_wake(rk808_rtc->irq); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | #endif | ||
324 | |||
325 | static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops, | ||
326 | rk808_rtc_suspend, rk808_rtc_resume); | ||
327 | |||
328 | static int rk808_rtc_probe(struct platform_device *pdev) | ||
329 | { | ||
330 | struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); | ||
331 | struct rk808_rtc *rk808_rtc; | ||
332 | struct rtc_time tm; | ||
333 | int ret; | ||
334 | |||
335 | rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL); | ||
336 | if (rk808_rtc == NULL) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | platform_set_drvdata(pdev, rk808_rtc); | ||
340 | rk808_rtc->rk808 = rk808; | ||
341 | |||
342 | /* start rtc running by default, and use shadowed timer. */ | ||
343 | ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, | ||
344 | BIT_RTC_CTRL_REG_STOP_RTC_M | | ||
345 | BIT_RTC_CTRL_REG_RTC_READSEL_M, | ||
346 | BIT_RTC_CTRL_REG_RTC_READSEL_M); | ||
347 | if (ret) { | ||
348 | dev_err(&pdev->dev, | ||
349 | "Failed to update RTC control: %d\n", ret); | ||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, | ||
354 | RTC_STATUS_MASK); | ||
355 | if (ret) { | ||
356 | dev_err(&pdev->dev, | ||
357 | "Failed to write RTC status: %d\n", ret); | ||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | /* set init time */ | ||
362 | ret = rk808_rtc_readtime(&pdev->dev, &tm); | ||
363 | if (ret) { | ||
364 | dev_err(&pdev->dev, "Failed to read RTC time\n"); | ||
365 | return ret; | ||
366 | } | ||
367 | ret = rtc_valid_tm(&tm); | ||
368 | if (ret) | ||
369 | dev_warn(&pdev->dev, "invalid date/time\n"); | ||
370 | |||
371 | device_init_wakeup(&pdev->dev, 1); | ||
372 | |||
373 | rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc", | ||
374 | &rk808_rtc_ops, THIS_MODULE); | ||
375 | if (IS_ERR(rk808_rtc->rtc)) { | ||
376 | ret = PTR_ERR(rk808_rtc->rtc); | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | rk808_rtc->irq = platform_get_irq(pdev, 0); | ||
381 | if (rk808_rtc->irq < 0) { | ||
382 | if (rk808_rtc->irq != -EPROBE_DEFER) | ||
383 | dev_err(&pdev->dev, "Wake up is not possible as irq = %d\n", | ||
384 | rk808_rtc->irq); | ||
385 | return rk808_rtc->irq; | ||
386 | } | ||
387 | |||
388 | /* request alarm irq of rk808 */ | ||
389 | ret = devm_request_threaded_irq(&pdev->dev, rk808_rtc->irq, NULL, | ||
390 | rk808_alarm_irq, 0, | ||
391 | "RTC alarm", rk808_rtc); | ||
392 | if (ret) { | ||
393 | dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", | ||
394 | rk808_rtc->irq, ret); | ||
395 | } | ||
396 | |||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | static struct platform_driver rk808_rtc_driver = { | ||
401 | .probe = rk808_rtc_probe, | ||
402 | .driver = { | ||
403 | .name = "rk808-rtc", | ||
404 | .pm = &rk808_rtc_pm_ops, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | module_platform_driver(rk808_rtc_driver); | ||
409 | |||
410 | MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs"); | ||
411 | MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); | ||
412 | MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); | ||
413 | MODULE_LICENSE("GPL"); | ||
414 | MODULE_ALIAS("platform:rk808-rtc"); | ||
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index ccf54f06396b..28871cd7e3b5 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -142,12 +142,11 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) | |||
142 | } | 142 | } |
143 | 143 | ||
144 | dev_dbg(&client->dev, | 144 | dev_dbg(&client->dev, |
145 | "%02x %02x %02x (%02x) %02x %02x %02x (%02x), " | 145 | "%3ph (%02x) %3ph (%02x), %3ph, %3ph; %02x %02x\n", |
146 | "%02x %02x %02x, %02x %02x %02x; %02x %02x\n", | 146 | rs5c->regs + 0, rs5c->regs[3], |
147 | rs5c->regs[0], rs5c->regs[1], rs5c->regs[2], rs5c->regs[3], | 147 | rs5c->regs + 4, rs5c->regs[7], |
148 | rs5c->regs[4], rs5c->regs[5], rs5c->regs[6], rs5c->regs[7], | 148 | rs5c->regs + 8, rs5c->regs + 11, |
149 | rs5c->regs[8], rs5c->regs[9], rs5c->regs[10], rs5c->regs[11], | 149 | rs5c->regs[14], rs5c->regs[15]); |
150 | rs5c->regs[12], rs5c->regs[13], rs5c->regs[14], rs5c->regs[15]); | ||
151 | 150 | ||
152 | return 0; | 151 | return 0; |
153 | } | 152 | } |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 4958a363b2c7..a6b1252c9941 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -32,155 +32,150 @@ | |||
32 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
33 | #include "rtc-s3c.h" | 33 | #include "rtc-s3c.h" |
34 | 34 | ||
35 | enum s3c_cpu_type { | 35 | struct s3c_rtc { |
36 | TYPE_S3C2410, | 36 | struct device *dev; |
37 | TYPE_S3C2416, | 37 | struct rtc_device *rtc; |
38 | TYPE_S3C2443, | ||
39 | TYPE_S3C64XX, | ||
40 | }; | ||
41 | 38 | ||
42 | struct s3c_rtc_drv_data { | 39 | void __iomem *base; |
43 | int cpu_type; | 40 | struct clk *rtc_clk; |
44 | }; | 41 | struct clk *rtc_src_clk; |
42 | bool enabled; | ||
43 | |||
44 | struct s3c_rtc_data *data; | ||
45 | 45 | ||
46 | /* I have yet to find an S3C implementation with more than one | 46 | int irq_alarm; |
47 | * of these rtc blocks in */ | 47 | int irq_tick; |
48 | 48 | ||
49 | static struct clk *rtc_clk; | 49 | spinlock_t pie_lock; |
50 | static void __iomem *s3c_rtc_base; | 50 | spinlock_t alarm_clk_lock; |
51 | static int s3c_rtc_alarmno; | ||
52 | static int s3c_rtc_tickno; | ||
53 | static enum s3c_cpu_type s3c_rtc_cpu_type; | ||
54 | 51 | ||
55 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); | 52 | int ticnt_save, ticnt_en_save; |
53 | bool wake_en; | ||
54 | }; | ||
55 | |||
56 | struct s3c_rtc_data { | ||
57 | int max_user_freq; | ||
58 | bool needs_src_clk; | ||
59 | |||
60 | void (*irq_handler) (struct s3c_rtc *info, int mask); | ||
61 | void (*set_freq) (struct s3c_rtc *info, int freq); | ||
62 | void (*enable_tick) (struct s3c_rtc *info, struct seq_file *seq); | ||
63 | void (*select_tick_clk) (struct s3c_rtc *info); | ||
64 | void (*save_tick_cnt) (struct s3c_rtc *info); | ||
65 | void (*restore_tick_cnt) (struct s3c_rtc *info); | ||
66 | void (*enable) (struct s3c_rtc *info); | ||
67 | void (*disable) (struct s3c_rtc *info); | ||
68 | }; | ||
56 | 69 | ||
57 | static void s3c_rtc_alarm_clk_enable(bool enable) | 70 | static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable) |
58 | { | 71 | { |
59 | static DEFINE_SPINLOCK(s3c_rtc_alarm_clk_lock); | ||
60 | static bool alarm_clk_enabled; | ||
61 | unsigned long irq_flags; | 72 | unsigned long irq_flags; |
62 | 73 | ||
63 | spin_lock_irqsave(&s3c_rtc_alarm_clk_lock, irq_flags); | 74 | spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); |
64 | if (enable) { | 75 | if (enable) { |
65 | if (!alarm_clk_enabled) { | 76 | if (!info->enabled) { |
66 | clk_enable(rtc_clk); | 77 | clk_enable(info->rtc_clk); |
67 | alarm_clk_enabled = true; | 78 | if (info->data->needs_src_clk) |
79 | clk_enable(info->rtc_src_clk); | ||
80 | info->enabled = true; | ||
68 | } | 81 | } |
69 | } else { | 82 | } else { |
70 | if (alarm_clk_enabled) { | 83 | if (info->enabled) { |
71 | clk_disable(rtc_clk); | 84 | if (info->data->needs_src_clk) |
72 | alarm_clk_enabled = false; | 85 | clk_disable(info->rtc_src_clk); |
86 | clk_disable(info->rtc_clk); | ||
87 | info->enabled = false; | ||
73 | } | 88 | } |
74 | } | 89 | } |
75 | spin_unlock_irqrestore(&s3c_rtc_alarm_clk_lock, irq_flags); | 90 | spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); |
76 | } | 91 | } |
77 | 92 | ||
78 | /* IRQ Handlers */ | 93 | /* IRQ Handlers */ |
79 | 94 | static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | |
80 | static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) | ||
81 | { | 95 | { |
82 | struct rtc_device *rdev = id; | 96 | struct s3c_rtc *info = (struct s3c_rtc *)id; |
83 | |||
84 | clk_enable(rtc_clk); | ||
85 | rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); | ||
86 | |||
87 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | ||
88 | writeb(S3C2410_INTP_ALM, s3c_rtc_base + S3C2410_INTP); | ||
89 | |||
90 | clk_disable(rtc_clk); | ||
91 | 97 | ||
92 | s3c_rtc_alarm_clk_enable(false); | 98 | if (info->data->irq_handler) |
99 | info->data->irq_handler(info, S3C2410_INTP_TIC); | ||
93 | 100 | ||
94 | return IRQ_HANDLED; | 101 | return IRQ_HANDLED; |
95 | } | 102 | } |
96 | 103 | ||
97 | static irqreturn_t s3c_rtc_tickirq(int irq, void *id) | 104 | static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) |
98 | { | 105 | { |
99 | struct rtc_device *rdev = id; | 106 | struct s3c_rtc *info = (struct s3c_rtc *)id; |
100 | 107 | ||
101 | clk_enable(rtc_clk); | 108 | if (info->data->irq_handler) |
102 | rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF); | 109 | info->data->irq_handler(info, S3C2410_INTP_ALM); |
103 | 110 | ||
104 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | ||
105 | writeb(S3C2410_INTP_TIC, s3c_rtc_base + S3C2410_INTP); | ||
106 | |||
107 | clk_disable(rtc_clk); | ||
108 | return IRQ_HANDLED; | 111 | return IRQ_HANDLED; |
109 | } | 112 | } |
110 | 113 | ||
111 | /* Update control registers */ | 114 | /* Update control registers */ |
112 | static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) | 115 | static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) |
113 | { | 116 | { |
117 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
114 | unsigned int tmp; | 118 | unsigned int tmp; |
115 | 119 | ||
116 | dev_dbg(dev, "%s: aie=%d\n", __func__, enabled); | 120 | dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled); |
117 | 121 | ||
118 | clk_enable(rtc_clk); | 122 | clk_enable(info->rtc_clk); |
119 | tmp = readb(s3c_rtc_base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | 123 | if (info->data->needs_src_clk) |
124 | clk_enable(info->rtc_src_clk); | ||
125 | tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; | ||
120 | 126 | ||
121 | if (enabled) | 127 | if (enabled) |
122 | tmp |= S3C2410_RTCALM_ALMEN; | 128 | tmp |= S3C2410_RTCALM_ALMEN; |
123 | 129 | ||
124 | writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); | 130 | writeb(tmp, info->base + S3C2410_RTCALM); |
125 | clk_disable(rtc_clk); | 131 | if (info->data->needs_src_clk) |
132 | clk_disable(info->rtc_src_clk); | ||
133 | clk_disable(info->rtc_clk); | ||
126 | 134 | ||
127 | s3c_rtc_alarm_clk_enable(enabled); | 135 | s3c_rtc_alarm_clk_enable(info, enabled); |
128 | 136 | ||
129 | return 0; | 137 | return 0; |
130 | } | 138 | } |
131 | 139 | ||
132 | static int s3c_rtc_setfreq(struct device *dev, int freq) | 140 | /* Set RTC frequency */ |
141 | static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
133 | { | 142 | { |
134 | struct platform_device *pdev = to_platform_device(dev); | ||
135 | struct rtc_device *rtc_dev = platform_get_drvdata(pdev); | ||
136 | unsigned int tmp = 0; | ||
137 | int val; | ||
138 | |||
139 | if (!is_power_of_2(freq)) | 143 | if (!is_power_of_2(freq)) |
140 | return -EINVAL; | 144 | return -EINVAL; |
141 | 145 | ||
142 | clk_enable(rtc_clk); | 146 | clk_enable(info->rtc_clk); |
143 | spin_lock_irq(&s3c_rtc_pie_lock); | 147 | if (info->data->needs_src_clk) |
148 | clk_enable(info->rtc_src_clk); | ||
149 | spin_lock_irq(&info->pie_lock); | ||
144 | 150 | ||
145 | if (s3c_rtc_cpu_type != TYPE_S3C64XX) { | 151 | if (info->data->set_freq) |
146 | tmp = readb(s3c_rtc_base + S3C2410_TICNT); | 152 | info->data->set_freq(info, freq); |
147 | tmp &= S3C2410_TICNT_ENABLE; | ||
148 | } | ||
149 | 153 | ||
150 | val = (rtc_dev->max_user_freq / freq) - 1; | 154 | spin_unlock_irq(&info->pie_lock); |
151 | 155 | if (info->data->needs_src_clk) | |
152 | if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { | 156 | clk_disable(info->rtc_src_clk); |
153 | tmp |= S3C2443_TICNT_PART(val); | 157 | clk_disable(info->rtc_clk); |
154 | writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1); | ||
155 | |||
156 | if (s3c_rtc_cpu_type == TYPE_S3C2416) | ||
157 | writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2); | ||
158 | } else { | ||
159 | tmp |= val; | ||
160 | } | ||
161 | |||
162 | writel(tmp, s3c_rtc_base + S3C2410_TICNT); | ||
163 | spin_unlock_irq(&s3c_rtc_pie_lock); | ||
164 | clk_disable(rtc_clk); | ||
165 | 158 | ||
166 | return 0; | 159 | return 0; |
167 | } | 160 | } |
168 | 161 | ||
169 | /* Time read/write */ | 162 | /* Time read/write */ |
170 | |||
171 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | 163 | static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) |
172 | { | 164 | { |
165 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
173 | unsigned int have_retried = 0; | 166 | unsigned int have_retried = 0; |
174 | void __iomem *base = s3c_rtc_base; | ||
175 | 167 | ||
176 | clk_enable(rtc_clk); | 168 | clk_enable(info->rtc_clk); |
169 | if (info->data->needs_src_clk) | ||
170 | clk_enable(info->rtc_src_clk); | ||
171 | |||
177 | retry_get_time: | 172 | retry_get_time: |
178 | rtc_tm->tm_min = readb(base + S3C2410_RTCMIN); | 173 | rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN); |
179 | rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR); | 174 | rtc_tm->tm_hour = readb(info->base + S3C2410_RTCHOUR); |
180 | rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE); | 175 | rtc_tm->tm_mday = readb(info->base + S3C2410_RTCDATE); |
181 | rtc_tm->tm_mon = readb(base + S3C2410_RTCMON); | 176 | rtc_tm->tm_mon = readb(info->base + S3C2410_RTCMON); |
182 | rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR); | 177 | rtc_tm->tm_year = readb(info->base + S3C2410_RTCYEAR); |
183 | rtc_tm->tm_sec = readb(base + S3C2410_RTCSEC); | 178 | rtc_tm->tm_sec = readb(info->base + S3C2410_RTCSEC); |
184 | 179 | ||
185 | /* the only way to work out whether the system was mid-update | 180 | /* the only way to work out whether the system was mid-update |
186 | * when we read it is to check the second counter, and if it | 181 | * when we read it is to check the second counter, and if it |
@@ -207,13 +202,16 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
207 | 202 | ||
208 | rtc_tm->tm_mon -= 1; | 203 | rtc_tm->tm_mon -= 1; |
209 | 204 | ||
210 | clk_disable(rtc_clk); | 205 | if (info->data->needs_src_clk) |
206 | clk_disable(info->rtc_src_clk); | ||
207 | clk_disable(info->rtc_clk); | ||
208 | |||
211 | return rtc_valid_tm(rtc_tm); | 209 | return rtc_valid_tm(rtc_tm); |
212 | } | 210 | } |
213 | 211 | ||
214 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | 212 | static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) |
215 | { | 213 | { |
216 | void __iomem *base = s3c_rtc_base; | 214 | struct s3c_rtc *info = dev_get_drvdata(dev); |
217 | int year = tm->tm_year - 100; | 215 | int year = tm->tm_year - 100; |
218 | 216 | ||
219 | dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", | 217 | dev_dbg(dev, "set time %04d.%02d.%02d %02d:%02d:%02d\n", |
@@ -227,33 +225,42 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
227 | return -EINVAL; | 225 | return -EINVAL; |
228 | } | 226 | } |
229 | 227 | ||
230 | clk_enable(rtc_clk); | 228 | clk_enable(info->rtc_clk); |
231 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); | 229 | if (info->data->needs_src_clk) |
232 | writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); | 230 | clk_enable(info->rtc_src_clk); |
233 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); | 231 | |
234 | writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); | 232 | writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC); |
235 | writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); | 233 | writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN); |
236 | writeb(bin2bcd(year), base + S3C2410_RTCYEAR); | 234 | writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR); |
237 | clk_disable(rtc_clk); | 235 | writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE); |
236 | writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON); | ||
237 | writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR); | ||
238 | |||
239 | if (info->data->needs_src_clk) | ||
240 | clk_disable(info->rtc_src_clk); | ||
241 | clk_disable(info->rtc_clk); | ||
238 | 242 | ||
239 | return 0; | 243 | return 0; |
240 | } | 244 | } |
241 | 245 | ||
242 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | 246 | static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) |
243 | { | 247 | { |
248 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
244 | struct rtc_time *alm_tm = &alrm->time; | 249 | struct rtc_time *alm_tm = &alrm->time; |
245 | void __iomem *base = s3c_rtc_base; | ||
246 | unsigned int alm_en; | 250 | unsigned int alm_en; |
247 | 251 | ||
248 | clk_enable(rtc_clk); | 252 | clk_enable(info->rtc_clk); |
249 | alm_tm->tm_sec = readb(base + S3C2410_ALMSEC); | 253 | if (info->data->needs_src_clk) |
250 | alm_tm->tm_min = readb(base + S3C2410_ALMMIN); | 254 | clk_enable(info->rtc_src_clk); |
251 | alm_tm->tm_hour = readb(base + S3C2410_ALMHOUR); | ||
252 | alm_tm->tm_mon = readb(base + S3C2410_ALMMON); | ||
253 | alm_tm->tm_mday = readb(base + S3C2410_ALMDATE); | ||
254 | alm_tm->tm_year = readb(base + S3C2410_ALMYEAR); | ||
255 | 255 | ||
256 | alm_en = readb(base + S3C2410_RTCALM); | 256 | alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC); |
257 | alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN); | ||
258 | alm_tm->tm_hour = readb(info->base + S3C2410_ALMHOUR); | ||
259 | alm_tm->tm_mon = readb(info->base + S3C2410_ALMMON); | ||
260 | alm_tm->tm_mday = readb(info->base + S3C2410_ALMDATE); | ||
261 | alm_tm->tm_year = readb(info->base + S3C2410_ALMYEAR); | ||
262 | |||
263 | alm_en = readb(info->base + S3C2410_RTCALM); | ||
257 | 264 | ||
258 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; | 265 | alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; |
259 | 266 | ||
@@ -297,65 +304,74 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
297 | else | 304 | else |
298 | alm_tm->tm_year = -1; | 305 | alm_tm->tm_year = -1; |
299 | 306 | ||
300 | clk_disable(rtc_clk); | 307 | if (info->data->needs_src_clk) |
308 | clk_disable(info->rtc_src_clk); | ||
309 | clk_disable(info->rtc_clk); | ||
310 | |||
301 | return 0; | 311 | return 0; |
302 | } | 312 | } |
303 | 313 | ||
304 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | 314 | static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) |
305 | { | 315 | { |
316 | struct s3c_rtc *info = dev_get_drvdata(dev); | ||
306 | struct rtc_time *tm = &alrm->time; | 317 | struct rtc_time *tm = &alrm->time; |
307 | void __iomem *base = s3c_rtc_base; | ||
308 | unsigned int alrm_en; | 318 | unsigned int alrm_en; |
309 | 319 | ||
310 | clk_enable(rtc_clk); | 320 | clk_enable(info->rtc_clk); |
321 | if (info->data->needs_src_clk) | ||
322 | clk_enable(info->rtc_src_clk); | ||
323 | |||
311 | dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", | 324 | dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", |
312 | alrm->enabled, | 325 | alrm->enabled, |
313 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, | 326 | 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, |
314 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 327 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
315 | 328 | ||
316 | alrm_en = readb(base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; | 329 | alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; |
317 | writeb(0x00, base + S3C2410_RTCALM); | 330 | writeb(0x00, info->base + S3C2410_RTCALM); |
318 | 331 | ||
319 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { | 332 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { |
320 | alrm_en |= S3C2410_RTCALM_SECEN; | 333 | alrm_en |= S3C2410_RTCALM_SECEN; |
321 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC); | 334 | writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_ALMSEC); |
322 | } | 335 | } |
323 | 336 | ||
324 | if (tm->tm_min < 60 && tm->tm_min >= 0) { | 337 | if (tm->tm_min < 60 && tm->tm_min >= 0) { |
325 | alrm_en |= S3C2410_RTCALM_MINEN; | 338 | alrm_en |= S3C2410_RTCALM_MINEN; |
326 | writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN); | 339 | writeb(bin2bcd(tm->tm_min), info->base + S3C2410_ALMMIN); |
327 | } | 340 | } |
328 | 341 | ||
329 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { | 342 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { |
330 | alrm_en |= S3C2410_RTCALM_HOUREN; | 343 | alrm_en |= S3C2410_RTCALM_HOUREN; |
331 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); | 344 | writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_ALMHOUR); |
332 | } | 345 | } |
333 | 346 | ||
334 | dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); | 347 | dev_dbg(dev, "setting S3C2410_RTCALM to %08x\n", alrm_en); |
335 | 348 | ||
336 | writeb(alrm_en, base + S3C2410_RTCALM); | 349 | writeb(alrm_en, info->base + S3C2410_RTCALM); |
337 | 350 | ||
338 | s3c_rtc_setaie(dev, alrm->enabled); | 351 | s3c_rtc_setaie(dev, alrm->enabled); |
339 | 352 | ||
340 | clk_disable(rtc_clk); | 353 | if (info->data->needs_src_clk) |
354 | clk_disable(info->rtc_src_clk); | ||
355 | clk_disable(info->rtc_clk); | ||
356 | |||
341 | return 0; | 357 | return 0; |
342 | } | 358 | } |
343 | 359 | ||
344 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) | 360 | static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) |
345 | { | 361 | { |
346 | unsigned int ticnt; | 362 | struct s3c_rtc *info = dev_get_drvdata(dev); |
347 | 363 | ||
348 | clk_enable(rtc_clk); | 364 | clk_enable(info->rtc_clk); |
349 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 365 | if (info->data->needs_src_clk) |
350 | ticnt = readw(s3c_rtc_base + S3C2410_RTCCON); | 366 | clk_enable(info->rtc_src_clk); |
351 | ticnt &= S3C64XX_RTCCON_TICEN; | 367 | |
352 | } else { | 368 | if (info->data->enable_tick) |
353 | ticnt = readb(s3c_rtc_base + S3C2410_TICNT); | 369 | info->data->enable_tick(info, seq); |
354 | ticnt &= S3C2410_TICNT_ENABLE; | 370 | |
355 | } | 371 | if (info->data->needs_src_clk) |
372 | clk_disable(info->rtc_src_clk); | ||
373 | clk_disable(info->rtc_clk); | ||
356 | 374 | ||
357 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | ||
358 | clk_disable(rtc_clk); | ||
359 | return 0; | 375 | return 0; |
360 | } | 376 | } |
361 | 377 | ||
@@ -368,152 +384,199 @@ static const struct rtc_class_ops s3c_rtcops = { | |||
368 | .alarm_irq_enable = s3c_rtc_setaie, | 384 | .alarm_irq_enable = s3c_rtc_setaie, |
369 | }; | 385 | }; |
370 | 386 | ||
371 | static void s3c_rtc_enable(struct platform_device *pdev, int en) | 387 | static void s3c24xx_rtc_enable(struct s3c_rtc *info) |
372 | { | 388 | { |
373 | void __iomem *base = s3c_rtc_base; | 389 | unsigned int con, tmp; |
374 | unsigned int tmp; | ||
375 | 390 | ||
376 | if (s3c_rtc_base == NULL) | 391 | clk_enable(info->rtc_clk); |
377 | return; | 392 | if (info->data->needs_src_clk) |
378 | 393 | clk_enable(info->rtc_src_clk); | |
379 | clk_enable(rtc_clk); | ||
380 | if (!en) { | ||
381 | tmp = readw(base + S3C2410_RTCCON); | ||
382 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) | ||
383 | tmp &= ~S3C64XX_RTCCON_TICEN; | ||
384 | tmp &= ~S3C2410_RTCCON_RTCEN; | ||
385 | writew(tmp, base + S3C2410_RTCCON); | ||
386 | |||
387 | if (s3c_rtc_cpu_type != TYPE_S3C64XX) { | ||
388 | tmp = readb(base + S3C2410_TICNT); | ||
389 | tmp &= ~S3C2410_TICNT_ENABLE; | ||
390 | writeb(tmp, base + S3C2410_TICNT); | ||
391 | } | ||
392 | } else { | ||
393 | /* re-enable the device, and check it is ok */ | ||
394 | 394 | ||
395 | if ((readw(base+S3C2410_RTCCON) & S3C2410_RTCCON_RTCEN) == 0) { | 395 | con = readw(info->base + S3C2410_RTCCON); |
396 | dev_info(&pdev->dev, "rtc disabled, re-enabling\n"); | 396 | /* re-enable the device, and check it is ok */ |
397 | if ((con & S3C2410_RTCCON_RTCEN) == 0) { | ||
398 | dev_info(info->dev, "rtc disabled, re-enabling\n"); | ||
397 | 399 | ||
398 | tmp = readw(base + S3C2410_RTCCON); | 400 | tmp = readw(info->base + S3C2410_RTCCON); |
399 | writew(tmp | S3C2410_RTCCON_RTCEN, | 401 | writew(tmp | S3C2410_RTCCON_RTCEN, |
400 | base + S3C2410_RTCCON); | 402 | info->base + S3C2410_RTCCON); |
401 | } | 403 | } |
402 | 404 | ||
403 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CNTSEL)) { | 405 | if (con & S3C2410_RTCCON_CNTSEL) { |
404 | dev_info(&pdev->dev, "removing RTCCON_CNTSEL\n"); | 406 | dev_info(info->dev, "removing RTCCON_CNTSEL\n"); |
405 | 407 | ||
406 | tmp = readw(base + S3C2410_RTCCON); | 408 | tmp = readw(info->base + S3C2410_RTCCON); |
407 | writew(tmp & ~S3C2410_RTCCON_CNTSEL, | 409 | writew(tmp & ~S3C2410_RTCCON_CNTSEL, |
408 | base + S3C2410_RTCCON); | 410 | info->base + S3C2410_RTCCON); |
409 | } | 411 | } |
410 | 412 | ||
411 | if ((readw(base + S3C2410_RTCCON) & S3C2410_RTCCON_CLKRST)) { | 413 | if (con & S3C2410_RTCCON_CLKRST) { |
412 | dev_info(&pdev->dev, "removing RTCCON_CLKRST\n"); | 414 | dev_info(info->dev, "removing RTCCON_CLKRST\n"); |
413 | 415 | ||
414 | tmp = readw(base + S3C2410_RTCCON); | 416 | tmp = readw(info->base + S3C2410_RTCCON); |
415 | writew(tmp & ~S3C2410_RTCCON_CLKRST, | 417 | writew(tmp & ~S3C2410_RTCCON_CLKRST, |
416 | base + S3C2410_RTCCON); | 418 | info->base + S3C2410_RTCCON); |
417 | } | ||
418 | } | 419 | } |
419 | clk_disable(rtc_clk); | 420 | |
421 | if (info->data->needs_src_clk) | ||
422 | clk_disable(info->rtc_src_clk); | ||
423 | clk_disable(info->rtc_clk); | ||
420 | } | 424 | } |
421 | 425 | ||
422 | static int s3c_rtc_remove(struct platform_device *dev) | 426 | static void s3c24xx_rtc_disable(struct s3c_rtc *info) |
423 | { | 427 | { |
424 | s3c_rtc_setaie(&dev->dev, 0); | 428 | unsigned int con; |
429 | |||
430 | clk_enable(info->rtc_clk); | ||
431 | if (info->data->needs_src_clk) | ||
432 | clk_enable(info->rtc_src_clk); | ||
433 | |||
434 | con = readw(info->base + S3C2410_RTCCON); | ||
435 | con &= ~S3C2410_RTCCON_RTCEN; | ||
436 | writew(con, info->base + S3C2410_RTCCON); | ||
425 | 437 | ||
426 | clk_unprepare(rtc_clk); | 438 | con = readb(info->base + S3C2410_TICNT); |
427 | rtc_clk = NULL; | 439 | con &= ~S3C2410_TICNT_ENABLE; |
440 | writeb(con, info->base + S3C2410_TICNT); | ||
441 | |||
442 | if (info->data->needs_src_clk) | ||
443 | clk_disable(info->rtc_src_clk); | ||
444 | clk_disable(info->rtc_clk); | ||
445 | } | ||
446 | |||
447 | static void s3c6410_rtc_disable(struct s3c_rtc *info) | ||
448 | { | ||
449 | unsigned int con; | ||
450 | |||
451 | clk_enable(info->rtc_clk); | ||
452 | if (info->data->needs_src_clk) | ||
453 | clk_enable(info->rtc_src_clk); | ||
454 | |||
455 | con = readw(info->base + S3C2410_RTCCON); | ||
456 | con &= ~S3C64XX_RTCCON_TICEN; | ||
457 | con &= ~S3C2410_RTCCON_RTCEN; | ||
458 | writew(con, info->base + S3C2410_RTCCON); | ||
459 | |||
460 | if (info->data->needs_src_clk) | ||
461 | clk_disable(info->rtc_src_clk); | ||
462 | clk_disable(info->rtc_clk); | ||
463 | } | ||
464 | |||
465 | static int s3c_rtc_remove(struct platform_device *pdev) | ||
466 | { | ||
467 | struct s3c_rtc *info = platform_get_drvdata(pdev); | ||
468 | |||
469 | s3c_rtc_setaie(info->dev, 0); | ||
470 | |||
471 | clk_unprepare(info->rtc_clk); | ||
472 | info->rtc_clk = NULL; | ||
428 | 473 | ||
429 | return 0; | 474 | return 0; |
430 | } | 475 | } |
431 | 476 | ||
432 | static const struct of_device_id s3c_rtc_dt_match[]; | 477 | static const struct of_device_id s3c_rtc_dt_match[]; |
433 | 478 | ||
434 | static inline int s3c_rtc_get_driver_data(struct platform_device *pdev) | 479 | static struct s3c_rtc_data *s3c_rtc_get_data(struct platform_device *pdev) |
435 | { | 480 | { |
436 | #ifdef CONFIG_OF | 481 | const struct of_device_id *match; |
437 | struct s3c_rtc_drv_data *data; | 482 | |
438 | if (pdev->dev.of_node) { | 483 | match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); |
439 | const struct of_device_id *match; | 484 | return (struct s3c_rtc_data *)match->data; |
440 | match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); | ||
441 | data = (struct s3c_rtc_drv_data *) match->data; | ||
442 | return data->cpu_type; | ||
443 | } | ||
444 | #endif | ||
445 | return platform_get_device_id(pdev)->driver_data; | ||
446 | } | 485 | } |
447 | 486 | ||
448 | static int s3c_rtc_probe(struct platform_device *pdev) | 487 | static int s3c_rtc_probe(struct platform_device *pdev) |
449 | { | 488 | { |
450 | struct rtc_device *rtc; | 489 | struct s3c_rtc *info = NULL; |
451 | struct rtc_time rtc_tm; | 490 | struct rtc_time rtc_tm; |
452 | struct resource *res; | 491 | struct resource *res; |
453 | int ret; | 492 | int ret; |
454 | int tmp; | ||
455 | 493 | ||
456 | dev_dbg(&pdev->dev, "%s: probe=%p\n", __func__, pdev); | 494 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
495 | if (!info) | ||
496 | return -ENOMEM; | ||
457 | 497 | ||
458 | /* find the IRQs */ | 498 | /* find the IRQs */ |
459 | 499 | info->irq_tick = platform_get_irq(pdev, 1); | |
460 | s3c_rtc_tickno = platform_get_irq(pdev, 1); | 500 | if (info->irq_tick < 0) { |
461 | if (s3c_rtc_tickno < 0) { | ||
462 | dev_err(&pdev->dev, "no irq for rtc tick\n"); | 501 | dev_err(&pdev->dev, "no irq for rtc tick\n"); |
463 | return s3c_rtc_tickno; | 502 | return info->irq_tick; |
503 | } | ||
504 | |||
505 | info->dev = &pdev->dev; | ||
506 | info->data = s3c_rtc_get_data(pdev); | ||
507 | if (!info->data) { | ||
508 | dev_err(&pdev->dev, "failed getting s3c_rtc_data\n"); | ||
509 | return -EINVAL; | ||
464 | } | 510 | } |
511 | spin_lock_init(&info->pie_lock); | ||
512 | spin_lock_init(&info->alarm_clk_lock); | ||
513 | |||
514 | platform_set_drvdata(pdev, info); | ||
465 | 515 | ||
466 | s3c_rtc_alarmno = platform_get_irq(pdev, 0); | 516 | info->irq_alarm = platform_get_irq(pdev, 0); |
467 | if (s3c_rtc_alarmno < 0) { | 517 | if (info->irq_alarm < 0) { |
468 | dev_err(&pdev->dev, "no irq for alarm\n"); | 518 | dev_err(&pdev->dev, "no irq for alarm\n"); |
469 | return s3c_rtc_alarmno; | 519 | return info->irq_alarm; |
470 | } | 520 | } |
471 | 521 | ||
472 | dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", | 522 | dev_dbg(&pdev->dev, "s3c2410_rtc: tick irq %d, alarm irq %d\n", |
473 | s3c_rtc_tickno, s3c_rtc_alarmno); | 523 | info->irq_tick, info->irq_alarm); |
474 | 524 | ||
475 | /* get the memory region */ | 525 | /* get the memory region */ |
476 | |||
477 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 526 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
478 | s3c_rtc_base = devm_ioremap_resource(&pdev->dev, res); | 527 | info->base = devm_ioremap_resource(&pdev->dev, res); |
479 | if (IS_ERR(s3c_rtc_base)) | 528 | if (IS_ERR(info->base)) |
480 | return PTR_ERR(s3c_rtc_base); | 529 | return PTR_ERR(info->base); |
481 | 530 | ||
482 | rtc_clk = devm_clk_get(&pdev->dev, "rtc"); | 531 | info->rtc_clk = devm_clk_get(&pdev->dev, "rtc"); |
483 | if (IS_ERR(rtc_clk)) { | 532 | if (IS_ERR(info->rtc_clk)) { |
484 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); | 533 | dev_err(&pdev->dev, "failed to find rtc clock\n"); |
485 | ret = PTR_ERR(rtc_clk); | 534 | return PTR_ERR(info->rtc_clk); |
486 | rtc_clk = NULL; | ||
487 | return ret; | ||
488 | } | 535 | } |
536 | clk_prepare_enable(info->rtc_clk); | ||
489 | 537 | ||
490 | clk_prepare_enable(rtc_clk); | 538 | info->rtc_src_clk = devm_clk_get(&pdev->dev, "rtc_src"); |
539 | if (IS_ERR(info->rtc_src_clk)) { | ||
540 | dev_err(&pdev->dev, "failed to find rtc source clock\n"); | ||
541 | return PTR_ERR(info->rtc_src_clk); | ||
542 | } | ||
543 | clk_prepare_enable(info->rtc_src_clk); | ||
491 | 544 | ||
492 | /* check to see if everything is setup correctly */ | ||
493 | 545 | ||
494 | s3c_rtc_enable(pdev, 1); | 546 | /* check to see if everything is setup correctly */ |
547 | if (info->data->enable) | ||
548 | info->data->enable(info); | ||
495 | 549 | ||
496 | dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", | 550 | dev_dbg(&pdev->dev, "s3c2410_rtc: RTCCON=%02x\n", |
497 | readw(s3c_rtc_base + S3C2410_RTCCON)); | 551 | readw(info->base + S3C2410_RTCCON)); |
498 | 552 | ||
499 | device_init_wakeup(&pdev->dev, 1); | 553 | device_init_wakeup(&pdev->dev, 1); |
500 | 554 | ||
501 | /* register RTC and exit */ | 555 | /* register RTC and exit */ |
502 | 556 | info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, | |
503 | rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, | ||
504 | THIS_MODULE); | 557 | THIS_MODULE); |
505 | 558 | if (IS_ERR(info->rtc)) { | |
506 | if (IS_ERR(rtc)) { | ||
507 | dev_err(&pdev->dev, "cannot attach rtc\n"); | 559 | dev_err(&pdev->dev, "cannot attach rtc\n"); |
508 | ret = PTR_ERR(rtc); | 560 | ret = PTR_ERR(info->rtc); |
509 | goto err_nortc; | 561 | goto err_nortc; |
510 | } | 562 | } |
511 | 563 | ||
512 | s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev); | 564 | ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq, |
565 | 0, "s3c2410-rtc alarm", info); | ||
566 | if (ret) { | ||
567 | dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_alarm, ret); | ||
568 | goto err_nortc; | ||
569 | } | ||
513 | 570 | ||
514 | /* Check RTC Time */ | 571 | ret = devm_request_irq(&pdev->dev, info->irq_tick, s3c_rtc_tickirq, |
572 | 0, "s3c2410-rtc tick", info); | ||
573 | if (ret) { | ||
574 | dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq_tick, ret); | ||
575 | goto err_nortc; | ||
576 | } | ||
515 | 577 | ||
516 | s3c_rtc_gettime(NULL, &rtc_tm); | 578 | /* Check RTC Time */ |
579 | s3c_rtc_gettime(&pdev->dev, &rtc_tm); | ||
517 | 580 | ||
518 | if (rtc_valid_tm(&rtc_tm)) { | 581 | if (rtc_valid_tm(&rtc_tm)) { |
519 | rtc_tm.tm_year = 100; | 582 | rtc_tm.tm_year = 100; |
@@ -523,163 +586,312 @@ static int s3c_rtc_probe(struct platform_device *pdev) | |||
523 | rtc_tm.tm_min = 0; | 586 | rtc_tm.tm_min = 0; |
524 | rtc_tm.tm_sec = 0; | 587 | rtc_tm.tm_sec = 0; |
525 | 588 | ||
526 | s3c_rtc_settime(NULL, &rtc_tm); | 589 | s3c_rtc_settime(&pdev->dev, &rtc_tm); |
527 | 590 | ||
528 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); | 591 | dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); |
529 | } | 592 | } |
530 | 593 | ||
531 | if (s3c_rtc_cpu_type != TYPE_S3C2410) | 594 | if (info->data->select_tick_clk) |
532 | rtc->max_user_freq = 32768; | 595 | info->data->select_tick_clk(info); |
533 | else | ||
534 | rtc->max_user_freq = 128; | ||
535 | |||
536 | if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) { | ||
537 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); | ||
538 | tmp |= S3C2443_RTCCON_TICSEL; | ||
539 | writew(tmp, s3c_rtc_base + S3C2410_RTCCON); | ||
540 | } | ||
541 | 596 | ||
542 | platform_set_drvdata(pdev, rtc); | 597 | s3c_rtc_setfreq(info, 1); |
543 | 598 | ||
544 | s3c_rtc_setfreq(&pdev->dev, 1); | 599 | if (info->data->needs_src_clk) |
545 | 600 | clk_disable(info->rtc_src_clk); | |
546 | ret = devm_request_irq(&pdev->dev, s3c_rtc_alarmno, s3c_rtc_alarmirq, | 601 | clk_disable(info->rtc_clk); |
547 | 0, "s3c2410-rtc alarm", rtc); | ||
548 | if (ret) { | ||
549 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret); | ||
550 | goto err_nortc; | ||
551 | } | ||
552 | |||
553 | ret = devm_request_irq(&pdev->dev, s3c_rtc_tickno, s3c_rtc_tickirq, | ||
554 | 0, "s3c2410-rtc tick", rtc); | ||
555 | if (ret) { | ||
556 | dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret); | ||
557 | goto err_nortc; | ||
558 | } | ||
559 | |||
560 | clk_disable(rtc_clk); | ||
561 | 602 | ||
562 | return 0; | 603 | return 0; |
563 | 604 | ||
564 | err_nortc: | 605 | err_nortc: |
565 | s3c_rtc_enable(pdev, 0); | 606 | if (info->data->disable) |
566 | clk_disable_unprepare(rtc_clk); | 607 | info->data->disable(info); |
608 | clk_disable_unprepare(info->rtc_clk); | ||
567 | 609 | ||
568 | return ret; | 610 | return ret; |
569 | } | 611 | } |
570 | 612 | ||
571 | #ifdef CONFIG_PM_SLEEP | 613 | #ifdef CONFIG_PM_SLEEP |
572 | /* RTC Power management control */ | ||
573 | |||
574 | static int ticnt_save, ticnt_en_save; | ||
575 | static bool wake_en; | ||
576 | 614 | ||
577 | static int s3c_rtc_suspend(struct device *dev) | 615 | static int s3c_rtc_suspend(struct device *dev) |
578 | { | 616 | { |
579 | struct platform_device *pdev = to_platform_device(dev); | 617 | struct s3c_rtc *info = dev_get_drvdata(dev); |
618 | |||
619 | clk_enable(info->rtc_clk); | ||
620 | if (info->data->needs_src_clk) | ||
621 | clk_enable(info->rtc_src_clk); | ||
580 | 622 | ||
581 | clk_enable(rtc_clk); | ||
582 | /* save TICNT for anyone using periodic interrupts */ | 623 | /* save TICNT for anyone using periodic interrupts */ |
583 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 624 | if (info->data->save_tick_cnt) |
584 | ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); | 625 | info->data->save_tick_cnt(info); |
585 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | 626 | |
586 | ticnt_save = readl(s3c_rtc_base + S3C2410_TICNT); | 627 | if (info->data->disable) |
587 | } else { | 628 | info->data->disable(info); |
588 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | ||
589 | } | ||
590 | s3c_rtc_enable(pdev, 0); | ||
591 | 629 | ||
592 | if (device_may_wakeup(dev) && !wake_en) { | 630 | if (device_may_wakeup(dev) && !info->wake_en) { |
593 | if (enable_irq_wake(s3c_rtc_alarmno) == 0) | 631 | if (enable_irq_wake(info->irq_alarm) == 0) |
594 | wake_en = true; | 632 | info->wake_en = true; |
595 | else | 633 | else |
596 | dev_err(dev, "enable_irq_wake failed\n"); | 634 | dev_err(dev, "enable_irq_wake failed\n"); |
597 | } | 635 | } |
598 | clk_disable(rtc_clk); | 636 | |
637 | if (info->data->needs_src_clk) | ||
638 | clk_disable(info->rtc_src_clk); | ||
639 | clk_disable(info->rtc_clk); | ||
599 | 640 | ||
600 | return 0; | 641 | return 0; |
601 | } | 642 | } |
602 | 643 | ||
603 | static int s3c_rtc_resume(struct device *dev) | 644 | static int s3c_rtc_resume(struct device *dev) |
604 | { | 645 | { |
605 | struct platform_device *pdev = to_platform_device(dev); | 646 | struct s3c_rtc *info = dev_get_drvdata(dev); |
606 | unsigned int tmp; | ||
607 | 647 | ||
608 | clk_enable(rtc_clk); | 648 | clk_enable(info->rtc_clk); |
609 | s3c_rtc_enable(pdev, 1); | 649 | if (info->data->needs_src_clk) |
610 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 650 | clk_enable(info->rtc_src_clk); |
611 | writel(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | ||
612 | if (ticnt_en_save) { | ||
613 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); | ||
614 | writew(tmp | ticnt_en_save, | ||
615 | s3c_rtc_base + S3C2410_RTCCON); | ||
616 | } | ||
617 | } else { | ||
618 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | ||
619 | } | ||
620 | 651 | ||
621 | if (device_may_wakeup(dev) && wake_en) { | 652 | if (info->data->enable) |
622 | disable_irq_wake(s3c_rtc_alarmno); | 653 | info->data->enable(info); |
623 | wake_en = false; | 654 | |
655 | if (info->data->restore_tick_cnt) | ||
656 | info->data->restore_tick_cnt(info); | ||
657 | |||
658 | if (device_may_wakeup(dev) && info->wake_en) { | ||
659 | disable_irq_wake(info->irq_alarm); | ||
660 | info->wake_en = false; | ||
624 | } | 661 | } |
625 | clk_disable(rtc_clk); | 662 | |
663 | if (info->data->needs_src_clk) | ||
664 | clk_disable(info->rtc_src_clk); | ||
665 | clk_disable(info->rtc_clk); | ||
626 | 666 | ||
627 | return 0; | 667 | return 0; |
628 | } | 668 | } |
629 | #endif | 669 | #endif |
630 | |||
631 | static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); | 670 | static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); |
632 | 671 | ||
633 | #ifdef CONFIG_OF | 672 | static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) |
634 | static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { | 673 | { |
635 | [TYPE_S3C2410] = { TYPE_S3C2410 }, | 674 | clk_enable(info->rtc_clk); |
636 | [TYPE_S3C2416] = { TYPE_S3C2416 }, | 675 | if (info->data->needs_src_clk) |
637 | [TYPE_S3C2443] = { TYPE_S3C2443 }, | 676 | clk_enable(info->rtc_src_clk); |
638 | [TYPE_S3C64XX] = { TYPE_S3C64XX }, | 677 | rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); |
678 | if (info->data->needs_src_clk) | ||
679 | clk_disable(info->rtc_src_clk); | ||
680 | clk_disable(info->rtc_clk); | ||
681 | |||
682 | s3c_rtc_alarm_clk_enable(info, false); | ||
683 | } | ||
684 | |||
685 | static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) | ||
686 | { | ||
687 | clk_enable(info->rtc_clk); | ||
688 | if (info->data->needs_src_clk) | ||
689 | clk_enable(info->rtc_src_clk); | ||
690 | rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); | ||
691 | writeb(mask, info->base + S3C2410_INTP); | ||
692 | if (info->data->needs_src_clk) | ||
693 | clk_disable(info->rtc_src_clk); | ||
694 | clk_disable(info->rtc_clk); | ||
695 | |||
696 | s3c_rtc_alarm_clk_enable(info, false); | ||
697 | } | ||
698 | |||
699 | static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
700 | { | ||
701 | unsigned int tmp = 0; | ||
702 | int val; | ||
703 | |||
704 | tmp = readb(info->base + S3C2410_TICNT); | ||
705 | tmp &= S3C2410_TICNT_ENABLE; | ||
706 | |||
707 | val = (info->rtc->max_user_freq / freq) - 1; | ||
708 | tmp |= val; | ||
709 | |||
710 | writel(tmp, info->base + S3C2410_TICNT); | ||
711 | } | ||
712 | |||
713 | static void s3c2416_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
714 | { | ||
715 | unsigned int tmp = 0; | ||
716 | int val; | ||
717 | |||
718 | tmp = readb(info->base + S3C2410_TICNT); | ||
719 | tmp &= S3C2410_TICNT_ENABLE; | ||
720 | |||
721 | val = (info->rtc->max_user_freq / freq) - 1; | ||
722 | |||
723 | tmp |= S3C2443_TICNT_PART(val); | ||
724 | writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); | ||
725 | |||
726 | writel(S3C2416_TICNT2_PART(val), info->base + S3C2416_TICNT2); | ||
727 | |||
728 | writel(tmp, info->base + S3C2410_TICNT); | ||
729 | } | ||
730 | |||
731 | static void s3c2443_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
732 | { | ||
733 | unsigned int tmp = 0; | ||
734 | int val; | ||
735 | |||
736 | tmp = readb(info->base + S3C2410_TICNT); | ||
737 | tmp &= S3C2410_TICNT_ENABLE; | ||
738 | |||
739 | val = (info->rtc->max_user_freq / freq) - 1; | ||
740 | |||
741 | tmp |= S3C2443_TICNT_PART(val); | ||
742 | writel(S3C2443_TICNT1_PART(val), info->base + S3C2443_TICNT1); | ||
743 | |||
744 | writel(tmp, info->base + S3C2410_TICNT); | ||
745 | } | ||
746 | |||
747 | static void s3c6410_rtc_setfreq(struct s3c_rtc *info, int freq) | ||
748 | { | ||
749 | int val; | ||
750 | |||
751 | val = (info->rtc->max_user_freq / freq) - 1; | ||
752 | writel(val, info->base + S3C2410_TICNT); | ||
753 | } | ||
754 | |||
755 | static void s3c24xx_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) | ||
756 | { | ||
757 | unsigned int ticnt; | ||
758 | |||
759 | ticnt = readb(info->base + S3C2410_TICNT); | ||
760 | ticnt &= S3C2410_TICNT_ENABLE; | ||
761 | |||
762 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | ||
763 | } | ||
764 | |||
765 | static void s3c2416_rtc_select_tick_clk(struct s3c_rtc *info) | ||
766 | { | ||
767 | unsigned int con; | ||
768 | |||
769 | con = readw(info->base + S3C2410_RTCCON); | ||
770 | con |= S3C2443_RTCCON_TICSEL; | ||
771 | writew(con, info->base + S3C2410_RTCCON); | ||
772 | } | ||
773 | |||
774 | static void s3c6410_rtc_enable_tick(struct s3c_rtc *info, struct seq_file *seq) | ||
775 | { | ||
776 | unsigned int ticnt; | ||
777 | |||
778 | ticnt = readw(info->base + S3C2410_RTCCON); | ||
779 | ticnt &= S3C64XX_RTCCON_TICEN; | ||
780 | |||
781 | seq_printf(seq, "periodic_IRQ\t: %s\n", ticnt ? "yes" : "no"); | ||
782 | } | ||
783 | |||
784 | static void s3c24xx_rtc_save_tick_cnt(struct s3c_rtc *info) | ||
785 | { | ||
786 | info->ticnt_save = readb(info->base + S3C2410_TICNT); | ||
787 | } | ||
788 | |||
789 | static void s3c24xx_rtc_restore_tick_cnt(struct s3c_rtc *info) | ||
790 | { | ||
791 | writeb(info->ticnt_save, info->base + S3C2410_TICNT); | ||
792 | } | ||
793 | |||
794 | static void s3c6410_rtc_save_tick_cnt(struct s3c_rtc *info) | ||
795 | { | ||
796 | info->ticnt_en_save = readw(info->base + S3C2410_RTCCON); | ||
797 | info->ticnt_en_save &= S3C64XX_RTCCON_TICEN; | ||
798 | info->ticnt_save = readl(info->base + S3C2410_TICNT); | ||
799 | } | ||
800 | |||
801 | static void s3c6410_rtc_restore_tick_cnt(struct s3c_rtc *info) | ||
802 | { | ||
803 | unsigned int con; | ||
804 | |||
805 | writel(info->ticnt_save, info->base + S3C2410_TICNT); | ||
806 | if (info->ticnt_en_save) { | ||
807 | con = readw(info->base + S3C2410_RTCCON); | ||
808 | writew(con | info->ticnt_en_save, | ||
809 | info->base + S3C2410_RTCCON); | ||
810 | } | ||
811 | } | ||
812 | |||
813 | static struct s3c_rtc_data const s3c2410_rtc_data = { | ||
814 | .max_user_freq = 128, | ||
815 | .irq_handler = s3c24xx_rtc_irq, | ||
816 | .set_freq = s3c2410_rtc_setfreq, | ||
817 | .enable_tick = s3c24xx_rtc_enable_tick, | ||
818 | .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, | ||
819 | .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, | ||
820 | .enable = s3c24xx_rtc_enable, | ||
821 | .disable = s3c24xx_rtc_disable, | ||
822 | }; | ||
823 | |||
824 | static struct s3c_rtc_data const s3c2416_rtc_data = { | ||
825 | .max_user_freq = 32768, | ||
826 | .irq_handler = s3c24xx_rtc_irq, | ||
827 | .set_freq = s3c2416_rtc_setfreq, | ||
828 | .enable_tick = s3c24xx_rtc_enable_tick, | ||
829 | .select_tick_clk = s3c2416_rtc_select_tick_clk, | ||
830 | .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, | ||
831 | .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, | ||
832 | .enable = s3c24xx_rtc_enable, | ||
833 | .disable = s3c24xx_rtc_disable, | ||
834 | }; | ||
835 | |||
836 | static struct s3c_rtc_data const s3c2443_rtc_data = { | ||
837 | .max_user_freq = 32768, | ||
838 | .irq_handler = s3c24xx_rtc_irq, | ||
839 | .set_freq = s3c2443_rtc_setfreq, | ||
840 | .enable_tick = s3c24xx_rtc_enable_tick, | ||
841 | .select_tick_clk = s3c2416_rtc_select_tick_clk, | ||
842 | .save_tick_cnt = s3c24xx_rtc_save_tick_cnt, | ||
843 | .restore_tick_cnt = s3c24xx_rtc_restore_tick_cnt, | ||
844 | .enable = s3c24xx_rtc_enable, | ||
845 | .disable = s3c24xx_rtc_disable, | ||
846 | }; | ||
847 | |||
848 | static struct s3c_rtc_data const s3c6410_rtc_data = { | ||
849 | .max_user_freq = 32768, | ||
850 | .irq_handler = s3c6410_rtc_irq, | ||
851 | .set_freq = s3c6410_rtc_setfreq, | ||
852 | .enable_tick = s3c6410_rtc_enable_tick, | ||
853 | .save_tick_cnt = s3c6410_rtc_save_tick_cnt, | ||
854 | .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, | ||
855 | .enable = s3c24xx_rtc_enable, | ||
856 | .disable = s3c6410_rtc_disable, | ||
857 | }; | ||
858 | |||
859 | static struct s3c_rtc_data const exynos3250_rtc_data = { | ||
860 | .max_user_freq = 32768, | ||
861 | .needs_src_clk = true, | ||
862 | .irq_handler = s3c6410_rtc_irq, | ||
863 | .set_freq = s3c6410_rtc_setfreq, | ||
864 | .enable_tick = s3c6410_rtc_enable_tick, | ||
865 | .save_tick_cnt = s3c6410_rtc_save_tick_cnt, | ||
866 | .restore_tick_cnt = s3c6410_rtc_restore_tick_cnt, | ||
867 | .enable = s3c24xx_rtc_enable, | ||
868 | .disable = s3c6410_rtc_disable, | ||
639 | }; | 869 | }; |
640 | 870 | ||
641 | static const struct of_device_id s3c_rtc_dt_match[] = { | 871 | static const struct of_device_id s3c_rtc_dt_match[] = { |
642 | { | 872 | { |
643 | .compatible = "samsung,s3c2410-rtc", | 873 | .compatible = "samsung,s3c2410-rtc", |
644 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2410], | 874 | .data = (void *)&s3c2410_rtc_data, |
645 | }, { | 875 | }, { |
646 | .compatible = "samsung,s3c2416-rtc", | 876 | .compatible = "samsung,s3c2416-rtc", |
647 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2416], | 877 | .data = (void *)&s3c2416_rtc_data, |
648 | }, { | 878 | }, { |
649 | .compatible = "samsung,s3c2443-rtc", | 879 | .compatible = "samsung,s3c2443-rtc", |
650 | .data = &s3c_rtc_drv_data_array[TYPE_S3C2443], | 880 | .data = (void *)&s3c2443_rtc_data, |
651 | }, { | 881 | }, { |
652 | .compatible = "samsung,s3c6410-rtc", | 882 | .compatible = "samsung,s3c6410-rtc", |
653 | .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX], | 883 | .data = (void *)&s3c6410_rtc_data, |
654 | }, | ||
655 | {}, | ||
656 | }; | ||
657 | MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); | ||
658 | #endif | ||
659 | |||
660 | static struct platform_device_id s3c_rtc_driver_ids[] = { | ||
661 | { | ||
662 | .name = "s3c2410-rtc", | ||
663 | .driver_data = TYPE_S3C2410, | ||
664 | }, { | ||
665 | .name = "s3c2416-rtc", | ||
666 | .driver_data = TYPE_S3C2416, | ||
667 | }, { | ||
668 | .name = "s3c2443-rtc", | ||
669 | .driver_data = TYPE_S3C2443, | ||
670 | }, { | 884 | }, { |
671 | .name = "s3c64xx-rtc", | 885 | .compatible = "samsung,exynos3250-rtc", |
672 | .driver_data = TYPE_S3C64XX, | 886 | .data = (void *)&exynos3250_rtc_data, |
673 | }, | 887 | }, |
674 | { } | 888 | { /* sentinel */ }, |
675 | }; | 889 | }; |
676 | 890 | MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match); | |
677 | MODULE_DEVICE_TABLE(platform, s3c_rtc_driver_ids); | ||
678 | 891 | ||
679 | static struct platform_driver s3c_rtc_driver = { | 892 | static struct platform_driver s3c_rtc_driver = { |
680 | .probe = s3c_rtc_probe, | 893 | .probe = s3c_rtc_probe, |
681 | .remove = s3c_rtc_remove, | 894 | .remove = s3c_rtc_remove, |
682 | .id_table = s3c_rtc_driver_ids, | ||
683 | .driver = { | 895 | .driver = { |
684 | .name = "s3c-rtc", | 896 | .name = "s3c-rtc", |
685 | .owner = THIS_MODULE, | 897 | .owner = THIS_MODULE, |
@@ -687,7 +899,6 @@ static struct platform_driver s3c_rtc_driver = { | |||
687 | .of_match_table = of_match_ptr(s3c_rtc_dt_match), | 899 | .of_match_table = of_match_ptr(s3c_rtc_dt_match), |
688 | }, | 900 | }, |
689 | }; | 901 | }; |
690 | |||
691 | module_platform_driver(s3c_rtc_driver); | 902 | module_platform_driver(s3c_rtc_driver); |
692 | 903 | ||
693 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); | 904 | MODULE_DESCRIPTION("Samsung S3C RTC Driver"); |
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index d497aa05a72f..c692dfebd0ba 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c | |||
@@ -257,11 +257,11 @@ static ssize_t chp_status_write(struct device *dev, | |||
257 | if (!num_args) | 257 | if (!num_args) |
258 | return count; | 258 | return count; |
259 | 259 | ||
260 | if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) { | 260 | if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) { |
261 | mutex_lock(&cp->lock); | 261 | mutex_lock(&cp->lock); |
262 | error = s390_vary_chpid(cp->chpid, 1); | 262 | error = s390_vary_chpid(cp->chpid, 1); |
263 | mutex_unlock(&cp->lock); | 263 | mutex_unlock(&cp->lock); |
264 | } else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) { | 264 | } else if (!strncasecmp(cmd, "off", 3) || !strcmp(cmd, "0")) { |
265 | mutex_lock(&cp->lock); | 265 | mutex_lock(&cp->lock); |
266 | error = s390_vary_chpid(cp->chpid, 0); | 266 | error = s390_vary_chpid(cp->chpid, 0); |
267 | mutex_unlock(&cp->lock); | 267 | mutex_unlock(&cp->lock); |
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 52a216f21ae5..e5afc3884d74 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -528,7 +528,7 @@ ips_setup(char *ips_str) | |||
528 | * Update the variables | 528 | * Update the variables |
529 | */ | 529 | */ |
530 | for (i = 0; i < ARRAY_SIZE(options); i++) { | 530 | for (i = 0; i < ARRAY_SIZE(options); i++) { |
531 | if (strnicmp | 531 | if (strncasecmp |
532 | (key, options[i].option_name, | 532 | (key, options[i].option_name, |
533 | strlen(options[i].option_name)) == 0) { | 533 | strlen(options[i].option_name)) == 0) { |
534 | if (value) | 534 | if (value) |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2b6d447ad6d6..238e06f13b8a 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -3371,7 +3371,7 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf, | |||
3371 | char work[20]; | 3371 | char work[20]; |
3372 | 3372 | ||
3373 | if (1 == sscanf(buf, "%10s", work)) { | 3373 | if (1 == sscanf(buf, "%10s", work)) { |
3374 | if (0 == strnicmp(work,"0x", 2)) { | 3374 | if (0 == strncasecmp(work,"0x", 2)) { |
3375 | if (1 == sscanf(&work[2], "%x", &opts)) | 3375 | if (1 == sscanf(&work[2], "%x", &opts)) |
3376 | goto opts_done; | 3376 | goto opts_done; |
3377 | } else { | 3377 | } else { |
diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c index 1718229f6278..d9d55d12fd5f 100644 --- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c +++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c | |||
@@ -79,7 +79,7 @@ int rtw_android_cmdstr_to_num(char *cmdstr) | |||
79 | { | 79 | { |
80 | int cmd_num; | 80 | int cmd_num; |
81 | for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++) | 81 | for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++) |
82 | if (0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num], | 82 | if (0 == strncasecmp(cmdstr , android_wifi_cmd_str[cmd_num], |
83 | strlen(android_wifi_cmd_str[cmd_num]))) | 83 | strlen(android_wifi_cmd_str[cmd_num]))) |
84 | break; | 84 | break; |
85 | return cmd_num; | 85 | return cmd_num; |
diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 91d35df286c3..2d82f8993ea1 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h | |||
@@ -2957,25 +2957,13 @@ extern inline int rtllib_get_scans(struct rtllib_device *ieee) | |||
2957 | static inline const char *escape_essid(const char *essid, u8 essid_len) | 2957 | static inline const char *escape_essid(const char *essid, u8 essid_len) |
2958 | { | 2958 | { |
2959 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 2959 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
2960 | const char *s = essid; | ||
2961 | char *d = escaped; | ||
2962 | 2960 | ||
2963 | if (rtllib_is_empty_essid(essid, essid_len)) { | 2961 | if (rtllib_is_empty_essid(essid, essid_len)) { |
2964 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); | 2962 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); |
2965 | return escaped; | 2963 | return escaped; |
2966 | } | 2964 | } |
2967 | 2965 | ||
2968 | essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); | 2966 | snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); |
2969 | while (essid_len--) { | ||
2970 | if (*s == '\0') { | ||
2971 | *d++ = '\\'; | ||
2972 | *d++ = '0'; | ||
2973 | s++; | ||
2974 | } else { | ||
2975 | *d++ = *s++; | ||
2976 | } | ||
2977 | } | ||
2978 | *d = '\0'; | ||
2979 | return escaped; | 2967 | return escaped; |
2980 | } | 2968 | } |
2981 | 2969 | ||
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 9ecfa4a2421d..b44aa17d30a7 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h | |||
@@ -2593,25 +2593,13 @@ static inline int ieee80211_get_scans(struct ieee80211_device *ieee) | |||
2593 | 2593 | ||
2594 | static inline const char *escape_essid(const char *essid, u8 essid_len) { | 2594 | static inline const char *escape_essid(const char *essid, u8 essid_len) { |
2595 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | 2595 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; |
2596 | const char *s = essid; | ||
2597 | char *d = escaped; | ||
2598 | 2596 | ||
2599 | if (ieee80211_is_empty_essid(essid, essid_len)) { | 2597 | if (ieee80211_is_empty_essid(essid, essid_len)) { |
2600 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); | 2598 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); |
2601 | return escaped; | 2599 | return escaped; |
2602 | } | 2600 | } |
2603 | 2601 | ||
2604 | essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); | 2602 | snprintf(escaped, sizeof(escaped), "%*pEn", essid_len, essid); |
2605 | while (essid_len--) { | ||
2606 | if (*s == '\0') { | ||
2607 | *d++ = '\\'; | ||
2608 | *d++ = '0'; | ||
2609 | s++; | ||
2610 | } else { | ||
2611 | *d++ = *s++; | ||
2612 | } | ||
2613 | } | ||
2614 | *d = '\0'; | ||
2615 | return escaped; | 2603 | return escaped; |
2616 | } | 2604 | } |
2617 | 2605 | ||
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 799ce8aa70ef..df577dfe7ffb 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #include <linux/netdevice.h> | 60 | #include <linux/netdevice.h> |
61 | #include <linux/workqueue.h> | 61 | #include <linux/workqueue.h> |
62 | #include <linux/byteorder/generic.h> | 62 | #include <linux/byteorder/generic.h> |
63 | #include <linux/ctype.h> | ||
64 | 63 | ||
65 | #include <linux/io.h> | 64 | #include <linux/io.h> |
66 | #include <linux/delay.h> | 65 | #include <linux/delay.h> |
@@ -81,27 +80,6 @@ | |||
81 | #include "hfa384x.h" | 80 | #include "hfa384x.h" |
82 | #include "prism2mgmt.h" | 81 | #include "prism2mgmt.h" |
83 | 82 | ||
84 | /* Create a string of printable chars from something that might not be */ | ||
85 | /* It's recommended that the str be 4*len + 1 bytes long */ | ||
86 | #define wlan_mkprintstr(buf, buflen, str, strlen) \ | ||
87 | { \ | ||
88 | int i = 0; \ | ||
89 | int j = 0; \ | ||
90 | memset(str, 0, (strlen)); \ | ||
91 | for (i = 0; i < (buflen); i++) { \ | ||
92 | if (isprint((buf)[i])) { \ | ||
93 | (str)[j] = (buf)[i]; \ | ||
94 | j++; \ | ||
95 | } else { \ | ||
96 | (str)[j] = '\\'; \ | ||
97 | (str)[j+1] = 'x'; \ | ||
98 | (str)[j+2] = hex_asc_hi((buf)[i]); \ | ||
99 | (str)[j+3] = hex_asc_lo((buf)[i]); \ | ||
100 | j += 4; \ | ||
101 | } \ | ||
102 | } \ | ||
103 | } | ||
104 | |||
105 | static char *dev_info = "prism2_usb"; | 83 | static char *dev_info = "prism2_usb"; |
106 | static wlandevice_t *create_wlan(void); | 84 | static wlandevice_t *create_wlan(void); |
107 | 85 | ||
@@ -607,7 +585,6 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev) | |||
607 | hfa384x_t *hw = (hfa384x_t *) wlandev->priv; | 585 | hfa384x_t *hw = (hfa384x_t *) wlandev->priv; |
608 | u16 temp; | 586 | u16 temp; |
609 | u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; | 587 | u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; |
610 | char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1]; | ||
611 | 588 | ||
612 | /* Collect version and compatibility info */ | 589 | /* Collect version and compatibility info */ |
613 | /* Some are critical, some are not */ | 590 | /* Some are critical, some are not */ |
@@ -862,9 +839,8 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev) | |||
862 | result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, | 839 | result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, |
863 | snum, HFA384x_RID_NICSERIALNUMBER_LEN); | 840 | snum, HFA384x_RID_NICSERIALNUMBER_LEN); |
864 | if (!result) { | 841 | if (!result) { |
865 | wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN, | 842 | netdev_info(wlandev->netdev, "Prism2 card SN: %*pEhp\n", |
866 | pstr, sizeof(pstr)); | 843 | HFA384x_RID_NICSERIALNUMBER_LEN, snum); |
867 | netdev_info(wlandev->netdev, "Prism2 card SN: %s\n", pstr); | ||
868 | } else { | 844 | } else { |
869 | netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); | 845 | netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); |
870 | goto failed; | 846 | goto failed; |
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 71b0ec0c370d..1e23f4f8d2c2 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c | |||
@@ -66,7 +66,7 @@ static struct thermal_governor *__find_governor(const char *name) | |||
66 | return def_governor; | 66 | return def_governor; |
67 | 67 | ||
68 | list_for_each_entry(pos, &thermal_governor_list, governor_list) | 68 | list_for_each_entry(pos, &thermal_governor_list, governor_list) |
69 | if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH)) | 69 | if (!strncasecmp(name, pos->name, THERMAL_NAME_LENGTH)) |
70 | return pos; | 70 | return pos; |
71 | 71 | ||
72 | return NULL; | 72 | return NULL; |
@@ -104,7 +104,7 @@ int thermal_register_governor(struct thermal_governor *governor) | |||
104 | 104 | ||
105 | name = pos->tzp->governor_name; | 105 | name = pos->tzp->governor_name; |
106 | 106 | ||
107 | if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH)) | 107 | if (!strncasecmp(name, governor->name, THERMAL_NAME_LENGTH)) |
108 | pos->governor = governor; | 108 | pos->governor = governor; |
109 | } | 109 | } |
110 | 110 | ||
@@ -129,7 +129,7 @@ void thermal_unregister_governor(struct thermal_governor *governor) | |||
129 | mutex_lock(&thermal_list_lock); | 129 | mutex_lock(&thermal_list_lock); |
130 | 130 | ||
131 | list_for_each_entry(pos, &thermal_tz_list, node) { | 131 | list_for_each_entry(pos, &thermal_tz_list, node) { |
132 | if (!strnicmp(pos->governor->name, governor->name, | 132 | if (!strncasecmp(pos->governor->name, governor->name, |
133 | THERMAL_NAME_LENGTH)) | 133 | THERMAL_NAME_LENGTH)) |
134 | pos->governor = NULL; | 134 | pos->governor = NULL; |
135 | } | 135 | } |
@@ -1665,7 +1665,7 @@ struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name) | |||
1665 | 1665 | ||
1666 | mutex_lock(&thermal_list_lock); | 1666 | mutex_lock(&thermal_list_lock); |
1667 | list_for_each_entry(pos, &thermal_tz_list, node) | 1667 | list_for_each_entry(pos, &thermal_tz_list, node) |
1668 | if (!strnicmp(name, pos->type, THERMAL_NAME_LENGTH)) { | 1668 | if (!strncasecmp(name, pos->type, THERMAL_NAME_LENGTH)) { |
1669 | found++; | 1669 | found++; |
1670 | ref = pos; | 1670 | ref = pos; |
1671 | } | 1671 | } |
diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 167cffff3d4e..7c74f58fc101 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c | |||
@@ -1001,7 +1001,7 @@ static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val, | |||
1001 | 1001 | ||
1002 | for (i = 0 ; i < size ; i++ ) { | 1002 | for (i = 0 ; i < size ; i++ ) { |
1003 | if (s != NULL) { | 1003 | if (s != NULL) { |
1004 | if (!strnicmp(p[i].name, s, strlen(s))) | 1004 | if (!strncasecmp(p[i].name, s, strlen(s))) |
1005 | return p[i].val; | 1005 | return p[i].val; |
1006 | } else { | 1006 | } else { |
1007 | if (p[i].val == val) | 1007 | if (p[i].val == val) |
diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c index 43c63a4f3178..e350eb57f11d 100644 --- a/drivers/video/fbdev/s3c2410fb.c +++ b/drivers/video/fbdev/s3c2410fb.c | |||
@@ -601,12 +601,12 @@ static int s3c2410fb_debug_store(struct device *dev, | |||
601 | if (len < 1) | 601 | if (len < 1) |
602 | return -EINVAL; | 602 | return -EINVAL; |
603 | 603 | ||
604 | if (strnicmp(buf, "on", 2) == 0 || | 604 | if (strncasecmp(buf, "on", 2) == 0 || |
605 | strnicmp(buf, "1", 1) == 0) { | 605 | strncasecmp(buf, "1", 1) == 0) { |
606 | debug = 1; | 606 | debug = 1; |
607 | dev_dbg(dev, "s3c2410fb: Debug On"); | 607 | dev_dbg(dev, "s3c2410fb: Debug On"); |
608 | } else if (strnicmp(buf, "off", 3) == 0 || | 608 | } else if (strncasecmp(buf, "off", 3) == 0 || |
609 | strnicmp(buf, "0", 1) == 0) { | 609 | strncasecmp(buf, "0", 1) == 0) { |
610 | debug = 0; | 610 | debug = 0; |
611 | dev_dbg(dev, "s3c2410fb: Debug Off"); | 611 | dev_dbg(dev, "s3c2410fb: Debug Off"); |
612 | } else { | 612 | } else { |
diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 3f12a2dd959a..4f5cf035ac3c 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c | |||
@@ -162,7 +162,7 @@ static void sisfb_search_mode(char *name, bool quiet) | |||
162 | return; | 162 | return; |
163 | } | 163 | } |
164 | 164 | ||
165 | if(!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { | 165 | if(!strncasecmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) { |
166 | if(!quiet) | 166 | if(!quiet) |
167 | printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); | 167 | printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n"); |
168 | 168 | ||
@@ -201,7 +201,7 @@ static void sisfb_search_mode(char *name, bool quiet) | |||
201 | 201 | ||
202 | i = 0; j = 0; | 202 | i = 0; j = 0; |
203 | while(sisbios_mode[i].mode_no[0] != 0) { | 203 | while(sisbios_mode[i].mode_no[0] != 0) { |
204 | if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { | 204 | if(!strncasecmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) { |
205 | if(sisfb_fstn) { | 205 | if(sisfb_fstn) { |
206 | if(sisbios_mode[i-1].mode_no[1] == 0x50 || | 206 | if(sisbios_mode[i-1].mode_no[1] == 0x50 || |
207 | sisbios_mode[i-1].mode_no[1] == 0x56 || | 207 | sisbios_mode[i-1].mode_no[1] == 0x56 || |
@@ -262,7 +262,7 @@ sisfb_search_crt2type(const char *name) | |||
262 | if(name == NULL) return; | 262 | if(name == NULL) return; |
263 | 263 | ||
264 | while(sis_crt2type[i].type_no != -1) { | 264 | while(sis_crt2type[i].type_no != -1) { |
265 | if(!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { | 265 | if(!strncasecmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) { |
266 | sisfb_crt2type = sis_crt2type[i].type_no; | 266 | sisfb_crt2type = sis_crt2type[i].type_no; |
267 | sisfb_tvplug = sis_crt2type[i].tvplug_no; | 267 | sisfb_tvplug = sis_crt2type[i].tvplug_no; |
268 | sisfb_crt2flags = sis_crt2type[i].flags; | 268 | sisfb_crt2flags = sis_crt2type[i].flags; |
@@ -289,7 +289,7 @@ sisfb_search_tvstd(const char *name) | |||
289 | return; | 289 | return; |
290 | 290 | ||
291 | while(sis_tvtype[i].type_no != -1) { | 291 | while(sis_tvtype[i].type_no != -1) { |
292 | if(!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { | 292 | if(!strncasecmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) { |
293 | sisfb_tvstd = sis_tvtype[i].type_no; | 293 | sisfb_tvstd = sis_tvtype[i].type_no; |
294 | break; | 294 | break; |
295 | } | 295 | } |
@@ -308,12 +308,12 @@ sisfb_search_specialtiming(const char *name) | |||
308 | if(name == NULL) | 308 | if(name == NULL) |
309 | return; | 309 | return; |
310 | 310 | ||
311 | if(!strnicmp(name, "none", 4)) { | 311 | if(!strncasecmp(name, "none", 4)) { |
312 | sisfb_specialtiming = CUT_FORCENONE; | 312 | sisfb_specialtiming = CUT_FORCENONE; |
313 | printk(KERN_DEBUG "sisfb: Special timing disabled\n"); | 313 | printk(KERN_DEBUG "sisfb: Special timing disabled\n"); |
314 | } else { | 314 | } else { |
315 | while(mycustomttable[i].chipID != 0) { | 315 | while(mycustomttable[i].chipID != 0) { |
316 | if(!strnicmp(name,mycustomttable[i].optionName, | 316 | if(!strncasecmp(name,mycustomttable[i].optionName, |
317 | strlen(mycustomttable[i].optionName))) { | 317 | strlen(mycustomttable[i].optionName))) { |
318 | sisfb_specialtiming = mycustomttable[i].SpecialID; | 318 | sisfb_specialtiming = mycustomttable[i].SpecialID; |
319 | found = true; | 319 | found = true; |
@@ -3952,68 +3952,68 @@ static int __init sisfb_setup(char *options) | |||
3952 | 3952 | ||
3953 | if(!(*this_opt)) continue; | 3953 | if(!(*this_opt)) continue; |
3954 | 3954 | ||
3955 | if(!strnicmp(this_opt, "off", 3)) { | 3955 | if(!strncasecmp(this_opt, "off", 3)) { |
3956 | sisfb_off = 1; | 3956 | sisfb_off = 1; |
3957 | } else if(!strnicmp(this_opt, "forcecrt2type:", 14)) { | 3957 | } else if(!strncasecmp(this_opt, "forcecrt2type:", 14)) { |
3958 | /* Need to check crt2 type first for fstn/dstn */ | 3958 | /* Need to check crt2 type first for fstn/dstn */ |
3959 | sisfb_search_crt2type(this_opt + 14); | 3959 | sisfb_search_crt2type(this_opt + 14); |
3960 | } else if(!strnicmp(this_opt, "tvmode:",7)) { | 3960 | } else if(!strncasecmp(this_opt, "tvmode:",7)) { |
3961 | sisfb_search_tvstd(this_opt + 7); | 3961 | sisfb_search_tvstd(this_opt + 7); |
3962 | } else if(!strnicmp(this_opt, "tvstandard:",11)) { | 3962 | } else if(!strncasecmp(this_opt, "tvstandard:",11)) { |
3963 | sisfb_search_tvstd(this_opt + 11); | 3963 | sisfb_search_tvstd(this_opt + 11); |
3964 | } else if(!strnicmp(this_opt, "mode:", 5)) { | 3964 | } else if(!strncasecmp(this_opt, "mode:", 5)) { |
3965 | sisfb_search_mode(this_opt + 5, false); | 3965 | sisfb_search_mode(this_opt + 5, false); |
3966 | } else if(!strnicmp(this_opt, "vesa:", 5)) { | 3966 | } else if(!strncasecmp(this_opt, "vesa:", 5)) { |
3967 | sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); | 3967 | sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false); |
3968 | } else if(!strnicmp(this_opt, "rate:", 5)) { | 3968 | } else if(!strncasecmp(this_opt, "rate:", 5)) { |
3969 | sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); | 3969 | sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0); |
3970 | } else if(!strnicmp(this_opt, "forcecrt1:", 10)) { | 3970 | } else if(!strncasecmp(this_opt, "forcecrt1:", 10)) { |
3971 | sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); | 3971 | sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0); |
3972 | } else if(!strnicmp(this_opt, "mem:",4)) { | 3972 | } else if(!strncasecmp(this_opt, "mem:",4)) { |
3973 | sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); | 3973 | sisfb_parm_mem = simple_strtoul(this_opt + 4, NULL, 0); |
3974 | } else if(!strnicmp(this_opt, "pdc:", 4)) { | 3974 | } else if(!strncasecmp(this_opt, "pdc:", 4)) { |
3975 | sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); | 3975 | sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0); |
3976 | } else if(!strnicmp(this_opt, "pdc1:", 5)) { | 3976 | } else if(!strncasecmp(this_opt, "pdc1:", 5)) { |
3977 | sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); | 3977 | sisfb_pdca = simple_strtoul(this_opt + 5, NULL, 0); |
3978 | } else if(!strnicmp(this_opt, "noaccel", 7)) { | 3978 | } else if(!strncasecmp(this_opt, "noaccel", 7)) { |
3979 | sisfb_accel = 0; | 3979 | sisfb_accel = 0; |
3980 | } else if(!strnicmp(this_opt, "accel", 5)) { | 3980 | } else if(!strncasecmp(this_opt, "accel", 5)) { |
3981 | sisfb_accel = -1; | 3981 | sisfb_accel = -1; |
3982 | } else if(!strnicmp(this_opt, "noypan", 6)) { | 3982 | } else if(!strncasecmp(this_opt, "noypan", 6)) { |
3983 | sisfb_ypan = 0; | 3983 | sisfb_ypan = 0; |
3984 | } else if(!strnicmp(this_opt, "ypan", 4)) { | 3984 | } else if(!strncasecmp(this_opt, "ypan", 4)) { |
3985 | sisfb_ypan = -1; | 3985 | sisfb_ypan = -1; |
3986 | } else if(!strnicmp(this_opt, "nomax", 5)) { | 3986 | } else if(!strncasecmp(this_opt, "nomax", 5)) { |
3987 | sisfb_max = 0; | 3987 | sisfb_max = 0; |
3988 | } else if(!strnicmp(this_opt, "max", 3)) { | 3988 | } else if(!strncasecmp(this_opt, "max", 3)) { |
3989 | sisfb_max = -1; | 3989 | sisfb_max = -1; |
3990 | } else if(!strnicmp(this_opt, "userom:", 7)) { | 3990 | } else if(!strncasecmp(this_opt, "userom:", 7)) { |
3991 | sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); | 3991 | sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0); |
3992 | } else if(!strnicmp(this_opt, "useoem:", 7)) { | 3992 | } else if(!strncasecmp(this_opt, "useoem:", 7)) { |
3993 | sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); | 3993 | sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); |
3994 | } else if(!strnicmp(this_opt, "nocrt2rate", 10)) { | 3994 | } else if(!strncasecmp(this_opt, "nocrt2rate", 10)) { |
3995 | sisfb_nocrt2rate = 1; | 3995 | sisfb_nocrt2rate = 1; |
3996 | } else if(!strnicmp(this_opt, "scalelcd:", 9)) { | 3996 | } else if(!strncasecmp(this_opt, "scalelcd:", 9)) { |
3997 | unsigned long temp = 2; | 3997 | unsigned long temp = 2; |
3998 | temp = simple_strtoul(this_opt + 9, NULL, 0); | 3998 | temp = simple_strtoul(this_opt + 9, NULL, 0); |
3999 | if((temp == 0) || (temp == 1)) { | 3999 | if((temp == 0) || (temp == 1)) { |
4000 | sisfb_scalelcd = temp ^ 1; | 4000 | sisfb_scalelcd = temp ^ 1; |
4001 | } | 4001 | } |
4002 | } else if(!strnicmp(this_opt, "tvxposoffset:", 13)) { | 4002 | } else if(!strncasecmp(this_opt, "tvxposoffset:", 13)) { |
4003 | int temp = 0; | 4003 | int temp = 0; |
4004 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); | 4004 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); |
4005 | if((temp >= -32) && (temp <= 32)) { | 4005 | if((temp >= -32) && (temp <= 32)) { |
4006 | sisfb_tvxposoffset = temp; | 4006 | sisfb_tvxposoffset = temp; |
4007 | } | 4007 | } |
4008 | } else if(!strnicmp(this_opt, "tvyposoffset:", 13)) { | 4008 | } else if(!strncasecmp(this_opt, "tvyposoffset:", 13)) { |
4009 | int temp = 0; | 4009 | int temp = 0; |
4010 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); | 4010 | temp = (int)simple_strtol(this_opt + 13, NULL, 0); |
4011 | if((temp >= -32) && (temp <= 32)) { | 4011 | if((temp >= -32) && (temp <= 32)) { |
4012 | sisfb_tvyposoffset = temp; | 4012 | sisfb_tvyposoffset = temp; |
4013 | } | 4013 | } |
4014 | } else if(!strnicmp(this_opt, "specialtiming:", 14)) { | 4014 | } else if(!strncasecmp(this_opt, "specialtiming:", 14)) { |
4015 | sisfb_search_specialtiming(this_opt + 14); | 4015 | sisfb_search_specialtiming(this_opt + 14); |
4016 | } else if(!strnicmp(this_opt, "lvdshl:", 7)) { | 4016 | } else if(!strncasecmp(this_opt, "lvdshl:", 7)) { |
4017 | int temp = 4; | 4017 | int temp = 4; |
4018 | temp = simple_strtoul(this_opt + 7, NULL, 0); | 4018 | temp = simple_strtoul(this_opt + 7, NULL, 0); |
4019 | if((temp >= 0) && (temp <= 3)) { | 4019 | if((temp >= 0) && (temp <= 3)) { |
@@ -4022,9 +4022,9 @@ static int __init sisfb_setup(char *options) | |||
4022 | } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { | 4022 | } else if(this_opt[0] >= '0' && this_opt[0] <= '9') { |
4023 | sisfb_search_mode(this_opt, true); | 4023 | sisfb_search_mode(this_opt, true); |
4024 | #if !defined(__i386__) && !defined(__x86_64__) | 4024 | #if !defined(__i386__) && !defined(__x86_64__) |
4025 | } else if(!strnicmp(this_opt, "resetcard", 9)) { | 4025 | } else if(!strncasecmp(this_opt, "resetcard", 9)) { |
4026 | sisfb_resetcard = 1; | 4026 | sisfb_resetcard = 1; |
4027 | } else if(!strnicmp(this_opt, "videoram:", 9)) { | 4027 | } else if(!strncasecmp(this_opt, "videoram:", 9)) { |
4028 | sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); | 4028 | sisfb_videoram = simple_strtoul(this_opt + 9, NULL, 0); |
4029 | #endif | 4029 | #endif |
4030 | } else { | 4030 | } else { |
diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index c2c8eb668784..9e74e8fbe074 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c | |||
@@ -1187,9 +1187,9 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev, | |||
1187 | if (len < 1) | 1187 | if (len < 1) |
1188 | return -EINVAL; | 1188 | return -EINVAL; |
1189 | 1189 | ||
1190 | if (strnicmp(buf, "crt", 3) == 0) | 1190 | if (strncasecmp(buf, "crt", 3) == 0) |
1191 | head = HEAD_CRT; | 1191 | head = HEAD_CRT; |
1192 | else if (strnicmp(buf, "panel", 5) == 0) | 1192 | else if (strncasecmp(buf, "panel", 5) == 0) |
1193 | head = HEAD_PANEL; | 1193 | head = HEAD_PANEL; |
1194 | else | 1194 | else |
1195 | return -EINVAL; | 1195 | return -EINVAL; |
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index 406b29836b19..abc853968fed 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c | |||
@@ -10,8 +10,6 @@ | |||
10 | 10 | ||
11 | #include "affs.h" | 11 | #include "affs.h" |
12 | 12 | ||
13 | extern struct timezone sys_tz; | ||
14 | |||
15 | static char ErrorBuffer[256]; | 13 | static char ErrorBuffer[256]; |
16 | 14 | ||
17 | /* | 15 | /* |
diff --git a/fs/affs/file.c b/fs/affs/file.c index a7fe57d2cd9a..1ed590aafecf 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c | |||
@@ -584,11 +584,14 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize) | |||
584 | bh->b_state &= ~(1UL << BH_New); | 584 | bh->b_state &= ~(1UL << BH_New); |
585 | mark_buffer_dirty_inode(bh, inode); | 585 | mark_buffer_dirty_inode(bh, inode); |
586 | if (prev_bh) { | 586 | if (prev_bh) { |
587 | u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next); | 587 | u32 tmp_next = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next); |
588 | if (tmp) | 588 | |
589 | affs_warning(sb, "extent_file_ofs", "next block already set for %d (%d)", bidx, tmp); | 589 | if (tmp_next) |
590 | affs_warning(sb, "extent_file_ofs", | ||
591 | "next block already set for %d (%d)", | ||
592 | bidx, tmp_next); | ||
590 | AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr); | 593 | AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr); |
591 | affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp); | 594 | affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next); |
592 | mark_buffer_dirty_inode(prev_bh, inode); | 595 | mark_buffer_dirty_inode(prev_bh, inode); |
593 | affs_brelse(prev_bh); | 596 | affs_brelse(prev_bh); |
594 | } | 597 | } |
@@ -727,11 +730,14 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping, | |||
727 | AFFS_DATA_HEAD(bh)->next = 0; | 730 | AFFS_DATA_HEAD(bh)->next = 0; |
728 | bh->b_state &= ~(1UL << BH_New); | 731 | bh->b_state &= ~(1UL << BH_New); |
729 | if (prev_bh) { | 732 | if (prev_bh) { |
730 | u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next); | 733 | u32 tmp_next = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next); |
731 | if (tmp) | 734 | |
732 | affs_warning(sb, "commit_write_ofs", "next block already set for %d (%d)", bidx, tmp); | 735 | if (tmp_next) |
736 | affs_warning(sb, "commit_write_ofs", | ||
737 | "next block already set for %d (%d)", | ||
738 | bidx, tmp_next); | ||
733 | AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr); | 739 | AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr); |
734 | affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp); | 740 | affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next); |
735 | mark_buffer_dirty_inode(prev_bh, inode); | 741 | mark_buffer_dirty_inode(prev_bh, inode); |
736 | } | 742 | } |
737 | } | 743 | } |
@@ -758,11 +764,14 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping, | |||
758 | AFFS_DATA_HEAD(bh)->next = 0; | 764 | AFFS_DATA_HEAD(bh)->next = 0; |
759 | bh->b_state &= ~(1UL << BH_New); | 765 | bh->b_state &= ~(1UL << BH_New); |
760 | if (prev_bh) { | 766 | if (prev_bh) { |
761 | u32 tmp = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next); | 767 | u32 tmp_next = be32_to_cpu(AFFS_DATA_HEAD(prev_bh)->next); |
762 | if (tmp) | 768 | |
763 | affs_warning(sb, "commit_write_ofs", "next block already set for %d (%d)", bidx, tmp); | 769 | if (tmp_next) |
770 | affs_warning(sb, "commit_write_ofs", | ||
771 | "next block already set for %d (%d)", | ||
772 | bidx, tmp_next); | ||
764 | AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr); | 773 | AFFS_DATA_HEAD(prev_bh)->next = cpu_to_be32(bh->b_blocknr); |
765 | affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp); | 774 | affs_adjust_checksum(prev_bh, bh->b_blocknr - tmp_next); |
766 | mark_buffer_dirty_inode(prev_bh, inode); | 775 | mark_buffer_dirty_inode(prev_bh, inode); |
767 | } | 776 | } |
768 | } else if (be32_to_cpu(AFFS_DATA_HEAD(bh)->size) < tmp) | 777 | } else if (be32_to_cpu(AFFS_DATA_HEAD(bh)->size) < tmp) |
@@ -842,12 +851,12 @@ affs_truncate(struct inode *inode) | |||
842 | struct address_space *mapping = inode->i_mapping; | 851 | struct address_space *mapping = inode->i_mapping; |
843 | struct page *page; | 852 | struct page *page; |
844 | void *fsdata; | 853 | void *fsdata; |
845 | loff_t size = inode->i_size; | 854 | loff_t isize = inode->i_size; |
846 | int res; | 855 | int res; |
847 | 856 | ||
848 | res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata); | 857 | res = mapping->a_ops->write_begin(NULL, mapping, isize, 0, 0, &page, &fsdata); |
849 | if (!res) | 858 | if (!res) |
850 | res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata); | 859 | res = mapping->a_ops->write_end(NULL, mapping, isize, 0, 0, page, fsdata); |
851 | else | 860 | else |
852 | inode->i_size = AFFS_I(inode)->mmu_private; | 861 | inode->i_size = AFFS_I(inode)->mmu_private; |
853 | mark_inode_dirty(inode); | 862 | mark_inode_dirty(inode); |
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index bec2d1a0c91c..e217c511459b 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -14,13 +14,11 @@ | |||
14 | #include "affs.h" | 14 | #include "affs.h" |
15 | 15 | ||
16 | extern const struct inode_operations affs_symlink_inode_operations; | 16 | extern const struct inode_operations affs_symlink_inode_operations; |
17 | extern struct timezone sys_tz; | ||
18 | 17 | ||
19 | struct inode *affs_iget(struct super_block *sb, unsigned long ino) | 18 | struct inode *affs_iget(struct super_block *sb, unsigned long ino) |
20 | { | 19 | { |
21 | struct affs_sb_info *sbi = AFFS_SB(sb); | 20 | struct affs_sb_info *sbi = AFFS_SB(sb); |
22 | struct buffer_head *bh; | 21 | struct buffer_head *bh; |
23 | struct affs_head *head; | ||
24 | struct affs_tail *tail; | 22 | struct affs_tail *tail; |
25 | struct inode *inode; | 23 | struct inode *inode; |
26 | u32 block; | 24 | u32 block; |
@@ -49,7 +47,6 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) | |||
49 | goto bad_inode; | 47 | goto bad_inode; |
50 | } | 48 | } |
51 | 49 | ||
52 | head = AFFS_HEAD(bh); | ||
53 | tail = AFFS_TAIL(sb, bh); | 50 | tail = AFFS_TAIL(sb, bh); |
54 | prot = be32_to_cpu(tail->protect); | 51 | prot = be32_to_cpu(tail->protect); |
55 | 52 | ||
diff --git a/fs/affs/super.c b/fs/affs/super.c index 51f1a95bff73..f754ab68a840 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -20,8 +20,6 @@ | |||
20 | #include <linux/writeback.h> | 20 | #include <linux/writeback.h> |
21 | #include "affs.h" | 21 | #include "affs.h" |
22 | 22 | ||
23 | extern struct timezone sys_tz; | ||
24 | |||
25 | static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); | 23 | static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); |
26 | static int affs_remount (struct super_block *sb, int *flags, char *data); | 24 | static int affs_remount (struct super_block *sb, int *flags, char *data); |
27 | 25 | ||
@@ -308,7 +306,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
308 | u32 chksum; | 306 | u32 chksum; |
309 | int num_bm; | 307 | int num_bm; |
310 | int i, j; | 308 | int i, j; |
311 | s32 key; | ||
312 | kuid_t uid; | 309 | kuid_t uid; |
313 | kgid_t gid; | 310 | kgid_t gid; |
314 | int reserved; | 311 | int reserved; |
@@ -367,7 +364,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
367 | i = j = blocksize; | 364 | i = j = blocksize; |
368 | size = size / (blocksize / 512); | 365 | size = size / (blocksize / 512); |
369 | } | 366 | } |
370 | for (blocksize = i, key = 0; blocksize <= j; blocksize <<= 1, size >>= 1) { | 367 | for (blocksize = i; blocksize <= j; blocksize <<= 1, size >>= 1) { |
371 | sbi->s_root_block = root_block; | 368 | sbi->s_root_block = root_block; |
372 | if (root_block < 0) | 369 | if (root_block < 0) |
373 | sbi->s_root_block = (reserved + size - 1) / 2; | 370 | sbi->s_root_block = (reserved + size - 1) / 2; |
@@ -399,7 +396,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
399 | be32_to_cpu(AFFS_ROOT_TAIL(sb, root_bh)->stype) == ST_ROOT) { | 396 | be32_to_cpu(AFFS_ROOT_TAIL(sb, root_bh)->stype) == ST_ROOT) { |
400 | sbi->s_hashsize = blocksize / 4 - 56; | 397 | sbi->s_hashsize = blocksize / 4 - 56; |
401 | sbi->s_root_block += num_bm; | 398 | sbi->s_root_block += num_bm; |
402 | key = 1; | ||
403 | goto got_root; | 399 | goto got_root; |
404 | } | 400 | } |
405 | affs_brelse(root_bh); | 401 | affs_brelse(root_bh); |
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 9e359fb20c0a..8e98cf954bab 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -79,6 +79,10 @@ struct autofs_info { | |||
79 | }; | 79 | }; |
80 | 80 | ||
81 | #define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ | 81 | #define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */ |
82 | #define AUTOFS_INF_NO_RCU (1<<1) /* the dentry is being considered | ||
83 | * for expiry, so RCU_walk is | ||
84 | * not permitted | ||
85 | */ | ||
82 | #define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */ | 86 | #define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */ |
83 | 87 | ||
84 | struct autofs_wait_queue { | 88 | struct autofs_wait_queue { |
@@ -148,7 +152,7 @@ void autofs4_free_ino(struct autofs_info *); | |||
148 | 152 | ||
149 | /* Expiration */ | 153 | /* Expiration */ |
150 | int is_autofs4_dentry(struct dentry *); | 154 | int is_autofs4_dentry(struct dentry *); |
151 | int autofs4_expire_wait(struct dentry *dentry); | 155 | int autofs4_expire_wait(struct dentry *dentry, int rcu_walk); |
152 | int autofs4_expire_run(struct super_block *, struct vfsmount *, | 156 | int autofs4_expire_run(struct super_block *, struct vfsmount *, |
153 | struct autofs_sb_info *, | 157 | struct autofs_sb_info *, |
154 | struct autofs_packet_expire __user *); | 158 | struct autofs_packet_expire __user *); |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 5b570b6efa28..aaf96cb25452 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
@@ -450,7 +450,7 @@ static int autofs_dev_ioctl_requester(struct file *fp, | |||
450 | ino = autofs4_dentry_ino(path.dentry); | 450 | ino = autofs4_dentry_ino(path.dentry); |
451 | if (ino) { | 451 | if (ino) { |
452 | err = 0; | 452 | err = 0; |
453 | autofs4_expire_wait(path.dentry); | 453 | autofs4_expire_wait(path.dentry, 0); |
454 | spin_lock(&sbi->fs_lock); | 454 | spin_lock(&sbi->fs_lock); |
455 | param->requester.uid = from_kuid_munged(current_user_ns(), ino->uid); | 455 | param->requester.uid = from_kuid_munged(current_user_ns(), ino->uid); |
456 | param->requester.gid = from_kgid_munged(current_user_ns(), ino->gid); | 456 | param->requester.gid = from_kgid_munged(current_user_ns(), ino->gid); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 8fa3895cda02..683a5b9ce22a 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -30,12 +30,6 @@ static inline int autofs4_can_expire(struct dentry *dentry, | |||
30 | /* Too young to die */ | 30 | /* Too young to die */ |
31 | if (!timeout || time_after(ino->last_used + timeout, now)) | 31 | if (!timeout || time_after(ino->last_used + timeout, now)) |
32 | return 0; | 32 | return 0; |
33 | |||
34 | /* update last_used here :- | ||
35 | - obviously makes sense if it is in use now | ||
36 | - less obviously, prevents rapid-fire expire | ||
37 | attempts if expire fails the first time */ | ||
38 | ino->last_used = now; | ||
39 | } | 33 | } |
40 | return 1; | 34 | return 1; |
41 | } | 35 | } |
@@ -327,10 +321,19 @@ struct dentry *autofs4_expire_direct(struct super_block *sb, | |||
327 | if (ino->flags & AUTOFS_INF_PENDING) | 321 | if (ino->flags & AUTOFS_INF_PENDING) |
328 | goto out; | 322 | goto out; |
329 | if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { | 323 | if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { |
330 | ino->flags |= AUTOFS_INF_EXPIRING; | 324 | ino->flags |= AUTOFS_INF_NO_RCU; |
331 | init_completion(&ino->expire_complete); | ||
332 | spin_unlock(&sbi->fs_lock); | 325 | spin_unlock(&sbi->fs_lock); |
333 | return root; | 326 | synchronize_rcu(); |
327 | spin_lock(&sbi->fs_lock); | ||
328 | if (!autofs4_direct_busy(mnt, root, timeout, do_now)) { | ||
329 | ino->flags |= AUTOFS_INF_EXPIRING; | ||
330 | smp_mb(); | ||
331 | ino->flags &= ~AUTOFS_INF_NO_RCU; | ||
332 | init_completion(&ino->expire_complete); | ||
333 | spin_unlock(&sbi->fs_lock); | ||
334 | return root; | ||
335 | } | ||
336 | ino->flags &= ~AUTOFS_INF_NO_RCU; | ||
334 | } | 337 | } |
335 | out: | 338 | out: |
336 | spin_unlock(&sbi->fs_lock); | 339 | spin_unlock(&sbi->fs_lock); |
@@ -339,6 +342,89 @@ out: | |||
339 | return NULL; | 342 | return NULL; |
340 | } | 343 | } |
341 | 344 | ||
345 | /* Check if 'dentry' should expire, or return a nearby | ||
346 | * dentry that is suitable. | ||
347 | * If returned dentry is different from arg dentry, | ||
348 | * then a dget() reference was taken, else not. | ||
349 | */ | ||
350 | static struct dentry *should_expire(struct dentry *dentry, | ||
351 | struct vfsmount *mnt, | ||
352 | unsigned long timeout, | ||
353 | int how) | ||
354 | { | ||
355 | int do_now = how & AUTOFS_EXP_IMMEDIATE; | ||
356 | int exp_leaves = how & AUTOFS_EXP_LEAVES; | ||
357 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
358 | unsigned int ino_count; | ||
359 | |||
360 | /* No point expiring a pending mount */ | ||
361 | if (ino->flags & AUTOFS_INF_PENDING) | ||
362 | return NULL; | ||
363 | |||
364 | /* | ||
365 | * Case 1: (i) indirect mount or top level pseudo direct mount | ||
366 | * (autofs-4.1). | ||
367 | * (ii) indirect mount with offset mount, check the "/" | ||
368 | * offset (autofs-5.0+). | ||
369 | */ | ||
370 | if (d_mountpoint(dentry)) { | ||
371 | DPRINTK("checking mountpoint %p %.*s", | ||
372 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | ||
373 | |||
374 | /* Can we umount this guy */ | ||
375 | if (autofs4_mount_busy(mnt, dentry)) | ||
376 | return NULL; | ||
377 | |||
378 | /* Can we expire this guy */ | ||
379 | if (autofs4_can_expire(dentry, timeout, do_now)) | ||
380 | return dentry; | ||
381 | return NULL; | ||
382 | } | ||
383 | |||
384 | if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) { | ||
385 | DPRINTK("checking symlink %p %.*s", | ||
386 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | ||
387 | /* | ||
388 | * A symlink can't be "busy" in the usual sense so | ||
389 | * just check last used for expire timeout. | ||
390 | */ | ||
391 | if (autofs4_can_expire(dentry, timeout, do_now)) | ||
392 | return dentry; | ||
393 | return NULL; | ||
394 | } | ||
395 | |||
396 | if (simple_empty(dentry)) | ||
397 | return NULL; | ||
398 | |||
399 | /* Case 2: tree mount, expire iff entire tree is not busy */ | ||
400 | if (!exp_leaves) { | ||
401 | /* Path walk currently on this dentry? */ | ||
402 | ino_count = atomic_read(&ino->count) + 1; | ||
403 | if (d_count(dentry) > ino_count) | ||
404 | return NULL; | ||
405 | |||
406 | if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) | ||
407 | return dentry; | ||
408 | /* | ||
409 | * Case 3: pseudo direct mount, expire individual leaves | ||
410 | * (autofs-4.1). | ||
411 | */ | ||
412 | } else { | ||
413 | /* Path walk currently on this dentry? */ | ||
414 | struct dentry *expired; | ||
415 | ino_count = atomic_read(&ino->count) + 1; | ||
416 | if (d_count(dentry) > ino_count) | ||
417 | return NULL; | ||
418 | |||
419 | expired = autofs4_check_leaves(mnt, dentry, timeout, do_now); | ||
420 | if (expired) { | ||
421 | if (expired == dentry) | ||
422 | dput(dentry); | ||
423 | return expired; | ||
424 | } | ||
425 | } | ||
426 | return NULL; | ||
427 | } | ||
342 | /* | 428 | /* |
343 | * Find an eligible tree to time-out | 429 | * Find an eligible tree to time-out |
344 | * A tree is eligible if :- | 430 | * A tree is eligible if :- |
@@ -353,11 +439,8 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
353 | unsigned long timeout; | 439 | unsigned long timeout; |
354 | struct dentry *root = sb->s_root; | 440 | struct dentry *root = sb->s_root; |
355 | struct dentry *dentry; | 441 | struct dentry *dentry; |
356 | struct dentry *expired = NULL; | 442 | struct dentry *expired; |
357 | int do_now = how & AUTOFS_EXP_IMMEDIATE; | ||
358 | int exp_leaves = how & AUTOFS_EXP_LEAVES; | ||
359 | struct autofs_info *ino; | 443 | struct autofs_info *ino; |
360 | unsigned int ino_count; | ||
361 | 444 | ||
362 | if (!root) | 445 | if (!root) |
363 | return NULL; | 446 | return NULL; |
@@ -369,77 +452,28 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
369 | while ((dentry = get_next_positive_subdir(dentry, root))) { | 452 | while ((dentry = get_next_positive_subdir(dentry, root))) { |
370 | spin_lock(&sbi->fs_lock); | 453 | spin_lock(&sbi->fs_lock); |
371 | ino = autofs4_dentry_ino(dentry); | 454 | ino = autofs4_dentry_ino(dentry); |
372 | /* No point expiring a pending mount */ | 455 | if (ino->flags & AUTOFS_INF_NO_RCU) |
373 | if (ino->flags & AUTOFS_INF_PENDING) | 456 | expired = NULL; |
374 | goto next; | 457 | else |
375 | 458 | expired = should_expire(dentry, mnt, timeout, how); | |
376 | /* | 459 | if (!expired) { |
377 | * Case 1: (i) indirect mount or top level pseudo direct mount | 460 | spin_unlock(&sbi->fs_lock); |
378 | * (autofs-4.1). | 461 | continue; |
379 | * (ii) indirect mount with offset mount, check the "/" | ||
380 | * offset (autofs-5.0+). | ||
381 | */ | ||
382 | if (d_mountpoint(dentry)) { | ||
383 | DPRINTK("checking mountpoint %p %.*s", | ||
384 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | ||
385 | |||
386 | /* Can we umount this guy */ | ||
387 | if (autofs4_mount_busy(mnt, dentry)) | ||
388 | goto next; | ||
389 | |||
390 | /* Can we expire this guy */ | ||
391 | if (autofs4_can_expire(dentry, timeout, do_now)) { | ||
392 | expired = dentry; | ||
393 | goto found; | ||
394 | } | ||
395 | goto next; | ||
396 | } | 462 | } |
397 | 463 | ino = autofs4_dentry_ino(expired); | |
398 | if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) { | 464 | ino->flags |= AUTOFS_INF_NO_RCU; |
399 | DPRINTK("checking symlink %p %.*s", | 465 | spin_unlock(&sbi->fs_lock); |
400 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | 466 | synchronize_rcu(); |
401 | /* | 467 | spin_lock(&sbi->fs_lock); |
402 | * A symlink can't be "busy" in the usual sense so | 468 | if (should_expire(expired, mnt, timeout, how)) { |
403 | * just check last used for expire timeout. | 469 | if (expired != dentry) |
404 | */ | ||
405 | if (autofs4_can_expire(dentry, timeout, do_now)) { | ||
406 | expired = dentry; | ||
407 | goto found; | ||
408 | } | ||
409 | goto next; | ||
410 | } | ||
411 | |||
412 | if (simple_empty(dentry)) | ||
413 | goto next; | ||
414 | |||
415 | /* Case 2: tree mount, expire iff entire tree is not busy */ | ||
416 | if (!exp_leaves) { | ||
417 | /* Path walk currently on this dentry? */ | ||
418 | ino_count = atomic_read(&ino->count) + 1; | ||
419 | if (d_count(dentry) > ino_count) | ||
420 | goto next; | ||
421 | |||
422 | if (!autofs4_tree_busy(mnt, dentry, timeout, do_now)) { | ||
423 | expired = dentry; | ||
424 | goto found; | ||
425 | } | ||
426 | /* | ||
427 | * Case 3: pseudo direct mount, expire individual leaves | ||
428 | * (autofs-4.1). | ||
429 | */ | ||
430 | } else { | ||
431 | /* Path walk currently on this dentry? */ | ||
432 | ino_count = atomic_read(&ino->count) + 1; | ||
433 | if (d_count(dentry) > ino_count) | ||
434 | goto next; | ||
435 | |||
436 | expired = autofs4_check_leaves(mnt, dentry, timeout, do_now); | ||
437 | if (expired) { | ||
438 | dput(dentry); | 470 | dput(dentry); |
439 | goto found; | 471 | goto found; |
440 | } | ||
441 | } | 472 | } |
442 | next: | 473 | |
474 | ino->flags &= ~AUTOFS_INF_NO_RCU; | ||
475 | if (expired != dentry) | ||
476 | dput(expired); | ||
443 | spin_unlock(&sbi->fs_lock); | 477 | spin_unlock(&sbi->fs_lock); |
444 | } | 478 | } |
445 | return NULL; | 479 | return NULL; |
@@ -447,8 +481,9 @@ next: | |||
447 | found: | 481 | found: |
448 | DPRINTK("returning %p %.*s", | 482 | DPRINTK("returning %p %.*s", |
449 | expired, (int)expired->d_name.len, expired->d_name.name); | 483 | expired, (int)expired->d_name.len, expired->d_name.name); |
450 | ino = autofs4_dentry_ino(expired); | ||
451 | ino->flags |= AUTOFS_INF_EXPIRING; | 484 | ino->flags |= AUTOFS_INF_EXPIRING; |
485 | smp_mb(); | ||
486 | ino->flags &= ~AUTOFS_INF_NO_RCU; | ||
452 | init_completion(&ino->expire_complete); | 487 | init_completion(&ino->expire_complete); |
453 | spin_unlock(&sbi->fs_lock); | 488 | spin_unlock(&sbi->fs_lock); |
454 | spin_lock(&sbi->lookup_lock); | 489 | spin_lock(&sbi->lookup_lock); |
@@ -461,13 +496,18 @@ found: | |||
461 | return expired; | 496 | return expired; |
462 | } | 497 | } |
463 | 498 | ||
464 | int autofs4_expire_wait(struct dentry *dentry) | 499 | int autofs4_expire_wait(struct dentry *dentry, int rcu_walk) |
465 | { | 500 | { |
466 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 501 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
467 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 502 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
468 | int status; | 503 | int status; |
469 | 504 | ||
470 | /* Block on any pending expire */ | 505 | /* Block on any pending expire */ |
506 | if (!(ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU))) | ||
507 | return 0; | ||
508 | if (rcu_walk) | ||
509 | return -ECHILD; | ||
510 | |||
471 | spin_lock(&sbi->fs_lock); | 511 | spin_lock(&sbi->fs_lock); |
472 | if (ino->flags & AUTOFS_INF_EXPIRING) { | 512 | if (ino->flags & AUTOFS_INF_EXPIRING) { |
473 | spin_unlock(&sbi->fs_lock); | 513 | spin_unlock(&sbi->fs_lock); |
@@ -519,6 +559,8 @@ int autofs4_expire_run(struct super_block *sb, | |||
519 | 559 | ||
520 | spin_lock(&sbi->fs_lock); | 560 | spin_lock(&sbi->fs_lock); |
521 | ino = autofs4_dentry_ino(dentry); | 561 | ino = autofs4_dentry_ino(dentry); |
562 | /* avoid rapid-fire expire attempts if expiry fails */ | ||
563 | ino->last_used = now; | ||
522 | ino->flags &= ~AUTOFS_INF_EXPIRING; | 564 | ino->flags &= ~AUTOFS_INF_EXPIRING; |
523 | complete_all(&ino->expire_complete); | 565 | complete_all(&ino->expire_complete); |
524 | spin_unlock(&sbi->fs_lock); | 566 | spin_unlock(&sbi->fs_lock); |
@@ -545,6 +587,8 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt, | |||
545 | ret = autofs4_wait(sbi, dentry, NFY_EXPIRE); | 587 | ret = autofs4_wait(sbi, dentry, NFY_EXPIRE); |
546 | 588 | ||
547 | spin_lock(&sbi->fs_lock); | 589 | spin_lock(&sbi->fs_lock); |
590 | /* avoid rapid-fire expire attempts if expiry fails */ | ||
591 | ino->last_used = now; | ||
548 | ino->flags &= ~AUTOFS_INF_EXPIRING; | 592 | ino->flags &= ~AUTOFS_INF_EXPIRING; |
549 | complete_all(&ino->expire_complete); | 593 | complete_all(&ino->expire_complete); |
550 | spin_unlock(&sbi->fs_lock); | 594 | spin_unlock(&sbi->fs_lock); |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index cdb25ebccc4c..d76d083f2f06 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -210,7 +210,8 @@ next: | |||
210 | return NULL; | 210 | return NULL; |
211 | } | 211 | } |
212 | 212 | ||
213 | static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | 213 | static struct dentry *autofs4_lookup_expiring(struct dentry *dentry, |
214 | bool rcu_walk) | ||
214 | { | 215 | { |
215 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 216 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
216 | struct dentry *parent = dentry->d_parent; | 217 | struct dentry *parent = dentry->d_parent; |
@@ -229,6 +230,11 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
229 | struct dentry *expiring; | 230 | struct dentry *expiring; |
230 | struct qstr *qstr; | 231 | struct qstr *qstr; |
231 | 232 | ||
233 | if (rcu_walk) { | ||
234 | spin_unlock(&sbi->lookup_lock); | ||
235 | return ERR_PTR(-ECHILD); | ||
236 | } | ||
237 | |||
232 | ino = list_entry(p, struct autofs_info, expiring); | 238 | ino = list_entry(p, struct autofs_info, expiring); |
233 | expiring = ino->dentry; | 239 | expiring = ino->dentry; |
234 | 240 | ||
@@ -264,13 +270,15 @@ next: | |||
264 | return NULL; | 270 | return NULL; |
265 | } | 271 | } |
266 | 272 | ||
267 | static int autofs4_mount_wait(struct dentry *dentry) | 273 | static int autofs4_mount_wait(struct dentry *dentry, bool rcu_walk) |
268 | { | 274 | { |
269 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); | 275 | struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); |
270 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 276 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
271 | int status = 0; | 277 | int status = 0; |
272 | 278 | ||
273 | if (ino->flags & AUTOFS_INF_PENDING) { | 279 | if (ino->flags & AUTOFS_INF_PENDING) { |
280 | if (rcu_walk) | ||
281 | return -ECHILD; | ||
274 | DPRINTK("waiting for mount name=%.*s", | 282 | DPRINTK("waiting for mount name=%.*s", |
275 | dentry->d_name.len, dentry->d_name.name); | 283 | dentry->d_name.len, dentry->d_name.name); |
276 | status = autofs4_wait(sbi, dentry, NFY_MOUNT); | 284 | status = autofs4_wait(sbi, dentry, NFY_MOUNT); |
@@ -280,20 +288,22 @@ static int autofs4_mount_wait(struct dentry *dentry) | |||
280 | return status; | 288 | return status; |
281 | } | 289 | } |
282 | 290 | ||
283 | static int do_expire_wait(struct dentry *dentry) | 291 | static int do_expire_wait(struct dentry *dentry, bool rcu_walk) |
284 | { | 292 | { |
285 | struct dentry *expiring; | 293 | struct dentry *expiring; |
286 | 294 | ||
287 | expiring = autofs4_lookup_expiring(dentry); | 295 | expiring = autofs4_lookup_expiring(dentry, rcu_walk); |
296 | if (IS_ERR(expiring)) | ||
297 | return PTR_ERR(expiring); | ||
288 | if (!expiring) | 298 | if (!expiring) |
289 | return autofs4_expire_wait(dentry); | 299 | return autofs4_expire_wait(dentry, rcu_walk); |
290 | else { | 300 | else { |
291 | /* | 301 | /* |
292 | * If we are racing with expire the request might not | 302 | * If we are racing with expire the request might not |
293 | * be quite complete, but the directory has been removed | 303 | * be quite complete, but the directory has been removed |
294 | * so it must have been successful, just wait for it. | 304 | * so it must have been successful, just wait for it. |
295 | */ | 305 | */ |
296 | autofs4_expire_wait(expiring); | 306 | autofs4_expire_wait(expiring, 0); |
297 | autofs4_del_expiring(expiring); | 307 | autofs4_del_expiring(expiring); |
298 | dput(expiring); | 308 | dput(expiring); |
299 | } | 309 | } |
@@ -345,7 +355,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path) | |||
345 | * and the directory was removed, so just go ahead and try | 355 | * and the directory was removed, so just go ahead and try |
346 | * the mount. | 356 | * the mount. |
347 | */ | 357 | */ |
348 | status = do_expire_wait(dentry); | 358 | status = do_expire_wait(dentry, 0); |
349 | if (status && status != -EAGAIN) | 359 | if (status && status != -EAGAIN) |
350 | return NULL; | 360 | return NULL; |
351 | 361 | ||
@@ -353,7 +363,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path) | |||
353 | spin_lock(&sbi->fs_lock); | 363 | spin_lock(&sbi->fs_lock); |
354 | if (ino->flags & AUTOFS_INF_PENDING) { | 364 | if (ino->flags & AUTOFS_INF_PENDING) { |
355 | spin_unlock(&sbi->fs_lock); | 365 | spin_unlock(&sbi->fs_lock); |
356 | status = autofs4_mount_wait(dentry); | 366 | status = autofs4_mount_wait(dentry, 0); |
357 | if (status) | 367 | if (status) |
358 | return ERR_PTR(status); | 368 | return ERR_PTR(status); |
359 | goto done; | 369 | goto done; |
@@ -394,7 +404,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path) | |||
394 | } | 404 | } |
395 | ino->flags |= AUTOFS_INF_PENDING; | 405 | ino->flags |= AUTOFS_INF_PENDING; |
396 | spin_unlock(&sbi->fs_lock); | 406 | spin_unlock(&sbi->fs_lock); |
397 | status = autofs4_mount_wait(dentry); | 407 | status = autofs4_mount_wait(dentry, 0); |
398 | spin_lock(&sbi->fs_lock); | 408 | spin_lock(&sbi->fs_lock); |
399 | ino->flags &= ~AUTOFS_INF_PENDING; | 409 | ino->flags &= ~AUTOFS_INF_PENDING; |
400 | if (status) { | 410 | if (status) { |
@@ -423,28 +433,46 @@ static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk) | |||
423 | 433 | ||
424 | /* The daemon never waits. */ | 434 | /* The daemon never waits. */ |
425 | if (autofs4_oz_mode(sbi)) { | 435 | if (autofs4_oz_mode(sbi)) { |
426 | if (rcu_walk) | ||
427 | return 0; | ||
428 | if (!d_mountpoint(dentry)) | 436 | if (!d_mountpoint(dentry)) |
429 | return -EISDIR; | 437 | return -EISDIR; |
430 | return 0; | 438 | return 0; |
431 | } | 439 | } |
432 | 440 | ||
433 | /* We need to sleep, so we need pathwalk to be in ref-mode */ | ||
434 | if (rcu_walk) | ||
435 | return -ECHILD; | ||
436 | |||
437 | /* Wait for pending expires */ | 441 | /* Wait for pending expires */ |
438 | do_expire_wait(dentry); | 442 | if (do_expire_wait(dentry, rcu_walk) == -ECHILD) |
443 | return -ECHILD; | ||
439 | 444 | ||
440 | /* | 445 | /* |
441 | * This dentry may be under construction so wait on mount | 446 | * This dentry may be under construction so wait on mount |
442 | * completion. | 447 | * completion. |
443 | */ | 448 | */ |
444 | status = autofs4_mount_wait(dentry); | 449 | status = autofs4_mount_wait(dentry, rcu_walk); |
445 | if (status) | 450 | if (status) |
446 | return status; | 451 | return status; |
447 | 452 | ||
453 | if (rcu_walk) { | ||
454 | /* We don't need fs_lock in rcu_walk mode, | ||
455 | * just testing 'AUTOFS_INFO_NO_RCU' is enough. | ||
456 | * simple_empty() takes a spinlock, so leave it | ||
457 | * to last. | ||
458 | * We only return -EISDIR when certain this isn't | ||
459 | * a mount-trap. | ||
460 | */ | ||
461 | struct inode *inode; | ||
462 | if (ino->flags & (AUTOFS_INF_EXPIRING | AUTOFS_INF_NO_RCU)) | ||
463 | return 0; | ||
464 | if (d_mountpoint(dentry)) | ||
465 | return 0; | ||
466 | inode = ACCESS_ONCE(dentry->d_inode); | ||
467 | if (inode && S_ISLNK(inode->i_mode)) | ||
468 | return -EISDIR; | ||
469 | if (list_empty(&dentry->d_subdirs)) | ||
470 | return 0; | ||
471 | if (!simple_empty(dentry)) | ||
472 | return -EISDIR; | ||
473 | return 0; | ||
474 | } | ||
475 | |||
448 | spin_lock(&sbi->fs_lock); | 476 | spin_lock(&sbi->fs_lock); |
449 | /* | 477 | /* |
450 | * If the dentry has been selected for expire while we slept | 478 | * If the dentry has been selected for expire while we slept |
diff --git a/fs/befs/btree.c b/fs/befs/btree.c index 9c7faa8a9288..0826e91dacda 100644 --- a/fs/befs/btree.c +++ b/fs/befs/btree.c | |||
@@ -78,11 +78,11 @@ | |||
78 | /* | 78 | /* |
79 | * In memory structure of each btree node | 79 | * In memory structure of each btree node |
80 | */ | 80 | */ |
81 | typedef struct { | 81 | struct befs_btree_node { |
82 | befs_host_btree_nodehead head; /* head of node converted to cpu byteorder */ | 82 | befs_host_btree_nodehead head; /* head of node converted to cpu byteorder */ |
83 | struct buffer_head *bh; | 83 | struct buffer_head *bh; |
84 | befs_btree_nodehead *od_node; /* on disk node */ | 84 | befs_btree_nodehead *od_node; /* on disk node */ |
85 | } befs_btree_node; | 85 | }; |
86 | 86 | ||
87 | /* local constants */ | 87 | /* local constants */ |
88 | static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL; | 88 | static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL; |
@@ -90,27 +90,30 @@ static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL; | |||
90 | /* local functions */ | 90 | /* local functions */ |
91 | static int befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds, | 91 | static int befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds, |
92 | befs_btree_super * bt_super, | 92 | befs_btree_super * bt_super, |
93 | befs_btree_node * this_node, | 93 | struct befs_btree_node *this_node, |
94 | befs_off_t * node_off); | 94 | befs_off_t * node_off); |
95 | 95 | ||
96 | static int befs_bt_read_super(struct super_block *sb, befs_data_stream * ds, | 96 | static int befs_bt_read_super(struct super_block *sb, befs_data_stream * ds, |
97 | befs_btree_super * sup); | 97 | befs_btree_super * sup); |
98 | 98 | ||
99 | static int befs_bt_read_node(struct super_block *sb, befs_data_stream * ds, | 99 | static int befs_bt_read_node(struct super_block *sb, befs_data_stream * ds, |
100 | befs_btree_node * node, befs_off_t node_off); | 100 | struct befs_btree_node *node, |
101 | befs_off_t node_off); | ||
101 | 102 | ||
102 | static int befs_leafnode(befs_btree_node * node); | 103 | static int befs_leafnode(struct befs_btree_node *node); |
103 | 104 | ||
104 | static fs16 *befs_bt_keylen_index(befs_btree_node * node); | 105 | static fs16 *befs_bt_keylen_index(struct befs_btree_node *node); |
105 | 106 | ||
106 | static fs64 *befs_bt_valarray(befs_btree_node * node); | 107 | static fs64 *befs_bt_valarray(struct befs_btree_node *node); |
107 | 108 | ||
108 | static char *befs_bt_keydata(befs_btree_node * node); | 109 | static char *befs_bt_keydata(struct befs_btree_node *node); |
109 | 110 | ||
110 | static int befs_find_key(struct super_block *sb, befs_btree_node * node, | 111 | static int befs_find_key(struct super_block *sb, |
112 | struct befs_btree_node *node, | ||
111 | const char *findkey, befs_off_t * value); | 113 | const char *findkey, befs_off_t * value); |
112 | 114 | ||
113 | static char *befs_bt_get_key(struct super_block *sb, befs_btree_node * node, | 115 | static char *befs_bt_get_key(struct super_block *sb, |
116 | struct befs_btree_node *node, | ||
114 | int index, u16 * keylen); | 117 | int index, u16 * keylen); |
115 | 118 | ||
116 | static int befs_compare_strings(const void *key1, int keylen1, | 119 | static int befs_compare_strings(const void *key1, int keylen1, |
@@ -191,7 +194,7 @@ befs_bt_read_super(struct super_block *sb, befs_data_stream * ds, | |||
191 | 194 | ||
192 | static int | 195 | static int |
193 | befs_bt_read_node(struct super_block *sb, befs_data_stream * ds, | 196 | befs_bt_read_node(struct super_block *sb, befs_data_stream * ds, |
194 | befs_btree_node * node, befs_off_t node_off) | 197 | struct befs_btree_node *node, befs_off_t node_off) |
195 | { | 198 | { |
196 | uint off = 0; | 199 | uint off = 0; |
197 | 200 | ||
@@ -247,7 +250,7 @@ int | |||
247 | befs_btree_find(struct super_block *sb, befs_data_stream * ds, | 250 | befs_btree_find(struct super_block *sb, befs_data_stream * ds, |
248 | const char *key, befs_off_t * value) | 251 | const char *key, befs_off_t * value) |
249 | { | 252 | { |
250 | befs_btree_node *this_node = NULL; | 253 | struct befs_btree_node *this_node = NULL; |
251 | befs_btree_super bt_super; | 254 | befs_btree_super bt_super; |
252 | befs_off_t node_off; | 255 | befs_off_t node_off; |
253 | int res; | 256 | int res; |
@@ -260,11 +263,11 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds, | |||
260 | goto error; | 263 | goto error; |
261 | } | 264 | } |
262 | 265 | ||
263 | this_node = kmalloc(sizeof (befs_btree_node), | 266 | this_node = kmalloc(sizeof(struct befs_btree_node), |
264 | GFP_NOFS); | 267 | GFP_NOFS); |
265 | if (!this_node) { | 268 | if (!this_node) { |
266 | befs_error(sb, "befs_btree_find() failed to allocate %zu " | 269 | befs_error(sb, "befs_btree_find() failed to allocate %zu " |
267 | "bytes of memory", sizeof (befs_btree_node)); | 270 | "bytes of memory", sizeof(struct befs_btree_node)); |
268 | goto error; | 271 | goto error; |
269 | } | 272 | } |
270 | 273 | ||
@@ -333,7 +336,7 @@ befs_btree_find(struct super_block *sb, befs_data_stream * ds, | |||
333 | * Use binary search instead of a linear. | 336 | * Use binary search instead of a linear. |
334 | */ | 337 | */ |
335 | static int | 338 | static int |
336 | befs_find_key(struct super_block *sb, befs_btree_node * node, | 339 | befs_find_key(struct super_block *sb, struct befs_btree_node *node, |
337 | const char *findkey, befs_off_t * value) | 340 | const char *findkey, befs_off_t * value) |
338 | { | 341 | { |
339 | int first, last, mid; | 342 | int first, last, mid; |
@@ -417,7 +420,7 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds, | |||
417 | loff_t key_no, size_t bufsize, char *keybuf, size_t * keysize, | 420 | loff_t key_no, size_t bufsize, char *keybuf, size_t * keysize, |
418 | befs_off_t * value) | 421 | befs_off_t * value) |
419 | { | 422 | { |
420 | befs_btree_node *this_node; | 423 | struct befs_btree_node *this_node; |
421 | befs_btree_super bt_super; | 424 | befs_btree_super bt_super; |
422 | befs_off_t node_off = 0; | 425 | befs_off_t node_off = 0; |
423 | int cur_key; | 426 | int cur_key; |
@@ -436,9 +439,10 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds, | |||
436 | goto error; | 439 | goto error; |
437 | } | 440 | } |
438 | 441 | ||
439 | if ((this_node = kmalloc(sizeof (befs_btree_node), GFP_NOFS)) == NULL) { | 442 | this_node = kmalloc(sizeof(struct befs_btree_node), GFP_NOFS); |
443 | if (this_node == NULL) { | ||
440 | befs_error(sb, "befs_btree_read() failed to allocate %zu " | 444 | befs_error(sb, "befs_btree_read() failed to allocate %zu " |
441 | "bytes of memory", sizeof (befs_btree_node)); | 445 | "bytes of memory", sizeof(struct befs_btree_node)); |
442 | goto error; | 446 | goto error; |
443 | } | 447 | } |
444 | 448 | ||
@@ -545,7 +549,8 @@ befs_btree_read(struct super_block *sb, befs_data_stream * ds, | |||
545 | */ | 549 | */ |
546 | static int | 550 | static int |
547 | befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds, | 551 | befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds, |
548 | befs_btree_super * bt_super, befs_btree_node * this_node, | 552 | befs_btree_super *bt_super, |
553 | struct befs_btree_node *this_node, | ||
549 | befs_off_t * node_off) | 554 | befs_off_t * node_off) |
550 | { | 555 | { |
551 | 556 | ||
@@ -600,7 +605,7 @@ befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds, | |||
600 | * Return 1 if leaf, 0 if interior | 605 | * Return 1 if leaf, 0 if interior |
601 | */ | 606 | */ |
602 | static int | 607 | static int |
603 | befs_leafnode(befs_btree_node * node) | 608 | befs_leafnode(struct befs_btree_node *node) |
604 | { | 609 | { |
605 | /* all interior nodes (and only interior nodes) have an overflow node */ | 610 | /* all interior nodes (and only interior nodes) have an overflow node */ |
606 | if (node->head.overflow == befs_bt_inval) | 611 | if (node->head.overflow == befs_bt_inval) |
@@ -623,7 +628,7 @@ befs_leafnode(befs_btree_node * node) | |||
623 | * Except that rounding up to 8 works, and rounding up to 4 doesn't. | 628 | * Except that rounding up to 8 works, and rounding up to 4 doesn't. |
624 | */ | 629 | */ |
625 | static fs16 * | 630 | static fs16 * |
626 | befs_bt_keylen_index(befs_btree_node * node) | 631 | befs_bt_keylen_index(struct befs_btree_node *node) |
627 | { | 632 | { |
628 | const int keylen_align = 8; | 633 | const int keylen_align = 8; |
629 | unsigned long int off = | 634 | unsigned long int off = |
@@ -644,7 +649,7 @@ befs_bt_keylen_index(befs_btree_node * node) | |||
644 | * of the node pointed to by the node header | 649 | * of the node pointed to by the node header |
645 | */ | 650 | */ |
646 | static fs64 * | 651 | static fs64 * |
647 | befs_bt_valarray(befs_btree_node * node) | 652 | befs_bt_valarray(struct befs_btree_node *node) |
648 | { | 653 | { |
649 | void *keylen_index_start = (void *) befs_bt_keylen_index(node); | 654 | void *keylen_index_start = (void *) befs_bt_keylen_index(node); |
650 | size_t keylen_index_size = node->head.all_key_count * sizeof (fs16); | 655 | size_t keylen_index_size = node->head.all_key_count * sizeof (fs16); |
@@ -660,7 +665,7 @@ befs_bt_valarray(befs_btree_node * node) | |||
660 | * of the node pointed to by the node header | 665 | * of the node pointed to by the node header |
661 | */ | 666 | */ |
662 | static char * | 667 | static char * |
663 | befs_bt_keydata(befs_btree_node * node) | 668 | befs_bt_keydata(struct befs_btree_node *node) |
664 | { | 669 | { |
665 | return (char *) ((void *) node->od_node + sizeof (befs_btree_nodehead)); | 670 | return (char *) ((void *) node->od_node + sizeof (befs_btree_nodehead)); |
666 | } | 671 | } |
@@ -676,7 +681,7 @@ befs_bt_keydata(befs_btree_node * node) | |||
676 | * Returns NULL on failure (bad input) and sets *@keylen = 0 | 681 | * Returns NULL on failure (bad input) and sets *@keylen = 0 |
677 | */ | 682 | */ |
678 | static char * | 683 | static char * |
679 | befs_bt_get_key(struct super_block *sb, befs_btree_node * node, | 684 | befs_bt_get_key(struct super_block *sb, struct befs_btree_node *node, |
680 | int index, u16 * keylen) | 685 | int index, u16 * keylen) |
681 | { | 686 | { |
682 | int prev_key_end; | 687 | int prev_key_end; |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index b60500300dd7..fd8beb9657a2 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -62,7 +62,22 @@ static struct file_system_type bm_fs_type; | |||
62 | static struct vfsmount *bm_mnt; | 62 | static struct vfsmount *bm_mnt; |
63 | static int entry_count; | 63 | static int entry_count; |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Max length of the register string. Determined by: | ||
67 | * - 7 delimiters | ||
68 | * - name: ~50 bytes | ||
69 | * - type: 1 byte | ||
70 | * - offset: 3 bytes (has to be smaller than BINPRM_BUF_SIZE) | ||
71 | * - magic: 128 bytes (512 in escaped form) | ||
72 | * - mask: 128 bytes (512 in escaped form) | ||
73 | * - interp: ~50 bytes | ||
74 | * - flags: 5 bytes | ||
75 | * Round that up a bit, and then back off to hold the internal data | ||
76 | * (like struct Node). | ||
77 | */ | ||
78 | #define MAX_REGISTER_LENGTH 1920 | ||
79 | |||
80 | /* | ||
66 | * Check if we support the binfmt | 81 | * Check if we support the binfmt |
67 | * if we do, return the node, else NULL | 82 | * if we do, return the node, else NULL |
68 | * locking is done in load_misc_binary | 83 | * locking is done in load_misc_binary |
@@ -279,7 +294,7 @@ static Node *create_entry(const char __user *buffer, size_t count) | |||
279 | 294 | ||
280 | /* some sanity checks */ | 295 | /* some sanity checks */ |
281 | err = -EINVAL; | 296 | err = -EINVAL; |
282 | if ((count < 11) || (count > 256)) | 297 | if ((count < 11) || (count > MAX_REGISTER_LENGTH)) |
283 | goto out; | 298 | goto out; |
284 | 299 | ||
285 | err = -ENOMEM; | 300 | err = -ENOMEM; |
@@ -396,12 +411,12 @@ static int parse_command(const char __user *buffer, size_t count) | |||
396 | { | 411 | { |
397 | char s[4]; | 412 | char s[4]; |
398 | 413 | ||
399 | if (!count) | ||
400 | return 0; | ||
401 | if (count > 3) | 414 | if (count > 3) |
402 | return -EINVAL; | 415 | return -EINVAL; |
403 | if (copy_from_user(s, buffer, count)) | 416 | if (copy_from_user(s, buffer, count)) |
404 | return -EFAULT; | 417 | return -EFAULT; |
418 | if (!count) | ||
419 | return 0; | ||
405 | if (s[count-1] == '\n') | 420 | if (s[count-1] == '\n') |
406 | count--; | 421 | count--; |
407 | if (count == 1 && s[0] == '0') | 422 | if (count == 1 && s[0] == '0') |
diff --git a/fs/buffer.c b/fs/buffer.c index d1f704806264..9614adc7e754 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1331,8 +1331,8 @@ lookup_bh_lru(struct block_device *bdev, sector_t block, unsigned size) | |||
1331 | for (i = 0; i < BH_LRU_SIZE; i++) { | 1331 | for (i = 0; i < BH_LRU_SIZE; i++) { |
1332 | struct buffer_head *bh = __this_cpu_read(bh_lrus.bhs[i]); | 1332 | struct buffer_head *bh = __this_cpu_read(bh_lrus.bhs[i]); |
1333 | 1333 | ||
1334 | if (bh && bh->b_bdev == bdev && | 1334 | if (bh && bh->b_blocknr == block && bh->b_bdev == bdev && |
1335 | bh->b_blocknr == block && bh->b_size == size) { | 1335 | bh->b_size == size) { |
1336 | if (i) { | 1336 | if (i) { |
1337 | while (i) { | 1337 | while (i) { |
1338 | __this_cpu_write(bh_lrus.bhs[i], | 1338 | __this_cpu_write(bh_lrus.bhs[i], |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 58df174deb10..b8602f199815 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
@@ -195,15 +195,15 @@ char *cifs_compose_mount_options(const char *sb_mountdata, | |||
195 | else | 195 | else |
196 | noff = tkn_e - (sb_mountdata + off) + 1; | 196 | noff = tkn_e - (sb_mountdata + off) + 1; |
197 | 197 | ||
198 | if (strnicmp(sb_mountdata + off, "unc=", 4) == 0) { | 198 | if (strncasecmp(sb_mountdata + off, "unc=", 4) == 0) { |
199 | off += noff; | 199 | off += noff; |
200 | continue; | 200 | continue; |
201 | } | 201 | } |
202 | if (strnicmp(sb_mountdata + off, "ip=", 3) == 0) { | 202 | if (strncasecmp(sb_mountdata + off, "ip=", 3) == 0) { |
203 | off += noff; | 203 | off += noff; |
204 | continue; | 204 | continue; |
205 | } | 205 | } |
206 | if (strnicmp(sb_mountdata + off, "prefixpath=", 11) == 0) { | 206 | if (strncasecmp(sb_mountdata + off, "prefixpath=", 11) == 0) { |
207 | off += noff; | 207 | off += noff; |
208 | continue; | 208 | continue; |
209 | } | 209 | } |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 36ca2045009b..239e1fb33000 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1718,7 +1718,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1718 | goto cifs_parse_mount_err; | 1718 | goto cifs_parse_mount_err; |
1719 | } | 1719 | } |
1720 | 1720 | ||
1721 | if (strnicmp(string, "default", 7) != 0) { | 1721 | if (strncasecmp(string, "default", 7) != 0) { |
1722 | vol->iocharset = kstrdup(string, | 1722 | vol->iocharset = kstrdup(string, |
1723 | GFP_KERNEL); | 1723 | GFP_KERNEL); |
1724 | if (!vol->iocharset) { | 1724 | if (!vol->iocharset) { |
@@ -1790,7 +1790,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1790 | if (string == NULL) | 1790 | if (string == NULL) |
1791 | goto out_nomem; | 1791 | goto out_nomem; |
1792 | 1792 | ||
1793 | if (strnicmp(string, "1", 1) == 0) { | 1793 | if (strncasecmp(string, "1", 1) == 0) { |
1794 | /* This is the default */ | 1794 | /* This is the default */ |
1795 | break; | 1795 | break; |
1796 | } | 1796 | } |
diff --git a/fs/coredump.c b/fs/coredump.c index a93f7e6ea4cf..b5c86ffd5033 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -199,6 +199,14 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm) | |||
199 | err = cn_printf(cn, "%d", | 199 | err = cn_printf(cn, "%d", |
200 | task_tgid_nr(current)); | 200 | task_tgid_nr(current)); |
201 | break; | 201 | break; |
202 | case 'i': | ||
203 | err = cn_printf(cn, "%d", | ||
204 | task_pid_vnr(current)); | ||
205 | break; | ||
206 | case 'I': | ||
207 | err = cn_printf(cn, "%d", | ||
208 | task_pid_nr(current)); | ||
209 | break; | ||
202 | /* uid */ | 210 | /* uid */ |
203 | case 'u': | 211 | case 'u': |
204 | err = cn_printf(cn, "%d", cred->uid); | 212 | err = cn_printf(cn, "%d", cred->uid); |
diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 628e22a5a543..d8da2d2e30ae 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c | |||
@@ -164,8 +164,6 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster) | |||
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | extern struct timezone sys_tz; | ||
168 | |||
169 | /* | 167 | /* |
170 | * The epoch of FAT timestamp is 1980. | 168 | * The epoch of FAT timestamp is 1980. |
171 | * : bits : value | 169 | * : bits : value |
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index 0524cda47a6e..95d255219b1e 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -242,8 +242,6 @@ extern int hfs_mac2asc(struct super_block *, char *, const struct hfs_name *); | |||
242 | /* super.c */ | 242 | /* super.c */ |
243 | extern void hfs_mark_mdb_dirty(struct super_block *sb); | 243 | extern void hfs_mark_mdb_dirty(struct super_block *sb); |
244 | 244 | ||
245 | extern struct timezone sys_tz; | ||
246 | |||
247 | /* | 245 | /* |
248 | * There are two time systems. Both are based on seconds since | 246 | * There are two time systems. Both are based on seconds since |
249 | * a particular time/date. | 247 | * a particular time/date. |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 5ddaf8625d3b..881b3bd0143f 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -247,7 +247,7 @@ static int isofs_dentry_cmp_common( | |||
247 | } | 247 | } |
248 | if (alen == blen) { | 248 | if (alen == blen) { |
249 | if (ci) { | 249 | if (ci) { |
250 | if (strnicmp(name->name, str, alen) == 0) | 250 | if (strncasecmp(name->name, str, alen) == 0) |
251 | return 0; | 251 | return 0; |
252 | } else { | 252 | } else { |
253 | if (strncmp(name->name, str, alen) == 0) | 253 | if (strncmp(name->name, str, alen) == 0) |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 314e7add99b8..7cb751dfbeef 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -1178,9 +1178,6 @@ static int day_n[] = | |||
1178 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0}; | 1178 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0}; |
1179 | /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ | 1179 | /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ |
1180 | 1180 | ||
1181 | |||
1182 | extern struct timezone sys_tz; | ||
1183 | |||
1184 | static int utc2local(int time) | 1181 | static int utc2local(int time) |
1185 | { | 1182 | { |
1186 | return time - sys_tz.tz_minuteswest * 60; | 1183 | return time - sys_tz.tz_minuteswest * 60; |
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 24978153c0c4..e9e3325f29f3 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c | |||
@@ -56,11 +56,9 @@ int nilfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
56 | mutex_unlock(&inode->i_mutex); | 56 | mutex_unlock(&inode->i_mutex); |
57 | 57 | ||
58 | nilfs = inode->i_sb->s_fs_info; | 58 | nilfs = inode->i_sb->s_fs_info; |
59 | if (!err && nilfs_test_opt(nilfs, BARRIER)) { | 59 | if (!err) |
60 | err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); | 60 | err = nilfs_flush_device(nilfs); |
61 | if (err != -EIO) | 61 | |
62 | err = 0; | ||
63 | } | ||
64 | return err; | 62 | return err; |
65 | } | 63 | } |
66 | 64 | ||
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index d071e7f23de2..e1fa69b341b9 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -126,7 +126,7 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
126 | nilfs_transaction_abort(inode->i_sb); | 126 | nilfs_transaction_abort(inode->i_sb); |
127 | goto out; | 127 | goto out; |
128 | } | 128 | } |
129 | nilfs_mark_inode_dirty(inode); | 129 | nilfs_mark_inode_dirty_sync(inode); |
130 | nilfs_transaction_commit(inode->i_sb); /* never fails */ | 130 | nilfs_transaction_commit(inode->i_sb); /* never fails */ |
131 | /* Error handling should be detailed */ | 131 | /* Error handling should be detailed */ |
132 | set_buffer_new(bh_result); | 132 | set_buffer_new(bh_result); |
@@ -672,7 +672,7 @@ void nilfs_write_inode_common(struct inode *inode, | |||
672 | for substitutions of appended fields */ | 672 | for substitutions of appended fields */ |
673 | } | 673 | } |
674 | 674 | ||
675 | void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh) | 675 | void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh, int flags) |
676 | { | 676 | { |
677 | ino_t ino = inode->i_ino; | 677 | ino_t ino = inode->i_ino; |
678 | struct nilfs_inode_info *ii = NILFS_I(inode); | 678 | struct nilfs_inode_info *ii = NILFS_I(inode); |
@@ -683,7 +683,8 @@ void nilfs_update_inode(struct inode *inode, struct buffer_head *ibh) | |||
683 | 683 | ||
684 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) | 684 | if (test_and_clear_bit(NILFS_I_NEW, &ii->i_state)) |
685 | memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size); | 685 | memset(raw_inode, 0, NILFS_MDT(ifile)->mi_entry_size); |
686 | set_bit(NILFS_I_INODE_DIRTY, &ii->i_state); | 686 | if (flags & I_DIRTY_DATASYNC) |
687 | set_bit(NILFS_I_INODE_SYNC, &ii->i_state); | ||
687 | 688 | ||
688 | nilfs_write_inode_common(inode, raw_inode, 0); | 689 | nilfs_write_inode_common(inode, raw_inode, 0); |
689 | /* XXX: call with has_bmap = 0 is a workaround to avoid | 690 | /* XXX: call with has_bmap = 0 is a workaround to avoid |
@@ -939,7 +940,7 @@ int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty) | |||
939 | return 0; | 940 | return 0; |
940 | } | 941 | } |
941 | 942 | ||
942 | int nilfs_mark_inode_dirty(struct inode *inode) | 943 | int __nilfs_mark_inode_dirty(struct inode *inode, int flags) |
943 | { | 944 | { |
944 | struct buffer_head *ibh; | 945 | struct buffer_head *ibh; |
945 | int err; | 946 | int err; |
@@ -950,7 +951,7 @@ int nilfs_mark_inode_dirty(struct inode *inode) | |||
950 | "failed to reget inode block.\n"); | 951 | "failed to reget inode block.\n"); |
951 | return err; | 952 | return err; |
952 | } | 953 | } |
953 | nilfs_update_inode(inode, ibh); | 954 | nilfs_update_inode(inode, ibh, flags); |
954 | mark_buffer_dirty(ibh); | 955 | mark_buffer_dirty(ibh); |
955 | nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile); | 956 | nilfs_mdt_mark_dirty(NILFS_I(inode)->i_root->ifile); |
956 | brelse(ibh); | 957 | brelse(ibh); |
@@ -983,7 +984,7 @@ void nilfs_dirty_inode(struct inode *inode, int flags) | |||
983 | return; | 984 | return; |
984 | } | 985 | } |
985 | nilfs_transaction_begin(inode->i_sb, &ti, 0); | 986 | nilfs_transaction_begin(inode->i_sb, &ti, 0); |
986 | nilfs_mark_inode_dirty(inode); | 987 | __nilfs_mark_inode_dirty(inode, flags); |
987 | nilfs_transaction_commit(inode->i_sb); /* never fails */ | 988 | nilfs_transaction_commit(inode->i_sb); /* never fails */ |
988 | } | 989 | } |
989 | 990 | ||
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 422fb54b7377..9a20e513d7eb 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -1022,11 +1022,9 @@ static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, | |||
1022 | return ret; | 1022 | return ret; |
1023 | 1023 | ||
1024 | nilfs = inode->i_sb->s_fs_info; | 1024 | nilfs = inode->i_sb->s_fs_info; |
1025 | if (nilfs_test_opt(nilfs, BARRIER)) { | 1025 | ret = nilfs_flush_device(nilfs); |
1026 | ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); | 1026 | if (ret < 0) |
1027 | if (ret == -EIO) | 1027 | return ret; |
1028 | return ret; | ||
1029 | } | ||
1030 | 1028 | ||
1031 | if (argp != NULL) { | 1029 | if (argp != NULL) { |
1032 | down_read(&nilfs->ns_segctor_sem); | 1030 | down_read(&nilfs->ns_segctor_sem); |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 0696161bf59d..91093cd74f0d 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
@@ -104,7 +104,7 @@ enum { | |||
104 | constructor */ | 104 | constructor */ |
105 | NILFS_I_COLLECTED, /* All dirty blocks are collected */ | 105 | NILFS_I_COLLECTED, /* All dirty blocks are collected */ |
106 | NILFS_I_UPDATED, /* The file has been written back */ | 106 | NILFS_I_UPDATED, /* The file has been written back */ |
107 | NILFS_I_INODE_DIRTY, /* write_inode is requested */ | 107 | NILFS_I_INODE_SYNC, /* dsync is not allowed for inode */ |
108 | NILFS_I_BMAP, /* has bmap and btnode_cache */ | 108 | NILFS_I_BMAP, /* has bmap and btnode_cache */ |
109 | NILFS_I_GCINODE, /* inode for GC, on memory only */ | 109 | NILFS_I_GCINODE, /* inode for GC, on memory only */ |
110 | }; | 110 | }; |
@@ -273,7 +273,7 @@ struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, | |||
273 | unsigned long ino); | 273 | unsigned long ino); |
274 | extern struct inode *nilfs_iget_for_gc(struct super_block *sb, | 274 | extern struct inode *nilfs_iget_for_gc(struct super_block *sb, |
275 | unsigned long ino, __u64 cno); | 275 | unsigned long ino, __u64 cno); |
276 | extern void nilfs_update_inode(struct inode *, struct buffer_head *); | 276 | extern void nilfs_update_inode(struct inode *, struct buffer_head *, int); |
277 | extern void nilfs_truncate(struct inode *); | 277 | extern void nilfs_truncate(struct inode *); |
278 | extern void nilfs_evict_inode(struct inode *); | 278 | extern void nilfs_evict_inode(struct inode *); |
279 | extern int nilfs_setattr(struct dentry *, struct iattr *); | 279 | extern int nilfs_setattr(struct dentry *, struct iattr *); |
@@ -282,10 +282,18 @@ int nilfs_permission(struct inode *inode, int mask); | |||
282 | int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); | 282 | int nilfs_load_inode_block(struct inode *inode, struct buffer_head **pbh); |
283 | extern int nilfs_inode_dirty(struct inode *); | 283 | extern int nilfs_inode_dirty(struct inode *); |
284 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); | 284 | int nilfs_set_file_dirty(struct inode *inode, unsigned nr_dirty); |
285 | extern int nilfs_mark_inode_dirty(struct inode *); | 285 | extern int __nilfs_mark_inode_dirty(struct inode *, int); |
286 | extern void nilfs_dirty_inode(struct inode *, int flags); | 286 | extern void nilfs_dirty_inode(struct inode *, int flags); |
287 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 287 | int nilfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
288 | __u64 start, __u64 len); | 288 | __u64 start, __u64 len); |
289 | static inline int nilfs_mark_inode_dirty(struct inode *inode) | ||
290 | { | ||
291 | return __nilfs_mark_inode_dirty(inode, I_DIRTY); | ||
292 | } | ||
293 | static inline int nilfs_mark_inode_dirty_sync(struct inode *inode) | ||
294 | { | ||
295 | return __nilfs_mark_inode_dirty(inode, I_DIRTY_SYNC); | ||
296 | } | ||
289 | 297 | ||
290 | /* super.c */ | 298 | /* super.c */ |
291 | extern struct inode *nilfs_alloc_inode(struct super_block *); | 299 | extern struct inode *nilfs_alloc_inode(struct super_block *); |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index a1a191634abc..7ef18fc656c2 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -930,7 +930,7 @@ static void nilfs_drop_collected_inodes(struct list_head *head) | |||
930 | if (!test_and_clear_bit(NILFS_I_COLLECTED, &ii->i_state)) | 930 | if (!test_and_clear_bit(NILFS_I_COLLECTED, &ii->i_state)) |
931 | continue; | 931 | continue; |
932 | 932 | ||
933 | clear_bit(NILFS_I_INODE_DIRTY, &ii->i_state); | 933 | clear_bit(NILFS_I_INODE_SYNC, &ii->i_state); |
934 | set_bit(NILFS_I_UPDATED, &ii->i_state); | 934 | set_bit(NILFS_I_UPDATED, &ii->i_state); |
935 | } | 935 | } |
936 | } | 936 | } |
@@ -1833,6 +1833,7 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
1833 | nilfs_set_next_segment(nilfs, segbuf); | 1833 | nilfs_set_next_segment(nilfs, segbuf); |
1834 | 1834 | ||
1835 | if (update_sr) { | 1835 | if (update_sr) { |
1836 | nilfs->ns_flushed_device = 0; | ||
1836 | nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, | 1837 | nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, |
1837 | segbuf->sb_sum.seg_seq, nilfs->ns_cno++); | 1838 | segbuf->sb_sum.seg_seq, nilfs->ns_cno++); |
1838 | 1839 | ||
@@ -2194,7 +2195,7 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode, | |||
2194 | nilfs_transaction_lock(sb, &ti, 0); | 2195 | nilfs_transaction_lock(sb, &ti, 0); |
2195 | 2196 | ||
2196 | ii = NILFS_I(inode); | 2197 | ii = NILFS_I(inode); |
2197 | if (test_bit(NILFS_I_INODE_DIRTY, &ii->i_state) || | 2198 | if (test_bit(NILFS_I_INODE_SYNC, &ii->i_state) || |
2198 | nilfs_test_opt(nilfs, STRICT_ORDER) || | 2199 | nilfs_test_opt(nilfs, STRICT_ORDER) || |
2199 | test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) || | 2200 | test_bit(NILFS_SC_UNCLOSED, &sci->sc_flags) || |
2200 | nilfs_discontinued(nilfs)) { | 2201 | nilfs_discontinued(nilfs)) { |
@@ -2216,6 +2217,8 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode, | |||
2216 | sci->sc_dsync_end = end; | 2217 | sci->sc_dsync_end = end; |
2217 | 2218 | ||
2218 | err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC); | 2219 | err = nilfs_segctor_do_construct(sci, SC_LSEG_DSYNC); |
2220 | if (!err) | ||
2221 | nilfs->ns_flushed_device = 0; | ||
2219 | 2222 | ||
2220 | nilfs_transaction_unlock(sb); | 2223 | nilfs_transaction_unlock(sb); |
2221 | return err; | 2224 | return err; |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 228f5bdf0772..2e5b3ec85b8f 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -310,6 +310,9 @@ int nilfs_commit_super(struct super_block *sb, int flag) | |||
310 | nilfs->ns_sbsize)); | 310 | nilfs->ns_sbsize)); |
311 | } | 311 | } |
312 | clear_nilfs_sb_dirty(nilfs); | 312 | clear_nilfs_sb_dirty(nilfs); |
313 | nilfs->ns_flushed_device = 1; | ||
314 | /* make sure store to ns_flushed_device cannot be reordered */ | ||
315 | smp_wmb(); | ||
313 | return nilfs_sync_super(sb, flag); | 316 | return nilfs_sync_super(sb, flag); |
314 | } | 317 | } |
315 | 318 | ||
@@ -514,6 +517,9 @@ static int nilfs_sync_fs(struct super_block *sb, int wait) | |||
514 | } | 517 | } |
515 | up_write(&nilfs->ns_sem); | 518 | up_write(&nilfs->ns_sem); |
516 | 519 | ||
520 | if (!err) | ||
521 | err = nilfs_flush_device(nilfs); | ||
522 | |||
517 | return err; | 523 | return err; |
518 | } | 524 | } |
519 | 525 | ||
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index d01ead1bea9a..23778d385836 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -46,6 +46,7 @@ enum { | |||
46 | /** | 46 | /** |
47 | * struct the_nilfs - struct to supervise multiple nilfs mount points | 47 | * struct the_nilfs - struct to supervise multiple nilfs mount points |
48 | * @ns_flags: flags | 48 | * @ns_flags: flags |
49 | * @ns_flushed_device: flag indicating if all volatile data was flushed | ||
49 | * @ns_bdev: block device | 50 | * @ns_bdev: block device |
50 | * @ns_sem: semaphore for shared states | 51 | * @ns_sem: semaphore for shared states |
51 | * @ns_snapshot_mount_mutex: mutex to protect snapshot mounts | 52 | * @ns_snapshot_mount_mutex: mutex to protect snapshot mounts |
@@ -103,6 +104,7 @@ enum { | |||
103 | */ | 104 | */ |
104 | struct the_nilfs { | 105 | struct the_nilfs { |
105 | unsigned long ns_flags; | 106 | unsigned long ns_flags; |
107 | int ns_flushed_device; | ||
106 | 108 | ||
107 | struct block_device *ns_bdev; | 109 | struct block_device *ns_bdev; |
108 | struct rw_semaphore ns_sem; | 110 | struct rw_semaphore ns_sem; |
@@ -371,4 +373,24 @@ static inline int nilfs_segment_is_active(struct the_nilfs *nilfs, __u64 n) | |||
371 | return n == nilfs->ns_segnum || n == nilfs->ns_nextnum; | 373 | return n == nilfs->ns_segnum || n == nilfs->ns_nextnum; |
372 | } | 374 | } |
373 | 375 | ||
376 | static inline int nilfs_flush_device(struct the_nilfs *nilfs) | ||
377 | { | ||
378 | int err; | ||
379 | |||
380 | if (!nilfs_test_opt(nilfs, BARRIER) || nilfs->ns_flushed_device) | ||
381 | return 0; | ||
382 | |||
383 | nilfs->ns_flushed_device = 1; | ||
384 | /* | ||
385 | * the store to ns_flushed_device must not be reordered after | ||
386 | * blkdev_issue_flush(). | ||
387 | */ | ||
388 | smp_wmb(); | ||
389 | |||
390 | err = blkdev_issue_flush(nilfs->ns_bdev, GFP_KERNEL, NULL); | ||
391 | if (err != -EIO) | ||
392 | err = 0; | ||
393 | return err; | ||
394 | } | ||
395 | |||
374 | #endif /* _THE_NILFS_H */ | 396 | #endif /* _THE_NILFS_H */ |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index d13385448168..eb9d48746ab4 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -2244,7 +2244,7 @@ ssize_t o2hb_heartbeat_group_mode_store(struct o2hb_heartbeat_group *group, | |||
2244 | return -EINVAL; | 2244 | return -EINVAL; |
2245 | 2245 | ||
2246 | for (i = 0; i < O2HB_HEARTBEAT_NUM_MODES; ++i) { | 2246 | for (i = 0; i < O2HB_HEARTBEAT_NUM_MODES; ++i) { |
2247 | if (strnicmp(page, o2hb_heartbeat_mode_desc[i], len)) | 2247 | if (strncasecmp(page, o2hb_heartbeat_mode_desc[i], len)) |
2248 | continue; | 2248 | continue; |
2249 | 2249 | ||
2250 | ret = o2hb_global_heartbeat_mode_set(i); | 2250 | ret = o2hb_global_heartbeat_mode_set(i); |
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index 07ac24fd9252..af7598bff1b5 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c | |||
@@ -49,13 +49,13 @@ static ssize_t mlog_mask_show(u64 mask, char *buf) | |||
49 | 49 | ||
50 | static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) | 50 | static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count) |
51 | { | 51 | { |
52 | if (!strnicmp(buf, "allow", 5)) { | 52 | if (!strncasecmp(buf, "allow", 5)) { |
53 | __mlog_set_u64(mask, mlog_and_bits); | 53 | __mlog_set_u64(mask, mlog_and_bits); |
54 | __mlog_clear_u64(mask, mlog_not_bits); | 54 | __mlog_clear_u64(mask, mlog_not_bits); |
55 | } else if (!strnicmp(buf, "deny", 4)) { | 55 | } else if (!strncasecmp(buf, "deny", 4)) { |
56 | __mlog_set_u64(mask, mlog_not_bits); | 56 | __mlog_set_u64(mask, mlog_not_bits); |
57 | __mlog_clear_u64(mask, mlog_and_bits); | 57 | __mlog_clear_u64(mask, mlog_and_bits); |
58 | } else if (!strnicmp(buf, "off", 3)) { | 58 | } else if (!strncasecmp(buf, "off", 3)) { |
59 | __mlog_clear_u64(mask, mlog_not_bits); | 59 | __mlog_clear_u64(mask, mlog_not_bits); |
60 | __mlog_clear_u64(mask, mlog_and_bits); | 60 | __mlog_clear_u64(mask, mlog_and_bits); |
61 | } else | 61 | } else |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index ba8819702c56..138321b0c6c2 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
@@ -306,9 +306,7 @@ static const struct super_operations omfs_sops = { | |||
306 | */ | 306 | */ |
307 | static int omfs_get_imap(struct super_block *sb) | 307 | static int omfs_get_imap(struct super_block *sb) |
308 | { | 308 | { |
309 | int bitmap_size; | 309 | unsigned int bitmap_size, count, array_size; |
310 | int array_size; | ||
311 | int count; | ||
312 | struct omfs_sb_info *sbi = OMFS_SB(sb); | 310 | struct omfs_sb_info *sbi = OMFS_SB(sb); |
313 | struct buffer_head *bh; | 311 | struct buffer_head *bh; |
314 | unsigned long **ptr; | 312 | unsigned long **ptr; |
@@ -473,6 +471,12 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) | |||
473 | sbi->s_sys_blocksize = be32_to_cpu(omfs_sb->s_sys_blocksize); | 471 | sbi->s_sys_blocksize = be32_to_cpu(omfs_sb->s_sys_blocksize); |
474 | mutex_init(&sbi->s_bitmap_lock); | 472 | mutex_init(&sbi->s_bitmap_lock); |
475 | 473 | ||
474 | if (sbi->s_num_blocks > OMFS_MAX_BLOCKS) { | ||
475 | printk(KERN_ERR "omfs: sysblock number (%llx) is out of range\n", | ||
476 | (unsigned long long)sbi->s_num_blocks); | ||
477 | goto out_brelse_bh; | ||
478 | } | ||
479 | |||
476 | if (sbi->s_sys_blocksize > PAGE_SIZE) { | 480 | if (sbi->s_sys_blocksize > PAGE_SIZE) { |
477 | printk(KERN_ERR "omfs: sysblock size (%d) is out of range\n", | 481 | printk(KERN_ERR "omfs: sysblock size (%d) is out of range\n", |
478 | sbi->s_sys_blocksize); | 482 | sbi->s_sys_blocksize); |
diff --git a/fs/omfs/omfs_fs.h b/fs/omfs/omfs_fs.h index ee5e4327de92..83a98330ed66 100644 --- a/fs/omfs/omfs_fs.h +++ b/fs/omfs/omfs_fs.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define OMFS_XOR_COUNT 19 | 18 | #define OMFS_XOR_COUNT 19 |
19 | #define OMFS_MAX_BLOCK_SIZE 8192 | 19 | #define OMFS_MAX_BLOCK_SIZE 8192 |
20 | #define OMFS_MAX_CLUSTER_SIZE 8 | 20 | #define OMFS_MAX_CLUSTER_SIZE 8 |
21 | #define OMFS_MAX_BLOCKS (1ul << 31) | ||
21 | 22 | ||
22 | struct omfs_super_block { | 23 | struct omfs_super_block { |
23 | char s_fill1[256]; | 24 | char s_fill1[256]; |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index b7a7dc963a35..4e0388cffe3d 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -827,8 +827,21 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
827 | .private = &cp, | 827 | .private = &cp, |
828 | }; | 828 | }; |
829 | down_read(&mm->mmap_sem); | 829 | down_read(&mm->mmap_sem); |
830 | if (type == CLEAR_REFS_SOFT_DIRTY) | 830 | if (type == CLEAR_REFS_SOFT_DIRTY) { |
831 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | ||
832 | if (!(vma->vm_flags & VM_SOFTDIRTY)) | ||
833 | continue; | ||
834 | up_read(&mm->mmap_sem); | ||
835 | down_write(&mm->mmap_sem); | ||
836 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | ||
837 | vma->vm_flags &= ~VM_SOFTDIRTY; | ||
838 | vma_set_page_prot(vma); | ||
839 | } | ||
840 | downgrade_write(&mm->mmap_sem); | ||
841 | break; | ||
842 | } | ||
831 | mmu_notifier_invalidate_range_start(mm, 0, -1); | 843 | mmu_notifier_invalidate_range_start(mm, 0, -1); |
844 | } | ||
832 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 845 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
833 | cp.vma = vma; | 846 | cp.vma = vma; |
834 | if (is_vm_hugetlb_page(vma)) | 847 | if (is_vm_hugetlb_page(vma)) |
@@ -848,10 +861,6 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
848 | continue; | 861 | continue; |
849 | if (type == CLEAR_REFS_MAPPED && !vma->vm_file) | 862 | if (type == CLEAR_REFS_MAPPED && !vma->vm_file) |
850 | continue; | 863 | continue; |
851 | if (type == CLEAR_REFS_SOFT_DIRTY) { | ||
852 | if (vma->vm_flags & VM_SOFTDIRTY) | ||
853 | vma->vm_flags &= ~VM_SOFTDIRTY; | ||
854 | } | ||
855 | walk_page_range(vma->vm_start, vma->vm_end, | 864 | walk_page_range(vma->vm_start, vma->vm_end, |
856 | &clear_refs_walk); | 865 | &clear_refs_walk); |
857 | } | 866 | } |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index a88b1b3e7db3..d571e173a990 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -699,11 +699,13 @@ static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh, | |||
699 | chunk->bh[chunk->nr++] = bh; | 699 | chunk->bh[chunk->nr++] = bh; |
700 | if (chunk->nr >= CHUNK_SIZE) { | 700 | if (chunk->nr >= CHUNK_SIZE) { |
701 | ret = 1; | 701 | ret = 1; |
702 | if (lock) | 702 | if (lock) { |
703 | spin_unlock(lock); | 703 | spin_unlock(lock); |
704 | fn(chunk); | 704 | fn(chunk); |
705 | if (lock) | ||
706 | spin_lock(lock); | 705 | spin_lock(lock); |
706 | } else { | ||
707 | fn(chunk); | ||
708 | } | ||
707 | } | 709 | } |
708 | return ret; | 710 | return ret; |
709 | } | 711 | } |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 7bc20809c99e..2c1036080d52 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -784,7 +784,6 @@ static u64 ufs_bitmap_search(struct super_block *sb, | |||
784 | 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe | 784 | 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe |
785 | }; | 785 | }; |
786 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; | 786 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
787 | struct ufs_cylinder_group *ucg; | ||
788 | unsigned start, length, loc; | 787 | unsigned start, length, loc; |
789 | unsigned pos, want, blockmap, mask, end; | 788 | unsigned pos, want, blockmap, mask, end; |
790 | u64 result; | 789 | u64 result; |
@@ -792,8 +791,6 @@ static u64 ufs_bitmap_search(struct super_block *sb, | |||
792 | UFSD("ENTER, cg %u, goal %llu, count %u\n", ucpi->c_cgx, | 791 | UFSD("ENTER, cg %u, goal %llu, count %u\n", ucpi->c_cgx, |
793 | (unsigned long long)goal, count); | 792 | (unsigned long long)goal, count); |
794 | 793 | ||
795 | ucg = ubh_get_ucg(UCPI_UBH(ucpi)); | ||
796 | |||
797 | if (goal) | 794 | if (goal) |
798 | start = ufs_dtogd(uspi, goal) >> 3; | 795 | start = ufs_dtogd(uspi, goal) >> 3; |
799 | else | 796 | else |
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 081ff8826bf6..752e30d63904 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
@@ -253,6 +253,20 @@ static inline int pmd_same(pmd_t pmd_a, pmd_t pmd_b) | |||
253 | #define pgprot_device pgprot_noncached | 253 | #define pgprot_device pgprot_noncached |
254 | #endif | 254 | #endif |
255 | 255 | ||
256 | #ifndef pgprot_modify | ||
257 | #define pgprot_modify pgprot_modify | ||
258 | static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | ||
259 | { | ||
260 | if (pgprot_val(oldprot) == pgprot_val(pgprot_noncached(oldprot))) | ||
261 | newprot = pgprot_noncached(newprot); | ||
262 | if (pgprot_val(oldprot) == pgprot_val(pgprot_writecombine(oldprot))) | ||
263 | newprot = pgprot_writecombine(newprot); | ||
264 | if (pgprot_val(oldprot) == pgprot_val(pgprot_device(oldprot))) | ||
265 | newprot = pgprot_device(newprot); | ||
266 | return newprot; | ||
267 | } | ||
268 | #endif | ||
269 | |||
256 | /* | 270 | /* |
257 | * When walking page tables, get the address of the next boundary, | 271 | * When walking page tables, get the address of the next boundary, |
258 | * or the end address of the range if that comes earlier. Although no | 272 | * or the end address of the range if that comes earlier. Although no |
diff --git a/include/linux/cma.h b/include/linux/cma.h index 371b93042520..0430ed05d3b9 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h | |||
@@ -22,6 +22,9 @@ extern int __init cma_declare_contiguous(phys_addr_t size, | |||
22 | phys_addr_t base, phys_addr_t limit, | 22 | phys_addr_t base, phys_addr_t limit, |
23 | phys_addr_t alignment, unsigned int order_per_bit, | 23 | phys_addr_t alignment, unsigned int order_per_bit, |
24 | bool fixed, struct cma **res_cma); | 24 | bool fixed, struct cma **res_cma); |
25 | extern int cma_init_reserved_mem(phys_addr_t size, | ||
26 | phys_addr_t base, int order_per_bit, | ||
27 | struct cma **res_cma); | ||
25 | extern struct page *cma_alloc(struct cma *cma, int count, unsigned int align); | 28 | extern struct page *cma_alloc(struct cma *cma, int count, unsigned int align); |
26 | extern bool cma_release(struct cma *cma, struct page *pages, int count); | 29 | extern bool cma_release(struct cma *cma, struct page *pages, int count); |
27 | #endif | 30 | #endif |
diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h new file mode 100644 index 000000000000..cdd1cc202d51 --- /dev/null +++ b/include/linux/compiler-gcc5.h | |||
@@ -0,0 +1,66 @@ | |||
1 | #ifndef __LINUX_COMPILER_H | ||
2 | #error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead." | ||
3 | #endif | ||
4 | |||
5 | #define __used __attribute__((__used__)) | ||
6 | #define __must_check __attribute__((warn_unused_result)) | ||
7 | #define __compiler_offsetof(a, b) __builtin_offsetof(a, b) | ||
8 | |||
9 | /* Mark functions as cold. gcc will assume any path leading to a call | ||
10 | to them will be unlikely. This means a lot of manual unlikely()s | ||
11 | are unnecessary now for any paths leading to the usual suspects | ||
12 | like BUG(), printk(), panic() etc. [but let's keep them for now for | ||
13 | older compilers] | ||
14 | |||
15 | Early snapshots of gcc 4.3 don't support this and we can't detect this | ||
16 | in the preprocessor, but we can live with this because they're unreleased. | ||
17 | Maketime probing would be overkill here. | ||
18 | |||
19 | gcc also has a __attribute__((__hot__)) to move hot functions into | ||
20 | a special section, but I don't see any sense in this right now in | ||
21 | the kernel context */ | ||
22 | #define __cold __attribute__((__cold__)) | ||
23 | |||
24 | #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) | ||
25 | |||
26 | #ifndef __CHECKER__ | ||
27 | # define __compiletime_warning(message) __attribute__((warning(message))) | ||
28 | # define __compiletime_error(message) __attribute__((error(message))) | ||
29 | #endif /* __CHECKER__ */ | ||
30 | |||
31 | /* | ||
32 | * Mark a position in code as unreachable. This can be used to | ||
33 | * suppress control flow warnings after asm blocks that transfer | ||
34 | * control elsewhere. | ||
35 | * | ||
36 | * Early snapshots of gcc 4.5 don't support this and we can't detect | ||
37 | * this in the preprocessor, but we can live with this because they're | ||
38 | * unreleased. Really, we need to have autoconf for the kernel. | ||
39 | */ | ||
40 | #define unreachable() __builtin_unreachable() | ||
41 | |||
42 | /* Mark a function definition as prohibited from being cloned. */ | ||
43 | #define __noclone __attribute__((__noclone__)) | ||
44 | |||
45 | /* | ||
46 | * Tell the optimizer that something else uses this function or variable. | ||
47 | */ | ||
48 | #define __visible __attribute__((externally_visible)) | ||
49 | |||
50 | /* | ||
51 | * GCC 'asm goto' miscompiles certain code sequences: | ||
52 | * | ||
53 | * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 | ||
54 | * | ||
55 | * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. | ||
56 | * Fixed in GCC 4.8.2 and later versions. | ||
57 | * | ||
58 | * (asm goto is automatically volatile - the naming reflects this.) | ||
59 | */ | ||
60 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) | ||
61 | |||
62 | #ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP | ||
63 | #define __HAVE_BUILTIN_BSWAP32__ | ||
64 | #define __HAVE_BUILTIN_BSWAP64__ | ||
65 | #define __HAVE_BUILTIN_BSWAP16__ | ||
66 | #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */ | ||
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 35c8ffb0136f..40728cf1c452 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -376,10 +376,6 @@ extern unsigned long simple_strtoul(const char *,char **,unsigned int); | |||
376 | extern long simple_strtol(const char *,char **,unsigned int); | 376 | extern long simple_strtol(const char *,char **,unsigned int); |
377 | extern unsigned long long simple_strtoull(const char *,char **,unsigned int); | 377 | extern unsigned long long simple_strtoull(const char *,char **,unsigned int); |
378 | extern long long simple_strtoll(const char *,char **,unsigned int); | 378 | extern long long simple_strtoll(const char *,char **,unsigned int); |
379 | #define strict_strtoul kstrtoul | ||
380 | #define strict_strtol kstrtol | ||
381 | #define strict_strtoull kstrtoull | ||
382 | #define strict_strtoll kstrtoll | ||
383 | 379 | ||
384 | extern int num_to_str(char *buf, int size, unsigned long long num); | 380 | extern int num_to_str(char *buf, int size, unsigned long long num); |
385 | 381 | ||
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 4b2a0e11cc5b..9d957b7ae095 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h | |||
@@ -178,6 +178,7 @@ struct kexec_buf { | |||
178 | struct kimage *image; | 178 | struct kimage *image; |
179 | char *buffer; | 179 | char *buffer; |
180 | unsigned long bufsz; | 180 | unsigned long bufsz; |
181 | unsigned long mem; | ||
181 | unsigned long memsz; | 182 | unsigned long memsz; |
182 | unsigned long buf_align; | 183 | unsigned long buf_align; |
183 | unsigned long buf_min; | 184 | unsigned long buf_min; |
diff --git a/include/linux/list.h b/include/linux/list.h index cbbb96fcead9..f33f831eb3c8 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/stddef.h> | 5 | #include <linux/stddef.h> |
6 | #include <linux/poison.h> | 6 | #include <linux/poison.h> |
7 | #include <linux/const.h> | 7 | #include <linux/const.h> |
8 | #include <linux/kernel.h> | ||
8 | 9 | ||
9 | /* | 10 | /* |
10 | * Simple doubly linked list implementation. | 11 | * Simple doubly linked list implementation. |
diff --git a/include/linux/mm.h b/include/linux/mm.h index fa0d74e06428..02d11ee7f19d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -347,6 +347,7 @@ static inline int put_page_unless_one(struct page *page) | |||
347 | } | 347 | } |
348 | 348 | ||
349 | extern int page_is_ram(unsigned long pfn); | 349 | extern int page_is_ram(unsigned long pfn); |
350 | extern int region_is_ram(resource_size_t phys_addr, unsigned long size); | ||
350 | 351 | ||
351 | /* Support for virtually mapped pages */ | 352 | /* Support for virtually mapped pages */ |
352 | struct page *vmalloc_to_page(const void *addr); | 353 | struct page *vmalloc_to_page(const void *addr); |
@@ -1973,11 +1974,16 @@ static inline struct vm_area_struct *find_exact_vma(struct mm_struct *mm, | |||
1973 | 1974 | ||
1974 | #ifdef CONFIG_MMU | 1975 | #ifdef CONFIG_MMU |
1975 | pgprot_t vm_get_page_prot(unsigned long vm_flags); | 1976 | pgprot_t vm_get_page_prot(unsigned long vm_flags); |
1977 | void vma_set_page_prot(struct vm_area_struct *vma); | ||
1976 | #else | 1978 | #else |
1977 | static inline pgprot_t vm_get_page_prot(unsigned long vm_flags) | 1979 | static inline pgprot_t vm_get_page_prot(unsigned long vm_flags) |
1978 | { | 1980 | { |
1979 | return __pgprot(0); | 1981 | return __pgprot(0); |
1980 | } | 1982 | } |
1983 | static inline void vma_set_page_prot(struct vm_area_struct *vma) | ||
1984 | { | ||
1985 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | ||
1986 | } | ||
1981 | #endif | 1987 | #endif |
1982 | 1988 | ||
1983 | #ifdef CONFIG_NUMA_BALANCING | 1989 | #ifdef CONFIG_NUMA_BALANCING |
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index b43f4752304e..1c9effa25e26 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h | |||
@@ -78,6 +78,8 @@ struct kernel_param { | |||
78 | }; | 78 | }; |
79 | }; | 79 | }; |
80 | 80 | ||
81 | extern const struct kernel_param __start___param[], __stop___param[]; | ||
82 | |||
81 | /* Special one for strings we want to copy into */ | 83 | /* Special one for strings we want to copy into */ |
82 | struct kparam_string { | 84 | struct kparam_string { |
83 | unsigned int maxlen; | 85 | unsigned int maxlen; |
diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 1d2a6ab6b8bb..9b2022ab4d85 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h | |||
@@ -24,6 +24,19 @@ static inline void touch_nmi_watchdog(void) | |||
24 | } | 24 | } |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #if defined(CONFIG_HARDLOCKUP_DETECTOR) | ||
28 | extern void watchdog_enable_hardlockup_detector(bool val); | ||
29 | extern bool watchdog_hardlockup_detector_is_enabled(void); | ||
30 | #else | ||
31 | static inline void watchdog_enable_hardlockup_detector(bool val) | ||
32 | { | ||
33 | } | ||
34 | static inline bool watchdog_hardlockup_detector_is_enabled(void) | ||
35 | { | ||
36 | return true; | ||
37 | } | ||
38 | #endif | ||
39 | |||
27 | /* | 40 | /* |
28 | * Create trigger_all_cpu_backtrace() out of the arch-provided | 41 | * Create trigger_all_cpu_backtrace() out of the arch-provided |
29 | * base function. Return whether such support was available, | 42 | * base function. Return whether such support was available, |
diff --git a/include/linux/prio_heap.h b/include/linux/prio_heap.h deleted file mode 100644 index 08094350f26a..000000000000 --- a/include/linux/prio_heap.h +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | #ifndef _LINUX_PRIO_HEAP_H | ||
2 | #define _LINUX_PRIO_HEAP_H | ||
3 | |||
4 | /* | ||
5 | * Simple insertion-only static-sized priority heap containing | ||
6 | * pointers, based on CLR, chapter 7 | ||
7 | */ | ||
8 | |||
9 | #include <linux/gfp.h> | ||
10 | |||
11 | /** | ||
12 | * struct ptr_heap - simple static-sized priority heap | ||
13 | * @ptrs - pointer to data area | ||
14 | * @max - max number of elements that can be stored in @ptrs | ||
15 | * @size - current number of valid elements in @ptrs (in the range 0..@size-1 | ||
16 | * @gt: comparison operator, which should implement "greater than" | ||
17 | */ | ||
18 | struct ptr_heap { | ||
19 | void **ptrs; | ||
20 | int max; | ||
21 | int size; | ||
22 | int (*gt)(void *, void *); | ||
23 | }; | ||
24 | |||
25 | /** | ||
26 | * heap_init - initialize an empty heap with a given memory size | ||
27 | * @heap: the heap structure to be initialized | ||
28 | * @size: amount of memory to use in bytes | ||
29 | * @gfp_mask: mask to pass to kmalloc() | ||
30 | * @gt: comparison operator, which should implement "greater than" | ||
31 | */ | ||
32 | extern int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask, | ||
33 | int (*gt)(void *, void *)); | ||
34 | |||
35 | /** | ||
36 | * heap_free - release a heap's storage | ||
37 | * @heap: the heap structure whose data should be released | ||
38 | */ | ||
39 | void heap_free(struct ptr_heap *heap); | ||
40 | |||
41 | /** | ||
42 | * heap_insert - insert a value into the heap and return any overflowed value | ||
43 | * @heap: the heap to be operated on | ||
44 | * @p: the pointer to be inserted | ||
45 | * | ||
46 | * Attempts to insert the given value into the priority heap. If the | ||
47 | * heap is full prior to the insertion, then the resulting heap will | ||
48 | * consist of the smallest @max elements of the original heap and the | ||
49 | * new element; the greatest element will be removed from the heap and | ||
50 | * returned. Note that the returned element will be the new element | ||
51 | * (i.e. no change to the heap) if the new element is greater than all | ||
52 | * elements currently in the heap. | ||
53 | */ | ||
54 | extern void *heap_insert(struct ptr_heap *heap, void *p); | ||
55 | |||
56 | |||
57 | |||
58 | #endif /* _LINUX_PRIO_HEAP_H */ | ||
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index fea49b5da12a..378c5ee75f78 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h | |||
@@ -43,6 +43,16 @@ struct rb_augment_callbacks { | |||
43 | 43 | ||
44 | extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, | 44 | extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, |
45 | void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); | 45 | void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); |
46 | /* | ||
47 | * Fixup the rbtree and update the augmented information when rebalancing. | ||
48 | * | ||
49 | * On insertion, the user must update the augmented information on the path | ||
50 | * leading to the inserted node, then call rb_link_node() as usual and | ||
51 | * rb_augment_inserted() instead of the usual rb_insert_color() call. | ||
52 | * If rb_augment_inserted() rebalances the rbtree, it will callback into | ||
53 | * a user provided function to update the augmented information on the | ||
54 | * affected subtrees. | ||
55 | */ | ||
46 | static inline void | 56 | static inline void |
47 | rb_insert_augmented(struct rb_node *node, struct rb_root *root, | 57 | rb_insert_augmented(struct rb_node *node, struct rb_root *root, |
48 | const struct rb_augment_callbacks *augment) | 58 | const struct rb_augment_callbacks *augment) |
diff --git a/include/linux/signal.h b/include/linux/signal.h index 750196fcc0a5..ab1e0392b5ac 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _LINUX_SIGNAL_H | 2 | #define _LINUX_SIGNAL_H |
3 | 3 | ||
4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
5 | #include <linux/bug.h> | ||
5 | #include <uapi/linux/signal.h> | 6 | #include <uapi/linux/signal.h> |
6 | 7 | ||
7 | struct task_struct; | 8 | struct task_struct; |
@@ -67,7 +68,6 @@ static inline int sigismember(sigset_t *set, int _sig) | |||
67 | 68 | ||
68 | static inline int sigisemptyset(sigset_t *set) | 69 | static inline int sigisemptyset(sigset_t *set) |
69 | { | 70 | { |
70 | extern void _NSIG_WORDS_is_unsupported_size(void); | ||
71 | switch (_NSIG_WORDS) { | 71 | switch (_NSIG_WORDS) { |
72 | case 4: | 72 | case 4: |
73 | return (set->sig[3] | set->sig[2] | | 73 | return (set->sig[3] | set->sig[2] | |
@@ -77,7 +77,7 @@ static inline int sigisemptyset(sigset_t *set) | |||
77 | case 1: | 77 | case 1: |
78 | return set->sig[0] == 0; | 78 | return set->sig[0] == 0; |
79 | default: | 79 | default: |
80 | _NSIG_WORDS_is_unsupported_size(); | 80 | BUILD_BUG(); |
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | } | 83 | } |
@@ -90,24 +90,23 @@ static inline int sigisemptyset(sigset_t *set) | |||
90 | #define _SIG_SET_BINOP(name, op) \ | 90 | #define _SIG_SET_BINOP(name, op) \ |
91 | static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \ | 91 | static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \ |
92 | { \ | 92 | { \ |
93 | extern void _NSIG_WORDS_is_unsupported_size(void); \ | ||
94 | unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \ | 93 | unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \ |
95 | \ | 94 | \ |
96 | switch (_NSIG_WORDS) { \ | 95 | switch (_NSIG_WORDS) { \ |
97 | case 4: \ | 96 | case 4: \ |
98 | a3 = a->sig[3]; a2 = a->sig[2]; \ | 97 | a3 = a->sig[3]; a2 = a->sig[2]; \ |
99 | b3 = b->sig[3]; b2 = b->sig[2]; \ | 98 | b3 = b->sig[3]; b2 = b->sig[2]; \ |
100 | r->sig[3] = op(a3, b3); \ | 99 | r->sig[3] = op(a3, b3); \ |
101 | r->sig[2] = op(a2, b2); \ | 100 | r->sig[2] = op(a2, b2); \ |
102 | case 2: \ | 101 | case 2: \ |
103 | a1 = a->sig[1]; b1 = b->sig[1]; \ | 102 | a1 = a->sig[1]; b1 = b->sig[1]; \ |
104 | r->sig[1] = op(a1, b1); \ | 103 | r->sig[1] = op(a1, b1); \ |
105 | case 1: \ | 104 | case 1: \ |
106 | a0 = a->sig[0]; b0 = b->sig[0]; \ | 105 | a0 = a->sig[0]; b0 = b->sig[0]; \ |
107 | r->sig[0] = op(a0, b0); \ | 106 | r->sig[0] = op(a0, b0); \ |
108 | break; \ | 107 | break; \ |
109 | default: \ | 108 | default: \ |
110 | _NSIG_WORDS_is_unsupported_size(); \ | 109 | BUILD_BUG(); \ |
111 | } \ | 110 | } \ |
112 | } | 111 | } |
113 | 112 | ||
@@ -128,16 +127,14 @@ _SIG_SET_BINOP(sigandnsets, _sig_andn) | |||
128 | #define _SIG_SET_OP(name, op) \ | 127 | #define _SIG_SET_OP(name, op) \ |
129 | static inline void name(sigset_t *set) \ | 128 | static inline void name(sigset_t *set) \ |
130 | { \ | 129 | { \ |
131 | extern void _NSIG_WORDS_is_unsupported_size(void); \ | ||
132 | \ | ||
133 | switch (_NSIG_WORDS) { \ | 130 | switch (_NSIG_WORDS) { \ |
134 | case 4: set->sig[3] = op(set->sig[3]); \ | 131 | case 4: set->sig[3] = op(set->sig[3]); \ |
135 | set->sig[2] = op(set->sig[2]); \ | 132 | set->sig[2] = op(set->sig[2]); \ |
136 | case 2: set->sig[1] = op(set->sig[1]); \ | 133 | case 2: set->sig[1] = op(set->sig[1]); \ |
137 | case 1: set->sig[0] = op(set->sig[0]); \ | 134 | case 1: set->sig[0] = op(set->sig[0]); \ |
138 | break; \ | 135 | break; \ |
139 | default: \ | 136 | default: \ |
140 | _NSIG_WORDS_is_unsupported_size(); \ | 137 | BUILD_BUG(); \ |
141 | } \ | 138 | } \ |
142 | } | 139 | } |
143 | 140 | ||
diff --git a/include/linux/string.h b/include/linux/string.h index d36977e029af..e6edfe51575a 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
@@ -41,7 +41,7 @@ extern int strcmp(const char *,const char *); | |||
41 | extern int strncmp(const char *,const char *,__kernel_size_t); | 41 | extern int strncmp(const char *,const char *,__kernel_size_t); |
42 | #endif | 42 | #endif |
43 | #ifndef __HAVE_ARCH_STRNICMP | 43 | #ifndef __HAVE_ARCH_STRNICMP |
44 | extern int strnicmp(const char *, const char *, __kernel_size_t); | 44 | #define strnicmp strncasecmp |
45 | #endif | 45 | #endif |
46 | #ifndef __HAVE_ARCH_STRCASECMP | 46 | #ifndef __HAVE_ARCH_STRCASECMP |
47 | extern int strcasecmp(const char *s1, const char *s2); | 47 | extern int strcasecmp(const char *s1, const char *s2); |
diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h index 3eeee9672a4a..6eb567ac56bc 100644 --- a/include/linux/string_helpers.h +++ b/include/linux/string_helpers.h | |||
@@ -20,40 +20,6 @@ int string_get_size(u64 size, enum string_size_units units, | |||
20 | #define UNESCAPE_ANY \ | 20 | #define UNESCAPE_ANY \ |
21 | (UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL) | 21 | (UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL) |
22 | 22 | ||
23 | /** | ||
24 | * string_unescape - unquote characters in the given string | ||
25 | * @src: source buffer (escaped) | ||
26 | * @dst: destination buffer (unescaped) | ||
27 | * @size: size of the destination buffer (0 to unlimit) | ||
28 | * @flags: combination of the flags (bitwise OR): | ||
29 | * %UNESCAPE_SPACE: | ||
30 | * '\f' - form feed | ||
31 | * '\n' - new line | ||
32 | * '\r' - carriage return | ||
33 | * '\t' - horizontal tab | ||
34 | * '\v' - vertical tab | ||
35 | * %UNESCAPE_OCTAL: | ||
36 | * '\NNN' - byte with octal value NNN (1 to 3 digits) | ||
37 | * %UNESCAPE_HEX: | ||
38 | * '\xHH' - byte with hexadecimal value HH (1 to 2 digits) | ||
39 | * %UNESCAPE_SPECIAL: | ||
40 | * '\"' - double quote | ||
41 | * '\\' - backslash | ||
42 | * '\a' - alert (BEL) | ||
43 | * '\e' - escape | ||
44 | * %UNESCAPE_ANY: | ||
45 | * all previous together | ||
46 | * | ||
47 | * Returns amount of characters processed to the destination buffer excluding | ||
48 | * trailing '\0'. | ||
49 | * | ||
50 | * Because the size of the output will be the same as or less than the size of | ||
51 | * the input, the transformation may be performed in place. | ||
52 | * | ||
53 | * Caller must provide valid source and destination pointers. Be aware that | ||
54 | * destination buffer will always be NULL-terminated. Source string must be | ||
55 | * NULL-terminated as well. | ||
56 | */ | ||
57 | int string_unescape(char *src, char *dst, size_t size, unsigned int flags); | 23 | int string_unescape(char *src, char *dst, size_t size, unsigned int flags); |
58 | 24 | ||
59 | static inline int string_unescape_inplace(char *buf, unsigned int flags) | 25 | static inline int string_unescape_inplace(char *buf, unsigned int flags) |
@@ -71,4 +37,35 @@ static inline int string_unescape_any_inplace(char *buf) | |||
71 | return string_unescape_any(buf, buf, 0); | 37 | return string_unescape_any(buf, buf, 0); |
72 | } | 38 | } |
73 | 39 | ||
40 | #define ESCAPE_SPACE 0x01 | ||
41 | #define ESCAPE_SPECIAL 0x02 | ||
42 | #define ESCAPE_NULL 0x04 | ||
43 | #define ESCAPE_OCTAL 0x08 | ||
44 | #define ESCAPE_ANY \ | ||
45 | (ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_SPECIAL | ESCAPE_NULL) | ||
46 | #define ESCAPE_NP 0x10 | ||
47 | #define ESCAPE_ANY_NP (ESCAPE_ANY | ESCAPE_NP) | ||
48 | #define ESCAPE_HEX 0x20 | ||
49 | |||
50 | int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz, | ||
51 | unsigned int flags, const char *esc); | ||
52 | |||
53 | static inline int string_escape_mem_any_np(const char *src, size_t isz, | ||
54 | char **dst, size_t osz, const char *esc) | ||
55 | { | ||
56 | return string_escape_mem(src, isz, dst, osz, ESCAPE_ANY_NP, esc); | ||
57 | } | ||
58 | |||
59 | static inline int string_escape_str(const char *src, char **dst, size_t sz, | ||
60 | unsigned int flags, const char *esc) | ||
61 | { | ||
62 | return string_escape_mem(src, strlen(src), dst, sz, flags, esc); | ||
63 | } | ||
64 | |||
65 | static inline int string_escape_str_any_np(const char *src, char **dst, | ||
66 | size_t sz, const char *esc) | ||
67 | { | ||
68 | return string_escape_str(src, dst, sz, ESCAPE_ANY_NP, esc); | ||
69 | } | ||
70 | |||
74 | #endif | 71 | #endif |
diff --git a/include/net/lib80211.h b/include/net/lib80211.h index be95b9262801..aab0f427edb5 100644 --- a/include/net/lib80211.h +++ b/include/net/lib80211.h | |||
@@ -32,11 +32,6 @@ | |||
32 | #include <linux/timer.h> | 32 | #include <linux/timer.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | 34 | ||
35 | /* print_ssid() is intended to be used in debug (and possibly error) | ||
36 | * messages. It should never be used for passing ssid to user space. */ | ||
37 | const char *print_ssid(char *buf, const char *ssid, u8 ssid_len); | ||
38 | #define DECLARE_SSID_BUF(var) char var[IEEE80211_MAX_SSID_LEN * 4 + 1] __maybe_unused | ||
39 | |||
40 | #define NUM_WEP_KEYS 4 | 35 | #define NUM_WEP_KEYS 4 |
41 | 36 | ||
42 | enum { | 37 | enum { |
diff --git a/init/Kconfig b/init/Kconfig index 1c505e090422..3ee28ae02cc8 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -838,6 +838,7 @@ config LOG_BUF_SHIFT | |||
838 | 838 | ||
839 | config LOG_CPU_MAX_BUF_SHIFT | 839 | config LOG_CPU_MAX_BUF_SHIFT |
840 | int "CPU kernel log buffer size contribution (13 => 8 KB, 17 => 128KB)" | 840 | int "CPU kernel log buffer size contribution (13 => 8 KB, 17 => 128KB)" |
841 | depends on SMP | ||
841 | range 0 21 | 842 | range 0 21 |
842 | default 12 if !BASE_SMALL | 843 | default 12 if !BASE_SMALL |
843 | default 0 if BASE_SMALL | 844 | default 0 if BASE_SMALL |
diff --git a/init/initramfs.c b/init/initramfs.c index bece48c3461e..ad1bd7787bbb 100644 --- a/init/initramfs.c +++ b/init/initramfs.c | |||
@@ -197,14 +197,14 @@ static __initdata enum state { | |||
197 | } state, next_state; | 197 | } state, next_state; |
198 | 198 | ||
199 | static __initdata char *victim; | 199 | static __initdata char *victim; |
200 | static unsigned long count __initdata; | 200 | static unsigned long byte_count __initdata; |
201 | static __initdata loff_t this_header, next_header; | 201 | static __initdata loff_t this_header, next_header; |
202 | 202 | ||
203 | static inline void __init eat(unsigned n) | 203 | static inline void __init eat(unsigned n) |
204 | { | 204 | { |
205 | victim += n; | 205 | victim += n; |
206 | this_header += n; | 206 | this_header += n; |
207 | count -= n; | 207 | byte_count -= n; |
208 | } | 208 | } |
209 | 209 | ||
210 | static __initdata char *vcollected; | 210 | static __initdata char *vcollected; |
@@ -214,7 +214,7 @@ static __initdata char *collect; | |||
214 | 214 | ||
215 | static void __init read_into(char *buf, unsigned size, enum state next) | 215 | static void __init read_into(char *buf, unsigned size, enum state next) |
216 | { | 216 | { |
217 | if (count >= size) { | 217 | if (byte_count >= size) { |
218 | collected = victim; | 218 | collected = victim; |
219 | eat(size); | 219 | eat(size); |
220 | state = next; | 220 | state = next; |
@@ -237,8 +237,8 @@ static int __init do_start(void) | |||
237 | static int __init do_collect(void) | 237 | static int __init do_collect(void) |
238 | { | 238 | { |
239 | unsigned long n = remains; | 239 | unsigned long n = remains; |
240 | if (count < n) | 240 | if (byte_count < n) |
241 | n = count; | 241 | n = byte_count; |
242 | memcpy(collect, victim, n); | 242 | memcpy(collect, victim, n); |
243 | eat(n); | 243 | eat(n); |
244 | collect += n; | 244 | collect += n; |
@@ -280,8 +280,8 @@ static int __init do_header(void) | |||
280 | 280 | ||
281 | static int __init do_skip(void) | 281 | static int __init do_skip(void) |
282 | { | 282 | { |
283 | if (this_header + count < next_header) { | 283 | if (this_header + byte_count < next_header) { |
284 | eat(count); | 284 | eat(byte_count); |
285 | return 1; | 285 | return 1; |
286 | } else { | 286 | } else { |
287 | eat(next_header - this_header); | 287 | eat(next_header - this_header); |
@@ -292,9 +292,9 @@ static int __init do_skip(void) | |||
292 | 292 | ||
293 | static int __init do_reset(void) | 293 | static int __init do_reset(void) |
294 | { | 294 | { |
295 | while(count && *victim == '\0') | 295 | while (byte_count && *victim == '\0') |
296 | eat(1); | 296 | eat(1); |
297 | if (count && (this_header & 3)) | 297 | if (byte_count && (this_header & 3)) |
298 | error("broken padding"); | 298 | error("broken padding"); |
299 | return 1; | 299 | return 1; |
300 | } | 300 | } |
@@ -309,11 +309,11 @@ static int __init maybe_link(void) | |||
309 | return 0; | 309 | return 0; |
310 | } | 310 | } |
311 | 311 | ||
312 | static void __init clean_path(char *path, umode_t mode) | 312 | static void __init clean_path(char *path, umode_t fmode) |
313 | { | 313 | { |
314 | struct stat st; | 314 | struct stat st; |
315 | 315 | ||
316 | if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) { | 316 | if (!sys_newlstat(path, &st) && (st.st_mode ^ fmode) & S_IFMT) { |
317 | if (S_ISDIR(st.st_mode)) | 317 | if (S_ISDIR(st.st_mode)) |
318 | sys_rmdir(path); | 318 | sys_rmdir(path); |
319 | else | 319 | else |
@@ -368,7 +368,7 @@ static int __init do_name(void) | |||
368 | 368 | ||
369 | static int __init do_copy(void) | 369 | static int __init do_copy(void) |
370 | { | 370 | { |
371 | if (count >= body_len) { | 371 | if (byte_count >= body_len) { |
372 | if (xwrite(wfd, victim, body_len) != body_len) | 372 | if (xwrite(wfd, victim, body_len) != body_len) |
373 | error("write error"); | 373 | error("write error"); |
374 | sys_close(wfd); | 374 | sys_close(wfd); |
@@ -378,10 +378,10 @@ static int __init do_copy(void) | |||
378 | state = SkipIt; | 378 | state = SkipIt; |
379 | return 0; | 379 | return 0; |
380 | } else { | 380 | } else { |
381 | if (xwrite(wfd, victim, count) != count) | 381 | if (xwrite(wfd, victim, byte_count) != byte_count) |
382 | error("write error"); | 382 | error("write error"); |
383 | body_len -= count; | 383 | body_len -= byte_count; |
384 | eat(count); | 384 | eat(byte_count); |
385 | return 1; | 385 | return 1; |
386 | } | 386 | } |
387 | } | 387 | } |
@@ -411,12 +411,12 @@ static __initdata int (*actions[])(void) = { | |||
411 | 411 | ||
412 | static long __init write_buffer(char *buf, unsigned long len) | 412 | static long __init write_buffer(char *buf, unsigned long len) |
413 | { | 413 | { |
414 | count = len; | 414 | byte_count = len; |
415 | victim = buf; | 415 | victim = buf; |
416 | 416 | ||
417 | while (!actions[state]()) | 417 | while (!actions[state]()) |
418 | ; | 418 | ; |
419 | return len - count; | 419 | return len - byte_count; |
420 | } | 420 | } |
421 | 421 | ||
422 | static long __init flush_buffer(void *bufv, unsigned long len) | 422 | static long __init flush_buffer(void *bufv, unsigned long len) |
diff --git a/init/main.c b/init/main.c index 89ec862da2d4..800a0daede7e 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -501,7 +501,6 @@ asmlinkage __visible void __init start_kernel(void) | |||
501 | { | 501 | { |
502 | char *command_line; | 502 | char *command_line; |
503 | char *after_dashes; | 503 | char *after_dashes; |
504 | extern const struct kernel_param __start___param[], __stop___param[]; | ||
505 | 504 | ||
506 | /* | 505 | /* |
507 | * Need to run as early as possible, to initialize the | 506 | * Need to run as early as possible, to initialize the |
@@ -844,7 +843,6 @@ static char *initcall_level_names[] __initdata = { | |||
844 | 843 | ||
845 | static void __init do_initcall_level(int level) | 844 | static void __init do_initcall_level(int level) |
846 | { | 845 | { |
847 | extern const struct kernel_param __start___param[], __stop___param[]; | ||
848 | initcall_t *fn; | 846 | initcall_t *fn; |
849 | 847 | ||
850 | strcpy(initcall_command_line, saved_command_line); | 848 | strcpy(initcall_command_line, saved_command_line); |
diff --git a/ipc/compat.c b/ipc/compat.c index b5ef4f7946dc..9b3c85f8a538 100644 --- a/ipc/compat.c +++ b/ipc/compat.c | |||
@@ -171,32 +171,32 @@ static inline int __put_compat_ipc64_perm(struct ipc64_perm *p64, | |||
171 | } | 171 | } |
172 | 172 | ||
173 | static inline int __put_compat_ipc_perm(struct ipc64_perm *p, | 173 | static inline int __put_compat_ipc_perm(struct ipc64_perm *p, |
174 | struct compat_ipc_perm __user *up) | 174 | struct compat_ipc_perm __user *uip) |
175 | { | 175 | { |
176 | int err; | 176 | int err; |
177 | __compat_uid_t u; | 177 | __compat_uid_t u; |
178 | __compat_gid_t g; | 178 | __compat_gid_t g; |
179 | 179 | ||
180 | err = __put_user(p->key, &up->key); | 180 | err = __put_user(p->key, &uip->key); |
181 | SET_UID(u, p->uid); | 181 | SET_UID(u, p->uid); |
182 | err |= __put_user(u, &up->uid); | 182 | err |= __put_user(u, &uip->uid); |
183 | SET_GID(g, p->gid); | 183 | SET_GID(g, p->gid); |
184 | err |= __put_user(g, &up->gid); | 184 | err |= __put_user(g, &uip->gid); |
185 | SET_UID(u, p->cuid); | 185 | SET_UID(u, p->cuid); |
186 | err |= __put_user(u, &up->cuid); | 186 | err |= __put_user(u, &uip->cuid); |
187 | SET_GID(g, p->cgid); | 187 | SET_GID(g, p->cgid); |
188 | err |= __put_user(g, &up->cgid); | 188 | err |= __put_user(g, &uip->cgid); |
189 | err |= __put_user(p->mode, &up->mode); | 189 | err |= __put_user(p->mode, &uip->mode); |
190 | err |= __put_user(p->seq, &up->seq); | 190 | err |= __put_user(p->seq, &uip->seq); |
191 | return err; | 191 | return err; |
192 | } | 192 | } |
193 | 193 | ||
194 | static inline int get_compat_semid64_ds(struct semid64_ds *s64, | 194 | static inline int get_compat_semid64_ds(struct semid64_ds *sem64, |
195 | struct compat_semid64_ds __user *up64) | 195 | struct compat_semid64_ds __user *up64) |
196 | { | 196 | { |
197 | if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) | 197 | if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) |
198 | return -EFAULT; | 198 | return -EFAULT; |
199 | return __get_compat_ipc64_perm(&s64->sem_perm, &up64->sem_perm); | 199 | return __get_compat_ipc64_perm(&sem64->sem_perm, &up64->sem_perm); |
200 | } | 200 | } |
201 | 201 | ||
202 | static inline int get_compat_semid_ds(struct semid64_ds *s, | 202 | static inline int get_compat_semid_ds(struct semid64_ds *s, |
@@ -207,17 +207,17 @@ static inline int get_compat_semid_ds(struct semid64_ds *s, | |||
207 | return __get_compat_ipc_perm(&s->sem_perm, &up->sem_perm); | 207 | return __get_compat_ipc_perm(&s->sem_perm, &up->sem_perm); |
208 | } | 208 | } |
209 | 209 | ||
210 | static inline int put_compat_semid64_ds(struct semid64_ds *s64, | 210 | static inline int put_compat_semid64_ds(struct semid64_ds *sem64, |
211 | struct compat_semid64_ds __user *up64) | 211 | struct compat_semid64_ds __user *up64) |
212 | { | 212 | { |
213 | int err; | 213 | int err; |
214 | 214 | ||
215 | if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) | 215 | if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) |
216 | return -EFAULT; | 216 | return -EFAULT; |
217 | err = __put_compat_ipc64_perm(&s64->sem_perm, &up64->sem_perm); | 217 | err = __put_compat_ipc64_perm(&sem64->sem_perm, &up64->sem_perm); |
218 | err |= __put_user(s64->sem_otime, &up64->sem_otime); | 218 | err |= __put_user(sem64->sem_otime, &up64->sem_otime); |
219 | err |= __put_user(s64->sem_ctime, &up64->sem_ctime); | 219 | err |= __put_user(sem64->sem_ctime, &up64->sem_ctime); |
220 | err |= __put_user(s64->sem_nsems, &up64->sem_nsems); | 220 | err |= __put_user(sem64->sem_nsems, &up64->sem_nsems); |
221 | return err; | 221 | return err; |
222 | } | 222 | } |
223 | 223 | ||
@@ -239,11 +239,11 @@ static long do_compat_semctl(int first, int second, int third, u32 pad) | |||
239 | { | 239 | { |
240 | unsigned long fourth; | 240 | unsigned long fourth; |
241 | int err, err2; | 241 | int err, err2; |
242 | struct semid64_ds s64; | 242 | struct semid64_ds sem64; |
243 | struct semid64_ds __user *up64; | 243 | struct semid64_ds __user *up64; |
244 | int version = compat_ipc_parse_version(&third); | 244 | int version = compat_ipc_parse_version(&third); |
245 | 245 | ||
246 | memset(&s64, 0, sizeof(s64)); | 246 | memset(&sem64, 0, sizeof(sem64)); |
247 | 247 | ||
248 | if ((third & (~IPC_64)) == SETVAL) | 248 | if ((third & (~IPC_64)) == SETVAL) |
249 | #ifdef __BIG_ENDIAN | 249 | #ifdef __BIG_ENDIAN |
@@ -269,29 +269,29 @@ static long do_compat_semctl(int first, int second, int third, u32 pad) | |||
269 | 269 | ||
270 | case IPC_STAT: | 270 | case IPC_STAT: |
271 | case SEM_STAT: | 271 | case SEM_STAT: |
272 | up64 = compat_alloc_user_space(sizeof(s64)); | 272 | up64 = compat_alloc_user_space(sizeof(sem64)); |
273 | fourth = (unsigned long)up64; | 273 | fourth = (unsigned long)up64; |
274 | err = sys_semctl(first, second, third, fourth); | 274 | err = sys_semctl(first, second, third, fourth); |
275 | if (err < 0) | 275 | if (err < 0) |
276 | break; | 276 | break; |
277 | if (copy_from_user(&s64, up64, sizeof(s64))) | 277 | if (copy_from_user(&sem64, up64, sizeof(sem64))) |
278 | err2 = -EFAULT; | 278 | err2 = -EFAULT; |
279 | else if (version == IPC_64) | 279 | else if (version == IPC_64) |
280 | err2 = put_compat_semid64_ds(&s64, compat_ptr(pad)); | 280 | err2 = put_compat_semid64_ds(&sem64, compat_ptr(pad)); |
281 | else | 281 | else |
282 | err2 = put_compat_semid_ds(&s64, compat_ptr(pad)); | 282 | err2 = put_compat_semid_ds(&sem64, compat_ptr(pad)); |
283 | if (err2) | 283 | if (err2) |
284 | err = -EFAULT; | 284 | err = -EFAULT; |
285 | break; | 285 | break; |
286 | 286 | ||
287 | case IPC_SET: | 287 | case IPC_SET: |
288 | if (version == IPC_64) | 288 | if (version == IPC_64) |
289 | err = get_compat_semid64_ds(&s64, compat_ptr(pad)); | 289 | err = get_compat_semid64_ds(&sem64, compat_ptr(pad)); |
290 | else | 290 | else |
291 | err = get_compat_semid_ds(&s64, compat_ptr(pad)); | 291 | err = get_compat_semid_ds(&sem64, compat_ptr(pad)); |
292 | 292 | ||
293 | up64 = compat_alloc_user_space(sizeof(s64)); | 293 | up64 = compat_alloc_user_space(sizeof(sem64)); |
294 | if (copy_to_user(up64, &s64, sizeof(s64))) | 294 | if (copy_to_user(up64, &sem64, sizeof(sem64))) |
295 | err = -EFAULT; | 295 | err = -EFAULT; |
296 | if (err) | 296 | if (err) |
297 | break; | 297 | break; |
@@ -561,12 +561,12 @@ COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg) | |||
561 | return (long)ret; | 561 | return (long)ret; |
562 | } | 562 | } |
563 | 563 | ||
564 | static inline int get_compat_shmid64_ds(struct shmid64_ds *s64, | 564 | static inline int get_compat_shmid64_ds(struct shmid64_ds *sem64, |
565 | struct compat_shmid64_ds __user *up64) | 565 | struct compat_shmid64_ds __user *up64) |
566 | { | 566 | { |
567 | if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) | 567 | if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) |
568 | return -EFAULT; | 568 | return -EFAULT; |
569 | return __get_compat_ipc64_perm(&s64->shm_perm, &up64->shm_perm); | 569 | return __get_compat_ipc64_perm(&sem64->shm_perm, &up64->shm_perm); |
570 | } | 570 | } |
571 | 571 | ||
572 | static inline int get_compat_shmid_ds(struct shmid64_ds *s, | 572 | static inline int get_compat_shmid_ds(struct shmid64_ds *s, |
@@ -577,21 +577,21 @@ static inline int get_compat_shmid_ds(struct shmid64_ds *s, | |||
577 | return __get_compat_ipc_perm(&s->shm_perm, &up->shm_perm); | 577 | return __get_compat_ipc_perm(&s->shm_perm, &up->shm_perm); |
578 | } | 578 | } |
579 | 579 | ||
580 | static inline int put_compat_shmid64_ds(struct shmid64_ds *s64, | 580 | static inline int put_compat_shmid64_ds(struct shmid64_ds *sem64, |
581 | struct compat_shmid64_ds __user *up64) | 581 | struct compat_shmid64_ds __user *up64) |
582 | { | 582 | { |
583 | int err; | 583 | int err; |
584 | 584 | ||
585 | if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) | 585 | if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) |
586 | return -EFAULT; | 586 | return -EFAULT; |
587 | err = __put_compat_ipc64_perm(&s64->shm_perm, &up64->shm_perm); | 587 | err = __put_compat_ipc64_perm(&sem64->shm_perm, &up64->shm_perm); |
588 | err |= __put_user(s64->shm_atime, &up64->shm_atime); | 588 | err |= __put_user(sem64->shm_atime, &up64->shm_atime); |
589 | err |= __put_user(s64->shm_dtime, &up64->shm_dtime); | 589 | err |= __put_user(sem64->shm_dtime, &up64->shm_dtime); |
590 | err |= __put_user(s64->shm_ctime, &up64->shm_ctime); | 590 | err |= __put_user(sem64->shm_ctime, &up64->shm_ctime); |
591 | err |= __put_user(s64->shm_segsz, &up64->shm_segsz); | 591 | err |= __put_user(sem64->shm_segsz, &up64->shm_segsz); |
592 | err |= __put_user(s64->shm_nattch, &up64->shm_nattch); | 592 | err |= __put_user(sem64->shm_nattch, &up64->shm_nattch); |
593 | err |= __put_user(s64->shm_cpid, &up64->shm_cpid); | 593 | err |= __put_user(sem64->shm_cpid, &up64->shm_cpid); |
594 | err |= __put_user(s64->shm_lpid, &up64->shm_lpid); | 594 | err |= __put_user(sem64->shm_lpid, &up64->shm_lpid); |
595 | return err; | 595 | return err; |
596 | } | 596 | } |
597 | 597 | ||
@@ -668,12 +668,12 @@ static inline int put_compat_shm_info(struct shm_info __user *ip, | |||
668 | COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr) | 668 | COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr) |
669 | { | 669 | { |
670 | void __user *p; | 670 | void __user *p; |
671 | struct shmid64_ds s64; | 671 | struct shmid64_ds sem64; |
672 | struct shminfo64 smi; | 672 | struct shminfo64 smi; |
673 | int err, err2; | 673 | int err, err2; |
674 | int version = compat_ipc_parse_version(&second); | 674 | int version = compat_ipc_parse_version(&second); |
675 | 675 | ||
676 | memset(&s64, 0, sizeof(s64)); | 676 | memset(&sem64, 0, sizeof(sem64)); |
677 | 677 | ||
678 | switch (second & (~IPC_64)) { | 678 | switch (second & (~IPC_64)) { |
679 | case IPC_RMID: | 679 | case IPC_RMID: |
@@ -700,14 +700,14 @@ COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr) | |||
700 | 700 | ||
701 | case IPC_SET: | 701 | case IPC_SET: |
702 | if (version == IPC_64) | 702 | if (version == IPC_64) |
703 | err = get_compat_shmid64_ds(&s64, uptr); | 703 | err = get_compat_shmid64_ds(&sem64, uptr); |
704 | else | 704 | else |
705 | err = get_compat_shmid_ds(&s64, uptr); | 705 | err = get_compat_shmid_ds(&sem64, uptr); |
706 | 706 | ||
707 | if (err) | 707 | if (err) |
708 | break; | 708 | break; |
709 | p = compat_alloc_user_space(sizeof(s64)); | 709 | p = compat_alloc_user_space(sizeof(sem64)); |
710 | if (copy_to_user(p, &s64, sizeof(s64))) | 710 | if (copy_to_user(p, &sem64, sizeof(sem64))) |
711 | err = -EFAULT; | 711 | err = -EFAULT; |
712 | else | 712 | else |
713 | err = sys_shmctl(first, second, p); | 713 | err = sys_shmctl(first, second, p); |
@@ -715,16 +715,16 @@ COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr) | |||
715 | 715 | ||
716 | case IPC_STAT: | 716 | case IPC_STAT: |
717 | case SHM_STAT: | 717 | case SHM_STAT: |
718 | p = compat_alloc_user_space(sizeof(s64)); | 718 | p = compat_alloc_user_space(sizeof(sem64)); |
719 | err = sys_shmctl(first, second, p); | 719 | err = sys_shmctl(first, second, p); |
720 | if (err < 0) | 720 | if (err < 0) |
721 | break; | 721 | break; |
722 | if (copy_from_user(&s64, p, sizeof(s64))) | 722 | if (copy_from_user(&sem64, p, sizeof(sem64))) |
723 | err2 = -EFAULT; | 723 | err2 = -EFAULT; |
724 | else if (version == IPC_64) | 724 | else if (version == IPC_64) |
725 | err2 = put_compat_shmid64_ds(&s64, uptr); | 725 | err2 = put_compat_shmid64_ds(&sem64, uptr); |
726 | else | 726 | else |
727 | err2 = put_compat_shmid_ds(&s64, uptr); | 727 | err2 = put_compat_shmid_ds(&sem64, uptr); |
728 | if (err2) | 728 | if (err2) |
729 | err = -EFAULT; | 729 | err = -EFAULT; |
730 | break; | 730 | break; |
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c index c3f0326e98db..e8075b247497 100644 --- a/ipc/ipc_sysctl.c +++ b/ipc/ipc_sysctl.c | |||
@@ -123,7 +123,6 @@ static int proc_ipcauto_dointvec_minmax(struct ctl_table *table, int write, | |||
123 | void __user *buffer, size_t *lenp, loff_t *ppos) | 123 | void __user *buffer, size_t *lenp, loff_t *ppos) |
124 | { | 124 | { |
125 | struct ctl_table ipc_table; | 125 | struct ctl_table ipc_table; |
126 | size_t lenp_bef = *lenp; | ||
127 | int oldval; | 126 | int oldval; |
128 | int rc; | 127 | int rc; |
129 | 128 | ||
@@ -133,7 +132,7 @@ static int proc_ipcauto_dointvec_minmax(struct ctl_table *table, int write, | |||
133 | 132 | ||
134 | rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); | 133 | rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); |
135 | 134 | ||
136 | if (write && !rc && lenp_bef == *lenp) { | 135 | if (write && !rc) { |
137 | int newval = *((int *)(ipc_table.data)); | 136 | int newval = *((int *)(ipc_table.data)); |
138 | /* | 137 | /* |
139 | * The file "auto_msgmni" has correctly been set. | 138 | * The file "auto_msgmni" has correctly been set. |
@@ -1172,13 +1172,6 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, | |||
1172 | 1172 | ||
1173 | if (find_vma_intersection(current->mm, addr, addr + size)) | 1173 | if (find_vma_intersection(current->mm, addr, addr + size)) |
1174 | goto invalid; | 1174 | goto invalid; |
1175 | /* | ||
1176 | * If shm segment goes below stack, make sure there is some | ||
1177 | * space left for the stack to grow (at least 4 pages). | ||
1178 | */ | ||
1179 | if (addr < current->mm->start_stack && | ||
1180 | addr > current->mm->start_stack - size - PAGE_SIZE * 5) | ||
1181 | goto invalid; | ||
1182 | } | 1175 | } |
1183 | 1176 | ||
1184 | addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate); | 1177 | addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate); |
diff --git a/ipc/util.c b/ipc/util.c index d73b7af581e2..88adc329888c 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -892,28 +892,16 @@ static const struct seq_operations sysvipc_proc_seqops = { | |||
892 | 892 | ||
893 | static int sysvipc_proc_open(struct inode *inode, struct file *file) | 893 | static int sysvipc_proc_open(struct inode *inode, struct file *file) |
894 | { | 894 | { |
895 | int ret; | ||
896 | struct seq_file *seq; | ||
897 | struct ipc_proc_iter *iter; | 895 | struct ipc_proc_iter *iter; |
898 | 896 | ||
899 | ret = -ENOMEM; | 897 | iter = __seq_open_private(file, &sysvipc_proc_seqops, sizeof(*iter)); |
900 | iter = kmalloc(sizeof(*iter), GFP_KERNEL); | ||
901 | if (!iter) | 898 | if (!iter) |
902 | goto out; | 899 | return -ENOMEM; |
903 | |||
904 | ret = seq_open(file, &sysvipc_proc_seqops); | ||
905 | if (ret) { | ||
906 | kfree(iter); | ||
907 | goto out; | ||
908 | } | ||
909 | |||
910 | seq = file->private_data; | ||
911 | seq->private = iter; | ||
912 | 900 | ||
913 | iter->iface = PDE_DATA(inode); | 901 | iter->iface = PDE_DATA(inode); |
914 | iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); | 902 | iter->ns = get_ipc_ns(current->nsproxy->ipc_ns); |
915 | out: | 903 | |
916 | return ret; | 904 | return 0; |
917 | } | 905 | } |
918 | 906 | ||
919 | static int sysvipc_proc_release(struct inode *inode, struct file *file) | 907 | static int sysvipc_proc_release(struct inode *inode, struct file *file) |
diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index 70a504601dc3..b20d544f20c2 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c | |||
@@ -52,11 +52,11 @@ static int kdb_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp) | |||
52 | 52 | ||
53 | bp->bph_length = 1; | 53 | bp->bph_length = 1; |
54 | if ((argc + 1) != nextarg) { | 54 | if ((argc + 1) != nextarg) { |
55 | if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) | 55 | if (strncasecmp(argv[nextarg], "datar", sizeof("datar")) == 0) |
56 | bp->bp_type = BP_ACCESS_WATCHPOINT; | 56 | bp->bp_type = BP_ACCESS_WATCHPOINT; |
57 | else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) | 57 | else if (strncasecmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) |
58 | bp->bp_type = BP_WRITE_WATCHPOINT; | 58 | bp->bp_type = BP_WRITE_WATCHPOINT; |
59 | else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) | 59 | else if (strncasecmp(argv[nextarg], "inst", sizeof("inst")) == 0) |
60 | bp->bp_type = BP_HARDWARE_BREAKPOINT; | 60 | bp->bp_type = BP_HARDWARE_BREAKPOINT; |
61 | else | 61 | else |
62 | return KDB_ARGCOUNT; | 62 | return KDB_ARGCOUNT; |
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index ae5167087845..5c5987f10819 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c | |||
@@ -565,19 +565,12 @@ static int kallsyms_open(struct inode *inode, struct file *file) | |||
565 | * using get_symbol_offset for every symbol. | 565 | * using get_symbol_offset for every symbol. |
566 | */ | 566 | */ |
567 | struct kallsym_iter *iter; | 567 | struct kallsym_iter *iter; |
568 | int ret; | 568 | iter = __seq_open_private(file, &kallsyms_op, sizeof(*iter)); |
569 | |||
570 | iter = kmalloc(sizeof(*iter), GFP_KERNEL); | ||
571 | if (!iter) | 569 | if (!iter) |
572 | return -ENOMEM; | 570 | return -ENOMEM; |
573 | reset_iter(iter, 0); | 571 | reset_iter(iter, 0); |
574 | 572 | ||
575 | ret = seq_open(file, &kallsyms_op); | 573 | return 0; |
576 | if (ret == 0) | ||
577 | ((struct seq_file *)file->private_data)->private = iter; | ||
578 | else | ||
579 | kfree(iter); | ||
580 | return ret; | ||
581 | } | 574 | } |
582 | 575 | ||
583 | #ifdef CONFIG_KGDB_KDB | 576 | #ifdef CONFIG_KGDB_KDB |
diff --git a/kernel/kexec.c b/kernel/kexec.c index 2bee072268d9..2abf9f6e9a61 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -1759,7 +1759,6 @@ static __initdata char *suffix_tbl[] = { | |||
1759 | */ | 1759 | */ |
1760 | static int __init parse_crashkernel_suffix(char *cmdline, | 1760 | static int __init parse_crashkernel_suffix(char *cmdline, |
1761 | unsigned long long *crash_size, | 1761 | unsigned long long *crash_size, |
1762 | unsigned long long *crash_base, | ||
1763 | const char *suffix) | 1762 | const char *suffix) |
1764 | { | 1763 | { |
1765 | char *cur = cmdline; | 1764 | char *cur = cmdline; |
@@ -1848,7 +1847,7 @@ static int __init __parse_crashkernel(char *cmdline, | |||
1848 | 1847 | ||
1849 | if (suffix) | 1848 | if (suffix) |
1850 | return parse_crashkernel_suffix(ck_cmdline, crash_size, | 1849 | return parse_crashkernel_suffix(ck_cmdline, crash_size, |
1851 | crash_base, suffix); | 1850 | suffix); |
1852 | /* | 1851 | /* |
1853 | * if the commandline contains a ':', then that's the extended | 1852 | * if the commandline contains a ':', then that's the extended |
1854 | * syntax -- if not, it must be the classic syntax | 1853 | * syntax -- if not, it must be the classic syntax |
@@ -2016,22 +2015,6 @@ static int __init crash_save_vmcoreinfo_init(void) | |||
2016 | subsys_initcall(crash_save_vmcoreinfo_init); | 2015 | subsys_initcall(crash_save_vmcoreinfo_init); |
2017 | 2016 | ||
2018 | #ifdef CONFIG_KEXEC_FILE | 2017 | #ifdef CONFIG_KEXEC_FILE |
2019 | static int __kexec_add_segment(struct kimage *image, char *buf, | ||
2020 | unsigned long bufsz, unsigned long mem, | ||
2021 | unsigned long memsz) | ||
2022 | { | ||
2023 | struct kexec_segment *ksegment; | ||
2024 | |||
2025 | ksegment = &image->segment[image->nr_segments]; | ||
2026 | ksegment->kbuf = buf; | ||
2027 | ksegment->bufsz = bufsz; | ||
2028 | ksegment->mem = mem; | ||
2029 | ksegment->memsz = memsz; | ||
2030 | image->nr_segments++; | ||
2031 | |||
2032 | return 0; | ||
2033 | } | ||
2034 | |||
2035 | static int locate_mem_hole_top_down(unsigned long start, unsigned long end, | 2018 | static int locate_mem_hole_top_down(unsigned long start, unsigned long end, |
2036 | struct kexec_buf *kbuf) | 2019 | struct kexec_buf *kbuf) |
2037 | { | 2020 | { |
@@ -2064,8 +2047,7 @@ static int locate_mem_hole_top_down(unsigned long start, unsigned long end, | |||
2064 | } while (1); | 2047 | } while (1); |
2065 | 2048 | ||
2066 | /* If we are here, we found a suitable memory range */ | 2049 | /* If we are here, we found a suitable memory range */ |
2067 | __kexec_add_segment(image, kbuf->buffer, kbuf->bufsz, temp_start, | 2050 | kbuf->mem = temp_start; |
2068 | kbuf->memsz); | ||
2069 | 2051 | ||
2070 | /* Success, stop navigating through remaining System RAM ranges */ | 2052 | /* Success, stop navigating through remaining System RAM ranges */ |
2071 | return 1; | 2053 | return 1; |
@@ -2099,8 +2081,7 @@ static int locate_mem_hole_bottom_up(unsigned long start, unsigned long end, | |||
2099 | } while (1); | 2081 | } while (1); |
2100 | 2082 | ||
2101 | /* If we are here, we found a suitable memory range */ | 2083 | /* If we are here, we found a suitable memory range */ |
2102 | __kexec_add_segment(image, kbuf->buffer, kbuf->bufsz, temp_start, | 2084 | kbuf->mem = temp_start; |
2103 | kbuf->memsz); | ||
2104 | 2085 | ||
2105 | /* Success, stop navigating through remaining System RAM ranges */ | 2086 | /* Success, stop navigating through remaining System RAM ranges */ |
2106 | return 1; | 2087 | return 1; |
@@ -2187,7 +2168,12 @@ int kexec_add_buffer(struct kimage *image, char *buffer, unsigned long bufsz, | |||
2187 | } | 2168 | } |
2188 | 2169 | ||
2189 | /* Found a suitable memory range */ | 2170 | /* Found a suitable memory range */ |
2190 | ksegment = &image->segment[image->nr_segments - 1]; | 2171 | ksegment = &image->segment[image->nr_segments]; |
2172 | ksegment->kbuf = kbuf->buffer; | ||
2173 | ksegment->bufsz = kbuf->bufsz; | ||
2174 | ksegment->mem = kbuf->mem; | ||
2175 | ksegment->memsz = kbuf->memsz; | ||
2176 | image->nr_segments++; | ||
2191 | *load_addr = ksegment->mem; | 2177 | *load_addr = ksegment->mem; |
2192 | return 0; | 2178 | return 0; |
2193 | } | 2179 | } |
diff --git a/kernel/params.c b/kernel/params.c index 041b5899d5e2..db97b791390f 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/moduleparam.h> | ||
22 | #include <linux/device.h> | 23 | #include <linux/device.h> |
23 | #include <linux/err.h> | 24 | #include <linux/err.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -513,8 +514,6 @@ EXPORT_SYMBOL(param_ops_string); | |||
513 | #define to_module_attr(n) container_of(n, struct module_attribute, attr) | 514 | #define to_module_attr(n) container_of(n, struct module_attribute, attr) |
514 | #define to_module_kobject(n) container_of(n, struct module_kobject, kobj) | 515 | #define to_module_kobject(n) container_of(n, struct module_kobject, kobj) |
515 | 516 | ||
516 | extern struct kernel_param __start___param[], __stop___param[]; | ||
517 | |||
518 | struct param_attribute | 517 | struct param_attribute |
519 | { | 518 | { |
520 | struct module_attribute mattr; | 519 | struct module_attribute mattr; |
@@ -774,7 +773,7 @@ static struct module_kobject * __init locate_module_kobject(const char *name) | |||
774 | } | 773 | } |
775 | 774 | ||
776 | static void __init kernel_add_sysfs_param(const char *name, | 775 | static void __init kernel_add_sysfs_param(const char *name, |
777 | struct kernel_param *kparam, | 776 | const struct kernel_param *kparam, |
778 | unsigned int name_skip) | 777 | unsigned int name_skip) |
779 | { | 778 | { |
780 | struct module_kobject *mk; | 779 | struct module_kobject *mk; |
@@ -809,7 +808,7 @@ static void __init kernel_add_sysfs_param(const char *name, | |||
809 | */ | 808 | */ |
810 | static void __init param_sysfs_builtin(void) | 809 | static void __init param_sysfs_builtin(void) |
811 | { | 810 | { |
812 | struct kernel_param *kp; | 811 | const struct kernel_param *kp; |
813 | unsigned int name_len; | 812 | unsigned int name_len; |
814 | char modname[MODULE_NAME_LEN]; | 813 | char modname[MODULE_NAME_LEN]; |
815 | 814 | ||
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 7a6e69441f75..e3962d63e368 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -267,7 +267,6 @@ static u32 clear_idx; | |||
267 | #define LOG_ALIGN __alignof__(struct printk_log) | 267 | #define LOG_ALIGN __alignof__(struct printk_log) |
268 | #endif | 268 | #endif |
269 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | 269 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) |
270 | #define __LOG_CPU_MAX_BUF_LEN (1 << CONFIG_LOG_CPU_MAX_BUF_SHIFT) | ||
271 | static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); | 270 | static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); |
272 | static char *log_buf = __log_buf; | 271 | static char *log_buf = __log_buf; |
273 | static u32 log_buf_len = __LOG_BUF_LEN; | 272 | static u32 log_buf_len = __LOG_BUF_LEN; |
@@ -852,6 +851,9 @@ static int __init log_buf_len_setup(char *str) | |||
852 | } | 851 | } |
853 | early_param("log_buf_len", log_buf_len_setup); | 852 | early_param("log_buf_len", log_buf_len_setup); |
854 | 853 | ||
854 | #ifdef CONFIG_SMP | ||
855 | #define __LOG_CPU_MAX_BUF_LEN (1 << CONFIG_LOG_CPU_MAX_BUF_SHIFT) | ||
856 | |||
855 | static void __init log_buf_add_cpu(void) | 857 | static void __init log_buf_add_cpu(void) |
856 | { | 858 | { |
857 | unsigned int cpu_extra; | 859 | unsigned int cpu_extra; |
@@ -878,6 +880,9 @@ static void __init log_buf_add_cpu(void) | |||
878 | 880 | ||
879 | log_buf_len_update(cpu_extra + __LOG_BUF_LEN); | 881 | log_buf_len_update(cpu_extra + __LOG_BUF_LEN); |
880 | } | 882 | } |
883 | #else /* !CONFIG_SMP */ | ||
884 | static inline void log_buf_add_cpu(void) {} | ||
885 | #endif /* CONFIG_SMP */ | ||
881 | 886 | ||
882 | void __init setup_log_buf(int early) | 887 | void __init setup_log_buf(int early) |
883 | { | 888 | { |
@@ -1674,12 +1679,7 @@ asmlinkage int vprintk_emit(int facility, int level, | |||
1674 | * The printf needs to come first; we need the syslog | 1679 | * The printf needs to come first; we need the syslog |
1675 | * prefix which might be passed-in as a parameter. | 1680 | * prefix which might be passed-in as a parameter. |
1676 | */ | 1681 | */ |
1677 | if (in_sched) | 1682 | text_len = vscnprintf(text, sizeof(textbuf), fmt, args); |
1678 | text_len = scnprintf(text, sizeof(textbuf), | ||
1679 | KERN_WARNING "[sched_delayed] "); | ||
1680 | |||
1681 | text_len += vscnprintf(text + text_len, | ||
1682 | sizeof(textbuf) - text_len, fmt, args); | ||
1683 | 1683 | ||
1684 | /* mark and strip a trailing newline */ | 1684 | /* mark and strip a trailing newline */ |
1685 | if (text_len && text[text_len-1] == '\n') { | 1685 | if (text_len && text[text_len-1] == '\n') { |
diff --git a/kernel/resource.c b/kernel/resource.c index 46322019ab7d..0bcebffc4e77 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -491,6 +491,42 @@ int __weak page_is_ram(unsigned long pfn) | |||
491 | } | 491 | } |
492 | EXPORT_SYMBOL_GPL(page_is_ram); | 492 | EXPORT_SYMBOL_GPL(page_is_ram); |
493 | 493 | ||
494 | /* | ||
495 | * Search for a resouce entry that fully contains the specified region. | ||
496 | * If found, return 1 if it is RAM, 0 if not. | ||
497 | * If not found, or region is not fully contained, return -1 | ||
498 | * | ||
499 | * Used by the ioremap functions to ensure the user is not remapping RAM and is | ||
500 | * a vast speed up over walking through the resource table page by page. | ||
501 | */ | ||
502 | int region_is_ram(resource_size_t start, unsigned long size) | ||
503 | { | ||
504 | struct resource *p; | ||
505 | resource_size_t end = start + size - 1; | ||
506 | int flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
507 | const char *name = "System RAM"; | ||
508 | int ret = -1; | ||
509 | |||
510 | read_lock(&resource_lock); | ||
511 | for (p = iomem_resource.child; p ; p = p->sibling) { | ||
512 | if (end < p->start) | ||
513 | continue; | ||
514 | |||
515 | if (p->start <= start && end <= p->end) { | ||
516 | /* resource fully contains region */ | ||
517 | if ((p->flags != flags) || strcmp(p->name, name)) | ||
518 | ret = 0; | ||
519 | else | ||
520 | ret = 1; | ||
521 | break; | ||
522 | } | ||
523 | if (p->end < start) | ||
524 | break; /* not found */ | ||
525 | } | ||
526 | read_unlock(&resource_lock); | ||
527 | return ret; | ||
528 | } | ||
529 | |||
494 | void __weak arch_remove_reservations(struct resource *avail) | 530 | void __weak arch_remove_reservations(struct resource *avail) |
495 | { | 531 | { |
496 | } | 532 | } |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index ff7fd80bef99..49e9537f3673 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -59,6 +59,25 @@ static unsigned long soft_lockup_nmi_warn; | |||
59 | static int hardlockup_panic = | 59 | static int hardlockup_panic = |
60 | CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; | 60 | CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; |
61 | 61 | ||
62 | static bool hardlockup_detector_enabled = true; | ||
63 | /* | ||
64 | * We may not want to enable hard lockup detection by default in all cases, | ||
65 | * for example when running the kernel as a guest on a hypervisor. In these | ||
66 | * cases this function can be called to disable hard lockup detection. This | ||
67 | * function should only be executed once by the boot processor before the | ||
68 | * kernel command line parameters are parsed, because otherwise it is not | ||
69 | * possible to override this in hardlockup_panic_setup(). | ||
70 | */ | ||
71 | void watchdog_enable_hardlockup_detector(bool val) | ||
72 | { | ||
73 | hardlockup_detector_enabled = val; | ||
74 | } | ||
75 | |||
76 | bool watchdog_hardlockup_detector_is_enabled(void) | ||
77 | { | ||
78 | return hardlockup_detector_enabled; | ||
79 | } | ||
80 | |||
62 | static int __init hardlockup_panic_setup(char *str) | 81 | static int __init hardlockup_panic_setup(char *str) |
63 | { | 82 | { |
64 | if (!strncmp(str, "panic", 5)) | 83 | if (!strncmp(str, "panic", 5)) |
@@ -67,6 +86,14 @@ static int __init hardlockup_panic_setup(char *str) | |||
67 | hardlockup_panic = 0; | 86 | hardlockup_panic = 0; |
68 | else if (!strncmp(str, "0", 1)) | 87 | else if (!strncmp(str, "0", 1)) |
69 | watchdog_user_enabled = 0; | 88 | watchdog_user_enabled = 0; |
89 | else if (!strncmp(str, "1", 1) || !strncmp(str, "2", 1)) { | ||
90 | /* | ||
91 | * Setting 'nmi_watchdog=1' or 'nmi_watchdog=2' (legacy option) | ||
92 | * has the same effect. | ||
93 | */ | ||
94 | watchdog_user_enabled = 1; | ||
95 | watchdog_enable_hardlockup_detector(true); | ||
96 | } | ||
70 | return 1; | 97 | return 1; |
71 | } | 98 | } |
72 | __setup("nmi_watchdog=", hardlockup_panic_setup); | 99 | __setup("nmi_watchdog=", hardlockup_panic_setup); |
@@ -465,6 +492,15 @@ static int watchdog_nmi_enable(unsigned int cpu) | |||
465 | struct perf_event_attr *wd_attr; | 492 | struct perf_event_attr *wd_attr; |
466 | struct perf_event *event = per_cpu(watchdog_ev, cpu); | 493 | struct perf_event *event = per_cpu(watchdog_ev, cpu); |
467 | 494 | ||
495 | /* | ||
496 | * Some kernels need to default hard lockup detection to | ||
497 | * 'disabled', for example a guest on a hypervisor. | ||
498 | */ | ||
499 | if (!watchdog_hardlockup_detector_is_enabled()) { | ||
500 | event = ERR_PTR(-ENOENT); | ||
501 | goto handle_err; | ||
502 | } | ||
503 | |||
468 | /* is it already setup and enabled? */ | 504 | /* is it already setup and enabled? */ |
469 | if (event && event->state > PERF_EVENT_STATE_OFF) | 505 | if (event && event->state > PERF_EVENT_STATE_OFF) |
470 | goto out; | 506 | goto out; |
@@ -479,6 +515,7 @@ static int watchdog_nmi_enable(unsigned int cpu) | |||
479 | /* Try to register using hardware perf events */ | 515 | /* Try to register using hardware perf events */ |
480 | event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); | 516 | event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); |
481 | 517 | ||
518 | handle_err: | ||
482 | /* save cpu0 error for future comparision */ | 519 | /* save cpu0 error for future comparision */ |
483 | if (cpu == 0 && IS_ERR(event)) | 520 | if (cpu == 0 && IS_ERR(event)) |
484 | cpu0_err = PTR_ERR(event); | 521 | cpu0_err = PTR_ERR(event); |
@@ -624,11 +661,13 @@ int proc_dowatchdog(struct ctl_table *table, int write, | |||
624 | void __user *buffer, size_t *lenp, loff_t *ppos) | 661 | void __user *buffer, size_t *lenp, loff_t *ppos) |
625 | { | 662 | { |
626 | int err, old_thresh, old_enabled; | 663 | int err, old_thresh, old_enabled; |
664 | bool old_hardlockup; | ||
627 | static DEFINE_MUTEX(watchdog_proc_mutex); | 665 | static DEFINE_MUTEX(watchdog_proc_mutex); |
628 | 666 | ||
629 | mutex_lock(&watchdog_proc_mutex); | 667 | mutex_lock(&watchdog_proc_mutex); |
630 | old_thresh = ACCESS_ONCE(watchdog_thresh); | 668 | old_thresh = ACCESS_ONCE(watchdog_thresh); |
631 | old_enabled = ACCESS_ONCE(watchdog_user_enabled); | 669 | old_enabled = ACCESS_ONCE(watchdog_user_enabled); |
670 | old_hardlockup = watchdog_hardlockup_detector_is_enabled(); | ||
632 | 671 | ||
633 | err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); | 672 | err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); |
634 | if (err || !write) | 673 | if (err || !write) |
@@ -640,15 +679,22 @@ int proc_dowatchdog(struct ctl_table *table, int write, | |||
640 | * disabled. The 'watchdog_running' variable check in | 679 | * disabled. The 'watchdog_running' variable check in |
641 | * watchdog_*_all_cpus() function takes care of this. | 680 | * watchdog_*_all_cpus() function takes care of this. |
642 | */ | 681 | */ |
643 | if (watchdog_user_enabled && watchdog_thresh) | 682 | if (watchdog_user_enabled && watchdog_thresh) { |
683 | /* | ||
684 | * Prevent a change in watchdog_thresh accidentally overriding | ||
685 | * the enablement of the hardlockup detector. | ||
686 | */ | ||
687 | if (watchdog_user_enabled != old_enabled) | ||
688 | watchdog_enable_hardlockup_detector(true); | ||
644 | err = watchdog_enable_all_cpus(old_thresh != watchdog_thresh); | 689 | err = watchdog_enable_all_cpus(old_thresh != watchdog_thresh); |
645 | else | 690 | } else |
646 | watchdog_disable_all_cpus(); | 691 | watchdog_disable_all_cpus(); |
647 | 692 | ||
648 | /* Restore old values on failure */ | 693 | /* Restore old values on failure */ |
649 | if (err) { | 694 | if (err) { |
650 | watchdog_thresh = old_thresh; | 695 | watchdog_thresh = old_thresh; |
651 | watchdog_user_enabled = old_enabled; | 696 | watchdog_user_enabled = old_enabled; |
697 | watchdog_enable_hardlockup_detector(old_hardlockup); | ||
652 | } | 698 | } |
653 | out: | 699 | out: |
654 | mutex_unlock(&watchdog_proc_mutex); | 700 | mutex_unlock(&watchdog_proc_mutex); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index e7ad58c5fbeb..4e35a5d767ed 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -1648,7 +1648,7 @@ config DMA_API_DEBUG | |||
1648 | 1648 | ||
1649 | If unsure, say N. | 1649 | If unsure, say N. |
1650 | 1650 | ||
1651 | config TEST_MODULE | 1651 | config TEST_LKM |
1652 | tristate "Test module loading with 'hello world' module" | 1652 | tristate "Test module loading with 'hello world' module" |
1653 | default n | 1653 | default n |
1654 | depends on m | 1654 | depends on m |
diff --git a/lib/Makefile b/lib/Makefile index d6b4bc496408..7512dc978f18 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -11,7 +11,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ | |||
11 | rbtree.o radix-tree.o dump_stack.o timerqueue.o\ | 11 | rbtree.o radix-tree.o dump_stack.o timerqueue.o\ |
12 | idr.o int_sqrt.o extable.o \ | 12 | idr.o int_sqrt.o extable.o \ |
13 | sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ | 13 | sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ |
14 | proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \ | 14 | proportions.o flex_proportions.o ratelimit.o show_mem.o \ |
15 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ | 15 | is_single_threaded.o plist.o decompress.o kobject_uevent.o \ |
16 | earlycpio.o | 16 | earlycpio.o |
17 | 17 | ||
@@ -31,7 +31,7 @@ obj-y += string_helpers.o | |||
31 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o | 31 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o |
32 | obj-y += kstrtox.o | 32 | obj-y += kstrtox.o |
33 | obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o | 33 | obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o |
34 | obj-$(CONFIG_TEST_MODULE) += test_module.o | 34 | obj-$(CONFIG_TEST_LKM) += test_module.o |
35 | obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o | 35 | obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o |
36 | obj-$(CONFIG_TEST_BPF) += test_bpf.o | 36 | obj-$(CONFIG_TEST_BPF) += test_bpf.o |
37 | obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o | 37 | obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o |
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 31fe79e31ab8..dfba05521748 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -819,22 +819,9 @@ static const struct seq_operations ddebug_proc_seqops = { | |||
819 | */ | 819 | */ |
820 | static int ddebug_proc_open(struct inode *inode, struct file *file) | 820 | static int ddebug_proc_open(struct inode *inode, struct file *file) |
821 | { | 821 | { |
822 | struct ddebug_iter *iter; | ||
823 | int err; | ||
824 | |||
825 | vpr_info("called\n"); | 822 | vpr_info("called\n"); |
826 | 823 | return seq_open_private(file, &ddebug_proc_seqops, | |
827 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 824 | sizeof(struct ddebug_iter)); |
828 | if (iter == NULL) | ||
829 | return -ENOMEM; | ||
830 | |||
831 | err = seq_open(file, &ddebug_proc_seqops); | ||
832 | if (err) { | ||
833 | kfree(iter); | ||
834 | return err; | ||
835 | } | ||
836 | ((struct seq_file *)file->private_data)->private = iter; | ||
837 | return 0; | ||
838 | } | 825 | } |
839 | 826 | ||
840 | static const struct file_operations ddebug_proc_fops = { | 827 | static const struct file_operations ddebug_proc_fops = { |
diff --git a/lib/prio_heap.c b/lib/prio_heap.c deleted file mode 100644 index a7af6f85eca8..000000000000 --- a/lib/prio_heap.c +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | * Simple insertion-only static-sized priority heap containing | ||
3 | * pointers, based on CLR, chapter 7 | ||
4 | */ | ||
5 | |||
6 | #include <linux/slab.h> | ||
7 | #include <linux/prio_heap.h> | ||
8 | |||
9 | int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask, | ||
10 | int (*gt)(void *, void *)) | ||
11 | { | ||
12 | heap->ptrs = kmalloc(size, gfp_mask); | ||
13 | if (!heap->ptrs) | ||
14 | return -ENOMEM; | ||
15 | heap->size = 0; | ||
16 | heap->max = size / sizeof(void *); | ||
17 | heap->gt = gt; | ||
18 | return 0; | ||
19 | } | ||
20 | |||
21 | void heap_free(struct ptr_heap *heap) | ||
22 | { | ||
23 | kfree(heap->ptrs); | ||
24 | } | ||
25 | |||
26 | void *heap_insert(struct ptr_heap *heap, void *p) | ||
27 | { | ||
28 | void *res; | ||
29 | void **ptrs = heap->ptrs; | ||
30 | int pos; | ||
31 | |||
32 | if (heap->size < heap->max) { | ||
33 | /* Heap insertion */ | ||
34 | pos = heap->size++; | ||
35 | while (pos > 0 && heap->gt(p, ptrs[(pos-1)/2])) { | ||
36 | ptrs[pos] = ptrs[(pos-1)/2]; | ||
37 | pos = (pos-1)/2; | ||
38 | } | ||
39 | ptrs[pos] = p; | ||
40 | return NULL; | ||
41 | } | ||
42 | |||
43 | /* The heap is full, so something will have to be dropped */ | ||
44 | |||
45 | /* If the new pointer is greater than the current max, drop it */ | ||
46 | if (heap->gt(p, ptrs[0])) | ||
47 | return p; | ||
48 | |||
49 | /* Replace the current max and heapify */ | ||
50 | res = ptrs[0]; | ||
51 | ptrs[0] = p; | ||
52 | pos = 0; | ||
53 | |||
54 | while (1) { | ||
55 | int left = 2 * pos + 1; | ||
56 | int right = 2 * pos + 2; | ||
57 | int largest = pos; | ||
58 | if (left < heap->size && heap->gt(ptrs[left], p)) | ||
59 | largest = left; | ||
60 | if (right < heap->size && heap->gt(ptrs[right], ptrs[largest])) | ||
61 | largest = right; | ||
62 | if (largest == pos) | ||
63 | break; | ||
64 | /* Push p down the heap one level and bump one up */ | ||
65 | ptrs[pos] = ptrs[largest]; | ||
66 | ptrs[largest] = p; | ||
67 | pos = largest; | ||
68 | } | ||
69 | return res; | ||
70 | } | ||
diff --git a/lib/string.c b/lib/string.c index f3c6ff596414..2fc20aa06f84 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -27,14 +27,14 @@ | |||
27 | #include <linux/bug.h> | 27 | #include <linux/bug.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | 29 | ||
30 | #ifndef __HAVE_ARCH_STRNICMP | 30 | #ifndef __HAVE_ARCH_STRNCASECMP |
31 | /** | 31 | /** |
32 | * strnicmp - Case insensitive, length-limited string comparison | 32 | * strncasecmp - Case insensitive, length-limited string comparison |
33 | * @s1: One string | 33 | * @s1: One string |
34 | * @s2: The other string | 34 | * @s2: The other string |
35 | * @len: the maximum number of characters to compare | 35 | * @len: the maximum number of characters to compare |
36 | */ | 36 | */ |
37 | int strnicmp(const char *s1, const char *s2, size_t len) | 37 | int strncasecmp(const char *s1, const char *s2, size_t len) |
38 | { | 38 | { |
39 | /* Yes, Virginia, it had better be unsigned */ | 39 | /* Yes, Virginia, it had better be unsigned */ |
40 | unsigned char c1, c2; | 40 | unsigned char c1, c2; |
@@ -56,6 +56,14 @@ int strnicmp(const char *s1, const char *s2, size_t len) | |||
56 | } while (--len); | 56 | } while (--len); |
57 | return (int)c1 - (int)c2; | 57 | return (int)c1 - (int)c2; |
58 | } | 58 | } |
59 | EXPORT_SYMBOL(strncasecmp); | ||
60 | #endif | ||
61 | #ifndef __HAVE_ARCH_STRNICMP | ||
62 | #undef strnicmp | ||
63 | int strnicmp(const char *s1, const char *s2, size_t len) | ||
64 | { | ||
65 | return strncasecmp(s1, s2, len); | ||
66 | } | ||
59 | EXPORT_SYMBOL(strnicmp); | 67 | EXPORT_SYMBOL(strnicmp); |
60 | #endif | 68 | #endif |
61 | 69 | ||
@@ -73,20 +81,6 @@ int strcasecmp(const char *s1, const char *s2) | |||
73 | EXPORT_SYMBOL(strcasecmp); | 81 | EXPORT_SYMBOL(strcasecmp); |
74 | #endif | 82 | #endif |
75 | 83 | ||
76 | #ifndef __HAVE_ARCH_STRNCASECMP | ||
77 | int strncasecmp(const char *s1, const char *s2, size_t n) | ||
78 | { | ||
79 | int c1, c2; | ||
80 | |||
81 | do { | ||
82 | c1 = tolower(*s1++); | ||
83 | c2 = tolower(*s2++); | ||
84 | } while ((--n > 0) && c1 == c2 && c1 != 0); | ||
85 | return c1 - c2; | ||
86 | } | ||
87 | EXPORT_SYMBOL(strncasecmp); | ||
88 | #endif | ||
89 | |||
90 | #ifndef __HAVE_ARCH_STRCPY | 84 | #ifndef __HAVE_ARCH_STRCPY |
91 | /** | 85 | /** |
92 | * strcpy - Copy a %NUL terminated string | 86 | * strcpy - Copy a %NUL terminated string |
diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 29033f319aea..58b78ba57439 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <linux/math64.h> | 8 | #include <linux/math64.h> |
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
10 | #include <linux/ctype.h> | 10 | #include <linux/ctype.h> |
11 | #include <linux/errno.h> | ||
12 | #include <linux/string.h> | ||
11 | #include <linux/string_helpers.h> | 13 | #include <linux/string_helpers.h> |
12 | 14 | ||
13 | /** | 15 | /** |
@@ -168,6 +170,44 @@ static bool unescape_special(char **src, char **dst) | |||
168 | return true; | 170 | return true; |
169 | } | 171 | } |
170 | 172 | ||
173 | /** | ||
174 | * string_unescape - unquote characters in the given string | ||
175 | * @src: source buffer (escaped) | ||
176 | * @dst: destination buffer (unescaped) | ||
177 | * @size: size of the destination buffer (0 to unlimit) | ||
178 | * @flags: combination of the flags (bitwise OR): | ||
179 | * %UNESCAPE_SPACE: | ||
180 | * '\f' - form feed | ||
181 | * '\n' - new line | ||
182 | * '\r' - carriage return | ||
183 | * '\t' - horizontal tab | ||
184 | * '\v' - vertical tab | ||
185 | * %UNESCAPE_OCTAL: | ||
186 | * '\NNN' - byte with octal value NNN (1 to 3 digits) | ||
187 | * %UNESCAPE_HEX: | ||
188 | * '\xHH' - byte with hexadecimal value HH (1 to 2 digits) | ||
189 | * %UNESCAPE_SPECIAL: | ||
190 | * '\"' - double quote | ||
191 | * '\\' - backslash | ||
192 | * '\a' - alert (BEL) | ||
193 | * '\e' - escape | ||
194 | * %UNESCAPE_ANY: | ||
195 | * all previous together | ||
196 | * | ||
197 | * Description: | ||
198 | * The function unquotes characters in the given string. | ||
199 | * | ||
200 | * Because the size of the output will be the same as or less than the size of | ||
201 | * the input, the transformation may be performed in place. | ||
202 | * | ||
203 | * Caller must provide valid source and destination pointers. Be aware that | ||
204 | * destination buffer will always be NULL-terminated. Source string must be | ||
205 | * NULL-terminated as well. | ||
206 | * | ||
207 | * Return: | ||
208 | * The amount of the characters processed to the destination buffer excluding | ||
209 | * trailing '\0' is returned. | ||
210 | */ | ||
171 | int string_unescape(char *src, char *dst, size_t size, unsigned int flags) | 211 | int string_unescape(char *src, char *dst, size_t size, unsigned int flags) |
172 | { | 212 | { |
173 | char *out = dst; | 213 | char *out = dst; |
@@ -202,3 +242,275 @@ int string_unescape(char *src, char *dst, size_t size, unsigned int flags) | |||
202 | return out - dst; | 242 | return out - dst; |
203 | } | 243 | } |
204 | EXPORT_SYMBOL(string_unescape); | 244 | EXPORT_SYMBOL(string_unescape); |
245 | |||
246 | static int escape_passthrough(unsigned char c, char **dst, size_t *osz) | ||
247 | { | ||
248 | char *out = *dst; | ||
249 | |||
250 | if (*osz < 1) | ||
251 | return -ENOMEM; | ||
252 | |||
253 | *out++ = c; | ||
254 | |||
255 | *dst = out; | ||
256 | *osz -= 1; | ||
257 | |||
258 | return 1; | ||
259 | } | ||
260 | |||
261 | static int escape_space(unsigned char c, char **dst, size_t *osz) | ||
262 | { | ||
263 | char *out = *dst; | ||
264 | unsigned char to; | ||
265 | |||
266 | if (*osz < 2) | ||
267 | return -ENOMEM; | ||
268 | |||
269 | switch (c) { | ||
270 | case '\n': | ||
271 | to = 'n'; | ||
272 | break; | ||
273 | case '\r': | ||
274 | to = 'r'; | ||
275 | break; | ||
276 | case '\t': | ||
277 | to = 't'; | ||
278 | break; | ||
279 | case '\v': | ||
280 | to = 'v'; | ||
281 | break; | ||
282 | case '\f': | ||
283 | to = 'f'; | ||
284 | break; | ||
285 | default: | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | *out++ = '\\'; | ||
290 | *out++ = to; | ||
291 | |||
292 | *dst = out; | ||
293 | *osz -= 2; | ||
294 | |||
295 | return 1; | ||
296 | } | ||
297 | |||
298 | static int escape_special(unsigned char c, char **dst, size_t *osz) | ||
299 | { | ||
300 | char *out = *dst; | ||
301 | unsigned char to; | ||
302 | |||
303 | if (*osz < 2) | ||
304 | return -ENOMEM; | ||
305 | |||
306 | switch (c) { | ||
307 | case '\\': | ||
308 | to = '\\'; | ||
309 | break; | ||
310 | case '\a': | ||
311 | to = 'a'; | ||
312 | break; | ||
313 | case '\e': | ||
314 | to = 'e'; | ||
315 | break; | ||
316 | default: | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | *out++ = '\\'; | ||
321 | *out++ = to; | ||
322 | |||
323 | *dst = out; | ||
324 | *osz -= 2; | ||
325 | |||
326 | return 1; | ||
327 | } | ||
328 | |||
329 | static int escape_null(unsigned char c, char **dst, size_t *osz) | ||
330 | { | ||
331 | char *out = *dst; | ||
332 | |||
333 | if (*osz < 2) | ||
334 | return -ENOMEM; | ||
335 | |||
336 | if (c) | ||
337 | return 0; | ||
338 | |||
339 | *out++ = '\\'; | ||
340 | *out++ = '0'; | ||
341 | |||
342 | *dst = out; | ||
343 | *osz -= 2; | ||
344 | |||
345 | return 1; | ||
346 | } | ||
347 | |||
348 | static int escape_octal(unsigned char c, char **dst, size_t *osz) | ||
349 | { | ||
350 | char *out = *dst; | ||
351 | |||
352 | if (*osz < 4) | ||
353 | return -ENOMEM; | ||
354 | |||
355 | *out++ = '\\'; | ||
356 | *out++ = ((c >> 6) & 0x07) + '0'; | ||
357 | *out++ = ((c >> 3) & 0x07) + '0'; | ||
358 | *out++ = ((c >> 0) & 0x07) + '0'; | ||
359 | |||
360 | *dst = out; | ||
361 | *osz -= 4; | ||
362 | |||
363 | return 1; | ||
364 | } | ||
365 | |||
366 | static int escape_hex(unsigned char c, char **dst, size_t *osz) | ||
367 | { | ||
368 | char *out = *dst; | ||
369 | |||
370 | if (*osz < 4) | ||
371 | return -ENOMEM; | ||
372 | |||
373 | *out++ = '\\'; | ||
374 | *out++ = 'x'; | ||
375 | *out++ = hex_asc_hi(c); | ||
376 | *out++ = hex_asc_lo(c); | ||
377 | |||
378 | *dst = out; | ||
379 | *osz -= 4; | ||
380 | |||
381 | return 1; | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * string_escape_mem - quote characters in the given memory buffer | ||
386 | * @src: source buffer (unescaped) | ||
387 | * @isz: source buffer size | ||
388 | * @dst: destination buffer (escaped) | ||
389 | * @osz: destination buffer size | ||
390 | * @flags: combination of the flags (bitwise OR): | ||
391 | * %ESCAPE_SPACE: | ||
392 | * '\f' - form feed | ||
393 | * '\n' - new line | ||
394 | * '\r' - carriage return | ||
395 | * '\t' - horizontal tab | ||
396 | * '\v' - vertical tab | ||
397 | * %ESCAPE_SPECIAL: | ||
398 | * '\\' - backslash | ||
399 | * '\a' - alert (BEL) | ||
400 | * '\e' - escape | ||
401 | * %ESCAPE_NULL: | ||
402 | * '\0' - null | ||
403 | * %ESCAPE_OCTAL: | ||
404 | * '\NNN' - byte with octal value NNN (3 digits) | ||
405 | * %ESCAPE_ANY: | ||
406 | * all previous together | ||
407 | * %ESCAPE_NP: | ||
408 | * escape only non-printable characters (checked by isprint) | ||
409 | * %ESCAPE_ANY_NP: | ||
410 | * all previous together | ||
411 | * %ESCAPE_HEX: | ||
412 | * '\xHH' - byte with hexadecimal value HH (2 digits) | ||
413 | * @esc: NULL-terminated string of characters any of which, if found in | ||
414 | * the source, has to be escaped | ||
415 | * | ||
416 | * Description: | ||
417 | * The process of escaping byte buffer includes several parts. They are applied | ||
418 | * in the following sequence. | ||
419 | * 1. The character is matched to the printable class, if asked, and in | ||
420 | * case of match it passes through to the output. | ||
421 | * 2. The character is not matched to the one from @esc string and thus | ||
422 | * must go as is to the output. | ||
423 | * 3. The character is checked if it falls into the class given by @flags. | ||
424 | * %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any | ||
425 | * character. Note that they actually can't go together, otherwise | ||
426 | * %ESCAPE_HEX will be ignored. | ||
427 | * | ||
428 | * Caller must provide valid source and destination pointers. Be aware that | ||
429 | * destination buffer will not be NULL-terminated, thus caller have to append | ||
430 | * it if needs. | ||
431 | * | ||
432 | * Return: | ||
433 | * The amount of the characters processed to the destination buffer, or | ||
434 | * %-ENOMEM if the size of buffer is not enough to put an escaped character is | ||
435 | * returned. | ||
436 | * | ||
437 | * Even in the case of error @dst pointer will be updated to point to the byte | ||
438 | * after the last processed character. | ||
439 | */ | ||
440 | int string_escape_mem(const char *src, size_t isz, char **dst, size_t osz, | ||
441 | unsigned int flags, const char *esc) | ||
442 | { | ||
443 | char *out = *dst, *p = out; | ||
444 | bool is_dict = esc && *esc; | ||
445 | int ret = 0; | ||
446 | |||
447 | while (isz--) { | ||
448 | unsigned char c = *src++; | ||
449 | |||
450 | /* | ||
451 | * Apply rules in the following sequence: | ||
452 | * - the character is printable, when @flags has | ||
453 | * %ESCAPE_NP bit set | ||
454 | * - the @esc string is supplied and does not contain a | ||
455 | * character under question | ||
456 | * - the character doesn't fall into a class of symbols | ||
457 | * defined by given @flags | ||
458 | * In these cases we just pass through a character to the | ||
459 | * output buffer. | ||
460 | */ | ||
461 | if ((flags & ESCAPE_NP && isprint(c)) || | ||
462 | (is_dict && !strchr(esc, c))) { | ||
463 | /* do nothing */ | ||
464 | } else { | ||
465 | if (flags & ESCAPE_SPACE) { | ||
466 | ret = escape_space(c, &p, &osz); | ||
467 | if (ret < 0) | ||
468 | break; | ||
469 | if (ret > 0) | ||
470 | continue; | ||
471 | } | ||
472 | |||
473 | if (flags & ESCAPE_SPECIAL) { | ||
474 | ret = escape_special(c, &p, &osz); | ||
475 | if (ret < 0) | ||
476 | break; | ||
477 | if (ret > 0) | ||
478 | continue; | ||
479 | } | ||
480 | |||
481 | if (flags & ESCAPE_NULL) { | ||
482 | ret = escape_null(c, &p, &osz); | ||
483 | if (ret < 0) | ||
484 | break; | ||
485 | if (ret > 0) | ||
486 | continue; | ||
487 | } | ||
488 | |||
489 | /* ESCAPE_OCTAL and ESCAPE_HEX always go last */ | ||
490 | if (flags & ESCAPE_OCTAL) { | ||
491 | ret = escape_octal(c, &p, &osz); | ||
492 | if (ret < 0) | ||
493 | break; | ||
494 | continue; | ||
495 | } | ||
496 | if (flags & ESCAPE_HEX) { | ||
497 | ret = escape_hex(c, &p, &osz); | ||
498 | if (ret < 0) | ||
499 | break; | ||
500 | continue; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | ret = escape_passthrough(c, &p, &osz); | ||
505 | if (ret < 0) | ||
506 | break; | ||
507 | } | ||
508 | |||
509 | *dst = p; | ||
510 | |||
511 | if (ret < 0) | ||
512 | return ret; | ||
513 | |||
514 | return p - out; | ||
515 | } | ||
516 | EXPORT_SYMBOL(string_escape_mem); | ||
diff --git a/lib/test-string_helpers.c b/lib/test-string_helpers.c index 6ac48de04c0e..ab0d30e1e18f 100644 --- a/lib/test-string_helpers.c +++ b/lib/test-string_helpers.c | |||
@@ -5,11 +5,32 @@ | |||
5 | 5 | ||
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/slab.h> | ||
8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
9 | #include <linux/random.h> | 10 | #include <linux/random.h> |
10 | #include <linux/string.h> | 11 | #include <linux/string.h> |
11 | #include <linux/string_helpers.h> | 12 | #include <linux/string_helpers.h> |
12 | 13 | ||
14 | static __init bool test_string_check_buf(const char *name, unsigned int flags, | ||
15 | char *in, size_t p, | ||
16 | char *out_real, size_t q_real, | ||
17 | char *out_test, size_t q_test) | ||
18 | { | ||
19 | if (q_real == q_test && !memcmp(out_test, out_real, q_test)) | ||
20 | return true; | ||
21 | |||
22 | pr_warn("Test '%s' failed: flags = %u\n", name, flags); | ||
23 | |||
24 | print_hex_dump(KERN_WARNING, "Input: ", DUMP_PREFIX_NONE, 16, 1, | ||
25 | in, p, true); | ||
26 | print_hex_dump(KERN_WARNING, "Expected: ", DUMP_PREFIX_NONE, 16, 1, | ||
27 | out_test, q_test, true); | ||
28 | print_hex_dump(KERN_WARNING, "Got: ", DUMP_PREFIX_NONE, 16, 1, | ||
29 | out_real, q_real, true); | ||
30 | |||
31 | return false; | ||
32 | } | ||
33 | |||
13 | struct test_string { | 34 | struct test_string { |
14 | const char *in; | 35 | const char *in; |
15 | const char *out; | 36 | const char *out; |
@@ -39,12 +60,17 @@ static const struct test_string strings[] __initconst = { | |||
39 | }, | 60 | }, |
40 | }; | 61 | }; |
41 | 62 | ||
42 | static void __init test_string_unescape(unsigned int flags, bool inplace) | 63 | static void __init test_string_unescape(const char *name, unsigned int flags, |
64 | bool inplace) | ||
43 | { | 65 | { |
44 | char in[256]; | 66 | int q_real = 256; |
45 | char out_test[256]; | 67 | char *in = kmalloc(q_real, GFP_KERNEL); |
46 | char out_real[256]; | 68 | char *out_test = kmalloc(q_real, GFP_KERNEL); |
47 | int i, p = 0, q_test = 0, q_real = sizeof(out_real); | 69 | char *out_real = kmalloc(q_real, GFP_KERNEL); |
70 | int i, p = 0, q_test = 0; | ||
71 | |||
72 | if (!in || !out_test || !out_real) | ||
73 | goto out; | ||
48 | 74 | ||
49 | for (i = 0; i < ARRAY_SIZE(strings); i++) { | 75 | for (i = 0; i < ARRAY_SIZE(strings); i++) { |
50 | const char *s = strings[i].in; | 76 | const char *s = strings[i].in; |
@@ -77,15 +103,225 @@ static void __init test_string_unescape(unsigned int flags, bool inplace) | |||
77 | q_real = string_unescape(in, out_real, q_real, flags); | 103 | q_real = string_unescape(in, out_real, q_real, flags); |
78 | } | 104 | } |
79 | 105 | ||
80 | if (q_real != q_test || memcmp(out_test, out_real, q_test)) { | 106 | test_string_check_buf(name, flags, in, p - 1, out_real, q_real, |
81 | pr_warn("Test failed: flags = %u\n", flags); | 107 | out_test, q_test); |
82 | print_hex_dump(KERN_WARNING, "Input: ", | 108 | out: |
83 | DUMP_PREFIX_NONE, 16, 1, in, p - 1, true); | 109 | kfree(out_real); |
84 | print_hex_dump(KERN_WARNING, "Expected: ", | 110 | kfree(out_test); |
85 | DUMP_PREFIX_NONE, 16, 1, out_test, q_test, true); | 111 | kfree(in); |
86 | print_hex_dump(KERN_WARNING, "Got: ", | 112 | } |
87 | DUMP_PREFIX_NONE, 16, 1, out_real, q_real, true); | 113 | |
114 | struct test_string_1 { | ||
115 | const char *out; | ||
116 | unsigned int flags; | ||
117 | }; | ||
118 | |||
119 | #define TEST_STRING_2_MAX_S1 32 | ||
120 | struct test_string_2 { | ||
121 | const char *in; | ||
122 | struct test_string_1 s1[TEST_STRING_2_MAX_S1]; | ||
123 | }; | ||
124 | |||
125 | #define TEST_STRING_2_DICT_0 NULL | ||
126 | static const struct test_string_2 escape0[] __initconst = {{ | ||
127 | .in = "\f\\ \n\r\t\v", | ||
128 | .s1 = {{ | ||
129 | .out = "\\f\\ \\n\\r\\t\\v", | ||
130 | .flags = ESCAPE_SPACE, | ||
131 | },{ | ||
132 | .out = "\\f\\134\\040\\n\\r\\t\\v", | ||
133 | .flags = ESCAPE_SPACE | ESCAPE_OCTAL, | ||
134 | },{ | ||
135 | .out = "\\f\\x5c\\x20\\n\\r\\t\\v", | ||
136 | .flags = ESCAPE_SPACE | ESCAPE_HEX, | ||
137 | },{ | ||
138 | /* terminator */ | ||
139 | }}, | ||
140 | },{ | ||
141 | .in = "\\h\\\"\a\e\\", | ||
142 | .s1 = {{ | ||
143 | .out = "\\\\h\\\\\"\\a\\e\\\\", | ||
144 | .flags = ESCAPE_SPECIAL, | ||
145 | },{ | ||
146 | .out = "\\\\\\150\\\\\\042\\a\\e\\\\", | ||
147 | .flags = ESCAPE_SPECIAL | ESCAPE_OCTAL, | ||
148 | },{ | ||
149 | .out = "\\\\\\x68\\\\\\x22\\a\\e\\\\", | ||
150 | .flags = ESCAPE_SPECIAL | ESCAPE_HEX, | ||
151 | },{ | ||
152 | /* terminator */ | ||
153 | }}, | ||
154 | },{ | ||
155 | .in = "\eb \\C\007\"\x90\r]", | ||
156 | .s1 = {{ | ||
157 | .out = "\eb \\C\007\"\x90\\r]", | ||
158 | .flags = ESCAPE_SPACE, | ||
159 | },{ | ||
160 | .out = "\\eb \\\\C\\a\"\x90\r]", | ||
161 | .flags = ESCAPE_SPECIAL, | ||
162 | },{ | ||
163 | .out = "\\eb \\\\C\\a\"\x90\\r]", | ||
164 | .flags = ESCAPE_SPACE | ESCAPE_SPECIAL, | ||
165 | },{ | ||
166 | .out = "\\033\\142\\040\\134\\103\\007\\042\\220\\015\\135", | ||
167 | .flags = ESCAPE_OCTAL, | ||
168 | },{ | ||
169 | .out = "\\033\\142\\040\\134\\103\\007\\042\\220\\r\\135", | ||
170 | .flags = ESCAPE_SPACE | ESCAPE_OCTAL, | ||
171 | },{ | ||
172 | .out = "\\e\\142\\040\\\\\\103\\a\\042\\220\\015\\135", | ||
173 | .flags = ESCAPE_SPECIAL | ESCAPE_OCTAL, | ||
174 | },{ | ||
175 | .out = "\\e\\142\\040\\\\\\103\\a\\042\\220\\r\\135", | ||
176 | .flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_OCTAL, | ||
177 | },{ | ||
178 | .out = "\eb \\C\007\"\x90\r]", | ||
179 | .flags = ESCAPE_NP, | ||
180 | },{ | ||
181 | .out = "\eb \\C\007\"\x90\\r]", | ||
182 | .flags = ESCAPE_SPACE | ESCAPE_NP, | ||
183 | },{ | ||
184 | .out = "\\eb \\C\\a\"\x90\r]", | ||
185 | .flags = ESCAPE_SPECIAL | ESCAPE_NP, | ||
186 | },{ | ||
187 | .out = "\\eb \\C\\a\"\x90\\r]", | ||
188 | .flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NP, | ||
189 | },{ | ||
190 | .out = "\\033b \\C\\007\"\\220\\015]", | ||
191 | .flags = ESCAPE_OCTAL | ESCAPE_NP, | ||
192 | },{ | ||
193 | .out = "\\033b \\C\\007\"\\220\\r]", | ||
194 | .flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NP, | ||
195 | },{ | ||
196 | .out = "\\eb \\C\\a\"\\220\\r]", | ||
197 | .flags = ESCAPE_SPECIAL | ESCAPE_SPACE | ESCAPE_OCTAL | | ||
198 | ESCAPE_NP, | ||
199 | },{ | ||
200 | .out = "\\x1bb \\C\\x07\"\\x90\\x0d]", | ||
201 | .flags = ESCAPE_NP | ESCAPE_HEX, | ||
202 | },{ | ||
203 | /* terminator */ | ||
204 | }}, | ||
205 | },{ | ||
206 | /* terminator */ | ||
207 | }}; | ||
208 | |||
209 | #define TEST_STRING_2_DICT_1 "b\\ \t\r" | ||
210 | static const struct test_string_2 escape1[] __initconst = {{ | ||
211 | .in = "\f\\ \n\r\t\v", | ||
212 | .s1 = {{ | ||
213 | .out = "\f\\134\\040\n\\015\\011\v", | ||
214 | .flags = ESCAPE_OCTAL, | ||
215 | },{ | ||
216 | .out = "\f\\x5c\\x20\n\\x0d\\x09\v", | ||
217 | .flags = ESCAPE_HEX, | ||
218 | },{ | ||
219 | /* terminator */ | ||
220 | }}, | ||
221 | },{ | ||
222 | .in = "\\h\\\"\a\e\\", | ||
223 | .s1 = {{ | ||
224 | .out = "\\134h\\134\"\a\e\\134", | ||
225 | .flags = ESCAPE_OCTAL, | ||
226 | },{ | ||
227 | /* terminator */ | ||
228 | }}, | ||
229 | },{ | ||
230 | .in = "\eb \\C\007\"\x90\r]", | ||
231 | .s1 = {{ | ||
232 | .out = "\e\\142\\040\\134C\007\"\x90\\015]", | ||
233 | .flags = ESCAPE_OCTAL, | ||
234 | },{ | ||
235 | /* terminator */ | ||
236 | }}, | ||
237 | },{ | ||
238 | /* terminator */ | ||
239 | }}; | ||
240 | |||
241 | static __init const char *test_string_find_match(const struct test_string_2 *s2, | ||
242 | unsigned int flags) | ||
243 | { | ||
244 | const struct test_string_1 *s1 = s2->s1; | ||
245 | unsigned int i; | ||
246 | |||
247 | if (!flags) | ||
248 | return s2->in; | ||
249 | |||
250 | /* Test cases are NULL-aware */ | ||
251 | flags &= ~ESCAPE_NULL; | ||
252 | |||
253 | /* ESCAPE_OCTAL has a higher priority */ | ||
254 | if (flags & ESCAPE_OCTAL) | ||
255 | flags &= ~ESCAPE_HEX; | ||
256 | |||
257 | for (i = 0; i < TEST_STRING_2_MAX_S1 && s1->out; i++, s1++) | ||
258 | if (s1->flags == flags) | ||
259 | return s1->out; | ||
260 | return NULL; | ||
261 | } | ||
262 | |||
263 | static __init void test_string_escape(const char *name, | ||
264 | const struct test_string_2 *s2, | ||
265 | unsigned int flags, const char *esc) | ||
266 | { | ||
267 | int q_real = 512; | ||
268 | char *out_test = kmalloc(q_real, GFP_KERNEL); | ||
269 | char *out_real = kmalloc(q_real, GFP_KERNEL); | ||
270 | char *in = kmalloc(256, GFP_KERNEL); | ||
271 | char *buf = out_real; | ||
272 | int p = 0, q_test = 0; | ||
273 | |||
274 | if (!out_test || !out_real || !in) | ||
275 | goto out; | ||
276 | |||
277 | for (; s2->in; s2++) { | ||
278 | const char *out; | ||
279 | int len; | ||
280 | |||
281 | /* NULL injection */ | ||
282 | if (flags & ESCAPE_NULL) { | ||
283 | in[p++] = '\0'; | ||
284 | out_test[q_test++] = '\\'; | ||
285 | out_test[q_test++] = '0'; | ||
286 | } | ||
287 | |||
288 | /* Don't try strings that have no output */ | ||
289 | out = test_string_find_match(s2, flags); | ||
290 | if (!out) | ||
291 | continue; | ||
292 | |||
293 | /* Copy string to in buffer */ | ||
294 | len = strlen(s2->in); | ||
295 | memcpy(&in[p], s2->in, len); | ||
296 | p += len; | ||
297 | |||
298 | /* Copy expected result for given flags */ | ||
299 | len = strlen(out); | ||
300 | memcpy(&out_test[q_test], out, len); | ||
301 | q_test += len; | ||
88 | } | 302 | } |
303 | |||
304 | q_real = string_escape_mem(in, p, &buf, q_real, flags, esc); | ||
305 | |||
306 | test_string_check_buf(name, flags, in, p, out_real, q_real, out_test, | ||
307 | q_test); | ||
308 | out: | ||
309 | kfree(in); | ||
310 | kfree(out_real); | ||
311 | kfree(out_test); | ||
312 | } | ||
313 | |||
314 | static __init void test_string_escape_nomem(void) | ||
315 | { | ||
316 | char *in = "\eb \\C\007\"\x90\r]"; | ||
317 | char out[64], *buf = out; | ||
318 | int rc = -ENOMEM, ret; | ||
319 | |||
320 | ret = string_escape_str_any_np(in, &buf, strlen(in), NULL); | ||
321 | if (ret == rc) | ||
322 | return; | ||
323 | |||
324 | pr_err("Test 'escape nomem' failed: got %d instead of %d\n", ret, rc); | ||
89 | } | 325 | } |
90 | 326 | ||
91 | static int __init test_string_helpers_init(void) | 327 | static int __init test_string_helpers_init(void) |
@@ -94,8 +330,19 @@ static int __init test_string_helpers_init(void) | |||
94 | 330 | ||
95 | pr_info("Running tests...\n"); | 331 | pr_info("Running tests...\n"); |
96 | for (i = 0; i < UNESCAPE_ANY + 1; i++) | 332 | for (i = 0; i < UNESCAPE_ANY + 1; i++) |
97 | test_string_unescape(i, false); | 333 | test_string_unescape("unescape", i, false); |
98 | test_string_unescape(get_random_int() % (UNESCAPE_ANY + 1), true); | 334 | test_string_unescape("unescape inplace", |
335 | get_random_int() % (UNESCAPE_ANY + 1), true); | ||
336 | |||
337 | /* Without dictionary */ | ||
338 | for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++) | ||
339 | test_string_escape("escape 0", escape0, i, TEST_STRING_2_DICT_0); | ||
340 | |||
341 | /* With dictionary */ | ||
342 | for (i = 0; i < (ESCAPE_ANY_NP | ESCAPE_HEX) + 1; i++) | ||
343 | test_string_escape("escape 1", escape1, i, TEST_STRING_2_DICT_1); | ||
344 | |||
345 | test_string_escape_nomem(); | ||
99 | 346 | ||
100 | return -EINVAL; | 347 | return -EINVAL; |
101 | } | 348 | } |
diff --git a/lib/textsearch.c b/lib/textsearch.c index 0c7e9ab2d88f..0b79908dfe89 100644 --- a/lib/textsearch.c +++ b/lib/textsearch.c | |||
@@ -249,9 +249,7 @@ EXPORT_SYMBOL(textsearch_find_continuous); | |||
249 | * @flags: search flags | 249 | * @flags: search flags |
250 | * | 250 | * |
251 | * Looks up the search algorithm module and creates a new textsearch | 251 | * Looks up the search algorithm module and creates a new textsearch |
252 | * configuration for the specified pattern. Upon completion all | 252 | * configuration for the specified pattern. |
253 | * necessary refcnts are held and the configuration must be put back | ||
254 | * using textsearch_put() after usage. | ||
255 | * | 253 | * |
256 | * Note: The format of the pattern may not be compatible between | 254 | * Note: The format of the pattern may not be compatible between |
257 | * the various search algorithms. | 255 | * the various search algorithms. |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index ba3cd0a35640..ec337f64f52d 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/page.h> /* for PAGE_SIZE */ | 33 | #include <asm/page.h> /* for PAGE_SIZE */ |
34 | #include <asm/sections.h> /* for dereference_function_descriptor() */ | 34 | #include <asm/sections.h> /* for dereference_function_descriptor() */ |
35 | 35 | ||
36 | #include <linux/string_helpers.h> | ||
36 | #include "kstrtox.h" | 37 | #include "kstrtox.h" |
37 | 38 | ||
38 | /** | 39 | /** |
@@ -1101,6 +1102,62 @@ char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *sa, | |||
1101 | } | 1102 | } |
1102 | 1103 | ||
1103 | static noinline_for_stack | 1104 | static noinline_for_stack |
1105 | char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec spec, | ||
1106 | const char *fmt) | ||
1107 | { | ||
1108 | bool found = true; | ||
1109 | int count = 1; | ||
1110 | unsigned int flags = 0; | ||
1111 | int len; | ||
1112 | |||
1113 | if (spec.field_width == 0) | ||
1114 | return buf; /* nothing to print */ | ||
1115 | |||
1116 | if (ZERO_OR_NULL_PTR(addr)) | ||
1117 | return string(buf, end, NULL, spec); /* NULL pointer */ | ||
1118 | |||
1119 | |||
1120 | do { | ||
1121 | switch (fmt[count++]) { | ||
1122 | case 'a': | ||
1123 | flags |= ESCAPE_ANY; | ||
1124 | break; | ||
1125 | case 'c': | ||
1126 | flags |= ESCAPE_SPECIAL; | ||
1127 | break; | ||
1128 | case 'h': | ||
1129 | flags |= ESCAPE_HEX; | ||
1130 | break; | ||
1131 | case 'n': | ||
1132 | flags |= ESCAPE_NULL; | ||
1133 | break; | ||
1134 | case 'o': | ||
1135 | flags |= ESCAPE_OCTAL; | ||
1136 | break; | ||
1137 | case 'p': | ||
1138 | flags |= ESCAPE_NP; | ||
1139 | break; | ||
1140 | case 's': | ||
1141 | flags |= ESCAPE_SPACE; | ||
1142 | break; | ||
1143 | default: | ||
1144 | found = false; | ||
1145 | break; | ||
1146 | } | ||
1147 | } while (found); | ||
1148 | |||
1149 | if (!flags) | ||
1150 | flags = ESCAPE_ANY_NP; | ||
1151 | |||
1152 | len = spec.field_width < 0 ? 1 : spec.field_width; | ||
1153 | |||
1154 | /* Ignore the error. We print as many characters as we can */ | ||
1155 | string_escape_mem(addr, len, &buf, end - buf, flags, NULL); | ||
1156 | |||
1157 | return buf; | ||
1158 | } | ||
1159 | |||
1160 | static noinline_for_stack | ||
1104 | char *uuid_string(char *buf, char *end, const u8 *addr, | 1161 | char *uuid_string(char *buf, char *end, const u8 *addr, |
1105 | struct printf_spec spec, const char *fmt) | 1162 | struct printf_spec spec, const char *fmt) |
1106 | { | 1163 | { |
@@ -1221,6 +1278,17 @@ int kptr_restrict __read_mostly; | |||
1221 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order | 1278 | * - '[Ii][4S][hnbl]' IPv4 addresses in host, network, big or little endian order |
1222 | * - 'I[6S]c' for IPv6 addresses printed as specified by | 1279 | * - 'I[6S]c' for IPv6 addresses printed as specified by |
1223 | * http://tools.ietf.org/html/rfc5952 | 1280 | * http://tools.ietf.org/html/rfc5952 |
1281 | * - 'E[achnops]' For an escaped buffer, where rules are defined by combination | ||
1282 | * of the following flags (see string_escape_mem() for the | ||
1283 | * details): | ||
1284 | * a - ESCAPE_ANY | ||
1285 | * c - ESCAPE_SPECIAL | ||
1286 | * h - ESCAPE_HEX | ||
1287 | * n - ESCAPE_NULL | ||
1288 | * o - ESCAPE_OCTAL | ||
1289 | * p - ESCAPE_NP | ||
1290 | * s - ESCAPE_SPACE | ||
1291 | * By default ESCAPE_ANY_NP is used. | ||
1224 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form | 1292 | * - 'U' For a 16 byte UUID/GUID, it prints the UUID/GUID in the form |
1225 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" | 1293 | * "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
1226 | * Options for %pU are: | 1294 | * Options for %pU are: |
@@ -1321,6 +1389,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1321 | }} | 1389 | }} |
1322 | } | 1390 | } |
1323 | break; | 1391 | break; |
1392 | case 'E': | ||
1393 | return escaped_string(buf, end, ptr, spec, fmt); | ||
1324 | case 'U': | 1394 | case 'U': |
1325 | return uuid_string(buf, end, ptr, spec, fmt); | 1395 | return uuid_string(buf, end, ptr, spec, fmt); |
1326 | case 'V': | 1396 | case 'V': |
@@ -1633,6 +1703,7 @@ qualifier: | |||
1633 | * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address | 1703 | * %piS depending on sa_family of 'struct sockaddr *' print IPv4/IPv6 address |
1634 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper | 1704 | * %pU[bBlL] print a UUID/GUID in big or little endian using lower or upper |
1635 | * case. | 1705 | * case. |
1706 | * %*pE[achnops] print an escaped buffer | ||
1636 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 | 1707 | * %*ph[CDN] a variable-length hex string with a separator (supports up to 64 |
1637 | * bytes of the input) | 1708 | * bytes of the input) |
1638 | * %n is ignored | 1709 | * %n is ignored |
@@ -58,7 +58,9 @@ unsigned long cma_get_size(struct cma *cma) | |||
58 | 58 | ||
59 | static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order) | 59 | static unsigned long cma_bitmap_aligned_mask(struct cma *cma, int align_order) |
60 | { | 60 | { |
61 | return (1UL << (align_order >> cma->order_per_bit)) - 1; | 61 | if (align_order <= cma->order_per_bit) |
62 | return 0; | ||
63 | return (1UL << (align_order - cma->order_per_bit)) - 1; | ||
62 | } | 64 | } |
63 | 65 | ||
64 | static unsigned long cma_bitmap_maxno(struct cma *cma) | 66 | static unsigned long cma_bitmap_maxno(struct cma *cma) |
@@ -141,6 +143,54 @@ static int __init cma_init_reserved_areas(void) | |||
141 | core_initcall(cma_init_reserved_areas); | 143 | core_initcall(cma_init_reserved_areas); |
142 | 144 | ||
143 | /** | 145 | /** |
146 | * cma_init_reserved_mem() - create custom contiguous area from reserved memory | ||
147 | * @base: Base address of the reserved area | ||
148 | * @size: Size of the reserved area (in bytes), | ||
149 | * @order_per_bit: Order of pages represented by one bit on bitmap. | ||
150 | * @res_cma: Pointer to store the created cma region. | ||
151 | * | ||
152 | * This function creates custom contiguous area from already reserved memory. | ||
153 | */ | ||
154 | int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, | ||
155 | int order_per_bit, struct cma **res_cma) | ||
156 | { | ||
157 | struct cma *cma; | ||
158 | phys_addr_t alignment; | ||
159 | |||
160 | /* Sanity checks */ | ||
161 | if (cma_area_count == ARRAY_SIZE(cma_areas)) { | ||
162 | pr_err("Not enough slots for CMA reserved regions!\n"); | ||
163 | return -ENOSPC; | ||
164 | } | ||
165 | |||
166 | if (!size || !memblock_is_region_reserved(base, size)) | ||
167 | return -EINVAL; | ||
168 | |||
169 | /* ensure minimal alignment requied by mm core */ | ||
170 | alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); | ||
171 | |||
172 | /* alignment should be aligned with order_per_bit */ | ||
173 | if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit)) | ||
174 | return -EINVAL; | ||
175 | |||
176 | if (ALIGN(base, alignment) != base || ALIGN(size, alignment) != size) | ||
177 | return -EINVAL; | ||
178 | |||
179 | /* | ||
180 | * Each reserved area must be initialised later, when more kernel | ||
181 | * subsystems (like slab allocator) are available. | ||
182 | */ | ||
183 | cma = &cma_areas[cma_area_count]; | ||
184 | cma->base_pfn = PFN_DOWN(base); | ||
185 | cma->count = size >> PAGE_SHIFT; | ||
186 | cma->order_per_bit = order_per_bit; | ||
187 | *res_cma = cma; | ||
188 | cma_area_count++; | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | /** | ||
144 | * cma_declare_contiguous() - reserve custom contiguous area | 194 | * cma_declare_contiguous() - reserve custom contiguous area |
145 | * @base: Base address of the reserved area optional, use 0 for any | 195 | * @base: Base address of the reserved area optional, use 0 for any |
146 | * @size: Size of the reserved area (in bytes), | 196 | * @size: Size of the reserved area (in bytes), |
@@ -163,7 +213,6 @@ int __init cma_declare_contiguous(phys_addr_t base, | |||
163 | phys_addr_t alignment, unsigned int order_per_bit, | 213 | phys_addr_t alignment, unsigned int order_per_bit, |
164 | bool fixed, struct cma **res_cma) | 214 | bool fixed, struct cma **res_cma) |
165 | { | 215 | { |
166 | struct cma *cma; | ||
167 | phys_addr_t memblock_end = memblock_end_of_DRAM(); | 216 | phys_addr_t memblock_end = memblock_end_of_DRAM(); |
168 | phys_addr_t highmem_start = __pa(high_memory); | 217 | phys_addr_t highmem_start = __pa(high_memory); |
169 | int ret = 0; | 218 | int ret = 0; |
@@ -235,16 +284,9 @@ int __init cma_declare_contiguous(phys_addr_t base, | |||
235 | } | 284 | } |
236 | } | 285 | } |
237 | 286 | ||
238 | /* | 287 | ret = cma_init_reserved_mem(base, size, order_per_bit, res_cma); |
239 | * Each reserved area must be initialised later, when more kernel | 288 | if (ret) |
240 | * subsystems (like slab allocator) are available. | 289 | goto err; |
241 | */ | ||
242 | cma = &cma_areas[cma_area_count]; | ||
243 | cma->base_pfn = PFN_DOWN(base); | ||
244 | cma->count = size >> PAGE_SHIFT; | ||
245 | cma->order_per_bit = order_per_bit; | ||
246 | *res_cma = cma; | ||
247 | cma_area_count++; | ||
248 | 290 | ||
249 | pr_info("Reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M, | 291 | pr_info("Reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M, |
250 | (unsigned long)base); | 292 | (unsigned long)base); |
diff --git a/mm/memory.c b/mm/memory.c index e229970e4223..1cc6bfbd872e 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -2053,7 +2053,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
2053 | old_page = vm_normal_page(vma, address, orig_pte); | 2053 | old_page = vm_normal_page(vma, address, orig_pte); |
2054 | if (!old_page) { | 2054 | if (!old_page) { |
2055 | /* | 2055 | /* |
2056 | * VM_MIXEDMAP !pfn_valid() case | 2056 | * VM_MIXEDMAP !pfn_valid() case, or VM_SOFTDIRTY clear on a |
2057 | * VM_PFNMAP VMA. | ||
2057 | * | 2058 | * |
2058 | * We should not cow pages in a shared writeable mapping. | 2059 | * We should not cow pages in a shared writeable mapping. |
2059 | * Just mark the pages writable as we can't do any dirty | 2060 | * Just mark the pages writable as we can't do any dirty |
@@ -89,6 +89,25 @@ pgprot_t vm_get_page_prot(unsigned long vm_flags) | |||
89 | } | 89 | } |
90 | EXPORT_SYMBOL(vm_get_page_prot); | 90 | EXPORT_SYMBOL(vm_get_page_prot); |
91 | 91 | ||
92 | static pgprot_t vm_pgprot_modify(pgprot_t oldprot, unsigned long vm_flags) | ||
93 | { | ||
94 | return pgprot_modify(oldprot, vm_get_page_prot(vm_flags)); | ||
95 | } | ||
96 | |||
97 | /* Update vma->vm_page_prot to reflect vma->vm_flags. */ | ||
98 | void vma_set_page_prot(struct vm_area_struct *vma) | ||
99 | { | ||
100 | unsigned long vm_flags = vma->vm_flags; | ||
101 | |||
102 | vma->vm_page_prot = vm_pgprot_modify(vma->vm_page_prot, vm_flags); | ||
103 | if (vma_wants_writenotify(vma)) { | ||
104 | vm_flags &= ~VM_SHARED; | ||
105 | vma->vm_page_prot = vm_pgprot_modify(vma->vm_page_prot, | ||
106 | vm_flags); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | |||
92 | int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS; /* heuristic overcommit */ | 111 | int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS; /* heuristic overcommit */ |
93 | int sysctl_overcommit_ratio __read_mostly = 50; /* default is 50% */ | 112 | int sysctl_overcommit_ratio __read_mostly = 50; /* default is 50% */ |
94 | unsigned long sysctl_overcommit_kbytes __read_mostly; | 113 | unsigned long sysctl_overcommit_kbytes __read_mostly; |
@@ -1475,11 +1494,16 @@ int vma_wants_writenotify(struct vm_area_struct *vma) | |||
1475 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) | 1494 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) |
1476 | return 1; | 1495 | return 1; |
1477 | 1496 | ||
1478 | /* The open routine did something to the protections already? */ | 1497 | /* The open routine did something to the protections that pgprot_modify |
1498 | * won't preserve? */ | ||
1479 | if (pgprot_val(vma->vm_page_prot) != | 1499 | if (pgprot_val(vma->vm_page_prot) != |
1480 | pgprot_val(vm_get_page_prot(vm_flags))) | 1500 | pgprot_val(vm_pgprot_modify(vma->vm_page_prot, vm_flags))) |
1481 | return 0; | 1501 | return 0; |
1482 | 1502 | ||
1503 | /* Do we need to track softdirty? */ | ||
1504 | if (IS_ENABLED(CONFIG_MEM_SOFT_DIRTY) && !(vm_flags & VM_SOFTDIRTY)) | ||
1505 | return 1; | ||
1506 | |||
1483 | /* Specialty mapping? */ | 1507 | /* Specialty mapping? */ |
1484 | if (vm_flags & VM_PFNMAP) | 1508 | if (vm_flags & VM_PFNMAP) |
1485 | return 0; | 1509 | return 0; |
@@ -1615,21 +1639,6 @@ munmap_back: | |||
1615 | goto free_vma; | 1639 | goto free_vma; |
1616 | } | 1640 | } |
1617 | 1641 | ||
1618 | if (vma_wants_writenotify(vma)) { | ||
1619 | pgprot_t pprot = vma->vm_page_prot; | ||
1620 | |||
1621 | /* Can vma->vm_page_prot have changed?? | ||
1622 | * | ||
1623 | * Answer: Yes, drivers may have changed it in their | ||
1624 | * f_op->mmap method. | ||
1625 | * | ||
1626 | * Ensures that vmas marked as uncached stay that way. | ||
1627 | */ | ||
1628 | vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); | ||
1629 | if (pgprot_val(pprot) == pgprot_val(pgprot_noncached(pprot))) | ||
1630 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | ||
1631 | } | ||
1632 | |||
1633 | vma_link(mm, vma, prev, rb_link, rb_parent); | 1642 | vma_link(mm, vma, prev, rb_link, rb_parent); |
1634 | /* Once vma denies write, undo our temporary denial count */ | 1643 | /* Once vma denies write, undo our temporary denial count */ |
1635 | if (file) { | 1644 | if (file) { |
@@ -1663,6 +1672,8 @@ out: | |||
1663 | */ | 1672 | */ |
1664 | vma->vm_flags |= VM_SOFTDIRTY; | 1673 | vma->vm_flags |= VM_SOFTDIRTY; |
1665 | 1674 | ||
1675 | vma_set_page_prot(vma); | ||
1676 | |||
1666 | return addr; | 1677 | return addr; |
1667 | 1678 | ||
1668 | unmap_and_free_vma: | 1679 | unmap_and_free_vma: |
diff --git a/mm/mprotect.c b/mm/mprotect.c index c43d557941f8..ace93454ce8e 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c | |||
@@ -29,13 +29,6 @@ | |||
29 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
30 | #include <asm/tlbflush.h> | 30 | #include <asm/tlbflush.h> |
31 | 31 | ||
32 | #ifndef pgprot_modify | ||
33 | static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | ||
34 | { | ||
35 | return newprot; | ||
36 | } | ||
37 | #endif | ||
38 | |||
39 | /* | 32 | /* |
40 | * For a prot_numa update we only hold mmap_sem for read so there is a | 33 | * For a prot_numa update we only hold mmap_sem for read so there is a |
41 | * potential race with faulting where a pmd was temporarily none. This | 34 | * potential race with faulting where a pmd was temporarily none. This |
@@ -93,7 +86,9 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
93 | * Avoid taking write faults for pages we | 86 | * Avoid taking write faults for pages we |
94 | * know to be dirty. | 87 | * know to be dirty. |
95 | */ | 88 | */ |
96 | if (dirty_accountable && pte_dirty(ptent)) | 89 | if (dirty_accountable && pte_dirty(ptent) && |
90 | (pte_soft_dirty(ptent) || | ||
91 | !(vma->vm_flags & VM_SOFTDIRTY))) | ||
97 | ptent = pte_mkwrite(ptent); | 92 | ptent = pte_mkwrite(ptent); |
98 | ptep_modify_prot_commit(mm, addr, pte, ptent); | 93 | ptep_modify_prot_commit(mm, addr, pte, ptent); |
99 | updated = true; | 94 | updated = true; |
@@ -320,13 +315,8 @@ success: | |||
320 | * held in write mode. | 315 | * held in write mode. |
321 | */ | 316 | */ |
322 | vma->vm_flags = newflags; | 317 | vma->vm_flags = newflags; |
323 | vma->vm_page_prot = pgprot_modify(vma->vm_page_prot, | 318 | dirty_accountable = vma_wants_writenotify(vma); |
324 | vm_get_page_prot(newflags)); | 319 | vma_set_page_prot(vma); |
325 | |||
326 | if (vma_wants_writenotify(vma)) { | ||
327 | vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED); | ||
328 | dirty_accountable = 1; | ||
329 | } | ||
330 | 320 | ||
331 | change_protection(vma, start, end, vma->vm_page_prot, | 321 | change_protection(vma, start, end, vma->vm_page_prot, |
332 | dirty_accountable, 0); | 322 | dirty_accountable, 0); |
@@ -1992,7 +1992,7 @@ static struct array_cache __percpu *alloc_kmem_cache_cpus( | |||
1992 | struct array_cache __percpu *cpu_cache; | 1992 | struct array_cache __percpu *cpu_cache; |
1993 | 1993 | ||
1994 | size = sizeof(void *) * entries + sizeof(struct array_cache); | 1994 | size = sizeof(void *) * entries + sizeof(struct array_cache); |
1995 | cpu_cache = __alloc_percpu(size, 0); | 1995 | cpu_cache = __alloc_percpu(size, sizeof(void *)); |
1996 | 1996 | ||
1997 | if (!cpu_cache) | 1997 | if (!cpu_cache) |
1998 | return NULL; | 1998 | return NULL; |
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 6f5e621f220a..88a1bc3804d1 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c | |||
@@ -44,10 +44,10 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, | |||
44 | if (strlen(buff) > 4) { | 44 | if (strlen(buff) > 4) { |
45 | tmp_ptr = buff + strlen(buff) - 4; | 45 | tmp_ptr = buff + strlen(buff) - 4; |
46 | 46 | ||
47 | if (strnicmp(tmp_ptr, "mbit", 4) == 0) | 47 | if (strncasecmp(tmp_ptr, "mbit", 4) == 0) |
48 | bw_unit_type = BATADV_BW_UNIT_MBIT; | 48 | bw_unit_type = BATADV_BW_UNIT_MBIT; |
49 | 49 | ||
50 | if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || | 50 | if ((strncasecmp(tmp_ptr, "kbit", 4) == 0) || |
51 | (bw_unit_type == BATADV_BW_UNIT_MBIT)) | 51 | (bw_unit_type == BATADV_BW_UNIT_MBIT)) |
52 | *tmp_ptr = '\0'; | 52 | *tmp_ptr = '\0'; |
53 | } | 53 | } |
@@ -77,10 +77,10 @@ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, | |||
77 | if (strlen(slash_ptr + 1) > 4) { | 77 | if (strlen(slash_ptr + 1) > 4) { |
78 | tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); | 78 | tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); |
79 | 79 | ||
80 | if (strnicmp(tmp_ptr, "mbit", 4) == 0) | 80 | if (strncasecmp(tmp_ptr, "mbit", 4) == 0) |
81 | bw_unit_type = BATADV_BW_UNIT_MBIT; | 81 | bw_unit_type = BATADV_BW_UNIT_MBIT; |
82 | 82 | ||
83 | if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || | 83 | if ((strncasecmp(tmp_ptr, "kbit", 4) == 0) || |
84 | (bw_unit_type == BATADV_BW_UNIT_MBIT)) | 84 | (bw_unit_type == BATADV_BW_UNIT_MBIT)) |
85 | *tmp_ptr = '\0'; | 85 | *tmp_ptr = '\0'; |
86 | } | 86 | } |
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index a64fa15790e5..1d5341f3761d 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c | |||
@@ -96,13 +96,13 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit, | |||
96 | 96 | ||
97 | if (data_limit - data < plen) { | 97 | if (data_limit - data < plen) { |
98 | /* check if there is partial match */ | 98 | /* check if there is partial match */ |
99 | if (strnicmp(data, pattern, data_limit - data) == 0) | 99 | if (strncasecmp(data, pattern, data_limit - data) == 0) |
100 | return -1; | 100 | return -1; |
101 | else | 101 | else |
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | if (strnicmp(data, pattern, plen) != 0) { | 105 | if (strncasecmp(data, pattern, plen) != 0) { |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | s = data + plen; | 108 | s = data + plen; |
@@ -354,7 +354,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
354 | data_limit = skb_tail_pointer(skb); | 354 | data_limit = skb_tail_pointer(skb); |
355 | 355 | ||
356 | while (data <= data_limit - 6) { | 356 | while (data <= data_limit - 6) { |
357 | if (strnicmp(data, "PASV\r\n", 6) == 0) { | 357 | if (strncasecmp(data, "PASV\r\n", 6) == 0) { |
358 | /* Passive mode on */ | 358 | /* Passive mode on */ |
359 | IP_VS_DBG(7, "got PASV at %td of %td\n", | 359 | IP_VS_DBG(7, "got PASV at %td of %td\n", |
360 | data - data_start, | 360 | data - data_start, |
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index b8a0924064ef..b666959f17c0 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c | |||
@@ -304,12 +304,12 @@ static int find_pattern(const char *data, size_t dlen, | |||
304 | 304 | ||
305 | if (dlen <= plen) { | 305 | if (dlen <= plen) { |
306 | /* Short packet: try for partial? */ | 306 | /* Short packet: try for partial? */ |
307 | if (strnicmp(data, pattern, dlen) == 0) | 307 | if (strncasecmp(data, pattern, dlen) == 0) |
308 | return -1; | 308 | return -1; |
309 | else return 0; | 309 | else return 0; |
310 | } | 310 | } |
311 | 311 | ||
312 | if (strnicmp(data, pattern, plen) != 0) { | 312 | if (strncasecmp(data, pattern, plen) != 0) { |
313 | #if 0 | 313 | #if 0 |
314 | size_t i; | 314 | size_t i; |
315 | 315 | ||
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 4c3ba1c8d682..885b4aba3695 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -247,7 +247,7 @@ int ct_sip_parse_request(const struct nf_conn *ct, | |||
247 | for (; dptr < limit - strlen("sip:"); dptr++) { | 247 | for (; dptr < limit - strlen("sip:"); dptr++) { |
248 | if (*dptr == '\r' || *dptr == '\n') | 248 | if (*dptr == '\r' || *dptr == '\n') |
249 | return -1; | 249 | return -1; |
250 | if (strnicmp(dptr, "sip:", strlen("sip:")) == 0) { | 250 | if (strncasecmp(dptr, "sip:", strlen("sip:")) == 0) { |
251 | dptr += strlen("sip:"); | 251 | dptr += strlen("sip:"); |
252 | break; | 252 | break; |
253 | } | 253 | } |
@@ -350,7 +350,7 @@ static const char *ct_sip_header_search(const char *dptr, const char *limit, | |||
350 | continue; | 350 | continue; |
351 | } | 351 | } |
352 | 352 | ||
353 | if (strnicmp(dptr, needle, len) == 0) | 353 | if (strncasecmp(dptr, needle, len) == 0) |
354 | return dptr; | 354 | return dptr; |
355 | } | 355 | } |
356 | return NULL; | 356 | return NULL; |
@@ -383,10 +383,10 @@ int ct_sip_get_header(const struct nf_conn *ct, const char *dptr, | |||
383 | /* Find header. Compact headers must be followed by a | 383 | /* Find header. Compact headers must be followed by a |
384 | * non-alphabetic character to avoid mismatches. */ | 384 | * non-alphabetic character to avoid mismatches. */ |
385 | if (limit - dptr >= hdr->len && | 385 | if (limit - dptr >= hdr->len && |
386 | strnicmp(dptr, hdr->name, hdr->len) == 0) | 386 | strncasecmp(dptr, hdr->name, hdr->len) == 0) |
387 | dptr += hdr->len; | 387 | dptr += hdr->len; |
388 | else if (hdr->cname && limit - dptr >= hdr->clen + 1 && | 388 | else if (hdr->cname && limit - dptr >= hdr->clen + 1 && |
389 | strnicmp(dptr, hdr->cname, hdr->clen) == 0 && | 389 | strncasecmp(dptr, hdr->cname, hdr->clen) == 0 && |
390 | !isalpha(*(dptr + hdr->clen))) | 390 | !isalpha(*(dptr + hdr->clen))) |
391 | dptr += hdr->clen; | 391 | dptr += hdr->clen; |
392 | else | 392 | else |
@@ -620,9 +620,9 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr, | |||
620 | 620 | ||
621 | if (ct_sip_parse_param(ct, dptr, dataoff, datalen, "transport=", | 621 | if (ct_sip_parse_param(ct, dptr, dataoff, datalen, "transport=", |
622 | &matchoff, &matchlen)) { | 622 | &matchoff, &matchlen)) { |
623 | if (!strnicmp(dptr + matchoff, "TCP", strlen("TCP"))) | 623 | if (!strncasecmp(dptr + matchoff, "TCP", strlen("TCP"))) |
624 | *proto = IPPROTO_TCP; | 624 | *proto = IPPROTO_TCP; |
625 | else if (!strnicmp(dptr + matchoff, "UDP", strlen("UDP"))) | 625 | else if (!strncasecmp(dptr + matchoff, "UDP", strlen("UDP"))) |
626 | *proto = IPPROTO_UDP; | 626 | *proto = IPPROTO_UDP; |
627 | else | 627 | else |
628 | return 0; | 628 | return 0; |
@@ -743,10 +743,10 @@ int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr, | |||
743 | 743 | ||
744 | if (term != SDP_HDR_UNSPEC && | 744 | if (term != SDP_HDR_UNSPEC && |
745 | limit - dptr >= thdr->len && | 745 | limit - dptr >= thdr->len && |
746 | strnicmp(dptr, thdr->name, thdr->len) == 0) | 746 | strncasecmp(dptr, thdr->name, thdr->len) == 0) |
747 | break; | 747 | break; |
748 | else if (limit - dptr >= hdr->len && | 748 | else if (limit - dptr >= hdr->len && |
749 | strnicmp(dptr, hdr->name, hdr->len) == 0) | 749 | strncasecmp(dptr, hdr->name, hdr->len) == 0) |
750 | dptr += hdr->len; | 750 | dptr += hdr->len; |
751 | else | 751 | else |
752 | continue; | 752 | continue; |
@@ -1394,7 +1394,7 @@ static int process_sip_response(struct sk_buff *skb, unsigned int protoff, | |||
1394 | if (handler->response == NULL) | 1394 | if (handler->response == NULL) |
1395 | continue; | 1395 | continue; |
1396 | if (*datalen < matchend + handler->len || | 1396 | if (*datalen < matchend + handler->len || |
1397 | strnicmp(*dptr + matchend, handler->method, handler->len)) | 1397 | strncasecmp(*dptr + matchend, handler->method, handler->len)) |
1398 | continue; | 1398 | continue; |
1399 | return handler->response(skb, protoff, dataoff, dptr, datalen, | 1399 | return handler->response(skb, protoff, dataoff, dptr, datalen, |
1400 | cseq, code); | 1400 | cseq, code); |
@@ -1435,7 +1435,7 @@ static int process_sip_request(struct sk_buff *skb, unsigned int protoff, | |||
1435 | if (handler->request == NULL) | 1435 | if (handler->request == NULL) |
1436 | continue; | 1436 | continue; |
1437 | if (*datalen < handler->len || | 1437 | if (*datalen < handler->len || |
1438 | strnicmp(*dptr, handler->method, handler->len)) | 1438 | strncasecmp(*dptr, handler->method, handler->len)) |
1439 | continue; | 1439 | continue; |
1440 | 1440 | ||
1441 | if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ, | 1441 | if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_CSEQ, |
@@ -1462,7 +1462,7 @@ static int process_sip_msg(struct sk_buff *skb, struct nf_conn *ct, | |||
1462 | const struct nf_nat_sip_hooks *hooks; | 1462 | const struct nf_nat_sip_hooks *hooks; |
1463 | int ret; | 1463 | int ret; |
1464 | 1464 | ||
1465 | if (strnicmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0) | 1465 | if (strncasecmp(*dptr, "SIP/2.0 ", strlen("SIP/2.0 ")) != 0) |
1466 | ret = process_sip_request(skb, protoff, dataoff, dptr, datalen); | 1466 | ret = process_sip_request(skb, protoff, dataoff, dptr, datalen); |
1467 | else | 1467 | else |
1468 | ret = process_sip_response(skb, protoff, dataoff, dptr, datalen); | 1468 | ret = process_sip_response(skb, protoff, dataoff, dptr, datalen); |
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index daad6022c689..d7197649dba6 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c | |||
@@ -30,7 +30,7 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger) | |||
30 | 30 | ||
31 | log = rcu_dereference_protected(loggers[pf][i], | 31 | log = rcu_dereference_protected(loggers[pf][i], |
32 | lockdep_is_held(&nf_log_mutex)); | 32 | lockdep_is_held(&nf_log_mutex)); |
33 | if (!strnicmp(str_logger, log->name, strlen(log->name))) | 33 | if (!strncasecmp(str_logger, log->name, strlen(log->name))) |
34 | return log; | 34 | return log; |
35 | } | 35 | } |
36 | 36 | ||
diff --git a/net/netfilter/nf_nat_sip.c b/net/netfilter/nf_nat_sip.c index b4d691db955e..791fac4fd745 100644 --- a/net/netfilter/nf_nat_sip.c +++ b/net/netfilter/nf_nat_sip.c | |||
@@ -155,7 +155,7 @@ static unsigned int nf_nat_sip(struct sk_buff *skb, unsigned int protoff, | |||
155 | int request, in_header; | 155 | int request, in_header; |
156 | 156 | ||
157 | /* Basic rules: requests and responses. */ | 157 | /* Basic rules: requests and responses. */ |
158 | if (strnicmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) { | 158 | if (strncasecmp(*dptr, "SIP/2.0", strlen("SIP/2.0")) != 0) { |
159 | if (ct_sip_parse_request(ct, *dptr, *datalen, | 159 | if (ct_sip_parse_request(ct, *dptr, *datalen, |
160 | &matchoff, &matchlen, | 160 | &matchoff, &matchlen, |
161 | &addr, &port) > 0 && | 161 | &addr, &port) > 0 && |
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c index a55c27b75ee5..459611577d3d 100644 --- a/net/wireless/lib80211.c +++ b/net/wireless/lib80211.c | |||
@@ -46,38 +46,6 @@ static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, | |||
46 | static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info); | 46 | static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info); |
47 | static void lib80211_crypt_deinit_handler(unsigned long data); | 47 | static void lib80211_crypt_deinit_handler(unsigned long data); |
48 | 48 | ||
49 | const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) | ||
50 | { | ||
51 | const char *s = ssid; | ||
52 | char *d = buf; | ||
53 | |||
54 | ssid_len = min_t(u8, ssid_len, IEEE80211_MAX_SSID_LEN); | ||
55 | while (ssid_len--) { | ||
56 | if (isprint(*s)) { | ||
57 | *d++ = *s++; | ||
58 | continue; | ||
59 | } | ||
60 | |||
61 | *d++ = '\\'; | ||
62 | if (*s == '\0') | ||
63 | *d++ = '0'; | ||
64 | else if (*s == '\n') | ||
65 | *d++ = 'n'; | ||
66 | else if (*s == '\r') | ||
67 | *d++ = 'r'; | ||
68 | else if (*s == '\t') | ||
69 | *d++ = 't'; | ||
70 | else if (*s == '\\') | ||
71 | *d++ = '\\'; | ||
72 | else | ||
73 | d += snprintf(d, 3, "%03o", *s); | ||
74 | s++; | ||
75 | } | ||
76 | *d = '\0'; | ||
77 | return buf; | ||
78 | } | ||
79 | EXPORT_SYMBOL(print_ssid); | ||
80 | |||
81 | int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, | 49 | int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, |
82 | spinlock_t *lock) | 50 | spinlock_t *lock) |
83 | { | 51 | { |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 4d08b398411f..374abf443636 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -9,7 +9,8 @@ use strict; | |||
9 | use POSIX; | 9 | use POSIX; |
10 | 10 | ||
11 | my $P = $0; | 11 | my $P = $0; |
12 | $P =~ s@.*/@@g; | 12 | $P =~ s@(.*)/@@g; |
13 | my $D = $1; | ||
13 | 14 | ||
14 | my $V = '0.32'; | 15 | my $V = '0.32'; |
15 | 16 | ||
@@ -43,6 +44,8 @@ my $configuration_file = ".checkpatch.conf"; | |||
43 | my $max_line_length = 80; | 44 | my $max_line_length = 80; |
44 | my $ignore_perl_version = 0; | 45 | my $ignore_perl_version = 0; |
45 | my $minimum_perl_version = 5.10.0; | 46 | my $minimum_perl_version = 5.10.0; |
47 | my $min_conf_desc_length = 4; | ||
48 | my $spelling_file = "$D/spelling.txt"; | ||
46 | 49 | ||
47 | sub help { | 50 | sub help { |
48 | my ($exitcode) = @_; | 51 | my ($exitcode) = @_; |
@@ -63,6 +66,7 @@ Options: | |||
63 | --types TYPE(,TYPE2...) show only these comma separated message types | 66 | --types TYPE(,TYPE2...) show only these comma separated message types |
64 | --ignore TYPE(,TYPE2...) ignore various comma separated message types | 67 | --ignore TYPE(,TYPE2...) ignore various comma separated message types |
65 | --max-line-length=n set the maximum line length, if exceeded, warn | 68 | --max-line-length=n set the maximum line length, if exceeded, warn |
69 | --min-conf-desc-length=n set the min description length, if shorter, warn | ||
66 | --show-types show the message "types" in the output | 70 | --show-types show the message "types" in the output |
67 | --root=PATH PATH to the kernel tree root | 71 | --root=PATH PATH to the kernel tree root |
68 | --no-summary suppress the per-file summary | 72 | --no-summary suppress the per-file summary |
@@ -131,6 +135,7 @@ GetOptions( | |||
131 | 'types=s' => \@use, | 135 | 'types=s' => \@use, |
132 | 'show-types!' => \$show_types, | 136 | 'show-types!' => \$show_types, |
133 | 'max-line-length=i' => \$max_line_length, | 137 | 'max-line-length=i' => \$max_line_length, |
138 | 'min-conf-desc-length=i' => \$min_conf_desc_length, | ||
134 | 'root=s' => \$root, | 139 | 'root=s' => \$root, |
135 | 'summary!' => \$summary, | 140 | 'summary!' => \$summary, |
136 | 'mailback!' => \$mailback, | 141 | 'mailback!' => \$mailback, |
@@ -425,10 +430,35 @@ foreach my $entry (@mode_permission_funcs) { | |||
425 | 430 | ||
426 | our $allowed_asm_includes = qr{(?x: | 431 | our $allowed_asm_includes = qr{(?x: |
427 | irq| | 432 | irq| |
428 | memory | 433 | memory| |
434 | time| | ||
435 | reboot | ||
429 | )}; | 436 | )}; |
430 | # memory.h: ARM has a custom one | 437 | # memory.h: ARM has a custom one |
431 | 438 | ||
439 | # Load common spelling mistakes and build regular expression list. | ||
440 | my $misspellings; | ||
441 | my @spelling_list; | ||
442 | my %spelling_fix; | ||
443 | open(my $spelling, '<', $spelling_file) | ||
444 | or die "$P: Can't open $spelling_file for reading: $!\n"; | ||
445 | while (<$spelling>) { | ||
446 | my $line = $_; | ||
447 | |||
448 | $line =~ s/\s*\n?$//g; | ||
449 | $line =~ s/^\s*//g; | ||
450 | |||
451 | next if ($line =~ m/^\s*#/); | ||
452 | next if ($line =~ m/^\s*$/); | ||
453 | |||
454 | my ($suspect, $fix) = split(/\|\|/, $line); | ||
455 | |||
456 | push(@spelling_list, $suspect); | ||
457 | $spelling_fix{$suspect} = $fix; | ||
458 | } | ||
459 | close($spelling); | ||
460 | $misspellings = join("|", @spelling_list); | ||
461 | |||
432 | sub build_types { | 462 | sub build_types { |
433 | my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; | 463 | my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; |
434 | my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; | 464 | my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; |
@@ -2215,6 +2245,23 @@ sub process { | |||
2215 | "8-bit UTF-8 used in possible commit log\n" . $herecurr); | 2245 | "8-bit UTF-8 used in possible commit log\n" . $herecurr); |
2216 | } | 2246 | } |
2217 | 2247 | ||
2248 | # Check for various typo / spelling mistakes | ||
2249 | if ($in_commit_log || $line =~ /^\+/) { | ||
2250 | while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:$|[^a-z@])/gi) { | ||
2251 | my $typo = $1; | ||
2252 | my $typo_fix = $spelling_fix{lc($typo)}; | ||
2253 | $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); | ||
2254 | $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); | ||
2255 | my $msg_type = \&WARN; | ||
2256 | $msg_type = \&CHK if ($file); | ||
2257 | if (&{$msg_type}("TYPO_SPELLING", | ||
2258 | "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && | ||
2259 | $fix) { | ||
2260 | $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; | ||
2261 | } | ||
2262 | } | ||
2263 | } | ||
2264 | |||
2218 | # ignore non-hunk lines and lines being removed | 2265 | # ignore non-hunk lines and lines being removed |
2219 | next if (!$hunk_line || $line =~ /^-/); | 2266 | next if (!$hunk_line || $line =~ /^-/); |
2220 | 2267 | ||
@@ -2283,8 +2330,10 @@ sub process { | |||
2283 | } | 2330 | } |
2284 | $length++; | 2331 | $length++; |
2285 | } | 2332 | } |
2286 | WARN("CONFIG_DESCRIPTION", | 2333 | if ($is_start && $is_end && $length < $min_conf_desc_length) { |
2287 | "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); | 2334 | WARN("CONFIG_DESCRIPTION", |
2335 | "please write a paragraph that describes the config symbol fully\n" . $herecurr); | ||
2336 | } | ||
2288 | #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; | 2337 | #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; |
2289 | } | 2338 | } |
2290 | 2339 | ||
@@ -2341,7 +2390,7 @@ sub process { | |||
2341 | } | 2390 | } |
2342 | 2391 | ||
2343 | # check we are in a valid source file if not then ignore this hunk | 2392 | # check we are in a valid source file if not then ignore this hunk |
2344 | next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); | 2393 | next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/); |
2345 | 2394 | ||
2346 | #line length limit | 2395 | #line length limit |
2347 | if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && | 2396 | if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && |
@@ -2402,7 +2451,7 @@ sub process { | |||
2402 | } | 2451 | } |
2403 | 2452 | ||
2404 | # check we are in a valid source file C or perl if not then ignore this hunk | 2453 | # check we are in a valid source file C or perl if not then ignore this hunk |
2405 | next if ($realfile !~ /\.(h|c|pl)$/); | 2454 | next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); |
2406 | 2455 | ||
2407 | # at the beginning of a line any tabs must come first and anything | 2456 | # at the beginning of a line any tabs must come first and anything |
2408 | # more than 8 must use tabs. | 2457 | # more than 8 must use tabs. |
@@ -2424,7 +2473,7 @@ sub process { | |||
2424 | "please, no space before tabs\n" . $herevet) && | 2473 | "please, no space before tabs\n" . $herevet) && |
2425 | $fix) { | 2474 | $fix) { |
2426 | while ($fixed[$fixlinenr] =~ | 2475 | while ($fixed[$fixlinenr] =~ |
2427 | s/(^\+.*) {8,8}+\t/$1\t\t/) {} | 2476 | s/(^\+.*) {8,8}\t/$1\t\t/) {} |
2428 | while ($fixed[$fixlinenr] =~ | 2477 | while ($fixed[$fixlinenr] =~ |
2429 | s/(^\+.*) +\t/$1\t/) {} | 2478 | s/(^\+.*) +\t/$1\t/) {} |
2430 | } | 2479 | } |
@@ -2592,10 +2641,14 @@ sub process { | |||
2592 | next if ($realfile !~ /\.(h|c)$/); | 2641 | next if ($realfile !~ /\.(h|c)$/); |
2593 | 2642 | ||
2594 | # check indentation of any line with a bare else | 2643 | # check indentation of any line with a bare else |
2644 | # (but not if it is a multiple line "if (foo) return bar; else return baz;") | ||
2595 | # if the previous line is a break or return and is indented 1 tab more... | 2645 | # if the previous line is a break or return and is indented 1 tab more... |
2596 | if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { | 2646 | if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { |
2597 | my $tabs = length($1) + 1; | 2647 | my $tabs = length($1) + 1; |
2598 | if ($prevline =~ /^\+\t{$tabs,$tabs}(?:break|return)\b/) { | 2648 | if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || |
2649 | ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && | ||
2650 | defined $lines[$linenr] && | ||
2651 | $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { | ||
2599 | WARN("UNNECESSARY_ELSE", | 2652 | WARN("UNNECESSARY_ELSE", |
2600 | "else is not generally useful after a break or return\n" . $hereprev); | 2653 | "else is not generally useful after a break or return\n" . $hereprev); |
2601 | } | 2654 | } |
@@ -3752,7 +3805,6 @@ sub process { | |||
3752 | if (ERROR("SPACING", | 3805 | if (ERROR("SPACING", |
3753 | "space prohibited before that close parenthesis ')'\n" . $herecurr) && | 3806 | "space prohibited before that close parenthesis ')'\n" . $herecurr) && |
3754 | $fix) { | 3807 | $fix) { |
3755 | print("fixlinenr: <$fixlinenr> fixed[fixlinenr]: <$fixed[$fixlinenr]>\n"); | ||
3756 | $fixed[$fixlinenr] =~ | 3808 | $fixed[$fixlinenr] =~ |
3757 | s/\s+\)/\)/; | 3809 | s/\s+\)/\)/; |
3758 | } | 3810 | } |
@@ -4060,12 +4112,17 @@ sub process { | |||
4060 | my $cnt = $realcnt; | 4112 | my $cnt = $realcnt; |
4061 | my ($off, $dstat, $dcond, $rest); | 4113 | my ($off, $dstat, $dcond, $rest); |
4062 | my $ctx = ''; | 4114 | my $ctx = ''; |
4115 | my $has_flow_statement = 0; | ||
4116 | my $has_arg_concat = 0; | ||
4063 | ($dstat, $dcond, $ln, $cnt, $off) = | 4117 | ($dstat, $dcond, $ln, $cnt, $off) = |
4064 | ctx_statement_block($linenr, $realcnt, 0); | 4118 | ctx_statement_block($linenr, $realcnt, 0); |
4065 | $ctx = $dstat; | 4119 | $ctx = $dstat; |
4066 | #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; | 4120 | #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; |
4067 | #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; | 4121 | #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; |
4068 | 4122 | ||
4123 | $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); | ||
4124 | $has_arg_concat = 1 if ($ctx =~ /\#\#/); | ||
4125 | |||
4069 | $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; | 4126 | $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; |
4070 | $dstat =~ s/$;//g; | 4127 | $dstat =~ s/$;//g; |
4071 | $dstat =~ s/\\\n.//g; | 4128 | $dstat =~ s/\\\n.//g; |
@@ -4126,10 +4183,23 @@ sub process { | |||
4126 | "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); | 4183 | "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); |
4127 | } else { | 4184 | } else { |
4128 | ERROR("COMPLEX_MACRO", | 4185 | ERROR("COMPLEX_MACRO", |
4129 | "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); | 4186 | "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); |
4130 | } | 4187 | } |
4131 | } | 4188 | } |
4132 | 4189 | ||
4190 | # check for macros with flow control, but without ## concatenation | ||
4191 | # ## concatenation is commonly a macro that defines a function so ignore those | ||
4192 | if ($has_flow_statement && !$has_arg_concat) { | ||
4193 | my $herectx = $here . "\n"; | ||
4194 | my $cnt = statement_rawlines($ctx); | ||
4195 | |||
4196 | for (my $n = 0; $n < $cnt; $n++) { | ||
4197 | $herectx .= raw_line($linenr, $n) . "\n"; | ||
4198 | } | ||
4199 | WARN("MACRO_WITH_FLOW_CONTROL", | ||
4200 | "Macros with flow control statements should be avoided\n" . "$herectx"); | ||
4201 | } | ||
4202 | |||
4133 | # check for line continuations outside of #defines, preprocessor #, and asm | 4203 | # check for line continuations outside of #defines, preprocessor #, and asm |
4134 | 4204 | ||
4135 | } else { | 4205 | } else { |
@@ -4338,6 +4408,12 @@ sub process { | |||
4338 | "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); | 4408 | "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); |
4339 | } | 4409 | } |
4340 | 4410 | ||
4411 | # concatenated string without spaces between elements | ||
4412 | if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) { | ||
4413 | CHK("CONCATENATED_STRING", | ||
4414 | "Concatenated strings should use spaces between elements\n" . $herecurr); | ||
4415 | } | ||
4416 | |||
4341 | # warn about #if 0 | 4417 | # warn about #if 0 |
4342 | if ($line =~ /^.\s*\#\s*if\s+0\b/) { | 4418 | if ($line =~ /^.\s*\#\s*if\s+0\b/) { |
4343 | CHK("REDUNDANT_CODE", | 4419 | CHK("REDUNDANT_CODE", |
@@ -4371,6 +4447,17 @@ sub process { | |||
4371 | } | 4447 | } |
4372 | } | 4448 | } |
4373 | 4449 | ||
4450 | # check for logging functions with KERN_<LEVEL> | ||
4451 | if ($line !~ /printk\s*\(/ && | ||
4452 | $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { | ||
4453 | my $level = $1; | ||
4454 | if (WARN("UNNECESSARY_KERN_LEVEL", | ||
4455 | "Possible unnecessary $level\n" . $herecurr) && | ||
4456 | $fix) { | ||
4457 | $fixed[$fixlinenr] =~ s/\s*$level\s*//; | ||
4458 | } | ||
4459 | } | ||
4460 | |||
4374 | # check for bad placement of section $InitAttribute (e.g.: __initdata) | 4461 | # check for bad placement of section $InitAttribute (e.g.: __initdata) |
4375 | if ($line =~ /(\b$InitAttribute\b)/) { | 4462 | if ($line =~ /(\b$InitAttribute\b)/) { |
4376 | my $attr = $1; | 4463 | my $attr = $1; |
diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh index 5de5660cb708..fdebd66f8fc1 100644 --- a/scripts/headers_install.sh +++ b/scripts/headers_install.sh | |||
@@ -1,8 +1,8 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | if [ $# -lt 1 ] | 3 | if [ $# -lt 2 ] |
4 | then | 4 | then |
5 | echo "Usage: headers_install.sh OUTDIR SRCDIR [FILES...] | 5 | echo "Usage: headers_install.sh OUTDIR SRCDIR [FILES...]" |
6 | echo | 6 | echo |
7 | echo "Prepares kernel header files for use by user space, by removing" | 7 | echo "Prepares kernel header files for use by user space, by removing" |
8 | echo "all compiler.h definitions and #includes, removing any" | 8 | echo "all compiler.h definitions and #includes, removing any" |
diff --git a/scripts/sortextable.h b/scripts/sortextable.h index 8fac3fd697a6..ba8700428e21 100644 --- a/scripts/sortextable.h +++ b/scripts/sortextable.h | |||
@@ -103,7 +103,7 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) | |||
103 | Elf_Sym *sort_needed_sym; | 103 | Elf_Sym *sort_needed_sym; |
104 | Elf_Shdr *sort_needed_sec; | 104 | Elf_Shdr *sort_needed_sec; |
105 | Elf_Rel *relocs = NULL; | 105 | Elf_Rel *relocs = NULL; |
106 | int relocs_size; | 106 | int relocs_size = 0; |
107 | uint32_t *sort_done_location; | 107 | uint32_t *sort_done_location; |
108 | const char *secstrtab; | 108 | const char *secstrtab; |
109 | const char *strtab; | 109 | const char *strtab; |
diff --git a/scripts/spelling.txt b/scripts/spelling.txt new file mode 100644 index 000000000000..fc7fd52b5e03 --- /dev/null +++ b/scripts/spelling.txt | |||
@@ -0,0 +1,1042 @@ | |||
1 | # Originally from Debian's Lintian tool. Various false positives have been | ||
2 | # removed, and various additions have been made as they've been discovered | ||
3 | # in the kernel source. | ||
4 | # | ||
5 | # License: GPLv2 | ||
6 | # | ||
7 | # The format of each line is: | ||
8 | # mistake||correction | ||
9 | # | ||
10 | abandonning||abandoning | ||
11 | abigious||ambiguous | ||
12 | abitrate||arbitrate | ||
13 | abov||above | ||
14 | abreviated||abbreviated | ||
15 | absense||absence | ||
16 | absolut||absolute | ||
17 | absoulte||absolute | ||
18 | acccess||access | ||
19 | acceleratoin||acceleration | ||
20 | accelleration||acceleration | ||
21 | accesing||accessing | ||
22 | accesnt||accent | ||
23 | accessable||accessible | ||
24 | accesss||access | ||
25 | accidentaly||accidentally | ||
26 | accidentually||accidentally | ||
27 | accoding||according | ||
28 | accomodate||accommodate | ||
29 | accomodates||accommodates | ||
30 | accordign||according | ||
31 | accoring||according | ||
32 | accout||account | ||
33 | accquire||acquire | ||
34 | accquired||acquired | ||
35 | acessable||accessible | ||
36 | acess||access | ||
37 | achitecture||architecture | ||
38 | acient||ancient | ||
39 | acitions||actions | ||
40 | acitve||active | ||
41 | acknowldegement||acknowldegement | ||
42 | acknowledgement||acknowledgment | ||
43 | ackowledge||acknowledge | ||
44 | ackowledged||acknowledged | ||
45 | acording||according | ||
46 | activete||activate | ||
47 | acumulating||accumulating | ||
48 | adapater||adapter | ||
49 | addional||additional | ||
50 | additionaly||additionally | ||
51 | addres||address | ||
52 | addreses||addresses | ||
53 | addresss||address | ||
54 | aditional||additional | ||
55 | aditionally||additionally | ||
56 | aditionaly||additionally | ||
57 | adminstrative||administrative | ||
58 | adress||address | ||
59 | adresses||addresses | ||
60 | adviced||advised | ||
61 | afecting||affecting | ||
62 | agaist||against | ||
63 | albumns||albums | ||
64 | alegorical||allegorical | ||
65 | algorith||algorithm | ||
66 | algorithmical||algorithmically | ||
67 | algoritm||algorithm | ||
68 | algoritms||algorithms | ||
69 | algorrithm||algorithm | ||
70 | algorritm||algorithm | ||
71 | allign||align | ||
72 | allocatrd||allocated | ||
73 | allocte||allocate | ||
74 | allpication||application | ||
75 | alocate||allocate | ||
76 | alogirhtms||algorithms | ||
77 | alogrithm||algorithm | ||
78 | alot||a lot | ||
79 | alow||allow | ||
80 | alows||allows | ||
81 | altough||although | ||
82 | alue||value | ||
83 | ambigious||ambiguous | ||
84 | amoung||among | ||
85 | amout||amount | ||
86 | analysator||analyzer | ||
87 | ang||and | ||
88 | anniversery||anniversary | ||
89 | annoucement||announcement | ||
90 | anomolies||anomalies | ||
91 | anomoly||anomaly | ||
92 | anway||anyway | ||
93 | aplication||application | ||
94 | appearence||appearance | ||
95 | applicaion||application | ||
96 | appliction||application | ||
97 | applictions||applications | ||
98 | appplications||applications | ||
99 | appropiate||appropriate | ||
100 | appropriatly||appropriately | ||
101 | approriate||appropriate | ||
102 | approriately||appropriately | ||
103 | aquainted||acquainted | ||
104 | aquired||acquired | ||
105 | arbitary||arbitrary | ||
106 | architechture||architecture | ||
107 | arguement||argument | ||
108 | arguements||arguments | ||
109 | aritmetic||arithmetic | ||
110 | arne't||aren't | ||
111 | arraival||arrival | ||
112 | artifical||artificial | ||
113 | artillary||artillery | ||
114 | assiged||assigned | ||
115 | assigment||assignment | ||
116 | assigments||assignments | ||
117 | assistent||assistant | ||
118 | assocation||association | ||
119 | associcated||associated | ||
120 | assotiated||associated | ||
121 | assum||assume | ||
122 | assumtpion||assumption | ||
123 | asuming||assuming | ||
124 | asycronous||asynchronous | ||
125 | asynchnous||asynchronous | ||
126 | atomatically||automatically | ||
127 | atomicly||atomically | ||
128 | attachement||attachment | ||
129 | attched||attached | ||
130 | attemps||attempts | ||
131 | attruibutes||attributes | ||
132 | authentification||authentication | ||
133 | automaticaly||automatically | ||
134 | automaticly||automatically | ||
135 | automatize||automate | ||
136 | automatized||automated | ||
137 | automatizes||automates | ||
138 | autonymous||autonomous | ||
139 | auxilliary||auxiliary | ||
140 | avaiable||available | ||
141 | avaible||available | ||
142 | availabe||available | ||
143 | availabled||available | ||
144 | availablity||availability | ||
145 | availale||available | ||
146 | availavility||availability | ||
147 | availble||available | ||
148 | availiable||available | ||
149 | avalable||available | ||
150 | avaliable||available | ||
151 | aysnc||async | ||
152 | backgroud||background | ||
153 | backword||backward | ||
154 | backwords||backwards | ||
155 | bahavior||behavior | ||
156 | bakup||backup | ||
157 | baloon||balloon | ||
158 | baloons||balloons | ||
159 | bandwith||bandwidth | ||
160 | batery||battery | ||
161 | beacuse||because | ||
162 | becasue||because | ||
163 | becomming||becoming | ||
164 | becuase||because | ||
165 | beeing||being | ||
166 | befor||before | ||
167 | begining||beginning | ||
168 | beter||better | ||
169 | betweeen||between | ||
170 | bianries||binaries | ||
171 | bitmast||bitmask | ||
172 | boardcast||broadcast | ||
173 | borad||board | ||
174 | boundry||boundary | ||
175 | brievely||briefly | ||
176 | broadcat||broadcast | ||
177 | cacluated||calculated | ||
178 | caculation||calculation | ||
179 | calender||calendar | ||
180 | calle||called | ||
181 | calucate||calculate | ||
182 | calulate||calculate | ||
183 | cancelation||cancellation | ||
184 | capabilites||capabilities | ||
185 | capabitilies||capabilities | ||
186 | capatibilities||capabilities | ||
187 | carefuly||carefully | ||
188 | cariage||carriage | ||
189 | catagory||category | ||
190 | challange||challenge | ||
191 | challanges||challenges | ||
192 | chanell||channel | ||
193 | changable||changeable | ||
194 | channle||channel | ||
195 | channnel||channel | ||
196 | charachter||character | ||
197 | charachters||characters | ||
198 | charactor||character | ||
199 | charater||character | ||
200 | charaters||characters | ||
201 | charcter||character | ||
202 | checksuming||checksumming | ||
203 | childern||children | ||
204 | childs||children | ||
205 | chiled||child | ||
206 | chked||checked | ||
207 | chnage||change | ||
208 | chnages||changes | ||
209 | chnnel||channel | ||
210 | choosen||chosen | ||
211 | chouse||chose | ||
212 | circumvernt||circumvent | ||
213 | claread||cleared | ||
214 | clared||cleared | ||
215 | closeing||closing | ||
216 | clustred||clustered | ||
217 | collapsable||collapsible | ||
218 | colorfull||colorful | ||
219 | comand||command | ||
220 | comit||commit | ||
221 | commerical||commercial | ||
222 | comming||coming | ||
223 | comminucation||communication | ||
224 | commited||committed | ||
225 | commiting||committing | ||
226 | committ||commit | ||
227 | commoditiy||commodity | ||
228 | compability||compatibility | ||
229 | compaibility||compatibility | ||
230 | compatability||compatibility | ||
231 | compatable||compatible | ||
232 | compatibiliy||compatibility | ||
233 | compatibilty||compatibility | ||
234 | compilant||compliant | ||
235 | compleatly||completely | ||
236 | completly||completely | ||
237 | complient||compliant | ||
238 | componnents||components | ||
239 | compres||compress | ||
240 | compresion||compression | ||
241 | comression||compression | ||
242 | comunication||communication | ||
243 | conbination||combination | ||
244 | conditionaly||conditionally | ||
245 | conected||connected | ||
246 | configuratoin||configuration | ||
247 | configuraton||configuration | ||
248 | configuretion||configuration | ||
249 | conider||consider | ||
250 | conjuction||conjunction | ||
251 | connectinos||connections | ||
252 | connnection||connection | ||
253 | connnections||connections | ||
254 | consistancy||consistency | ||
255 | consistant||consistent | ||
256 | containes||contains | ||
257 | containts||contains | ||
258 | contaisn||contains | ||
259 | contant||contact | ||
260 | contence||contents | ||
261 | continous||continuous | ||
262 | continously||continuously | ||
263 | continueing||continuing | ||
264 | contraints||constraints | ||
265 | controled||controlled | ||
266 | controler||controller | ||
267 | controll||control | ||
268 | contruction||construction | ||
269 | contry||country | ||
270 | convertion||conversion | ||
271 | convertor||converter | ||
272 | convienient||convenient | ||
273 | convinient||convenient | ||
274 | corected||corrected | ||
275 | correponding||corresponding | ||
276 | correponds||corresponds | ||
277 | correspoding||corresponding | ||
278 | cotrol||control | ||
279 | couter||counter | ||
280 | coutner||counter | ||
281 | cryptocraphic||cryptographic | ||
282 | cunter||counter | ||
283 | curently||currently | ||
284 | dafault||default | ||
285 | deafult||default | ||
286 | deamon||daemon | ||
287 | decompres||decompress | ||
288 | decription||description | ||
289 | defailt||default | ||
290 | defferred||deferred | ||
291 | definate||definite | ||
292 | definately||definitely | ||
293 | defintion||definition | ||
294 | defualt||default | ||
295 | defult||default | ||
296 | deivce||device | ||
297 | delared||declared | ||
298 | delare||declare | ||
299 | delares||declares | ||
300 | delaring||declaring | ||
301 | delemiter||delimiter | ||
302 | dependancies||dependencies | ||
303 | dependancy||dependency | ||
304 | dependant||dependent | ||
305 | depreacted||deprecated | ||
306 | depreacte||deprecate | ||
307 | desactivate||deactivate | ||
308 | desciptors||descriptors | ||
309 | descrition||description | ||
310 | descritptor||descriptor | ||
311 | desctiptor||descriptor | ||
312 | desriptor||descriptor | ||
313 | desriptors||descriptors | ||
314 | destory||destroy | ||
315 | destoryed||destroyed | ||
316 | destorys||destroys | ||
317 | destroied||destroyed | ||
318 | detabase||database | ||
319 | develope||develop | ||
320 | developement||development | ||
321 | developped||developed | ||
322 | developpement||development | ||
323 | developper||developer | ||
324 | developpment||development | ||
325 | deveolpment||development | ||
326 | devided||divided | ||
327 | deviece||device | ||
328 | diable||disable | ||
329 | dictionnary||dictionary | ||
330 | diferent||different | ||
331 | differrence||difference | ||
332 | difinition||definition | ||
333 | diplay||display | ||
334 | direectly||directly | ||
335 | disapear||disappear | ||
336 | disapeared||disappeared | ||
337 | disappared||disappeared | ||
338 | disconnet||disconnect | ||
339 | discontinous||discontinuous | ||
340 | dispertion||dispersion | ||
341 | dissapears||disappears | ||
342 | distiction||distinction | ||
343 | docuentation||documentation | ||
344 | documantation||documentation | ||
345 | documentaion||documentation | ||
346 | documment||document | ||
347 | dorp||drop | ||
348 | dosen||doesn | ||
349 | downlad||download | ||
350 | downlads||downloads | ||
351 | druing||during | ||
352 | dynmaic||dynamic | ||
353 | easilly||easily | ||
354 | ecspecially||especially | ||
355 | edditable||editable | ||
356 | editting||editing | ||
357 | efficently||efficiently | ||
358 | ehther||ether | ||
359 | eigth||eight | ||
360 | eletronic||electronic | ||
361 | enabledi||enabled | ||
362 | enchanced||enhanced | ||
363 | encorporating||incorporating | ||
364 | encrupted||encrypted | ||
365 | encrypiton||encryption | ||
366 | endianess||endianness | ||
367 | enhaced||enhanced | ||
368 | enlightnment||enlightenment | ||
369 | enocded||encoded | ||
370 | enterily||entirely | ||
371 | enviroiment||environment | ||
372 | enviroment||environment | ||
373 | environement||environment | ||
374 | environent||environment | ||
375 | eqivalent||equivalent | ||
376 | equiped||equipped | ||
377 | equivelant||equivalent | ||
378 | equivilant||equivalent | ||
379 | eror||error | ||
380 | estbalishment||establishment | ||
381 | etsablishment||establishment | ||
382 | etsbalishment||establishment | ||
383 | excecutable||executable | ||
384 | exceded||exceeded | ||
385 | excellant||excellent | ||
386 | existance||existence | ||
387 | existant||existent | ||
388 | exixt||exist | ||
389 | exlcude||exclude | ||
390 | exlcusive||exclusive | ||
391 | exmaple||example | ||
392 | expecially||especially | ||
393 | explicite||explicit | ||
394 | explicitely||explicitly | ||
395 | explict||explicit | ||
396 | explictly||explicitly | ||
397 | expresion||expression | ||
398 | exprimental||experimental | ||
399 | extened||extended | ||
400 | extensability||extensibility | ||
401 | extention||extension | ||
402 | extracter||extractor | ||
403 | faild||failed | ||
404 | faill||fail | ||
405 | failue||failure | ||
406 | failuer||failure | ||
407 | faireness||fairness | ||
408 | faliure||failure | ||
409 | familar||familiar | ||
410 | fatser||faster | ||
411 | feauture||feature | ||
412 | feautures||features | ||
413 | fetaure||feature | ||
414 | fetaures||features | ||
415 | fileystem||filesystem | ||
416 | finanize||finalize | ||
417 | findn||find | ||
418 | finilizes||finalizes | ||
419 | finsih||finish | ||
420 | flusing||flushing | ||
421 | folloing||following | ||
422 | followign||following | ||
423 | follwing||following | ||
424 | forseeable||foreseeable | ||
425 | forse||force | ||
426 | fortan||fortran | ||
427 | forwardig||forwarding | ||
428 | framwork||framework | ||
429 | frequncy||frequency | ||
430 | frome||from | ||
431 | fucntion||function | ||
432 | fuction||function | ||
433 | fuctions||functions | ||
434 | funcion||function | ||
435 | functionallity||functionality | ||
436 | functionaly||functionally | ||
437 | functionnality||functionality | ||
438 | functonality||functionality | ||
439 | funtion||function | ||
440 | funtions||functions | ||
441 | furthur||further | ||
442 | futhermore||furthermore | ||
443 | futrue||future | ||
444 | gaurenteed||guaranteed | ||
445 | generiously||generously | ||
446 | genric||generic | ||
447 | globel||global | ||
448 | grabing||grabbing | ||
449 | grahical||graphical | ||
450 | grahpical||graphical | ||
451 | grapic||graphic | ||
452 | guage||gauge | ||
453 | guarentee||guarantee | ||
454 | halfs||halves | ||
455 | hander||handler | ||
456 | handfull||handful | ||
457 | hanled||handled | ||
458 | harware||hardware | ||
459 | heirarchically||hierarchically | ||
460 | helpfull||helpful | ||
461 | hierachy||hierarchy | ||
462 | hierarchie||hierarchy | ||
463 | howver||however | ||
464 | hsould||should | ||
465 | hypter||hyper | ||
466 | identidier||identifier | ||
467 | imblance||imbalance | ||
468 | immeadiately||immediately | ||
469 | immedaite||immediate | ||
470 | immediatelly||immediately | ||
471 | immediatly||immediately | ||
472 | immidiate||immediate | ||
473 | impelentation||implementation | ||
474 | impementated||implemented | ||
475 | implemantation||implementation | ||
476 | implemenation||implementation | ||
477 | implementaiton||implementation | ||
478 | implementated||implemented | ||
479 | implemention||implementation | ||
480 | implemetation||implementation | ||
481 | implemntation||implementation | ||
482 | implentation||implementation | ||
483 | implmentation||implementation | ||
484 | implmenting||implementing | ||
485 | incomming||incoming | ||
486 | incompatabilities||incompatibilities | ||
487 | incompatable||incompatible | ||
488 | inconsistant||inconsistent | ||
489 | increas||increase | ||
490 | incrment||increment | ||
491 | indendation||indentation | ||
492 | indended||intended | ||
493 | independant||independent | ||
494 | independantly||independently | ||
495 | independed||independent | ||
496 | indiate||indicate | ||
497 | inexpect||inexpected | ||
498 | infomation||information | ||
499 | informatiom||information | ||
500 | informations||information | ||
501 | informtion||information | ||
502 | infromation||information | ||
503 | ingore||ignore | ||
504 | inital||initial | ||
505 | initalised||initialized | ||
506 | initalise||initialize | ||
507 | initalize||initialize | ||
508 | initation||initiation | ||
509 | initators||initiators | ||
510 | initializiation||initialization | ||
511 | initialzed||initialized | ||
512 | initilization||initialization | ||
513 | initilize||initialize | ||
514 | inofficial||unofficial | ||
515 | instal||install | ||
516 | inteface||interface | ||
517 | integreated||integrated | ||
518 | integrety||integrity | ||
519 | integrey||integrity | ||
520 | intendet||intended | ||
521 | intented||intended | ||
522 | interanl||internal | ||
523 | interchangable||interchangeable | ||
524 | interferring||interfering | ||
525 | interger||integer | ||
526 | intermittant||intermittent | ||
527 | internel||internal | ||
528 | interoprability||interoperability | ||
529 | interrface||interface | ||
530 | interrrupt||interrupt | ||
531 | interrup||interrupt | ||
532 | interrups||interrupts | ||
533 | interruptted||interrupted | ||
534 | interupted||interrupted | ||
535 | interupt||interrupt | ||
536 | intial||initial | ||
537 | intialized||initialized | ||
538 | intialize||initialize | ||
539 | intregral||integral | ||
540 | intrrupt||interrupt | ||
541 | intuative||intuitive | ||
542 | invaid||invalid | ||
543 | invalde||invald | ||
544 | invalide||invalid | ||
545 | invididual||individual | ||
546 | invokation||invocation | ||
547 | invokations||invocations | ||
548 | irrelevent||irrelevant | ||
549 | isssue||issue | ||
550 | itslef||itself | ||
551 | jave||java | ||
552 | jeffies||jiffies | ||
553 | juse||just | ||
554 | jus||just | ||
555 | kown||known | ||
556 | langage||language | ||
557 | langauage||language | ||
558 | langauge||language | ||
559 | langugage||language | ||
560 | lauch||launch | ||
561 | leightweight||lightweight | ||
562 | lengh||length | ||
563 | lenght||length | ||
564 | lenth||length | ||
565 | lesstiff||lesstif | ||
566 | libaries||libraries | ||
567 | libary||library | ||
568 | librairies||libraries | ||
569 | libraris||libraries | ||
570 | licenceing||licencing | ||
571 | loggging||logging | ||
572 | loggin||login | ||
573 | logile||logfile | ||
574 | loosing||losing | ||
575 | losted||lost | ||
576 | machinary||machinery | ||
577 | maintainance||maintenance | ||
578 | maintainence||maintenance | ||
579 | maintan||maintain | ||
580 | makeing||making | ||
581 | malplaced||misplaced | ||
582 | malplace||misplace | ||
583 | managable||manageable | ||
584 | managment||management | ||
585 | mangement||management | ||
586 | manoeuvering||maneuvering | ||
587 | mappping||mapping | ||
588 | mathimatical||mathematical | ||
589 | mathimatic||mathematic | ||
590 | mathimatics||mathematics | ||
591 | maxium||maximum | ||
592 | mechamism||mechanism | ||
593 | meetign||meeting | ||
594 | ment||meant | ||
595 | mergable||mergeable | ||
596 | mesage||message | ||
597 | messags||messages | ||
598 | messgaes||messages | ||
599 | messsage||message | ||
600 | messsages||messages | ||
601 | microprocesspr||microprocessor | ||
602 | milliseonds||milliseconds | ||
603 | minumum||minimum | ||
604 | miscelleneous||miscellaneous | ||
605 | misformed||malformed | ||
606 | mispelled||misspelled | ||
607 | mispelt||misspelt | ||
608 | miximum||maximum | ||
609 | mmnemonic||mnemonic | ||
610 | mnay||many | ||
611 | modeled||modelled | ||
612 | modulues||modules | ||
613 | monochorome||monochrome | ||
614 | monochromo||monochrome | ||
615 | monocrome||monochrome | ||
616 | mopdule||module | ||
617 | mroe||more | ||
618 | mulitplied||multiplied | ||
619 | multidimensionnal||multidimensional | ||
620 | multple||multiple | ||
621 | mumber||number | ||
622 | muticast||multicast | ||
623 | mutiple||multiple | ||
624 | mutli||multi | ||
625 | nams||names | ||
626 | navagating||navigating | ||
627 | nead||need | ||
628 | neccecary||necessary | ||
629 | neccesary||necessary | ||
630 | neccessary||necessary | ||
631 | necesary||necessary | ||
632 | negaive||negative | ||
633 | negoitation||negotiation | ||
634 | negotation||negotiation | ||
635 | nerver||never | ||
636 | nescessary||necessary | ||
637 | nessessary||necessary | ||
638 | noticable||noticeable | ||
639 | notications||notifications | ||
640 | notifed||notified | ||
641 | numebr||number | ||
642 | numner||number | ||
643 | obtaion||obtain | ||
644 | occassionally||occasionally | ||
645 | occationally||occasionally | ||
646 | occurance||occurrence | ||
647 | occurances||occurrences | ||
648 | occured||occurred | ||
649 | occurence||occurrence | ||
650 | occure||occurred | ||
651 | occuring||occurring | ||
652 | offet||offset | ||
653 | omitt||omit | ||
654 | ommiting||omitting | ||
655 | ommitted||omitted | ||
656 | onself||oneself | ||
657 | ony||only | ||
658 | operatione||operation | ||
659 | opertaions||operations | ||
660 | optionnal||optional | ||
661 | optmizations||optimizations | ||
662 | orientatied||orientated | ||
663 | orientied||oriented | ||
664 | otherise||otherwise | ||
665 | ouput||output | ||
666 | overaall||overall | ||
667 | overhread||overhead | ||
668 | overlaping||overlapping | ||
669 | overriden||overridden | ||
670 | overun||overrun | ||
671 | pacakge||package | ||
672 | pachage||package | ||
673 | packacge||package | ||
674 | packege||package | ||
675 | packge||package | ||
676 | packtes||packets | ||
677 | pakage||package | ||
678 | pallette||palette | ||
679 | paln||plan | ||
680 | paramameters||parameters | ||
681 | paramater||parameter | ||
682 | parametes||parameters | ||
683 | parametised||parametrised | ||
684 | paramter||parameter | ||
685 | paramters||parameters | ||
686 | particuarly||particularly | ||
687 | particularily||particularly | ||
688 | pased||passed | ||
689 | passin||passing | ||
690 | pathes||paths | ||
691 | pecularities||peculiarities | ||
692 | peformance||performance | ||
693 | peice||piece | ||
694 | pendantic||pedantic | ||
695 | peprocessor||preprocessor | ||
696 | perfoming||performing | ||
697 | permissons||permissions | ||
698 | peroid||period | ||
699 | persistance||persistence | ||
700 | persistant||persistent | ||
701 | platfrom||platform | ||
702 | plattform||platform | ||
703 | pleaes||please | ||
704 | ploting||plotting | ||
705 | plugable||pluggable | ||
706 | poinnter||pointer | ||
707 | poiter||pointer | ||
708 | posible||possible | ||
709 | positon||position | ||
710 | possibilites||possibilities | ||
711 | powerfull||powerful | ||
712 | preceeded||preceded | ||
713 | preceeding||preceding | ||
714 | preceed||precede | ||
715 | precendence||precedence | ||
716 | precission||precision | ||
717 | prefered||preferred | ||
718 | prefferably||preferably | ||
719 | premption||preemption | ||
720 | prepaired||prepared | ||
721 | pressre||pressure | ||
722 | primative||primitive | ||
723 | princliple||principle | ||
724 | priorty||priority | ||
725 | privilaged||privileged | ||
726 | privilage||privilege | ||
727 | priviledge||privilege | ||
728 | priviledges||privileges | ||
729 | probaly||probably | ||
730 | procceed||proceed | ||
731 | proccesors||processors | ||
732 | procesed||processed | ||
733 | proces||process | ||
734 | processessing||processing | ||
735 | processess||processes | ||
736 | processpr||processor | ||
737 | processsed||processed | ||
738 | processsing||processing | ||
739 | procteted||protected | ||
740 | prodecure||procedure | ||
741 | progams||programs | ||
742 | progess||progress | ||
743 | programers||programmers | ||
744 | programm||program | ||
745 | programms||programs | ||
746 | progresss||progress | ||
747 | promps||prompts | ||
748 | pronnounced||pronounced | ||
749 | prononciation||pronunciation | ||
750 | pronouce||pronounce | ||
751 | pronunce||pronounce | ||
752 | propery||property | ||
753 | propigate||propagate | ||
754 | propigation||propagation | ||
755 | propogate||propagate | ||
756 | prosess||process | ||
757 | protable||portable | ||
758 | protcol||protocol | ||
759 | protecion||protection | ||
760 | protocoll||protocol | ||
761 | psudo||pseudo | ||
762 | psuedo||pseudo | ||
763 | psychadelic||psychedelic | ||
764 | pwoer||power | ||
765 | quering||querying | ||
766 | raoming||roaming | ||
767 | reasearcher||researcher | ||
768 | reasearchers||researchers | ||
769 | reasearch||research | ||
770 | recepient||recipient | ||
771 | receving||receiving | ||
772 | recieved||received | ||
773 | recieve||receive | ||
774 | reciever||receiver | ||
775 | recieves||receives | ||
776 | recogniced||recognised | ||
777 | recognizeable||recognizable | ||
778 | recommanded||recommended | ||
779 | recyle||recycle | ||
780 | redircet||redirect | ||
781 | redirectrion||redirection | ||
782 | refcounf||refcount | ||
783 | refence||reference | ||
784 | refered||referred | ||
785 | referenace||reference | ||
786 | refering||referring | ||
787 | refernces||references | ||
788 | refernnce||reference | ||
789 | refrence||reference | ||
790 | registerd||registered | ||
791 | registeresd||registered | ||
792 | registes||registers | ||
793 | registraration||registration | ||
794 | regster||register | ||
795 | regualar||regular | ||
796 | reguator||regulator | ||
797 | regulamentations||regulations | ||
798 | reigstration||registration | ||
799 | releated||related | ||
800 | relevent||relevant | ||
801 | remoote||remote | ||
802 | remore||remote | ||
803 | removeable||removable | ||
804 | repectively||respectively | ||
805 | replacable||replaceable | ||
806 | replacments||replacements | ||
807 | replys||replies | ||
808 | reponse||response | ||
809 | representaion||representation | ||
810 | reqeust||request | ||
811 | requiere||require | ||
812 | requirment||requirement | ||
813 | requred||required | ||
814 | requried||required | ||
815 | requst||request | ||
816 | reseting||resetting | ||
817 | resizeable||resizable | ||
818 | resouces||resources | ||
819 | resoures||resources | ||
820 | ressizes||resizes | ||
821 | ressource||resource | ||
822 | ressources||resources | ||
823 | retransmited||retransmitted | ||
824 | retreived||retrieved | ||
825 | retreive||retrieve | ||
826 | retrive||retrieve | ||
827 | retuned||returned | ||
828 | reuest||request | ||
829 | reuqest||request | ||
830 | reutnred||returned | ||
831 | rmeoved||removed | ||
832 | rmeove||remove | ||
833 | rmeoves||removes | ||
834 | rountine||routine | ||
835 | routins||routines | ||
836 | rquest||request | ||
837 | runing||running | ||
838 | runned||ran | ||
839 | runnning||running | ||
840 | runtine||runtime | ||
841 | sacrifying||sacrificing | ||
842 | safly||safely | ||
843 | safty||safety | ||
844 | savable||saveable | ||
845 | scaned||scanned | ||
846 | scaning||scanning | ||
847 | scarch||search | ||
848 | seach||search | ||
849 | searchs||searches | ||
850 | secquence||sequence | ||
851 | secund||second | ||
852 | segement||segment | ||
853 | senarios||scenarios | ||
854 | sentivite||sensitive | ||
855 | separatly||separately | ||
856 | sepcify||specify | ||
857 | sepc||spec | ||
858 | seperated||separated | ||
859 | seperately||separately | ||
860 | seperate||separate | ||
861 | seperatly||separately | ||
862 | seperator||separator | ||
863 | sepperate||separate | ||
864 | sequece||sequence | ||
865 | sequencial||sequential | ||
866 | serveral||several | ||
867 | setts||sets | ||
868 | settting||setting | ||
869 | shotdown||shutdown | ||
870 | shoud||should | ||
871 | shoule||should | ||
872 | shrinked||shrunk | ||
873 | siginificantly||significantly | ||
874 | signabl||signal | ||
875 | similary||similarly | ||
876 | similiar||similar | ||
877 | simlar||similar | ||
878 | simliar||similar | ||
879 | simpified||simplified | ||
880 | singaled||signaled | ||
881 | singal||signal | ||
882 | singed||signed | ||
883 | sleeped||slept | ||
884 | softwares||software | ||
885 | speach||speech | ||
886 | specfic||specific | ||
887 | speciefied||specified | ||
888 | specifc||specific | ||
889 | specifed||specified | ||
890 | specificatin||specification | ||
891 | specificaton||specification | ||
892 | specifing||specifying | ||
893 | specifiying||specifying | ||
894 | speficied||specified | ||
895 | speicify||specify | ||
896 | speling||spelling | ||
897 | spinlcok||spinlock | ||
898 | spinock||spinlock | ||
899 | splitted||split | ||
900 | spreaded||spread | ||
901 | sructure||structure | ||
902 | stablilization||stabilization | ||
903 | staically||statically | ||
904 | staion||station | ||
905 | standardss||standards | ||
906 | standartization||standardization | ||
907 | standart||standard | ||
908 | staticly||statically | ||
909 | stoped||stopped | ||
910 | stoppped||stopped | ||
911 | straming||streaming | ||
912 | struc||struct | ||
913 | structres||structures | ||
914 | stuct||struct | ||
915 | sturcture||structure | ||
916 | subdirectoires||subdirectories | ||
917 | suble||subtle | ||
918 | succesfully||successfully | ||
919 | succesful||successful | ||
920 | successfull||successful | ||
921 | sucessfully||successfully | ||
922 | sucess||success | ||
923 | superflous||superfluous | ||
924 | superseeded||superseded | ||
925 | suplied||supplied | ||
926 | suported||supported | ||
927 | suport||support | ||
928 | suppored||supported | ||
929 | supportin||supporting | ||
930 | suppoted||supported | ||
931 | suppported||supported | ||
932 | suppport||support | ||
933 | supress||suppress | ||
934 | surpresses||suppresses | ||
935 | susbsystem||subsystem | ||
936 | suspicously||suspiciously | ||
937 | swaping||swapping | ||
938 | switchs||switches | ||
939 | symetric||symmetric | ||
940 | synax||syntax | ||
941 | synchonized||synchronized | ||
942 | syncronize||synchronize | ||
943 | syncronizing||synchronizing | ||
944 | syncronus||synchronous | ||
945 | syste||system | ||
946 | sytem||system | ||
947 | sythesis||synthesis | ||
948 | taht||that | ||
949 | targetted||targeted | ||
950 | targetting||targeting | ||
951 | teh||the | ||
952 | temorary||temporary | ||
953 | temproarily||temporarily | ||
954 | thier||their | ||
955 | threds||threads | ||
956 | threshhold||threshold | ||
957 | throught||through | ||
958 | thses||these | ||
959 | tiggered||triggered | ||
960 | tipically||typically | ||
961 | tmis||this | ||
962 | torerable||tolerable | ||
963 | tramsmitted||transmitted | ||
964 | tramsmit||transmit | ||
965 | tranfer||transfer | ||
966 | transciever||transceiver | ||
967 | transferd||transferrd | ||
968 | transfered||transferred | ||
969 | transfering||transferring | ||
970 | transision||transition | ||
971 | transmittd||transmitted | ||
972 | transormed||transformed | ||
973 | trasmission||transmission | ||
974 | treshold||threshold | ||
975 | trigerring||triggering | ||
976 | trun||turn | ||
977 | ture||true | ||
978 | tyep||type | ||
979 | udpate||update | ||
980 | uesd||used | ||
981 | unconditionaly||unconditionally | ||
982 | underun||underrun | ||
983 | unecessary||unnecessary | ||
984 | unexecpted||unexpected | ||
985 | unexpectd||unexpected | ||
986 | unexpeted||unexpected | ||
987 | unfortunatelly||unfortunately | ||
988 | unifiy||unify | ||
989 | unknonw||unknown | ||
990 | unknow||unknown | ||
991 | unkown||unknown | ||
992 | unneedingly||unnecessarily | ||
993 | unresgister||unregister | ||
994 | unsinged||unsigned | ||
995 | unstabel||unstable | ||
996 | unsuccessfull||unsuccessful | ||
997 | unsuported||unsupported | ||
998 | untill||until | ||
999 | unuseful||useless | ||
1000 | upate||update | ||
1001 | usefule||useful | ||
1002 | usefull||useful | ||
1003 | usege||usage | ||
1004 | usera||users | ||
1005 | usualy||usually | ||
1006 | utilites||utilities | ||
1007 | utillities||utilities | ||
1008 | utilties||utilities | ||
1009 | utiltity||utility | ||
1010 | utitity||utility | ||
1011 | utitlty||utility | ||
1012 | vaid||valid | ||
1013 | vaild||valid | ||
1014 | valide||valid | ||
1015 | variantions||variations | ||
1016 | varient||variant | ||
1017 | vaule||value | ||
1018 | verbse||verbose | ||
1019 | verisons||versions | ||
1020 | verison||version | ||
1021 | verson||version | ||
1022 | vicefersa||vice-versa | ||
1023 | virtal||virtual | ||
1024 | virtaul||virtual | ||
1025 | virtiual||virtual | ||
1026 | visiters||visitors | ||
1027 | vitual||virtual | ||
1028 | wating||waiting | ||
1029 | whataver||whatever | ||
1030 | whenver||whenever | ||
1031 | wheter||whether | ||
1032 | whe||when | ||
1033 | wierd||weird | ||
1034 | wiil||will | ||
1035 | wirte||write | ||
1036 | withing||within | ||
1037 | wnat||want | ||
1038 | workarould||workaround | ||
1039 | writeing||writing | ||
1040 | writting||writing | ||
1041 | zombe||zombie | ||
1042 | zomebie||zombie | ||