diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-05 14:09:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-05 14:09:16 -0400 |
commit | 11126c611e10abb18b6f1ed0300c0548c3906b54 (patch) | |
tree | 246227ad730c1e68f5a9c03db57cd4592abe7687 | |
parent | 67966e088b0c7dc926f4ce19565ebf208e18d058 (diff) | |
parent | 33e2a4227ddff7c18921ac175fae3ab0e3ff8a76 (diff) |
Merge branch 'akpm' (Andrew's patch-bomb)
Merge misc patches from Andrew Morton:
"The MM tree is rather stuck while I wait to find out what the heck is
happening with sched/numa. Probably I'll need to route around all the
code which was added to -next, sigh.
So this is "everything else", or at least most of it - other small
bits are still awaiting resolutions of various kinds."
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (180 commits)
lib/decompress.c add __init to decompress_method and data
kernel/resource.c: fix stack overflow in __reserve_region_with_split()
omfs: convert to use beXX_add_cpu()
taskstats: cgroupstats_user_cmd() may leak on error
aoe: update aoe-internal version number to 50
aoe: update documentation to better reflect aoe-plus-udev usage
aoe: remove unused code
aoe: make dynamic block minor numbers the default
aoe: update and specify AoE address guards and error messages
aoe: retain static block device numbers for backwards compatibility
aoe: support more AoE addresses with dynamic block device minor numbers
aoe: update documentation with new URL and VM settings reference
aoe: update copyright year in touched files
aoe: update internal version number to 49
aoe: remove unused code and add cosmetic improvements
aoe: increase net_device reference count while using it
aoe: associate frames with the AoE storage target
aoe: disallow unsupported AoE minor addresses
aoe: do revalidation steps in order
aoe: failover remote interface based on aoe_deadsecs parameter
...
308 files changed, 7393 insertions, 2728 deletions
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle index cb9258b8fd35..495e5ba1634c 100644 --- a/Documentation/CodingStyle +++ b/Documentation/CodingStyle | |||
@@ -454,6 +454,16 @@ The preferred style for long (multi-line) comments is: | |||
454 | * with beginning and ending almost-blank lines. | 454 | * with beginning and ending almost-blank lines. |
455 | */ | 455 | */ |
456 | 456 | ||
457 | For files in net/ and drivers/net/ the preferred style for long (multi-line) | ||
458 | comments is a little different. | ||
459 | |||
460 | /* The preferred comment style for files in net/ and drivers/net | ||
461 | * looks like this. | ||
462 | * | ||
463 | * It is nearly the same as the generally preferred comment style, | ||
464 | * but there is no initial almost-blank line. | ||
465 | */ | ||
466 | |||
457 | It's also important to comment data, whether they are basic types or derived | 467 | It's also important to comment data, whether they are basic types or derived |
458 | types. To this end, use just one data declaration per line (no commas for | 468 | types. To this end, use just one data declaration per line (no commas for |
459 | multiple data declarations). This leaves you room for a small comment on each | 469 | multiple data declarations). This leaves you room for a small comment on each |
diff --git a/Documentation/aoe/aoe.txt b/Documentation/aoe/aoe.txt index 5f5aa16047ff..bfc9cb19abcd 100644 --- a/Documentation/aoe/aoe.txt +++ b/Documentation/aoe/aoe.txt | |||
@@ -1,8 +1,16 @@ | |||
1 | The EtherDrive (R) HOWTO for users of 2.6 kernels is found at ... | 1 | ATA over Ethernet is a network protocol that provides simple access to |
2 | block storage on the LAN. | ||
2 | 3 | ||
3 | http://www.coraid.com/SUPPORT/EtherDrive-HBA | 4 | http://support.coraid.com/documents/AoEr11.txt |
4 | 5 | ||
5 | It has many tips and hints! | 6 | The EtherDrive (R) HOWTO for 2.6 and 3.x kernels is found at ... |
7 | |||
8 | http://support.coraid.com/support/linux/EtherDrive-2.6-HOWTO.html | ||
9 | |||
10 | It has many tips and hints! Please see, especially, recommended | ||
11 | tunings for virtual memory: | ||
12 | |||
13 | http://support.coraid.com/support/linux/EtherDrive-2.6-HOWTO-5.html#ss5.19 | ||
6 | 14 | ||
7 | The aoetools are userland programs that are designed to work with this | 15 | The aoetools are userland programs that are designed to work with this |
8 | driver. The aoetools are on sourceforge. | 16 | driver. The aoetools are on sourceforge. |
@@ -23,20 +31,12 @@ CREATING DEVICE NODES | |||
23 | There is a udev-install.sh script that shows how to install these | 31 | There is a udev-install.sh script that shows how to install these |
24 | rules on your system. | 32 | rules on your system. |
25 | 33 | ||
26 | If you are not using udev, two scripts are provided in | ||
27 | Documentation/aoe as examples of static device node creation for | ||
28 | using the aoe driver. | ||
29 | |||
30 | rm -rf /dev/etherd | ||
31 | sh Documentation/aoe/mkdevs.sh /dev/etherd | ||
32 | |||
33 | ... or to make just one shelf's worth of block device nodes ... | ||
34 | |||
35 | sh Documentation/aoe/mkshelf.sh /dev/etherd 0 | ||
36 | |||
37 | There is also an autoload script that shows how to edit | 34 | There is also an autoload script that shows how to edit |
38 | /etc/modprobe.d/aoe.conf to ensure that the aoe module is loaded when | 35 | /etc/modprobe.d/aoe.conf to ensure that the aoe module is loaded when |
39 | necessary. | 36 | necessary. Preloading the aoe module is preferable to autoloading, |
37 | however, because AoE discovery takes a few seconds. It can be | ||
38 | confusing when an AoE device is not present the first time the a | ||
39 | command is run but appears a second later. | ||
40 | 40 | ||
41 | USING DEVICE NODES | 41 | USING DEVICE NODES |
42 | 42 | ||
@@ -51,9 +51,9 @@ USING DEVICE NODES | |||
51 | "echo > /dev/etherd/discover" tells the driver to find out what AoE | 51 | "echo > /dev/etherd/discover" tells the driver to find out what AoE |
52 | devices are available. | 52 | devices are available. |
53 | 53 | ||
54 | These character devices may disappear and be replaced by sysfs | 54 | In the future these character devices may disappear and be replaced |
55 | counterparts. Using the commands in aoetools insulates users from | 55 | by sysfs counterparts. Using the commands in aoetools insulates |
56 | these implementation details. | 56 | users from these implementation details. |
57 | 57 | ||
58 | The block devices are named like this: | 58 | The block devices are named like this: |
59 | 59 | ||
@@ -76,8 +76,8 @@ USING SYSFS | |||
76 | The netif attribute is the network interface on the localhost | 76 | The netif attribute is the network interface on the localhost |
77 | through which we are communicating with the remote AoE device. | 77 | through which we are communicating with the remote AoE device. |
78 | 78 | ||
79 | There is a script in this directory that formats this information | 79 | There is a script in this directory that formats this information in |
80 | in a convenient way. Users with aoetools can use the aoe-stat | 80 | a convenient way. Users with aoetools should use the aoe-stat |
81 | command. | 81 | command. |
82 | 82 | ||
83 | root@makki root# sh Documentation/aoe/status.sh | 83 | root@makki root# sh Documentation/aoe/status.sh |
@@ -121,3 +121,21 @@ DRIVER OPTIONS | |||
121 | usage example for the module parameter. | 121 | usage example for the module parameter. |
122 | 122 | ||
123 | modprobe aoe_iflist="eth1 eth3" | 123 | modprobe aoe_iflist="eth1 eth3" |
124 | |||
125 | The aoe_deadsecs module parameter determines the maximum number of | ||
126 | seconds that the driver will wait for an AoE device to provide a | ||
127 | response to an AoE command. After aoe_deadsecs seconds have | ||
128 | elapsed, the AoE device will be marked as "down". | ||
129 | |||
130 | The aoe_maxout module parameter has a default of 128. This is the | ||
131 | maximum number of unresponded packets that will be sent to an AoE | ||
132 | target at one time. | ||
133 | |||
134 | The aoe_dyndevs module parameter defaults to 1, meaning that the | ||
135 | driver will assign a block device minor number to a discovered AoE | ||
136 | target based on the order of its discovery. With dynamic minor | ||
137 | device numbers in use, a greater range of AoE shelf and slot | ||
138 | addresses can be supported. Users with udev will never have to | ||
139 | think about minor numbers. Using aoe_dyndevs=0 allows device nodes | ||
140 | to be pre-created using a static minor-number scheme with the | ||
141 | aoe-mkshelf script in the aoetools. | ||
diff --git a/Documentation/aoe/mkdevs.sh b/Documentation/aoe/mkdevs.sh deleted file mode 100644 index 44c0ab702432..000000000000 --- a/Documentation/aoe/mkdevs.sh +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | n_shelves=${n_shelves:-10} | ||
4 | n_partitions=${n_partitions:-16} | ||
5 | |||
6 | if test "$#" != "1"; then | ||
7 | echo "Usage: sh `basename $0` {dir}" 1>&2 | ||
8 | echo " n_partitions=16 sh `basename $0` {dir}" 1>&2 | ||
9 | exit 1 | ||
10 | fi | ||
11 | dir=$1 | ||
12 | |||
13 | MAJOR=152 | ||
14 | |||
15 | echo "Creating AoE devnode files in $dir ..." | ||
16 | |||
17 | set -e | ||
18 | |||
19 | mkdir -p $dir | ||
20 | |||
21 | # (Status info is in sysfs. See status.sh.) | ||
22 | # rm -f $dir/stat | ||
23 | # mknod -m 0400 $dir/stat c $MAJOR 1 | ||
24 | rm -f $dir/err | ||
25 | mknod -m 0400 $dir/err c $MAJOR 2 | ||
26 | rm -f $dir/discover | ||
27 | mknod -m 0200 $dir/discover c $MAJOR 3 | ||
28 | rm -f $dir/interfaces | ||
29 | mknod -m 0200 $dir/interfaces c $MAJOR 4 | ||
30 | rm -f $dir/revalidate | ||
31 | mknod -m 0200 $dir/revalidate c $MAJOR 5 | ||
32 | rm -f $dir/flush | ||
33 | mknod -m 0200 $dir/flush c $MAJOR 6 | ||
34 | |||
35 | export n_partitions | ||
36 | mkshelf=`echo $0 | sed 's!mkdevs!mkshelf!'` | ||
37 | i=0 | ||
38 | while test $i -lt $n_shelves; do | ||
39 | sh -xc "sh $mkshelf $dir $i" | ||
40 | i=`expr $i + 1` | ||
41 | done | ||
diff --git a/Documentation/aoe/mkshelf.sh b/Documentation/aoe/mkshelf.sh deleted file mode 100644 index 32615814271c..000000000000 --- a/Documentation/aoe/mkshelf.sh +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | #! /bin/sh | ||
2 | |||
3 | if test "$#" != "2"; then | ||
4 | echo "Usage: sh `basename $0` {dir} {shelfaddress}" 1>&2 | ||
5 | echo " n_partitions=16 sh `basename $0` {dir} {shelfaddress}" 1>&2 | ||
6 | exit 1 | ||
7 | fi | ||
8 | n_partitions=${n_partitions:-16} | ||
9 | dir=$1 | ||
10 | shelf=$2 | ||
11 | nslots=16 | ||
12 | maxslot=`echo $nslots 1 - p | dc` | ||
13 | MAJOR=152 | ||
14 | |||
15 | set -e | ||
16 | |||
17 | minor=`echo $nslots \* $shelf \* $n_partitions | bc` | ||
18 | endp=`echo $n_partitions - 1 | bc` | ||
19 | for slot in `seq 0 $maxslot`; do | ||
20 | for part in `seq 0 $endp`; do | ||
21 | name=e$shelf.$slot | ||
22 | test "$part" != "0" && name=${name}p$part | ||
23 | rm -f $dir/$name | ||
24 | mknod -m 0660 $dir/$name b $MAJOR $minor | ||
25 | |||
26 | minor=`expr $minor + 1` | ||
27 | done | ||
28 | done | ||
diff --git a/Documentation/aoe/status.sh b/Documentation/aoe/status.sh index 751f3be514b8..eeec7baae57a 100644 --- a/Documentation/aoe/status.sh +++ b/Documentation/aoe/status.sh | |||
@@ -1,5 +1,8 @@ | |||
1 | #! /bin/sh | 1 | #! /bin/sh |
2 | # collate and present sysfs information about AoE storage | 2 | # collate and present sysfs information about AoE storage |
3 | # | ||
4 | # A more complete version of this script is aoe-stat, in the | ||
5 | # aoetools. | ||
3 | 6 | ||
4 | set -e | 7 | set -e |
5 | format="%8s\t%8s\t%8s\n" | 8 | format="%8s\t%8s\t%8s\n" |
diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt index bf57ecd5d73a..bd7ce120bc13 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt | |||
@@ -9,6 +9,7 @@ Copyright (C) 2008-2011 Freescale Semiconductor Inc. | |||
9 | -Run Time Integrity Check (RTIC) Node | 9 | -Run Time Integrity Check (RTIC) Node |
10 | -Run Time Integrity Check (RTIC) Memory Node | 10 | -Run Time Integrity Check (RTIC) Memory Node |
11 | -Secure Non-Volatile Storage (SNVS) Node | 11 | -Secure Non-Volatile Storage (SNVS) Node |
12 | -Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node | ||
12 | -Full Example | 13 | -Full Example |
13 | 14 | ||
14 | NOTE: the SEC 4 is also known as Freescale's Cryptographic Accelerator | 15 | NOTE: the SEC 4 is also known as Freescale's Cryptographic Accelerator |
@@ -294,6 +295,27 @@ Secure Non-Volatile Storage (SNVS) Node | |||
294 | address and length of the SEC4 configuration | 295 | address and length of the SEC4 configuration |
295 | registers. | 296 | registers. |
296 | 297 | ||
298 | - #address-cells | ||
299 | Usage: required | ||
300 | Value type: <u32> | ||
301 | Definition: A standard property. Defines the number of cells | ||
302 | for representing physical addresses in child nodes. Must | ||
303 | have a value of 1. | ||
304 | |||
305 | - #size-cells | ||
306 | Usage: required | ||
307 | Value type: <u32> | ||
308 | Definition: A standard property. Defines the number of cells | ||
309 | for representing the size of physical addresses in | ||
310 | child nodes. Must have a value of 1. | ||
311 | |||
312 | - ranges | ||
313 | Usage: required | ||
314 | Value type: <prop-encoded-array> | ||
315 | Definition: A standard property. Specifies the physical address | ||
316 | range of the SNVS register space. A triplet that includes | ||
317 | the child address, parent address, & length. | ||
318 | |||
297 | - interrupts | 319 | - interrupts |
298 | Usage: required | 320 | Usage: required |
299 | Value type: <prop_encoded-array> | 321 | Value type: <prop_encoded-array> |
@@ -314,11 +336,34 @@ EXAMPLE | |||
314 | sec_mon@314000 { | 336 | sec_mon@314000 { |
315 | compatible = "fsl,sec-v4.0-mon"; | 337 | compatible = "fsl,sec-v4.0-mon"; |
316 | reg = <0x314000 0x1000>; | 338 | reg = <0x314000 0x1000>; |
339 | ranges = <0 0x314000 0x1000>; | ||
317 | interrupt-parent = <&mpic>; | 340 | interrupt-parent = <&mpic>; |
318 | interrupts = <93 2>; | 341 | interrupts = <93 2>; |
319 | }; | 342 | }; |
320 | 343 | ||
321 | ===================================================================== | 344 | ===================================================================== |
345 | Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node | ||
346 | |||
347 | A SNVS child node that defines SNVS LP RTC. | ||
348 | |||
349 | - compatible | ||
350 | Usage: required | ||
351 | Value type: <string> | ||
352 | Definition: Must include "fsl,sec-v4.0-mon-rtc-lp". | ||
353 | |||
354 | - reg | ||
355 | Usage: required | ||
356 | Value type: <prop-encoded-array> | ||
357 | Definition: A standard property. Specifies the physical | ||
358 | address and length of the SNVS LP configuration registers. | ||
359 | |||
360 | EXAMPLE | ||
361 | sec_mon_rtc_lp@314000 { | ||
362 | compatible = "fsl,sec-v4.0-mon-rtc-lp"; | ||
363 | reg = <0x34 0x58>; | ||
364 | }; | ||
365 | |||
366 | ===================================================================== | ||
322 | FULL EXAMPLE | 367 | FULL EXAMPLE |
323 | 368 | ||
324 | crypto: crypto@300000 { | 369 | crypto: crypto@300000 { |
@@ -390,8 +435,14 @@ FULL EXAMPLE | |||
390 | sec_mon: sec_mon@314000 { | 435 | sec_mon: sec_mon@314000 { |
391 | compatible = "fsl,sec-v4.0-mon"; | 436 | compatible = "fsl,sec-v4.0-mon"; |
392 | reg = <0x314000 0x1000>; | 437 | reg = <0x314000 0x1000>; |
438 | ranges = <0 0x314000 0x1000>; | ||
393 | interrupt-parent = <&mpic>; | 439 | interrupt-parent = <&mpic>; |
394 | interrupts = <93 2>; | 440 | interrupts = <93 2>; |
441 | |||
442 | sec_mon_rtc_lp@34 { | ||
443 | compatible = "fsl,sec-v4.0-mon-rtc-lp"; | ||
444 | reg = <0x34 0x58>; | ||
445 | }; | ||
395 | }; | 446 | }; |
396 | 447 | ||
397 | ===================================================================== | 448 | ===================================================================== |
diff --git a/Documentation/devicetree/bindings/rtc/snvs-rtc.txt b/Documentation/devicetree/bindings/rtc/snvs-rtc.txt new file mode 100644 index 000000000000..fb61ed77ada3 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/snvs-rtc.txt | |||
@@ -0,0 +1 @@ | |||
See Documentation/devicetree/bindings/crypto/fsl-sec4.txt for details. | |||
diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 7561d7ed8e11..8ffb274367c7 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt | |||
@@ -69,6 +69,7 @@ MAC/FDDI addresses: | |||
69 | %pMR 05:04:03:02:01:00 | 69 | %pMR 05:04:03:02:01:00 |
70 | %pMF 00-01-02-03-04-05 | 70 | %pMF 00-01-02-03-04-05 |
71 | %pm 000102030405 | 71 | %pm 000102030405 |
72 | %pmR 050403020100 | ||
72 | 73 | ||
73 | For printing 6-byte MAC/FDDI addresses in hex notation. The 'M' and 'm' | 74 | For printing 6-byte MAC/FDDI addresses in hex notation. The 'M' and 'm' |
74 | specifiers result in a printed address with ('M') or without ('m') byte | 75 | specifiers result in a printed address with ('M') or without ('m') byte |
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt index 250160469d83..32aa4002de4a 100644 --- a/Documentation/rtc.txt +++ b/Documentation/rtc.txt | |||
@@ -119,8 +119,9 @@ three different userspace interfaces: | |||
119 | * /sys/class/rtc/rtcN ... sysfs attributes support readonly | 119 | * /sys/class/rtc/rtcN ... sysfs attributes support readonly |
120 | access to some RTC attributes. | 120 | access to some RTC attributes. |
121 | 121 | ||
122 | * /proc/driver/rtc ... the first RTC (rtc0) may expose itself | 122 | * /proc/driver/rtc ... the system clock RTC may expose itself |
123 | using a procfs interface. More information is (currently) shown | 123 | using a procfs interface. If there is no RTC for the system clock, |
124 | rtc0 is used by default. More information is (currently) shown | ||
124 | here than through sysfs. | 125 | here than through sysfs. |
125 | 126 | ||
126 | The RTC Class framework supports a wide variety of RTCs, ranging from those | 127 | The RTC Class framework supports a wide variety of RTCs, ranging from those |
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 6d78841fd416..2907ba6c3607 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt | |||
@@ -181,6 +181,8 @@ core_pattern is used to specify a core dumpfile pattern name. | |||
181 | %p pid | 181 | %p pid |
182 | %u uid | 182 | %u uid |
183 | %g gid | 183 | %g gid |
184 | %d dump mode, matches PR_SET_DUMPABLE and | ||
185 | /proc/sys/fs/suid_dumpable | ||
184 | %s signal number | 186 | %s signal number |
185 | %t UNIX time of dump | 187 | %t UNIX time of dump |
186 | %h hostname | 188 | %h hostname |
diff --git a/MAINTAINERS b/MAINTAINERS index f883fc1b1b46..0976bd1381b5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -572,7 +572,7 @@ F: drivers/net/appletalk/ | |||
572 | F: net/appletalk/ | 572 | F: net/appletalk/ |
573 | 573 | ||
574 | ARASAN COMPACT FLASH PATA CONTROLLER | 574 | ARASAN COMPACT FLASH PATA CONTROLLER |
575 | M: Viresh Kumar <viresh.linux@gmail.com> | 575 | M: Viresh Kumar <viresh.linux@gmail.com> |
576 | L: linux-ide@vger.kernel.org | 576 | L: linux-ide@vger.kernel.org |
577 | S: Maintained | 577 | S: Maintained |
578 | F: include/linux/pata_arasan_cf_data.h | 578 | F: include/linux/pata_arasan_cf_data.h |
@@ -760,6 +760,7 @@ S: Maintained | |||
760 | T: git git://git.pengutronix.de/git/imx/linux-2.6.git | 760 | T: git git://git.pengutronix.de/git/imx/linux-2.6.git |
761 | F: arch/arm/mach-imx/ | 761 | F: arch/arm/mach-imx/ |
762 | F: arch/arm/plat-mxc/ | 762 | F: arch/arm/plat-mxc/ |
763 | F: arch/arm/configs/imx*_defconfig | ||
763 | 764 | ||
764 | ARM/FREESCALE IMX6 | 765 | ARM/FREESCALE IMX6 |
765 | M: Shawn Guo <shawn.guo@linaro.org> | 766 | M: Shawn Guo <shawn.guo@linaro.org> |
@@ -1245,7 +1246,7 @@ F: include/linux/i2c/at24.h | |||
1245 | 1246 | ||
1246 | ATA OVER ETHERNET (AOE) DRIVER | 1247 | ATA OVER ETHERNET (AOE) DRIVER |
1247 | M: "Ed L. Cashin" <ecashin@coraid.com> | 1248 | M: "Ed L. Cashin" <ecashin@coraid.com> |
1248 | W: http://www.coraid.com/support/linux | 1249 | W: http://support.coraid.com/support/linux |
1249 | S: Supported | 1250 | S: Supported |
1250 | F: Documentation/aoe/ | 1251 | F: Documentation/aoe/ |
1251 | F: drivers/block/aoe/ | 1252 | F: drivers/block/aoe/ |
@@ -3123,6 +3124,7 @@ T: git git://git.secretlab.ca/git/linux-2.6.git | |||
3123 | F: Documentation/gpio.txt | 3124 | F: Documentation/gpio.txt |
3124 | F: drivers/gpio/ | 3125 | F: drivers/gpio/ |
3125 | F: include/linux/gpio* | 3126 | F: include/linux/gpio* |
3127 | F: include/asm-generic/gpio.h | ||
3126 | 3128 | ||
3127 | GRE DEMULTIPLEXER DRIVER | 3129 | GRE DEMULTIPLEXER DRIVER |
3128 | M: Dmitry Kozlov <xeb@mail.ru> | 3130 | M: Dmitry Kozlov <xeb@mail.ru> |
@@ -5265,7 +5267,7 @@ F: include/linux/i2c-algo-pca.h | |||
5265 | F: include/linux/i2c-pca-platform.h | 5267 | F: include/linux/i2c-pca-platform.h |
5266 | 5268 | ||
5267 | PCDP - PRIMARY CONSOLE AND DEBUG PORT | 5269 | PCDP - PRIMARY CONSOLE AND DEBUG PORT |
5268 | M: Khalid Aziz <khalid.aziz@hp.com> | 5270 | M: Khalid Aziz <khalid@gonehiking.org> |
5269 | S: Maintained | 5271 | S: Maintained |
5270 | F: drivers/firmware/pcdp.* | 5272 | F: drivers/firmware/pcdp.* |
5271 | 5273 | ||
@@ -5554,7 +5556,7 @@ S: Maintained | |||
5554 | W: http://linuxptp.sourceforge.net/ | 5556 | W: http://linuxptp.sourceforge.net/ |
5555 | F: Documentation/ABI/testing/sysfs-ptp | 5557 | F: Documentation/ABI/testing/sysfs-ptp |
5556 | F: Documentation/ptp/* | 5558 | F: Documentation/ptp/* |
5557 | F: drivers/net/gianfar_ptp.c | 5559 | F: drivers/net/ethernet/freescale/gianfar_ptp.c |
5558 | F: drivers/net/phy/dp83640* | 5560 | F: drivers/net/phy/dp83640* |
5559 | F: drivers/ptp/* | 5561 | F: drivers/ptp/* |
5560 | F: include/linux/ptp_cl* | 5562 | F: include/linux/ptp_cl* |
@@ -5986,7 +5988,7 @@ S: Maintained | |||
5986 | F: drivers/tty/serial | 5988 | F: drivers/tty/serial |
5987 | 5989 | ||
5988 | SYNOPSYS DESIGNWARE DMAC DRIVER | 5990 | SYNOPSYS DESIGNWARE DMAC DRIVER |
5989 | M: Viresh Kumar <viresh.linux@gmail.com> | 5991 | M: Viresh Kumar <viresh.linux@gmail.com> |
5990 | S: Maintained | 5992 | S: Maintained |
5991 | F: include/linux/dw_dmac.h | 5993 | F: include/linux/dw_dmac.h |
5992 | F: drivers/dma/dw_dmac_regs.h | 5994 | F: drivers/dma/dw_dmac_regs.h |
@@ -6134,7 +6136,7 @@ S: Maintained | |||
6134 | F: drivers/mmc/host/sdhci-s3c.c | 6136 | F: drivers/mmc/host/sdhci-s3c.c |
6135 | 6137 | ||
6136 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER | 6138 | SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) ST SPEAR DRIVER |
6137 | M: Viresh Kumar <viresh.linux@gmail.com> | 6139 | M: Viresh Kumar <viresh.linux@gmail.com> |
6138 | L: spear-devel@list.st.com | 6140 | L: spear-devel@list.st.com |
6139 | L: linux-mmc@vger.kernel.org | 6141 | L: linux-mmc@vger.kernel.org |
6140 | S: Maintained | 6142 | S: Maintained |
@@ -6499,7 +6501,7 @@ S: Maintained | |||
6499 | F: include/linux/compiler.h | 6501 | F: include/linux/compiler.h |
6500 | 6502 | ||
6501 | SPEAR PLATFORM SUPPORT | 6503 | SPEAR PLATFORM SUPPORT |
6502 | M: Viresh Kumar <viresh.linux@gmail.com> | 6504 | M: Viresh Kumar <viresh.linux@gmail.com> |
6503 | M: Shiraz Hashim <shiraz.hashim@st.com> | 6505 | M: Shiraz Hashim <shiraz.hashim@st.com> |
6504 | L: spear-devel@list.st.com | 6506 | L: spear-devel@list.st.com |
6505 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 6507 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -6508,7 +6510,7 @@ S: Maintained | |||
6508 | F: arch/arm/plat-spear/ | 6510 | F: arch/arm/plat-spear/ |
6509 | 6511 | ||
6510 | SPEAR13XX MACHINE SUPPORT | 6512 | SPEAR13XX MACHINE SUPPORT |
6511 | M: Viresh Kumar <viresh.linux@gmail.com> | 6513 | M: Viresh Kumar <viresh.linux@gmail.com> |
6512 | M: Shiraz Hashim <shiraz.hashim@st.com> | 6514 | M: Shiraz Hashim <shiraz.hashim@st.com> |
6513 | L: spear-devel@list.st.com | 6515 | L: spear-devel@list.st.com |
6514 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 6516 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -6517,7 +6519,7 @@ S: Maintained | |||
6517 | F: arch/arm/mach-spear13xx/ | 6519 | F: arch/arm/mach-spear13xx/ |
6518 | 6520 | ||
6519 | SPEAR3XX MACHINE SUPPORT | 6521 | SPEAR3XX MACHINE SUPPORT |
6520 | M: Viresh Kumar <viresh.linux@gmail.com> | 6522 | M: Viresh Kumar <viresh.linux@gmail.com> |
6521 | M: Shiraz Hashim <shiraz.hashim@st.com> | 6523 | M: Shiraz Hashim <shiraz.hashim@st.com> |
6522 | L: spear-devel@list.st.com | 6524 | L: spear-devel@list.st.com |
6523 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 6525 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -6528,7 +6530,7 @@ F: arch/arm/mach-spear3xx/ | |||
6528 | SPEAR6XX MACHINE SUPPORT | 6530 | SPEAR6XX MACHINE SUPPORT |
6529 | M: Rajeev Kumar <rajeev-dlh.kumar@st.com> | 6531 | M: Rajeev Kumar <rajeev-dlh.kumar@st.com> |
6530 | M: Shiraz Hashim <shiraz.hashim@st.com> | 6532 | M: Shiraz Hashim <shiraz.hashim@st.com> |
6531 | M: Viresh Kumar <viresh.linux@gmail.com> | 6533 | M: Viresh Kumar <viresh.linux@gmail.com> |
6532 | L: spear-devel@list.st.com | 6534 | L: spear-devel@list.st.com |
6533 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 6535 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
6534 | W: http://www.st.com/spear | 6536 | W: http://www.st.com/spear |
@@ -6536,7 +6538,7 @@ S: Maintained | |||
6536 | F: arch/arm/mach-spear6xx/ | 6538 | F: arch/arm/mach-spear6xx/ |
6537 | 6539 | ||
6538 | SPEAR CLOCK FRAMEWORK SUPPORT | 6540 | SPEAR CLOCK FRAMEWORK SUPPORT |
6539 | M: Viresh Kumar <viresh.linux@gmail.com> | 6541 | M: Viresh Kumar <viresh.linux@gmail.com> |
6540 | L: spear-devel@list.st.com | 6542 | L: spear-devel@list.st.com |
6541 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 6543 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
6542 | W: http://www.st.com/spear | 6544 | W: http://www.st.com/spear |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 188c82971ebd..33361505c0cd 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -625,7 +625,7 @@ fail: | |||
625 | return 0; | 625 | return 0; |
626 | } | 626 | } |
627 | 627 | ||
628 | static struct clk *const standard_pmc_clocks[] __initdata = { | 628 | static struct clk *const standard_pmc_clocks[] __initconst = { |
629 | /* four primary clocks */ | 629 | /* four primary clocks */ |
630 | &clk32k, | 630 | &clk32k, |
631 | &main_clk, | 631 | &main_clk, |
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index ac4e003ad863..be3099733b1f 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c | |||
@@ -88,7 +88,7 @@ static struct davinci_mmc_config mmc_config = { | |||
88 | .version = MMC_CTLR_VERSION_1, | 88 | .version = MMC_CTLR_VERSION_1, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static const short sdio1_pins[] __initdata = { | 91 | static const short sdio1_pins[] __initconst = { |
92 | TNETV107X_SDIO1_CLK_1, TNETV107X_SDIO1_CMD_1, | 92 | TNETV107X_SDIO1_CLK_1, TNETV107X_SDIO1_CMD_1, |
93 | TNETV107X_SDIO1_DATA0_1, TNETV107X_SDIO1_DATA1_1, | 93 | TNETV107X_SDIO1_DATA0_1, TNETV107X_SDIO1_DATA1_1, |
94 | TNETV107X_SDIO1_DATA2_1, TNETV107X_SDIO1_DATA3_1, | 94 | TNETV107X_SDIO1_DATA2_1, TNETV107X_SDIO1_DATA3_1, |
@@ -96,12 +96,12 @@ static const short sdio1_pins[] __initdata = { | |||
96 | -1 | 96 | -1 |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static const short uart1_pins[] __initdata = { | 99 | static const short uart1_pins[] __initconst = { |
100 | TNETV107X_UART1_RD, TNETV107X_UART1_TD, | 100 | TNETV107X_UART1_RD, TNETV107X_UART1_TD, |
101 | -1 | 101 | -1 |
102 | }; | 102 | }; |
103 | 103 | ||
104 | static const short ssp_pins[] __initdata = { | 104 | static const short ssp_pins[] __initconst = { |
105 | TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2, | 105 | TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2, |
106 | TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2, | 106 | TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2, |
107 | TNETV107X_SSP1_3, -1 | 107 | TNETV107X_SSP1_3, -1 |
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index deee5c2da754..510648e0394b 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c | |||
@@ -838,7 +838,7 @@ static const struct mux_config da830_pins[] = { | |||
838 | #endif | 838 | #endif |
839 | }; | 839 | }; |
840 | 840 | ||
841 | const short da830_emif25_pins[] __initdata = { | 841 | const short da830_emif25_pins[] __initconst = { |
842 | DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3, | 842 | DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3, |
843 | DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7, | 843 | DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7, |
844 | DA830_EMA_D_8, DA830_EMA_D_9, DA830_EMA_D_10, DA830_EMA_D_11, | 844 | DA830_EMA_D_8, DA830_EMA_D_9, DA830_EMA_D_10, DA830_EMA_D_11, |
@@ -853,19 +853,19 @@ const short da830_emif25_pins[] __initdata = { | |||
853 | -1 | 853 | -1 |
854 | }; | 854 | }; |
855 | 855 | ||
856 | const short da830_spi0_pins[] __initdata = { | 856 | const short da830_spi0_pins[] __initconst = { |
857 | DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA, | 857 | DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA, |
858 | DA830_NSPI0_SCS_0, | 858 | DA830_NSPI0_SCS_0, |
859 | -1 | 859 | -1 |
860 | }; | 860 | }; |
861 | 861 | ||
862 | const short da830_spi1_pins[] __initdata = { | 862 | const short da830_spi1_pins[] __initconst = { |
863 | DA830_SPI1_SOMI_0, DA830_SPI1_SIMO_0, DA830_SPI1_CLK, DA830_NSPI1_ENA, | 863 | DA830_SPI1_SOMI_0, DA830_SPI1_SIMO_0, DA830_SPI1_CLK, DA830_NSPI1_ENA, |
864 | DA830_NSPI1_SCS_0, | 864 | DA830_NSPI1_SCS_0, |
865 | -1 | 865 | -1 |
866 | }; | 866 | }; |
867 | 867 | ||
868 | const short da830_mmc_sd_pins[] __initdata = { | 868 | const short da830_mmc_sd_pins[] __initconst = { |
869 | DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2, | 869 | DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2, |
870 | DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5, | 870 | DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5, |
871 | DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK, | 871 | DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK, |
@@ -873,32 +873,32 @@ const short da830_mmc_sd_pins[] __initdata = { | |||
873 | -1 | 873 | -1 |
874 | }; | 874 | }; |
875 | 875 | ||
876 | const short da830_uart0_pins[] __initdata = { | 876 | const short da830_uart0_pins[] __initconst = { |
877 | DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD, | 877 | DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD, |
878 | -1 | 878 | -1 |
879 | }; | 879 | }; |
880 | 880 | ||
881 | const short da830_uart1_pins[] __initdata = { | 881 | const short da830_uart1_pins[] __initconst = { |
882 | DA830_UART1_RXD, DA830_UART1_TXD, | 882 | DA830_UART1_RXD, DA830_UART1_TXD, |
883 | -1 | 883 | -1 |
884 | }; | 884 | }; |
885 | 885 | ||
886 | const short da830_uart2_pins[] __initdata = { | 886 | const short da830_uart2_pins[] __initconst = { |
887 | DA830_UART2_RXD, DA830_UART2_TXD, | 887 | DA830_UART2_RXD, DA830_UART2_TXD, |
888 | -1 | 888 | -1 |
889 | }; | 889 | }; |
890 | 890 | ||
891 | const short da830_usb20_pins[] __initdata = { | 891 | const short da830_usb20_pins[] __initconst = { |
892 | DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN, | 892 | DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN, |
893 | -1 | 893 | -1 |
894 | }; | 894 | }; |
895 | 895 | ||
896 | const short da830_usb11_pins[] __initdata = { | 896 | const short da830_usb11_pins[] __initconst = { |
897 | DA830_USB_REFCLKIN, | 897 | DA830_USB_REFCLKIN, |
898 | -1 | 898 | -1 |
899 | }; | 899 | }; |
900 | 900 | ||
901 | const short da830_uhpi_pins[] __initdata = { | 901 | const short da830_uhpi_pins[] __initconst = { |
902 | DA830_UHPI_HD_0, DA830_UHPI_HD_1, DA830_UHPI_HD_2, DA830_UHPI_HD_3, | 902 | DA830_UHPI_HD_0, DA830_UHPI_HD_1, DA830_UHPI_HD_2, DA830_UHPI_HD_3, |
903 | DA830_UHPI_HD_4, DA830_UHPI_HD_5, DA830_UHPI_HD_6, DA830_UHPI_HD_7, | 903 | DA830_UHPI_HD_4, DA830_UHPI_HD_5, DA830_UHPI_HD_6, DA830_UHPI_HD_7, |
904 | DA830_UHPI_HD_8, DA830_UHPI_HD_9, DA830_UHPI_HD_10, DA830_UHPI_HD_11, | 904 | DA830_UHPI_HD_8, DA830_UHPI_HD_9, DA830_UHPI_HD_10, DA830_UHPI_HD_11, |
@@ -909,14 +909,14 @@ const short da830_uhpi_pins[] __initdata = { | |||
909 | -1 | 909 | -1 |
910 | }; | 910 | }; |
911 | 911 | ||
912 | const short da830_cpgmac_pins[] __initdata = { | 912 | const short da830_cpgmac_pins[] __initconst = { |
913 | DA830_RMII_TXD_0, DA830_RMII_TXD_1, DA830_RMII_TXEN, DA830_RMII_CRS_DV, | 913 | DA830_RMII_TXD_0, DA830_RMII_TXD_1, DA830_RMII_TXEN, DA830_RMII_CRS_DV, |
914 | DA830_RMII_RXD_0, DA830_RMII_RXD_1, DA830_RMII_RXER, DA830_MDIO_CLK, | 914 | DA830_RMII_RXD_0, DA830_RMII_RXD_1, DA830_RMII_RXER, DA830_MDIO_CLK, |
915 | DA830_MDIO_D, | 915 | DA830_MDIO_D, |
916 | -1 | 916 | -1 |
917 | }; | 917 | }; |
918 | 918 | ||
919 | const short da830_emif3c_pins[] __initdata = { | 919 | const short da830_emif3c_pins[] __initconst = { |
920 | DA830_EMB_SDCKE, DA830_EMB_CLK_GLUE, DA830_EMB_CLK, DA830_NEMB_CS_0, | 920 | DA830_EMB_SDCKE, DA830_EMB_CLK_GLUE, DA830_EMB_CLK, DA830_NEMB_CS_0, |
921 | DA830_NEMB_CAS, DA830_NEMB_RAS, DA830_NEMB_WE, DA830_EMB_BA_1, | 921 | DA830_NEMB_CAS, DA830_NEMB_RAS, DA830_NEMB_WE, DA830_EMB_BA_1, |
922 | DA830_EMB_BA_0, DA830_EMB_A_0, DA830_EMB_A_1, DA830_EMB_A_2, | 922 | DA830_EMB_BA_0, DA830_EMB_A_0, DA830_EMB_A_1, DA830_EMB_A_2, |
@@ -935,7 +935,7 @@ const short da830_emif3c_pins[] __initdata = { | |||
935 | -1 | 935 | -1 |
936 | }; | 936 | }; |
937 | 937 | ||
938 | const short da830_mcasp0_pins[] __initdata = { | 938 | const short da830_mcasp0_pins[] __initconst = { |
939 | DA830_AHCLKX0, DA830_ACLKX0, DA830_AFSX0, | 939 | DA830_AHCLKX0, DA830_ACLKX0, DA830_AFSX0, |
940 | DA830_AHCLKR0, DA830_ACLKR0, DA830_AFSR0, DA830_AMUTE0, | 940 | DA830_AHCLKR0, DA830_ACLKR0, DA830_AFSR0, DA830_AMUTE0, |
941 | DA830_AXR0_0, DA830_AXR0_1, DA830_AXR0_2, DA830_AXR0_3, | 941 | DA830_AXR0_0, DA830_AXR0_1, DA830_AXR0_2, DA830_AXR0_3, |
@@ -945,7 +945,7 @@ const short da830_mcasp0_pins[] __initdata = { | |||
945 | -1 | 945 | -1 |
946 | }; | 946 | }; |
947 | 947 | ||
948 | const short da830_mcasp1_pins[] __initdata = { | 948 | const short da830_mcasp1_pins[] __initconst = { |
949 | DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, | 949 | DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, |
950 | DA830_AHCLKR1, DA830_ACLKR1, DA830_AFSR1, DA830_AMUTE1, | 950 | DA830_AHCLKR1, DA830_ACLKR1, DA830_AFSR1, DA830_AMUTE1, |
951 | DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_3, | 951 | DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_3, |
@@ -954,24 +954,24 @@ const short da830_mcasp1_pins[] __initdata = { | |||
954 | -1 | 954 | -1 |
955 | }; | 955 | }; |
956 | 956 | ||
957 | const short da830_mcasp2_pins[] __initdata = { | 957 | const short da830_mcasp2_pins[] __initconst = { |
958 | DA830_AHCLKX2, DA830_ACLKX2, DA830_AFSX2, | 958 | DA830_AHCLKX2, DA830_ACLKX2, DA830_AFSX2, |
959 | DA830_AHCLKR2, DA830_ACLKR2, DA830_AFSR2, DA830_AMUTE2, | 959 | DA830_AHCLKR2, DA830_ACLKR2, DA830_AFSR2, DA830_AMUTE2, |
960 | DA830_AXR2_0, DA830_AXR2_1, DA830_AXR2_2, DA830_AXR2_3, | 960 | DA830_AXR2_0, DA830_AXR2_1, DA830_AXR2_2, DA830_AXR2_3, |
961 | -1 | 961 | -1 |
962 | }; | 962 | }; |
963 | 963 | ||
964 | const short da830_i2c0_pins[] __initdata = { | 964 | const short da830_i2c0_pins[] __initconst = { |
965 | DA830_I2C0_SDA, DA830_I2C0_SCL, | 965 | DA830_I2C0_SDA, DA830_I2C0_SCL, |
966 | -1 | 966 | -1 |
967 | }; | 967 | }; |
968 | 968 | ||
969 | const short da830_i2c1_pins[] __initdata = { | 969 | const short da830_i2c1_pins[] __initconst = { |
970 | DA830_I2C1_SCL, DA830_I2C1_SDA, | 970 | DA830_I2C1_SCL, DA830_I2C1_SDA, |
971 | -1 | 971 | -1 |
972 | }; | 972 | }; |
973 | 973 | ||
974 | const short da830_lcdcntl_pins[] __initdata = { | 974 | const short da830_lcdcntl_pins[] __initconst = { |
975 | DA830_LCD_D_0, DA830_LCD_D_1, DA830_LCD_D_2, DA830_LCD_D_3, | 975 | DA830_LCD_D_0, DA830_LCD_D_1, DA830_LCD_D_2, DA830_LCD_D_3, |
976 | DA830_LCD_D_4, DA830_LCD_D_5, DA830_LCD_D_6, DA830_LCD_D_7, | 976 | DA830_LCD_D_4, DA830_LCD_D_5, DA830_LCD_D_6, DA830_LCD_D_7, |
977 | DA830_LCD_D_8, DA830_LCD_D_9, DA830_LCD_D_10, DA830_LCD_D_11, | 977 | DA830_LCD_D_8, DA830_LCD_D_9, DA830_LCD_D_10, DA830_LCD_D_11, |
@@ -981,34 +981,34 @@ const short da830_lcdcntl_pins[] __initdata = { | |||
981 | -1 | 981 | -1 |
982 | }; | 982 | }; |
983 | 983 | ||
984 | const short da830_pwm_pins[] __initdata = { | 984 | const short da830_pwm_pins[] __initconst = { |
985 | DA830_ECAP0_APWM0, DA830_ECAP1_APWM1, DA830_EPWM0B, DA830_EPWM0A, | 985 | DA830_ECAP0_APWM0, DA830_ECAP1_APWM1, DA830_EPWM0B, DA830_EPWM0A, |
986 | DA830_EPWMSYNCI, DA830_EPWMSYNC0, DA830_ECAP2_APWM2, DA830_EHRPWMGLUETZ, | 986 | DA830_EPWMSYNCI, DA830_EPWMSYNC0, DA830_ECAP2_APWM2, DA830_EHRPWMGLUETZ, |
987 | DA830_EPWM2B, DA830_EPWM2A, DA830_EPWM1B, DA830_EPWM1A, | 987 | DA830_EPWM2B, DA830_EPWM2A, DA830_EPWM1B, DA830_EPWM1A, |
988 | -1 | 988 | -1 |
989 | }; | 989 | }; |
990 | 990 | ||
991 | const short da830_ecap0_pins[] __initdata = { | 991 | const short da830_ecap0_pins[] __initconst = { |
992 | DA830_ECAP0_APWM0, | 992 | DA830_ECAP0_APWM0, |
993 | -1 | 993 | -1 |
994 | }; | 994 | }; |
995 | 995 | ||
996 | const short da830_ecap1_pins[] __initdata = { | 996 | const short da830_ecap1_pins[] __initconst = { |
997 | DA830_ECAP1_APWM1, | 997 | DA830_ECAP1_APWM1, |
998 | -1 | 998 | -1 |
999 | }; | 999 | }; |
1000 | 1000 | ||
1001 | const short da830_ecap2_pins[] __initdata = { | 1001 | const short da830_ecap2_pins[] __initconst = { |
1002 | DA830_ECAP2_APWM2, | 1002 | DA830_ECAP2_APWM2, |
1003 | -1 | 1003 | -1 |
1004 | }; | 1004 | }; |
1005 | 1005 | ||
1006 | const short da830_eqep0_pins[] __initdata = { | 1006 | const short da830_eqep0_pins[] __initconst = { |
1007 | DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B, | 1007 | DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B, |
1008 | -1 | 1008 | -1 |
1009 | }; | 1009 | }; |
1010 | 1010 | ||
1011 | const short da830_eqep1_pins[] __initdata = { | 1011 | const short da830_eqep1_pins[] __initconst = { |
1012 | DA830_EQEP1I, DA830_EQEP1S, DA830_EQEP1A, DA830_EQEP1B, | 1012 | DA830_EQEP1I, DA830_EQEP1S, DA830_EQEP1A, DA830_EQEP1B, |
1013 | -1 | 1013 | -1 |
1014 | }; | 1014 | }; |
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index b44dc844e15e..6676dee7104e 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c | |||
@@ -576,17 +576,17 @@ static const struct mux_config da850_pins[] = { | |||
576 | #endif | 576 | #endif |
577 | }; | 577 | }; |
578 | 578 | ||
579 | const short da850_i2c0_pins[] __initdata = { | 579 | const short da850_i2c0_pins[] __initconst = { |
580 | DA850_I2C0_SDA, DA850_I2C0_SCL, | 580 | DA850_I2C0_SDA, DA850_I2C0_SCL, |
581 | -1 | 581 | -1 |
582 | }; | 582 | }; |
583 | 583 | ||
584 | const short da850_i2c1_pins[] __initdata = { | 584 | const short da850_i2c1_pins[] __initconst = { |
585 | DA850_I2C1_SCL, DA850_I2C1_SDA, | 585 | DA850_I2C1_SCL, DA850_I2C1_SDA, |
586 | -1 | 586 | -1 |
587 | }; | 587 | }; |
588 | 588 | ||
589 | const short da850_lcdcntl_pins[] __initdata = { | 589 | const short da850_lcdcntl_pins[] __initconst = { |
590 | DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3, | 590 | DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3, |
591 | DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7, | 591 | DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7, |
592 | DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11, | 592 | DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11, |
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index a344a373928b..2448fcf09eb1 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c | |||
@@ -37,8 +37,8 @@ | |||
37 | #include "devices.h" | 37 | #include "devices.h" |
38 | #include "common.h" | 38 | #include "common.h" |
39 | 39 | ||
40 | static const resource_size_t qsd8x50_surf_smc91x_base __initdata = 0x70000300; | 40 | static const resource_size_t qsd8x50_surf_smc91x_base __initconst = 0x70000300; |
41 | static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156; | 41 | static const unsigned qsd8x50_surf_smc91x_gpio __initconst = 156; |
42 | 42 | ||
43 | /* Leave smc91x resources empty here, as we'll fill them in | 43 | /* Leave smc91x resources empty here, as we'll fill them in |
44 | * at run-time: they vary from board to board, and the true | 44 | * at run-time: they vary from board to board, and the true |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index af1ed7d24a1f..e470c6e50acd 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
@@ -76,14 +76,14 @@ struct omap_dss_hwmod_data { | |||
76 | const int id; | 76 | const int id; |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initdata = { | 79 | static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initconst = { |
80 | { "dss_core", "omapdss_dss", -1 }, | 80 | { "dss_core", "omapdss_dss", -1 }, |
81 | { "dss_dispc", "omapdss_dispc", -1 }, | 81 | { "dss_dispc", "omapdss_dispc", -1 }, |
82 | { "dss_rfbi", "omapdss_rfbi", -1 }, | 82 | { "dss_rfbi", "omapdss_rfbi", -1 }, |
83 | { "dss_venc", "omapdss_venc", -1 }, | 83 | { "dss_venc", "omapdss_venc", -1 }, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = { | 86 | static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initconst = { |
87 | { "dss_core", "omapdss_dss", -1 }, | 87 | { "dss_core", "omapdss_dss", -1 }, |
88 | { "dss_dispc", "omapdss_dispc", -1 }, | 88 | { "dss_dispc", "omapdss_dispc", -1 }, |
89 | { "dss_rfbi", "omapdss_rfbi", -1 }, | 89 | { "dss_rfbi", "omapdss_rfbi", -1 }, |
@@ -91,7 +91,7 @@ static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = { | |||
91 | { "dss_dsi1", "omapdss_dsi", 0 }, | 91 | { "dss_dsi1", "omapdss_dsi", 0 }, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = { | 94 | static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = { |
95 | { "dss_core", "omapdss_dss", -1 }, | 95 | { "dss_core", "omapdss_dss", -1 }, |
96 | { "dss_dispc", "omapdss_dispc", -1 }, | 96 | { "dss_dispc", "omapdss_dispc", -1 }, |
97 | { "dss_rfbi", "omapdss_rfbi", -1 }, | 97 | { "dss_rfbi", "omapdss_rfbi", -1 }, |
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index a670a33ad736..37e610dc084e 100644 --- a/arch/arm64/include/asm/compat.h +++ b/arch/arm64/include/asm/compat.h | |||
@@ -55,6 +55,7 @@ typedef s64 compat_s64; | |||
55 | typedef u32 compat_uint_t; | 55 | typedef u32 compat_uint_t; |
56 | typedef u32 compat_ulong_t; | 56 | typedef u32 compat_ulong_t; |
57 | typedef u64 compat_u64; | 57 | typedef u64 compat_u64; |
58 | typedef u32 compat_uptr_t; | ||
58 | 59 | ||
59 | struct compat_timespec { | 60 | struct compat_timespec { |
60 | compat_time_t tv_sec; | 61 | compat_time_t tv_sec; |
@@ -130,6 +131,64 @@ typedef u32 compat_old_sigset_t; | |||
130 | 131 | ||
131 | typedef u32 compat_sigset_word; | 132 | typedef u32 compat_sigset_word; |
132 | 133 | ||
134 | typedef union compat_sigval { | ||
135 | compat_int_t sival_int; | ||
136 | compat_uptr_t sival_ptr; | ||
137 | } compat_sigval_t; | ||
138 | |||
139 | typedef struct compat_siginfo { | ||
140 | int si_signo; | ||
141 | int si_errno; | ||
142 | int si_code; | ||
143 | |||
144 | union { | ||
145 | /* The padding is the same size as AArch64. */ | ||
146 | int _pad[128/sizeof(int) - 3]; | ||
147 | |||
148 | /* kill() */ | ||
149 | struct { | ||
150 | compat_pid_t _pid; /* sender's pid */ | ||
151 | __compat_uid32_t _uid; /* sender's uid */ | ||
152 | } _kill; | ||
153 | |||
154 | /* POSIX.1b timers */ | ||
155 | struct { | ||
156 | compat_timer_t _tid; /* timer id */ | ||
157 | int _overrun; /* overrun count */ | ||
158 | compat_sigval_t _sigval; /* same as below */ | ||
159 | int _sys_private; /* not to be passed to user */ | ||
160 | } _timer; | ||
161 | |||
162 | /* POSIX.1b signals */ | ||
163 | struct { | ||
164 | compat_pid_t _pid; /* sender's pid */ | ||
165 | __compat_uid32_t _uid; /* sender's uid */ | ||
166 | compat_sigval_t _sigval; | ||
167 | } _rt; | ||
168 | |||
169 | /* SIGCHLD */ | ||
170 | struct { | ||
171 | compat_pid_t _pid; /* which child */ | ||
172 | __compat_uid32_t _uid; /* sender's uid */ | ||
173 | int _status; /* exit code */ | ||
174 | compat_clock_t _utime; | ||
175 | compat_clock_t _stime; | ||
176 | } _sigchld; | ||
177 | |||
178 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
179 | struct { | ||
180 | compat_uptr_t _addr; /* faulting insn/memory ref. */ | ||
181 | short _addr_lsb; /* LSB of the reported address */ | ||
182 | } _sigfault; | ||
183 | |||
184 | /* SIGPOLL */ | ||
185 | struct { | ||
186 | compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
187 | int _fd; | ||
188 | } _sigpoll; | ||
189 | } _sifields; | ||
190 | } compat_siginfo_t; | ||
191 | |||
133 | #define COMPAT_OFF_T_MAX 0x7fffffff | 192 | #define COMPAT_OFF_T_MAX 0x7fffffff |
134 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 193 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
135 | 194 | ||
@@ -139,7 +198,6 @@ typedef u32 compat_sigset_word; | |||
139 | * as pointers because the syscall entry code will have | 198 | * as pointers because the syscall entry code will have |
140 | * appropriately converted them already. | 199 | * appropriately converted them already. |
141 | */ | 200 | */ |
142 | typedef u32 compat_uptr_t; | ||
143 | 201 | ||
144 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 202 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
145 | { | 203 | { |
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index ac74c2f261e3..0790a87a4346 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c | |||
@@ -30,59 +30,6 @@ | |||
30 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
31 | #include <asm/unistd.h> | 31 | #include <asm/unistd.h> |
32 | 32 | ||
33 | typedef struct compat_siginfo { | ||
34 | int si_signo; | ||
35 | int si_errno; | ||
36 | int si_code; | ||
37 | |||
38 | union { | ||
39 | /* The padding is the same size as AArch64. */ | ||
40 | int _pad[SI_PAD_SIZE]; | ||
41 | |||
42 | /* kill() */ | ||
43 | struct { | ||
44 | compat_pid_t _pid; /* sender's pid */ | ||
45 | __compat_uid32_t _uid; /* sender's uid */ | ||
46 | } _kill; | ||
47 | |||
48 | /* POSIX.1b timers */ | ||
49 | struct { | ||
50 | compat_timer_t _tid; /* timer id */ | ||
51 | int _overrun; /* overrun count */ | ||
52 | compat_sigval_t _sigval; /* same as below */ | ||
53 | int _sys_private; /* not to be passed to user */ | ||
54 | } _timer; | ||
55 | |||
56 | /* POSIX.1b signals */ | ||
57 | struct { | ||
58 | compat_pid_t _pid; /* sender's pid */ | ||
59 | __compat_uid32_t _uid; /* sender's uid */ | ||
60 | compat_sigval_t _sigval; | ||
61 | } _rt; | ||
62 | |||
63 | /* SIGCHLD */ | ||
64 | struct { | ||
65 | compat_pid_t _pid; /* which child */ | ||
66 | __compat_uid32_t _uid; /* sender's uid */ | ||
67 | int _status; /* exit code */ | ||
68 | compat_clock_t _utime; | ||
69 | compat_clock_t _stime; | ||
70 | } _sigchld; | ||
71 | |||
72 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
73 | struct { | ||
74 | compat_uptr_t _addr; /* faulting insn/memory ref. */ | ||
75 | short _addr_lsb; /* LSB of the reported address */ | ||
76 | } _sigfault; | ||
77 | |||
78 | /* SIGPOLL */ | ||
79 | struct { | ||
80 | compat_long_t _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
81 | int _fd; | ||
82 | } _sigpoll; | ||
83 | } _sifields; | ||
84 | } compat_siginfo_t; | ||
85 | |||
86 | struct compat_sigaction { | 33 | struct compat_sigaction { |
87 | compat_uptr_t sa_handler; | 34 | compat_uptr_t sa_handler; |
88 | compat_ulong_t sa_flags; | 35 | compat_ulong_t sa_flags; |
diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h index 3b3159b710d4..e2c328739808 100644 --- a/arch/avr32/include/asm/elf.h +++ b/arch/avr32/include/asm/elf.h | |||
@@ -102,6 +102,7 @@ typedef struct user_fpu_struct elf_fpregset_t; | |||
102 | 102 | ||
103 | #define ELF_PLATFORM (NULL) | 103 | #define ELF_PLATFORM (NULL) |
104 | 104 | ||
105 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT) | 105 | #define SET_PERSONALITY(ex) \ |
106 | set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK))) | ||
106 | 107 | ||
107 | #endif /* __ASM_AVR32_ELF_H */ | 108 | #endif /* __ASM_AVR32_ELF_H */ |
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h index e6c6812a9abd..14bc98ff668f 100644 --- a/arch/blackfin/include/asm/elf.h +++ b/arch/blackfin/include/asm/elf.h | |||
@@ -132,6 +132,7 @@ do { \ | |||
132 | 132 | ||
133 | #define ELF_PLATFORM (NULL) | 133 | #define ELF_PLATFORM (NULL) |
134 | 134 | ||
135 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 135 | #define SET_PERSONALITY(ex) \ |
136 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
136 | 137 | ||
137 | #endif | 138 | #endif |
diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h index f4552db20b4a..32b997126adf 100644 --- a/arch/c6x/include/asm/elf.h +++ b/arch/c6x/include/asm/elf.h | |||
@@ -77,7 +77,8 @@ do { \ | |||
77 | 77 | ||
78 | #define ELF_PLATFORM (NULL) | 78 | #define ELF_PLATFORM (NULL) |
79 | 79 | ||
80 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 80 | #define SET_PERSONALITY(ex) \ |
81 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
81 | 82 | ||
82 | /* C6X specific section types */ | 83 | /* C6X specific section types */ |
83 | #define SHT_C6000_UNWIND 0x70000001 | 84 | #define SHT_C6000_UNWIND 0x70000001 |
diff --git a/arch/cris/include/asm/elf.h b/arch/cris/include/asm/elf.h index 8a3d8e2b33c1..8182f2dc89d0 100644 --- a/arch/cris/include/asm/elf.h +++ b/arch/cris/include/asm/elf.h | |||
@@ -86,6 +86,7 @@ typedef unsigned long elf_fpregset_t; | |||
86 | 86 | ||
87 | #define ELF_PLATFORM (NULL) | 87 | #define ELF_PLATFORM (NULL) |
88 | 88 | ||
89 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 89 | #define SET_PERSONALITY(ex) \ |
90 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
90 | 91 | ||
91 | #endif | 92 | #endif |
diff --git a/arch/frv/include/asm/elf.h b/arch/frv/include/asm/elf.h index c3819804a74b..9ccbc80f0b11 100644 --- a/arch/frv/include/asm/elf.h +++ b/arch/frv/include/asm/elf.h | |||
@@ -137,6 +137,7 @@ do { \ | |||
137 | 137 | ||
138 | #define ELF_PLATFORM (NULL) | 138 | #define ELF_PLATFORM (NULL) |
139 | 139 | ||
140 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 140 | #define SET_PERSONALITY(ex) \ |
141 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
141 | 142 | ||
142 | #endif | 143 | #endif |
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c index 5fa3889d858b..0b579927439d 100644 --- a/arch/frv/kernel/pm.c +++ b/arch/frv/kernel/pm.c | |||
@@ -153,23 +153,22 @@ static int user_atoi(char __user *ubuf, size_t len) | |||
153 | static int sysctl_pm_do_suspend(ctl_table *ctl, int write, | 153 | static int sysctl_pm_do_suspend(ctl_table *ctl, int write, |
154 | void __user *buffer, size_t *lenp, loff_t *fpos) | 154 | void __user *buffer, size_t *lenp, loff_t *fpos) |
155 | { | 155 | { |
156 | int retval, mode; | 156 | int mode; |
157 | 157 | ||
158 | if (*lenp <= 0) | 158 | if (*lenp <= 0) |
159 | return -EIO; | 159 | return -EIO; |
160 | 160 | ||
161 | mode = user_atoi(buffer, *lenp); | 161 | mode = user_atoi(buffer, *lenp); |
162 | if ((mode != 1) && (mode != 5)) | 162 | switch (mode) { |
163 | return -EINVAL; | 163 | case 1: |
164 | return pm_do_suspend(); | ||
164 | 165 | ||
165 | if (retval == 0) { | 166 | case 5: |
166 | if (mode == 5) | 167 | return pm_do_bus_sleep(); |
167 | retval = pm_do_bus_sleep(); | ||
168 | else | ||
169 | retval = pm_do_suspend(); | ||
170 | } | ||
171 | 168 | ||
172 | return retval; | 169 | default: |
170 | return -EINVAL; | ||
171 | } | ||
173 | } | 172 | } |
174 | 173 | ||
175 | static int try_set_cmode(int new_cmode) | 174 | static int try_set_cmode(int new_cmode) |
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index 75cf7f4b2fa8..1f1e5efb3385 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c | |||
@@ -184,7 +184,7 @@ static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = { | |||
184 | [6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, | 184 | [6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 }, |
185 | }; | 185 | }; |
186 | 186 | ||
187 | static const struct clock_cmode __pminitdata *clock_cmodes; | 187 | static const struct clock_cmode __pminitconst *clock_cmodes; |
188 | static int __pminitdata clock_doubled; | 188 | static int __pminitdata clock_doubled; |
189 | 189 | ||
190 | static struct uart_port __pminitdata __frv_uart0 = { | 190 | static struct uart_port __pminitdata __frv_uart0 = { |
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c index 20f6497b2cd5..c677b9d81d30 100644 --- a/arch/frv/mb93090-mb00/pci-irq.c +++ b/arch/frv/mb93090-mb00/pci-irq.c | |||
@@ -28,7 +28,7 @@ | |||
28 | * | 28 | * |
29 | */ | 29 | */ |
30 | 30 | ||
31 | static const uint8_t __initdata pci_bus0_irq_routing[32][4] = { | 31 | static const uint8_t __initconst pci_bus0_irq_routing[32][4] = { |
32 | [0 ] = { IRQ_FPGA_MB86943_PCI_INTA }, | 32 | [0 ] = { IRQ_FPGA_MB86943_PCI_INTA }, |
33 | [16] = { IRQ_FPGA_RTL8029_INTA }, | 33 | [16] = { IRQ_FPGA_RTL8029_INTA }, |
34 | [17] = { IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB }, | 34 | [17] = { IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB }, |
diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h index c24fa250d653..41193c396bff 100644 --- a/arch/h8300/include/asm/elf.h +++ b/arch/h8300/include/asm/elf.h | |||
@@ -54,7 +54,8 @@ typedef unsigned long elf_fpregset_t; | |||
54 | 54 | ||
55 | #define ELF_PLATFORM (NULL) | 55 | #define ELF_PLATFORM (NULL) |
56 | 56 | ||
57 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 57 | #define SET_PERSONALITY(ex) \ |
58 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
58 | 59 | ||
59 | #define R_H8_NONE 0 | 60 | #define R_H8_NONE 0 |
60 | #define R_H8_DIR32 1 | 61 | #define R_H8_DIR32 1 |
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index aaf5e5a48f93..4bdc7311784e 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c | |||
@@ -51,6 +51,7 @@ asmlinkage void syscall_print(void *dummy,...) | |||
51 | * Do a system call from kernel instead of calling sys_execve so we | 51 | * Do a system call from kernel instead of calling sys_execve so we |
52 | * end up with proper pt_regs. | 52 | * end up with proper pt_regs. |
53 | */ | 53 | */ |
54 | asmlinkage | ||
54 | int kernel_execve(const char *filename, | 55 | int kernel_execve(const char *filename, |
55 | const char *const argv[], | 56 | const char *const argv[], |
56 | const char *const envp[]) | 57 | const char *const envp[]) |
diff --git a/arch/h8300/kernel/timer/itu.c b/arch/h8300/kernel/timer/itu.c index a2ae5e952137..0a8b5cd5bf38 100644 --- a/arch/h8300/kernel/timer/itu.c +++ b/arch/h8300/kernel/timer/itu.c | |||
@@ -62,7 +62,7 @@ static struct irqaction itu_irq = { | |||
62 | .flags = IRQF_DISABLED | IRQF_TIMER, | 62 | .flags = IRQF_DISABLED | IRQF_TIMER, |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static const int __initdata divide_rate[] = {1, 2, 4, 8}; | 65 | static const int __initconst divide_rate[] = {1, 2, 4, 8}; |
66 | 66 | ||
67 | void __init h8300_timer_setup(void) | 67 | void __init h8300_timer_setup(void) |
68 | { | 68 | { |
diff --git a/arch/h8300/kernel/timer/timer16.c b/arch/h8300/kernel/timer/timer16.c index ae0d38161139..462d9f581719 100644 --- a/arch/h8300/kernel/timer/timer16.c +++ b/arch/h8300/kernel/timer/timer16.c | |||
@@ -57,7 +57,7 @@ static struct irqaction timer16_irq = { | |||
57 | .flags = IRQF_DISABLED | IRQF_TIMER, | 57 | .flags = IRQF_DISABLED | IRQF_TIMER, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static const int __initdata divide_rate[] = {1, 2, 4, 8}; | 60 | static const int __initconst divide_rate[] = {1, 2, 4, 8}; |
61 | 61 | ||
62 | void __init h8300_timer_setup(void) | 62 | void __init h8300_timer_setup(void) |
63 | { | 63 | { |
diff --git a/arch/h8300/kernel/timer/timer8.c b/arch/h8300/kernel/timer/timer8.c index 7a1533fad47d..505f3415b40f 100644 --- a/arch/h8300/kernel/timer/timer8.c +++ b/arch/h8300/kernel/timer/timer8.c | |||
@@ -77,7 +77,7 @@ static struct irqaction timer8_irq = { | |||
77 | .flags = IRQF_DISABLED | IRQF_TIMER, | 77 | .flags = IRQF_DISABLED | IRQF_TIMER, |
78 | }; | 78 | }; |
79 | 79 | ||
80 | static const int __initdata divide_rate[] = {8, 64, 8192}; | 80 | static const int __initconst divide_rate[] = {8, 64, 8192}; |
81 | 81 | ||
82 | void __init h8300_timer_setup(void) | 82 | void __init h8300_timer_setup(void) |
83 | { | 83 | { |
diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c index 2193a2e2859a..0350f6204ecf 100644 --- a/arch/h8300/kernel/timer/tpu.c +++ b/arch/h8300/kernel/timer/tpu.c | |||
@@ -66,7 +66,7 @@ static struct irqaction tpu_irq = { | |||
66 | .flags = IRQF_DISABLED | IRQF_TIMER, | 66 | .flags = IRQF_DISABLED | IRQF_TIMER, |
67 | }; | 67 | }; |
68 | 68 | ||
69 | static const int __initdata divide_rate[] = { | 69 | static const int __initconst divide_rate[] = { |
70 | #if CONFIG_H8300_TPU_CH == 0 | 70 | #if CONFIG_H8300_TPU_CH == 0 |
71 | 1,4,16,64,0,0,0,0, | 71 | 1,4,16,64,0,0,0,0, |
72 | #elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5) | 72 | #elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5) |
diff --git a/arch/h8300/platform/h8300h/irq.c b/arch/h8300/platform/h8300h/irq.c index bc4f51bceef5..0a50353e09d5 100644 --- a/arch/h8300/platform/h8300h/irq.c +++ b/arch/h8300/platform/h8300h/irq.c | |||
@@ -14,14 +14,14 @@ | |||
14 | #include <asm/gpio-internal.h> | 14 | #include <asm/gpio-internal.h> |
15 | #include <asm/regs306x.h> | 15 | #include <asm/regs306x.h> |
16 | 16 | ||
17 | const int __initdata h8300_saved_vectors[] = { | 17 | const int __initconst h8300_saved_vectors[] = { |
18 | #if defined(CONFIG_GDB_DEBUG) | 18 | #if defined(CONFIG_GDB_DEBUG) |
19 | TRAP3_VEC, /* TRAPA #3 is GDB breakpoint */ | 19 | TRAP3_VEC, /* TRAPA #3 is GDB breakpoint */ |
20 | #endif | 20 | #endif |
21 | -1, | 21 | -1, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | const h8300_vector __initdata h8300_trap_table[] = { | 24 | const h8300_vector __initconst h8300_trap_table[] = { |
25 | 0, 0, 0, 0, 0, 0, 0, 0, | 25 | 0, 0, 0, 0, 0, 0, 0, 0, |
26 | system_call, | 26 | system_call, |
27 | 0, | 27 | 0, |
diff --git a/arch/h8300/platform/h8s/irq.c b/arch/h8300/platform/h8s/irq.c index 7b5f29febc07..f3a5511c16b1 100644 --- a/arch/h8300/platform/h8s/irq.c +++ b/arch/h8300/platform/h8s/irq.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <asm/regs267x.h> | 18 | #include <asm/regs267x.h> |
19 | 19 | ||
20 | /* saved vector list */ | 20 | /* saved vector list */ |
21 | const int __initdata h8300_saved_vectors[]={ | 21 | const int __initconst h8300_saved_vectors[] = { |
22 | #if defined(CONFIG_GDB_DEBUG) | 22 | #if defined(CONFIG_GDB_DEBUG) |
23 | TRACE_VEC, | 23 | TRACE_VEC, |
24 | TRAP3_VEC, | 24 | TRAP3_VEC, |
@@ -27,7 +27,7 @@ const int __initdata h8300_saved_vectors[]={ | |||
27 | }; | 27 | }; |
28 | 28 | ||
29 | /* trap entry table */ | 29 | /* trap entry table */ |
30 | const H8300_VECTOR __initdata h8300_trap_table[] = { | 30 | const H8300_VECTOR __initconst h8300_trap_table[] = { |
31 | 0,0,0,0,0, | 31 | 0,0,0,0,0, |
32 | trace_break, /* TRACE */ | 32 | trace_break, /* TRACE */ |
33 | 0,0, | 33 | 0,0, |
diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h index 37976a0d3650..82b499621e05 100644 --- a/arch/hexagon/include/asm/elf.h +++ b/arch/hexagon/include/asm/elf.h | |||
@@ -217,7 +217,8 @@ do { \ | |||
217 | #define ELF_PLATFORM (NULL) | 217 | #define ELF_PLATFORM (NULL) |
218 | 218 | ||
219 | #ifdef __KERNEL__ | 219 | #ifdef __KERNEL__ |
220 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 220 | #define SET_PERSONALITY(ex) \ |
221 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
221 | #endif | 222 | #endif |
222 | 223 | ||
223 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | 224 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 |
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c index 3bb12230721f..01f479ee1c43 100644 --- a/arch/ia64/xen/irq_xen.c +++ b/arch/ia64/xen/irq_xen.c | |||
@@ -433,7 +433,7 @@ xen_resend_irq(unsigned int vector) | |||
433 | (void)resend_irq_on_evtchn(vector); | 433 | (void)resend_irq_on_evtchn(vector); |
434 | } | 434 | } |
435 | 435 | ||
436 | const struct pv_irq_ops xen_irq_ops __initdata = { | 436 | const struct pv_irq_ops xen_irq_ops __initconst = { |
437 | .register_ipi = xen_register_ipi, | 437 | .register_ipi = xen_register_ipi, |
438 | 438 | ||
439 | .assign_irq_vector = xen_assign_irq_vector, | 439 | .assign_irq_vector = xen_assign_irq_vector, |
diff --git a/arch/ia64/xen/irq_xen.h b/arch/ia64/xen/irq_xen.h index 26110f330c87..1778517b90fe 100644 --- a/arch/ia64/xen/irq_xen.h +++ b/arch/ia64/xen/irq_xen.h | |||
@@ -27,7 +27,7 @@ extern void (*late_time_init)(void); | |||
27 | extern char xen_event_callback; | 27 | extern char xen_event_callback; |
28 | void __init xen_init_IRQ(void); | 28 | void __init xen_init_IRQ(void); |
29 | 29 | ||
30 | extern const struct pv_irq_ops xen_irq_ops __initdata; | 30 | extern const struct pv_irq_ops xen_irq_ops __initconst; |
31 | extern void xen_smp_intr_init(void); | 31 | extern void xen_smp_intr_init(void); |
32 | extern void xen_send_ipi(int cpu, int vec); | 32 | extern void xen_send_ipi(int cpu, int vec); |
33 | 33 | ||
diff --git a/arch/m32r/include/asm/elf.h b/arch/m32r/include/asm/elf.h index b8da7d0574d2..70896161c636 100644 --- a/arch/m32r/include/asm/elf.h +++ b/arch/m32r/include/asm/elf.h | |||
@@ -128,6 +128,7 @@ typedef elf_fpreg_t elf_fpregset_t; | |||
128 | intent than poking at uname or /proc/cpuinfo. */ | 128 | intent than poking at uname or /proc/cpuinfo. */ |
129 | #define ELF_PLATFORM (NULL) | 129 | #define ELF_PLATFORM (NULL) |
130 | 130 | ||
131 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 131 | #define SET_PERSONALITY(ex) \ |
132 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
132 | 133 | ||
133 | #endif /* _ASM_M32R__ELF_H */ | 134 | #endif /* _ASM_M32R__ELF_H */ |
diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h index e9b7cda59744..f83c1d0a87cf 100644 --- a/arch/m68k/include/asm/elf.h +++ b/arch/m68k/include/asm/elf.h | |||
@@ -113,6 +113,7 @@ typedef struct user_m68kfp_struct elf_fpregset_t; | |||
113 | 113 | ||
114 | #define ELF_PLATFORM (NULL) | 114 | #define ELF_PLATFORM (NULL) |
115 | 115 | ||
116 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 116 | #define SET_PERSONALITY(ex) \ |
117 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
117 | 118 | ||
118 | #endif | 119 | #endif |
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h index 834849f59ae8..640ddd4b6a9b 100644 --- a/arch/microblaze/include/asm/elf.h +++ b/arch/microblaze/include/asm/elf.h | |||
@@ -116,7 +116,8 @@ do { \ | |||
116 | } while (0) | 116 | } while (0) |
117 | 117 | ||
118 | #ifdef __KERNEL__ | 118 | #ifdef __KERNEL__ |
119 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT) | 119 | #define SET_PERSONALITY(ex) \ |
120 | set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK))) | ||
120 | #endif | 121 | #endif |
121 | 122 | ||
122 | #endif /* __uClinux__ */ | 123 | #endif /* __uClinux__ */ |
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index feb05258a4d1..dd18e4b761a8 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c | |||
@@ -632,7 +632,7 @@ static struct board_info __initdata board_DWVS0 = { | |||
632 | /* | 632 | /* |
633 | * all boards | 633 | * all boards |
634 | */ | 634 | */ |
635 | static const struct board_info __initdata *bcm963xx_boards[] = { | 635 | static const struct board_info __initconst *bcm963xx_boards[] = { |
636 | #ifdef CONFIG_BCM63XX_CPU_6328 | 636 | #ifdef CONFIG_BCM63XX_CPU_6328 |
637 | &board_96328avng, | 637 | &board_96328avng, |
638 | #endif | 638 | #endif |
diff --git a/arch/mips/include/asm/compat-signal.h b/arch/mips/include/asm/compat-signal.h index 368a99e5c3e1..6599a901b63e 100644 --- a/arch/mips/include/asm/compat-signal.h +++ b/arch/mips/include/asm/compat-signal.h | |||
@@ -10,68 +10,6 @@ | |||
10 | 10 | ||
11 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
12 | 12 | ||
13 | #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) | ||
14 | |||
15 | typedef struct compat_siginfo { | ||
16 | int si_signo; | ||
17 | int si_code; | ||
18 | int si_errno; | ||
19 | |||
20 | union { | ||
21 | int _pad[SI_PAD_SIZE32]; | ||
22 | |||
23 | /* kill() */ | ||
24 | struct { | ||
25 | compat_pid_t _pid; /* sender's pid */ | ||
26 | compat_uid_t _uid; /* sender's uid */ | ||
27 | } _kill; | ||
28 | |||
29 | /* SIGCHLD */ | ||
30 | struct { | ||
31 | compat_pid_t _pid; /* which child */ | ||
32 | compat_uid_t _uid; /* sender's uid */ | ||
33 | int _status; /* exit code */ | ||
34 | compat_clock_t _utime; | ||
35 | compat_clock_t _stime; | ||
36 | } _sigchld; | ||
37 | |||
38 | /* IRIX SIGCHLD */ | ||
39 | struct { | ||
40 | compat_pid_t _pid; /* which child */ | ||
41 | compat_clock_t _utime; | ||
42 | int _status; /* exit code */ | ||
43 | compat_clock_t _stime; | ||
44 | } _irix_sigchld; | ||
45 | |||
46 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
47 | struct { | ||
48 | s32 _addr; /* faulting insn/memory ref. */ | ||
49 | } _sigfault; | ||
50 | |||
51 | /* SIGPOLL, SIGXFSZ (To do ...) */ | ||
52 | struct { | ||
53 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
54 | int _fd; | ||
55 | } _sigpoll; | ||
56 | |||
57 | /* POSIX.1b timers */ | ||
58 | struct { | ||
59 | timer_t _tid; /* timer id */ | ||
60 | int _overrun; /* overrun count */ | ||
61 | compat_sigval_t _sigval;/* same as below */ | ||
62 | int _sys_private; /* not to be passed to user */ | ||
63 | } _timer; | ||
64 | |||
65 | /* POSIX.1b signals */ | ||
66 | struct { | ||
67 | compat_pid_t _pid; /* sender's pid */ | ||
68 | compat_uid_t _uid; /* sender's uid */ | ||
69 | compat_sigval_t _sigval; | ||
70 | } _rt; | ||
71 | |||
72 | } _sifields; | ||
73 | } compat_siginfo_t; | ||
74 | |||
75 | static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d, | 13 | static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d, |
76 | const sigset_t *s) | 14 | const sigset_t *s) |
77 | { | 15 | { |
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index b77df0366ee6..58277e0e9cd4 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h | |||
@@ -43,6 +43,7 @@ typedef s64 compat_s64; | |||
43 | typedef u32 compat_uint_t; | 43 | typedef u32 compat_uint_t; |
44 | typedef u32 compat_ulong_t; | 44 | typedef u32 compat_ulong_t; |
45 | typedef u64 compat_u64; | 45 | typedef u64 compat_u64; |
46 | typedef u32 compat_uptr_t; | ||
46 | 47 | ||
47 | struct compat_timespec { | 48 | struct compat_timespec { |
48 | compat_time_t tv_sec; | 49 | compat_time_t tv_sec; |
@@ -124,6 +125,73 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */ | |||
124 | 125 | ||
125 | typedef u32 compat_sigset_word; | 126 | typedef u32 compat_sigset_word; |
126 | 127 | ||
128 | typedef union compat_sigval { | ||
129 | compat_int_t sival_int; | ||
130 | compat_uptr_t sival_ptr; | ||
131 | } compat_sigval_t; | ||
132 | |||
133 | #define SI_PAD_SIZE32 (128/sizeof(int) - 3) | ||
134 | |||
135 | typedef struct compat_siginfo { | ||
136 | int si_signo; | ||
137 | int si_code; | ||
138 | int si_errno; | ||
139 | |||
140 | union { | ||
141 | int _pad[SI_PAD_SIZE32]; | ||
142 | |||
143 | /* kill() */ | ||
144 | struct { | ||
145 | compat_pid_t _pid; /* sender's pid */ | ||
146 | __compat_uid_t _uid; /* sender's uid */ | ||
147 | } _kill; | ||
148 | |||
149 | /* SIGCHLD */ | ||
150 | struct { | ||
151 | compat_pid_t _pid; /* which child */ | ||
152 | __compat_uid_t _uid; /* sender's uid */ | ||
153 | int _status; /* exit code */ | ||
154 | compat_clock_t _utime; | ||
155 | compat_clock_t _stime; | ||
156 | } _sigchld; | ||
157 | |||
158 | /* IRIX SIGCHLD */ | ||
159 | struct { | ||
160 | compat_pid_t _pid; /* which child */ | ||
161 | compat_clock_t _utime; | ||
162 | int _status; /* exit code */ | ||
163 | compat_clock_t _stime; | ||
164 | } _irix_sigchld; | ||
165 | |||
166 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
167 | struct { | ||
168 | s32 _addr; /* faulting insn/memory ref. */ | ||
169 | } _sigfault; | ||
170 | |||
171 | /* SIGPOLL, SIGXFSZ (To do ...) */ | ||
172 | struct { | ||
173 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
174 | int _fd; | ||
175 | } _sigpoll; | ||
176 | |||
177 | /* POSIX.1b timers */ | ||
178 | struct { | ||
179 | timer_t _tid; /* timer id */ | ||
180 | int _overrun; /* overrun count */ | ||
181 | compat_sigval_t _sigval;/* same as below */ | ||
182 | int _sys_private; /* not to be passed to user */ | ||
183 | } _timer; | ||
184 | |||
185 | /* POSIX.1b signals */ | ||
186 | struct { | ||
187 | compat_pid_t _pid; /* sender's pid */ | ||
188 | __compat_uid_t _uid; /* sender's uid */ | ||
189 | compat_sigval_t _sigval; | ||
190 | } _rt; | ||
191 | |||
192 | } _sifields; | ||
193 | } compat_siginfo_t; | ||
194 | |||
127 | #define COMPAT_OFF_T_MAX 0x7fffffff | 195 | #define COMPAT_OFF_T_MAX 0x7fffffff |
128 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 196 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
129 | 197 | ||
@@ -133,7 +201,6 @@ typedef u32 compat_sigset_word; | |||
133 | * as pointers because the syscall entry code will have | 201 | * as pointers because the syscall entry code will have |
134 | * appropriately converted them already. | 202 | * appropriately converted them already. |
135 | */ | 203 | */ |
136 | typedef u32 compat_uptr_t; | ||
137 | 204 | ||
138 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 205 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
139 | { | 206 | { |
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index c5dfb2c87d44..4b0c347d7a82 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c | |||
@@ -58,7 +58,7 @@ union octeon_pci_address { | |||
58 | } s; | 58 | } s; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | int __initdata (*octeon_pcibios_map_irq)(const struct pci_dev *dev, | 61 | int __initconst (*octeon_pcibios_map_irq)(const struct pci_dev *dev, |
62 | u8 slot, u8 pin); | 62 | u8 slot, u8 pin); |
63 | enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; | 63 | enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; |
64 | 64 | ||
diff --git a/arch/mn10300/Makefile b/arch/mn10300/Makefile index 33188b6e81e4..a3d0fef3b126 100644 --- a/arch/mn10300/Makefile +++ b/arch/mn10300/Makefile | |||
@@ -26,7 +26,7 @@ CHECKFLAGS += | |||
26 | PROCESSOR := unset | 26 | PROCESSOR := unset |
27 | UNIT := unset | 27 | UNIT := unset |
28 | 28 | ||
29 | KBUILD_CFLAGS += -mam33 -mmem-funcs -DCPU=AM33 | 29 | KBUILD_CFLAGS += -mam33 -DCPU=AM33 $(call cc-option,-mmem-funcs,) |
30 | KBUILD_AFLAGS += -mam33 -DCPU=AM33 | 30 | KBUILD_AFLAGS += -mam33 -DCPU=AM33 |
31 | 31 | ||
32 | ifeq ($(CONFIG_MN10300_CURRENT_IN_E2),y) | 32 | ifeq ($(CONFIG_MN10300_CURRENT_IN_E2),y) |
diff --git a/arch/mn10300/include/asm/elf.h b/arch/mn10300/include/asm/elf.h index 8157c9267f42..4ebd6b3a0a1e 100644 --- a/arch/mn10300/include/asm/elf.h +++ b/arch/mn10300/include/asm/elf.h | |||
@@ -151,7 +151,8 @@ do { \ | |||
151 | #define ELF_PLATFORM (NULL) | 151 | #define ELF_PLATFORM (NULL) |
152 | 152 | ||
153 | #ifdef __KERNEL__ | 153 | #ifdef __KERNEL__ |
154 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 154 | #define SET_PERSONALITY(ex) \ |
155 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
155 | #endif | 156 | #endif |
156 | 157 | ||
157 | #endif /* _ASM_ELF_H */ | 158 | #endif /* _ASM_ELF_H */ |
diff --git a/arch/openrisc/include/asm/elf.h b/arch/openrisc/include/asm/elf.h index a8fe2c513070..225a7ff320ad 100644 --- a/arch/openrisc/include/asm/elf.h +++ b/arch/openrisc/include/asm/elf.h | |||
@@ -110,7 +110,8 @@ extern void dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt); | |||
110 | 110 | ||
111 | #define ELF_PLATFORM (NULL) | 111 | #define ELF_PLATFORM (NULL) |
112 | 112 | ||
113 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 113 | #define SET_PERSONALITY(ex) \ |
114 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
114 | 115 | ||
115 | #endif /* __KERNEL__ */ | 116 | #endif /* __KERNEL__ */ |
116 | #endif | 117 | #endif |
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 3ff21b536f28..b87438bb3384 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -13,6 +13,7 @@ config PARISC | |||
13 | select HAVE_PERF_EVENTS | 13 | select HAVE_PERF_EVENTS |
14 | select GENERIC_ATOMIC64 if !64BIT | 14 | select GENERIC_ATOMIC64 if !64BIT |
15 | select HAVE_GENERIC_HARDIRQS | 15 | select HAVE_GENERIC_HARDIRQS |
16 | select BROKEN_RODATA | ||
16 | select GENERIC_IRQ_PROBE | 17 | select GENERIC_IRQ_PROBE |
17 | select GENERIC_PCI_IOMAP | 18 | select GENERIC_PCI_IOMAP |
18 | select IRQ_PER_CPU | 19 | select IRQ_PER_CPU |
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 760f331d4fa3..db7a662691a8 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h | |||
@@ -36,6 +36,7 @@ typedef s64 compat_s64; | |||
36 | typedef u32 compat_uint_t; | 36 | typedef u32 compat_uint_t; |
37 | typedef u32 compat_ulong_t; | 37 | typedef u32 compat_ulong_t; |
38 | typedef u64 compat_u64; | 38 | typedef u64 compat_u64; |
39 | typedef u32 compat_uptr_t; | ||
39 | 40 | ||
40 | struct compat_timespec { | 41 | struct compat_timespec { |
41 | compat_time_t tv_sec; | 42 | compat_time_t tv_sec; |
@@ -127,6 +128,63 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */ | |||
127 | 128 | ||
128 | typedef u32 compat_sigset_word; | 129 | typedef u32 compat_sigset_word; |
129 | 130 | ||
131 | typedef union compat_sigval { | ||
132 | compat_int_t sival_int; | ||
133 | compat_uptr_t sival_ptr; | ||
134 | } compat_sigval_t; | ||
135 | |||
136 | typedef struct compat_siginfo { | ||
137 | int si_signo; | ||
138 | int si_errno; | ||
139 | int si_code; | ||
140 | |||
141 | union { | ||
142 | int _pad[128/sizeof(int) - 3]; | ||
143 | |||
144 | /* kill() */ | ||
145 | struct { | ||
146 | unsigned int _pid; /* sender's pid */ | ||
147 | unsigned int _uid; /* sender's uid */ | ||
148 | } _kill; | ||
149 | |||
150 | /* POSIX.1b timers */ | ||
151 | struct { | ||
152 | compat_timer_t _tid; /* timer id */ | ||
153 | int _overrun; /* overrun count */ | ||
154 | char _pad[sizeof(unsigned int) - sizeof(int)]; | ||
155 | compat_sigval_t _sigval; /* same as below */ | ||
156 | int _sys_private; /* not to be passed to user */ | ||
157 | } _timer; | ||
158 | |||
159 | /* POSIX.1b signals */ | ||
160 | struct { | ||
161 | unsigned int _pid; /* sender's pid */ | ||
162 | unsigned int _uid; /* sender's uid */ | ||
163 | compat_sigval_t _sigval; | ||
164 | } _rt; | ||
165 | |||
166 | /* SIGCHLD */ | ||
167 | struct { | ||
168 | unsigned int _pid; /* which child */ | ||
169 | unsigned int _uid; /* sender's uid */ | ||
170 | int _status; /* exit code */ | ||
171 | compat_clock_t _utime; | ||
172 | compat_clock_t _stime; | ||
173 | } _sigchld; | ||
174 | |||
175 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
176 | struct { | ||
177 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
178 | } _sigfault; | ||
179 | |||
180 | /* SIGPOLL */ | ||
181 | struct { | ||
182 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
183 | int _fd; | ||
184 | } _sigpoll; | ||
185 | } _sifields; | ||
186 | } compat_siginfo_t; | ||
187 | |||
130 | #define COMPAT_OFF_T_MAX 0x7fffffff | 188 | #define COMPAT_OFF_T_MAX 0x7fffffff |
131 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 189 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
132 | 190 | ||
@@ -136,7 +194,6 @@ typedef u32 compat_sigset_word; | |||
136 | * as pointers because the syscall entry code will have | 194 | * as pointers because the syscall entry code will have |
137 | * appropriately converted them already. | 195 | * appropriately converted them already. |
138 | */ | 196 | */ |
139 | typedef u32 compat_uptr_t; | ||
140 | 197 | ||
141 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 198 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
142 | { | 199 | { |
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index c7800846422c..08a88b5349a2 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h | |||
@@ -55,58 +55,6 @@ struct k_sigaction32 { | |||
55 | struct compat_sigaction sa; | 55 | struct compat_sigaction sa; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | typedef struct compat_siginfo { | ||
59 | int si_signo; | ||
60 | int si_errno; | ||
61 | int si_code; | ||
62 | |||
63 | union { | ||
64 | int _pad[((128/sizeof(int)) - 3)]; | ||
65 | |||
66 | /* kill() */ | ||
67 | struct { | ||
68 | unsigned int _pid; /* sender's pid */ | ||
69 | unsigned int _uid; /* sender's uid */ | ||
70 | } _kill; | ||
71 | |||
72 | /* POSIX.1b timers */ | ||
73 | struct { | ||
74 | compat_timer_t _tid; /* timer id */ | ||
75 | int _overrun; /* overrun count */ | ||
76 | char _pad[sizeof(unsigned int) - sizeof(int)]; | ||
77 | compat_sigval_t _sigval; /* same as below */ | ||
78 | int _sys_private; /* not to be passed to user */ | ||
79 | } _timer; | ||
80 | |||
81 | /* POSIX.1b signals */ | ||
82 | struct { | ||
83 | unsigned int _pid; /* sender's pid */ | ||
84 | unsigned int _uid; /* sender's uid */ | ||
85 | compat_sigval_t _sigval; | ||
86 | } _rt; | ||
87 | |||
88 | /* SIGCHLD */ | ||
89 | struct { | ||
90 | unsigned int _pid; /* which child */ | ||
91 | unsigned int _uid; /* sender's uid */ | ||
92 | int _status; /* exit code */ | ||
93 | compat_clock_t _utime; | ||
94 | compat_clock_t _stime; | ||
95 | } _sigchld; | ||
96 | |||
97 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
98 | struct { | ||
99 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
100 | } _sigfault; | ||
101 | |||
102 | /* SIGPOLL */ | ||
103 | struct { | ||
104 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
105 | int _fd; | ||
106 | } _sigpoll; | ||
107 | } _sifields; | ||
108 | } compat_siginfo_t; | ||
109 | |||
110 | int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); | 58 | int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); |
111 | int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); | 59 | int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); |
112 | 60 | ||
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index efdc92618b38..dc2cf9c6d9e6 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h | |||
@@ -288,6 +288,16 @@ static __inline__ int test_bit_le(unsigned long nr, | |||
288 | return (tmp[nr >> 3] >> (nr & 7)) & 1; | 288 | return (tmp[nr >> 3] >> (nr & 7)) & 1; |
289 | } | 289 | } |
290 | 290 | ||
291 | static inline void set_bit_le(int nr, void *addr) | ||
292 | { | ||
293 | set_bit(nr ^ BITOP_LE_SWIZZLE, addr); | ||
294 | } | ||
295 | |||
296 | static inline void clear_bit_le(int nr, void *addr) | ||
297 | { | ||
298 | clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); | ||
299 | } | ||
300 | |||
291 | static inline void __set_bit_le(int nr, void *addr) | 301 | static inline void __set_bit_le(int nr, void *addr) |
292 | { | 302 | { |
293 | __set_bit(nr ^ BITOP_LE_SWIZZLE, addr); | 303 | __set_bit(nr ^ BITOP_LE_SWIZZLE, addr); |
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index 88e602f6430d..84fdf6857c31 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h | |||
@@ -38,6 +38,7 @@ typedef s64 compat_s64; | |||
38 | typedef u32 compat_uint_t; | 38 | typedef u32 compat_uint_t; |
39 | typedef u32 compat_ulong_t; | 39 | typedef u32 compat_ulong_t; |
40 | typedef u64 compat_u64; | 40 | typedef u64 compat_u64; |
41 | typedef u32 compat_uptr_t; | ||
41 | 42 | ||
42 | struct compat_timespec { | 43 | struct compat_timespec { |
43 | compat_time_t tv_sec; | 44 | compat_time_t tv_sec; |
@@ -114,6 +115,64 @@ typedef u32 compat_old_sigset_t; | |||
114 | 115 | ||
115 | typedef u32 compat_sigset_word; | 116 | typedef u32 compat_sigset_word; |
116 | 117 | ||
118 | typedef union compat_sigval { | ||
119 | compat_int_t sival_int; | ||
120 | compat_uptr_t sival_ptr; | ||
121 | } compat_sigval_t; | ||
122 | |||
123 | #define SI_PAD_SIZE32 (128/sizeof(int) - 3) | ||
124 | |||
125 | typedef struct compat_siginfo { | ||
126 | int si_signo; | ||
127 | int si_errno; | ||
128 | int si_code; | ||
129 | |||
130 | union { | ||
131 | int _pad[SI_PAD_SIZE32]; | ||
132 | |||
133 | /* kill() */ | ||
134 | struct { | ||
135 | compat_pid_t _pid; /* sender's pid */ | ||
136 | __compat_uid_t _uid; /* sender's uid */ | ||
137 | } _kill; | ||
138 | |||
139 | /* POSIX.1b timers */ | ||
140 | struct { | ||
141 | compat_timer_t _tid; /* timer id */ | ||
142 | int _overrun; /* overrun count */ | ||
143 | compat_sigval_t _sigval; /* same as below */ | ||
144 | int _sys_private; /* not to be passed to user */ | ||
145 | } _timer; | ||
146 | |||
147 | /* POSIX.1b signals */ | ||
148 | struct { | ||
149 | compat_pid_t _pid; /* sender's pid */ | ||
150 | __compat_uid_t _uid; /* sender's uid */ | ||
151 | compat_sigval_t _sigval; | ||
152 | } _rt; | ||
153 | |||
154 | /* SIGCHLD */ | ||
155 | struct { | ||
156 | compat_pid_t _pid; /* which child */ | ||
157 | __compat_uid_t _uid; /* sender's uid */ | ||
158 | int _status; /* exit code */ | ||
159 | compat_clock_t _utime; | ||
160 | compat_clock_t _stime; | ||
161 | } _sigchld; | ||
162 | |||
163 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
164 | struct { | ||
165 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
166 | } _sigfault; | ||
167 | |||
168 | /* SIGPOLL */ | ||
169 | struct { | ||
170 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
171 | int _fd; | ||
172 | } _sigpoll; | ||
173 | } _sifields; | ||
174 | } compat_siginfo_t; | ||
175 | |||
117 | #define COMPAT_OFF_T_MAX 0x7fffffff | 176 | #define COMPAT_OFF_T_MAX 0x7fffffff |
118 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 177 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
119 | 178 | ||
@@ -123,7 +182,6 @@ typedef u32 compat_sigset_word; | |||
123 | * as pointers because the syscall entry code will have | 182 | * as pointers because the syscall entry code will have |
124 | * appropriately converted them already. | 183 | * appropriately converted them already. |
125 | */ | 184 | */ |
126 | typedef u32 compat_uptr_t; | ||
127 | 185 | ||
128 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 186 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
129 | { | 187 | { |
diff --git a/arch/powerpc/include/asm/siginfo.h b/arch/powerpc/include/asm/siginfo.h index 49495b0534ed..ccce3ef5cd86 100644 --- a/arch/powerpc/include/asm/siginfo.h +++ b/arch/powerpc/include/asm/siginfo.h | |||
@@ -10,7 +10,6 @@ | |||
10 | 10 | ||
11 | #ifdef __powerpc64__ | 11 | #ifdef __powerpc64__ |
12 | # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 12 | # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
13 | # define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) | ||
14 | #endif | 13 | #endif |
15 | 14 | ||
16 | #include <asm-generic/siginfo.h> | 15 | #include <asm-generic/siginfo.h> |
diff --git a/arch/powerpc/kernel/ppc32.h b/arch/powerpc/kernel/ppc32.h index dc16aefe1dd0..02fb0ee26093 100644 --- a/arch/powerpc/kernel/ppc32.h +++ b/arch/powerpc/kernel/ppc32.h | |||
@@ -16,57 +16,6 @@ | |||
16 | 16 | ||
17 | /* These are here to support 32-bit syscalls on a 64-bit kernel. */ | 17 | /* These are here to support 32-bit syscalls on a 64-bit kernel. */ |
18 | 18 | ||
19 | typedef struct compat_siginfo { | ||
20 | int si_signo; | ||
21 | int si_errno; | ||
22 | int si_code; | ||
23 | |||
24 | union { | ||
25 | int _pad[SI_PAD_SIZE32]; | ||
26 | |||
27 | /* kill() */ | ||
28 | struct { | ||
29 | compat_pid_t _pid; /* sender's pid */ | ||
30 | compat_uid_t _uid; /* sender's uid */ | ||
31 | } _kill; | ||
32 | |||
33 | /* POSIX.1b timers */ | ||
34 | struct { | ||
35 | compat_timer_t _tid; /* timer id */ | ||
36 | int _overrun; /* overrun count */ | ||
37 | compat_sigval_t _sigval; /* same as below */ | ||
38 | int _sys_private; /* not to be passed to user */ | ||
39 | } _timer; | ||
40 | |||
41 | /* POSIX.1b signals */ | ||
42 | struct { | ||
43 | compat_pid_t _pid; /* sender's pid */ | ||
44 | compat_uid_t _uid; /* sender's uid */ | ||
45 | compat_sigval_t _sigval; | ||
46 | } _rt; | ||
47 | |||
48 | /* SIGCHLD */ | ||
49 | struct { | ||
50 | compat_pid_t _pid; /* which child */ | ||
51 | compat_uid_t _uid; /* sender's uid */ | ||
52 | int _status; /* exit code */ | ||
53 | compat_clock_t _utime; | ||
54 | compat_clock_t _stime; | ||
55 | } _sigchld; | ||
56 | |||
57 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
58 | struct { | ||
59 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
60 | } _sigfault; | ||
61 | |||
62 | /* SIGPOLL */ | ||
63 | struct { | ||
64 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
65 | int _fd; | ||
66 | } _sigpoll; | ||
67 | } _sifields; | ||
68 | } compat_siginfo_t; | ||
69 | |||
70 | #define __old_sigaction32 old_sigaction32 | 19 | #define __old_sigaction32 old_sigaction32 |
71 | 20 | ||
72 | struct __old_sigaction32 { | 21 | struct __old_sigaction32 { |
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c index 97612068fae3..969dddcf3320 100644 --- a/arch/powerpc/platforms/40x/ppc40x_simple.c +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c | |||
@@ -50,7 +50,7 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe); | |||
50 | * Again, if your board needs to do things differently then create a | 50 | * Again, if your board needs to do things differently then create a |
51 | * board.c file for it rather than adding it to this list. | 51 | * board.c file for it rather than adding it to this list. |
52 | */ | 52 | */ |
53 | static const char *board[] __initdata = { | 53 | static const char * const board[] __initconst = { |
54 | "amcc,acadia", | 54 | "amcc,acadia", |
55 | "amcc,haleakala", | 55 | "amcc,haleakala", |
56 | "amcc,kilauea", | 56 | "amcc,kilauea", |
diff --git a/arch/powerpc/platforms/512x/mpc5121_generic.c b/arch/powerpc/platforms/512x/mpc5121_generic.c index 926731f1ff01..ca1ca6669990 100644 --- a/arch/powerpc/platforms/512x/mpc5121_generic.c +++ b/arch/powerpc/platforms/512x/mpc5121_generic.c | |||
@@ -26,7 +26,7 @@ | |||
26 | /* | 26 | /* |
27 | * list of supported boards | 27 | * list of supported boards |
28 | */ | 28 | */ |
29 | static const char *board[] __initdata = { | 29 | static const char * const board[] __initconst = { |
30 | "prt,prtlvt", | 30 | "prt,prtlvt", |
31 | NULL | 31 | NULL |
32 | }; | 32 | }; |
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c index 01ffa64d2aa7..448d862bcf3d 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c | |||
@@ -172,7 +172,7 @@ static void __init lite5200_setup_arch(void) | |||
172 | mpc52xx_setup_pci(); | 172 | mpc52xx_setup_pci(); |
173 | } | 173 | } |
174 | 174 | ||
175 | static const char *board[] __initdata = { | 175 | static const char * const board[] __initconst = { |
176 | "fsl,lite5200", | 176 | "fsl,lite5200", |
177 | "fsl,lite5200b", | 177 | "fsl,lite5200b", |
178 | NULL, | 178 | NULL, |
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index 17d91b7da315..070d315dd6cd 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c | |||
@@ -232,7 +232,7 @@ static void __init media5200_setup_arch(void) | |||
232 | } | 232 | } |
233 | 233 | ||
234 | /* list of the supported boards */ | 234 | /* list of the supported boards */ |
235 | static const char *board[] __initdata = { | 235 | static const char * const board[] __initconst = { |
236 | "fsl,media5200", | 236 | "fsl,media5200", |
237 | NULL | 237 | NULL |
238 | }; | 238 | }; |
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c index 16c9c9cbbb7f..eca1f0960fff 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c | |||
@@ -60,7 +60,7 @@ static void __init mpc837x_rdb_setup_arch(void) | |||
60 | 60 | ||
61 | machine_device_initcall(mpc837x_rdb, mpc83xx_declare_of_platform_devices); | 61 | machine_device_initcall(mpc837x_rdb, mpc83xx_declare_of_platform_devices); |
62 | 62 | ||
63 | static const char *board[] __initdata = { | 63 | static const char * const board[] __initconst = { |
64 | "fsl,mpc8377rdb", | 64 | "fsl,mpc8377rdb", |
65 | "fsl,mpc8378rdb", | 65 | "fsl,mpc8378rdb", |
66 | "fsl,mpc8379rdb", | 66 | "fsl,mpc8379rdb", |
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index 3e70a2035e53..b62fa87521a3 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c | |||
@@ -125,7 +125,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, | |||
125 | 125 | ||
126 | machine_device_initcall(tqm85xx, mpc85xx_common_publish_devices); | 126 | machine_device_initcall(tqm85xx, mpc85xx_common_publish_devices); |
127 | 127 | ||
128 | static const char *board[] __initdata = { | 128 | static const char * const board[] __initconst = { |
129 | "tqc,tqm8540", | 129 | "tqc,tqm8540", |
130 | "tqc,tqm8541", | 130 | "tqc,tqm8541", |
131 | "tqc,tqm8548", | 131 | "tqc,tqm8548", |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 234f1d859cea..a34a9d612fc0 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
@@ -65,6 +65,7 @@ typedef s64 compat_s64; | |||
65 | typedef u32 compat_uint_t; | 65 | typedef u32 compat_uint_t; |
66 | typedef u32 compat_ulong_t; | 66 | typedef u32 compat_ulong_t; |
67 | typedef u64 compat_u64; | 67 | typedef u64 compat_u64; |
68 | typedef u32 compat_uptr_t; | ||
68 | 69 | ||
69 | struct compat_timespec { | 70 | struct compat_timespec { |
70 | compat_time_t tv_sec; | 71 | compat_time_t tv_sec; |
@@ -144,6 +145,79 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */ | |||
144 | 145 | ||
145 | typedef u32 compat_sigset_word; | 146 | typedef u32 compat_sigset_word; |
146 | 147 | ||
148 | typedef union compat_sigval { | ||
149 | compat_int_t sival_int; | ||
150 | compat_uptr_t sival_ptr; | ||
151 | } compat_sigval_t; | ||
152 | |||
153 | typedef struct compat_siginfo { | ||
154 | int si_signo; | ||
155 | int si_errno; | ||
156 | int si_code; | ||
157 | |||
158 | union { | ||
159 | int _pad[128/sizeof(int) - 3]; | ||
160 | |||
161 | /* kill() */ | ||
162 | struct { | ||
163 | pid_t _pid; /* sender's pid */ | ||
164 | uid_t _uid; /* sender's uid */ | ||
165 | } _kill; | ||
166 | |||
167 | /* POSIX.1b timers */ | ||
168 | struct { | ||
169 | compat_timer_t _tid; /* timer id */ | ||
170 | int _overrun; /* overrun count */ | ||
171 | compat_sigval_t _sigval; /* same as below */ | ||
172 | int _sys_private; /* not to be passed to user */ | ||
173 | } _timer; | ||
174 | |||
175 | /* POSIX.1b signals */ | ||
176 | struct { | ||
177 | pid_t _pid; /* sender's pid */ | ||
178 | uid_t _uid; /* sender's uid */ | ||
179 | compat_sigval_t _sigval; | ||
180 | } _rt; | ||
181 | |||
182 | /* SIGCHLD */ | ||
183 | struct { | ||
184 | pid_t _pid; /* which child */ | ||
185 | uid_t _uid; /* sender's uid */ | ||
186 | int _status;/* exit code */ | ||
187 | compat_clock_t _utime; | ||
188 | compat_clock_t _stime; | ||
189 | } _sigchld; | ||
190 | |||
191 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
192 | struct { | ||
193 | __u32 _addr; /* faulting insn/memory ref. - pointer */ | ||
194 | } _sigfault; | ||
195 | |||
196 | /* SIGPOLL */ | ||
197 | struct { | ||
198 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
199 | int _fd; | ||
200 | } _sigpoll; | ||
201 | } _sifields; | ||
202 | } compat_siginfo_t; | ||
203 | |||
204 | /* | ||
205 | * How these fields are to be accessed. | ||
206 | */ | ||
207 | #define si_pid _sifields._kill._pid | ||
208 | #define si_uid _sifields._kill._uid | ||
209 | #define si_status _sifields._sigchld._status | ||
210 | #define si_utime _sifields._sigchld._utime | ||
211 | #define si_stime _sifields._sigchld._stime | ||
212 | #define si_value _sifields._rt._sigval | ||
213 | #define si_int _sifields._rt._sigval.sival_int | ||
214 | #define si_ptr _sifields._rt._sigval.sival_ptr | ||
215 | #define si_addr _sifields._sigfault._addr | ||
216 | #define si_band _sifields._sigpoll._band | ||
217 | #define si_fd _sifields._sigpoll._fd | ||
218 | #define si_tid _sifields._timer._tid | ||
219 | #define si_overrun _sifields._timer._overrun | ||
220 | |||
147 | #define COMPAT_OFF_T_MAX 0x7fffffff | 221 | #define COMPAT_OFF_T_MAX 0x7fffffff |
148 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 222 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
149 | 223 | ||
@@ -153,7 +227,6 @@ typedef u32 compat_sigset_word; | |||
153 | * as pointers because the syscall entry code will have | 227 | * as pointers because the syscall entry code will have |
154 | * appropriately converted them already. | 228 | * appropriately converted them already. |
155 | */ | 229 | */ |
156 | typedef u32 compat_uptr_t; | ||
157 | 230 | ||
158 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 231 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
159 | { | 232 | { |
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index 9635d759c2b9..90887bd98cf0 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h | |||
@@ -23,74 +23,6 @@ struct old_sigaction32 { | |||
23 | __u32 sa_flags; | 23 | __u32 sa_flags; |
24 | __u32 sa_restorer; /* Another 32 bit pointer */ | 24 | __u32 sa_restorer; /* Another 32 bit pointer */ |
25 | }; | 25 | }; |
26 | |||
27 | typedef struct compat_siginfo { | ||
28 | int si_signo; | ||
29 | int si_errno; | ||
30 | int si_code; | ||
31 | |||
32 | union { | ||
33 | int _pad[((128/sizeof(int)) - 3)]; | ||
34 | |||
35 | /* kill() */ | ||
36 | struct { | ||
37 | pid_t _pid; /* sender's pid */ | ||
38 | uid_t _uid; /* sender's uid */ | ||
39 | } _kill; | ||
40 | |||
41 | /* POSIX.1b timers */ | ||
42 | struct { | ||
43 | compat_timer_t _tid; /* timer id */ | ||
44 | int _overrun; /* overrun count */ | ||
45 | compat_sigval_t _sigval; /* same as below */ | ||
46 | int _sys_private; /* not to be passed to user */ | ||
47 | } _timer; | ||
48 | |||
49 | /* POSIX.1b signals */ | ||
50 | struct { | ||
51 | pid_t _pid; /* sender's pid */ | ||
52 | uid_t _uid; /* sender's uid */ | ||
53 | compat_sigval_t _sigval; | ||
54 | } _rt; | ||
55 | |||
56 | /* SIGCHLD */ | ||
57 | struct { | ||
58 | pid_t _pid; /* which child */ | ||
59 | uid_t _uid; /* sender's uid */ | ||
60 | int _status;/* exit code */ | ||
61 | compat_clock_t _utime; | ||
62 | compat_clock_t _stime; | ||
63 | } _sigchld; | ||
64 | |||
65 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
66 | struct { | ||
67 | __u32 _addr; /* faulting insn/memory ref. - pointer */ | ||
68 | } _sigfault; | ||
69 | |||
70 | /* SIGPOLL */ | ||
71 | struct { | ||
72 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
73 | int _fd; | ||
74 | } _sigpoll; | ||
75 | } _sifields; | ||
76 | } compat_siginfo_t; | ||
77 | |||
78 | /* | ||
79 | * How these fields are to be accessed. | ||
80 | */ | ||
81 | #define si_pid _sifields._kill._pid | ||
82 | #define si_uid _sifields._kill._uid | ||
83 | #define si_status _sifields._sigchld._status | ||
84 | #define si_utime _sifields._sigchld._utime | ||
85 | #define si_stime _sifields._sigchld._stime | ||
86 | #define si_value _sifields._rt._sigval | ||
87 | #define si_int _sifields._rt._sigval.sival_int | ||
88 | #define si_ptr _sifields._rt._sigval.sival_ptr | ||
89 | #define si_addr _sifields._sigfault._addr | ||
90 | #define si_band _sifields._sigpoll._band | ||
91 | #define si_fd _sifields._sigpoll._fd | ||
92 | #define si_tid _sifields._timer._tid | ||
93 | #define si_overrun _sifields._timer._overrun | ||
94 | 26 | ||
95 | /* asm/sigcontext.h */ | 27 | /* asm/sigcontext.h */ |
96 | typedef union | 28 | typedef union |
diff --git a/arch/score/Kconfig b/arch/score/Kconfig index ba0f412920be..461c23747491 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig | |||
@@ -5,6 +5,7 @@ config SCORE | |||
5 | select HAVE_GENERIC_HARDIRQS | 5 | select HAVE_GENERIC_HARDIRQS |
6 | select GENERIC_IRQ_SHOW | 6 | select GENERIC_IRQ_SHOW |
7 | select GENERIC_IOMAP | 7 | select GENERIC_IOMAP |
8 | select GENERIC_ATOMIC64 | ||
8 | select HAVE_MEMBLOCK | 9 | select HAVE_MEMBLOCK |
9 | select HAVE_MEMBLOCK_NODE_MAP | 10 | select HAVE_MEMBLOCK_NODE_MAP |
10 | select ARCH_DISCARD_MEMBLOCK | 11 | select ARCH_DISCARD_MEMBLOCK |
diff --git a/arch/score/include/asm/elf.h b/arch/score/include/asm/elf.h index f478ce94181f..5d566c7a0af2 100644 --- a/arch/score/include/asm/elf.h +++ b/arch/score/include/asm/elf.h | |||
@@ -54,7 +54,7 @@ typedef elf_fpreg_t elf_fpregset_t; | |||
54 | 54 | ||
55 | #define SET_PERSONALITY(ex) \ | 55 | #define SET_PERSONALITY(ex) \ |
56 | do { \ | 56 | do { \ |
57 | set_personality(PER_LINUX); \ | 57 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \ |
58 | } while (0) | 58 | } while (0) |
59 | 59 | ||
60 | struct task_struct; | 60 | struct task_struct; |
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c index e478bf9a7e91..21e867974066 100644 --- a/arch/score/kernel/sys_score.c +++ b/arch/score/kernel/sys_score.c | |||
@@ -112,6 +112,7 @@ score_execve(struct pt_regs *regs) | |||
112 | * Do a system call from kernel instead of calling sys_execve so we | 112 | * Do a system call from kernel instead of calling sys_execve so we |
113 | * end up with proper pt_regs. | 113 | * end up with proper pt_regs. |
114 | */ | 114 | */ |
115 | asmlinkage | ||
115 | int kernel_execve(const char *filename, | 116 | int kernel_execve(const char *filename, |
116 | const char *const argv[], | 117 | const char *const argv[], |
117 | const char *const envp[]) | 118 | const char *const envp[]) |
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h index f38112be67d2..37924afa8d8a 100644 --- a/arch/sh/include/asm/elf.h +++ b/arch/sh/include/asm/elf.h | |||
@@ -183,7 +183,8 @@ do { \ | |||
183 | } while (0) | 183 | } while (0) |
184 | #endif | 184 | #endif |
185 | 185 | ||
186 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT) | 186 | #define SET_PERSONALITY(ex) \ |
187 | set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK))) | ||
187 | 188 | ||
188 | #ifdef CONFIG_VSYSCALL | 189 | #ifdef CONFIG_VSYSCALL |
189 | /* vDSO has arch_setup_additional_pages */ | 190 | /* vDSO has arch_setup_additional_pages */ |
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 0cf60a628814..73a23f4617a3 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h | |||
@@ -134,7 +134,7 @@ __BUILD_MEMORY_STRING(__raw_, q, u64) | |||
134 | * load/store instructions. sh_io_port_base is the virtual address to | 134 | * load/store instructions. sh_io_port_base is the virtual address to |
135 | * which all ports are being mapped. | 135 | * which all ports are being mapped. |
136 | */ | 136 | */ |
137 | extern const unsigned long sh_io_port_base; | 137 | extern unsigned long sh_io_port_base; |
138 | 138 | ||
139 | static inline void __set_io_port_base(unsigned long pbase) | 139 | static inline void __set_io_port_base(unsigned long pbase) |
140 | { | 140 | { |
diff --git a/arch/sh/kernel/ioport.c b/arch/sh/kernel/ioport.c index e3ad6103e7c1..cca14ba84a37 100644 --- a/arch/sh/kernel/ioport.c +++ b/arch/sh/kernel/ioport.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | 13 | ||
14 | const unsigned long sh_io_port_base __read_mostly = -1; | 14 | unsigned long sh_io_port_base __read_mostly = -1; |
15 | EXPORT_SYMBOL(sh_io_port_base); | 15 | EXPORT_SYMBOL(sh_io_port_base); |
16 | 16 | ||
17 | void __iomem *__ioport_map(unsigned long addr, unsigned int size) | 17 | void __iomem *__ioport_map(unsigned long addr, unsigned int size) |
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index b8be20d42a0a..cef99fbc0a21 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h | |||
@@ -36,6 +36,7 @@ typedef s64 compat_s64; | |||
36 | typedef u32 compat_uint_t; | 36 | typedef u32 compat_uint_t; |
37 | typedef u32 compat_ulong_t; | 37 | typedef u32 compat_ulong_t; |
38 | typedef u64 compat_u64; | 38 | typedef u64 compat_u64; |
39 | typedef u32 compat_uptr_t; | ||
39 | 40 | ||
40 | struct compat_timespec { | 41 | struct compat_timespec { |
41 | compat_time_t tv_sec; | 42 | compat_time_t tv_sec; |
@@ -147,6 +148,65 @@ typedef u32 compat_old_sigset_t; | |||
147 | 148 | ||
148 | typedef u32 compat_sigset_word; | 149 | typedef u32 compat_sigset_word; |
149 | 150 | ||
151 | typedef union compat_sigval { | ||
152 | compat_int_t sival_int; | ||
153 | compat_uptr_t sival_ptr; | ||
154 | } compat_sigval_t; | ||
155 | |||
156 | #define SI_PAD_SIZE32 (128/sizeof(int) - 3) | ||
157 | |||
158 | typedef struct compat_siginfo { | ||
159 | int si_signo; | ||
160 | int si_errno; | ||
161 | int si_code; | ||
162 | |||
163 | union { | ||
164 | int _pad[SI_PAD_SIZE32]; | ||
165 | |||
166 | /* kill() */ | ||
167 | struct { | ||
168 | compat_pid_t _pid; /* sender's pid */ | ||
169 | unsigned int _uid; /* sender's uid */ | ||
170 | } _kill; | ||
171 | |||
172 | /* POSIX.1b timers */ | ||
173 | struct { | ||
174 | compat_timer_t _tid; /* timer id */ | ||
175 | int _overrun; /* overrun count */ | ||
176 | compat_sigval_t _sigval; /* same as below */ | ||
177 | int _sys_private; /* not to be passed to user */ | ||
178 | } _timer; | ||
179 | |||
180 | /* POSIX.1b signals */ | ||
181 | struct { | ||
182 | compat_pid_t _pid; /* sender's pid */ | ||
183 | unsigned int _uid; /* sender's uid */ | ||
184 | compat_sigval_t _sigval; | ||
185 | } _rt; | ||
186 | |||
187 | /* SIGCHLD */ | ||
188 | struct { | ||
189 | compat_pid_t _pid; /* which child */ | ||
190 | unsigned int _uid; /* sender's uid */ | ||
191 | int _status; /* exit code */ | ||
192 | compat_clock_t _utime; | ||
193 | compat_clock_t _stime; | ||
194 | } _sigchld; | ||
195 | |||
196 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
197 | struct { | ||
198 | u32 _addr; /* faulting insn/memory ref. */ | ||
199 | int _trapno; | ||
200 | } _sigfault; | ||
201 | |||
202 | /* SIGPOLL */ | ||
203 | struct { | ||
204 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
205 | int _fd; | ||
206 | } _sigpoll; | ||
207 | } _sifields; | ||
208 | } compat_siginfo_t; | ||
209 | |||
150 | #define COMPAT_OFF_T_MAX 0x7fffffff | 210 | #define COMPAT_OFF_T_MAX 0x7fffffff |
151 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 211 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
152 | 212 | ||
@@ -156,7 +216,6 @@ typedef u32 compat_sigset_word; | |||
156 | * as pointers because the syscall entry code will have | 216 | * as pointers because the syscall entry code will have |
157 | * appropriately converted them already. | 217 | * appropriately converted them already. |
158 | */ | 218 | */ |
159 | typedef u32 compat_uptr_t; | ||
160 | 219 | ||
161 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 220 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
162 | { | 221 | { |
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h index 2d4d755cba9e..ac74a2c98e6d 100644 --- a/arch/sparc/include/asm/elf_32.h +++ b/arch/sparc/include/asm/elf_32.h | |||
@@ -128,6 +128,7 @@ typedef struct { | |||
128 | 128 | ||
129 | #define ELF_PLATFORM (NULL) | 129 | #define ELF_PLATFORM (NULL) |
130 | 130 | ||
131 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX) | 131 | #define SET_PERSONALITY(ex) \ |
132 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | ||
132 | 133 | ||
133 | #endif /* !(__ASMSPARC_ELF_H) */ | 134 | #endif /* !(__ASMSPARC_ELF_H) */ |
diff --git a/arch/sparc/include/asm/siginfo.h b/arch/sparc/include/asm/siginfo.h index 215900fce21b..dbc182c438b4 100644 --- a/arch/sparc/include/asm/siginfo.h +++ b/arch/sparc/include/asm/siginfo.h | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | #if defined(__sparc__) && defined(__arch64__) | 4 | #if defined(__sparc__) && defined(__arch64__) |
5 | 5 | ||
6 | #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) | ||
7 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | 6 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) |
8 | #define __ARCH_SI_BAND_T int | 7 | #define __ARCH_SI_BAND_T int |
9 | 8 | ||
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index a53e0a5fd3a3..53e48f721ce3 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c | |||
@@ -54,58 +54,6 @@ struct signal_frame32 { | |||
54 | /* __siginfo_rwin_t * */u32 rwin_save; | 54 | /* __siginfo_rwin_t * */u32 rwin_save; |
55 | } __attribute__((aligned(8))); | 55 | } __attribute__((aligned(8))); |
56 | 56 | ||
57 | typedef struct compat_siginfo{ | ||
58 | int si_signo; | ||
59 | int si_errno; | ||
60 | int si_code; | ||
61 | |||
62 | union { | ||
63 | int _pad[SI_PAD_SIZE32]; | ||
64 | |||
65 | /* kill() */ | ||
66 | struct { | ||
67 | compat_pid_t _pid; /* sender's pid */ | ||
68 | unsigned int _uid; /* sender's uid */ | ||
69 | } _kill; | ||
70 | |||
71 | /* POSIX.1b timers */ | ||
72 | struct { | ||
73 | compat_timer_t _tid; /* timer id */ | ||
74 | int _overrun; /* overrun count */ | ||
75 | compat_sigval_t _sigval; /* same as below */ | ||
76 | int _sys_private; /* not to be passed to user */ | ||
77 | } _timer; | ||
78 | |||
79 | /* POSIX.1b signals */ | ||
80 | struct { | ||
81 | compat_pid_t _pid; /* sender's pid */ | ||
82 | unsigned int _uid; /* sender's uid */ | ||
83 | compat_sigval_t _sigval; | ||
84 | } _rt; | ||
85 | |||
86 | /* SIGCHLD */ | ||
87 | struct { | ||
88 | compat_pid_t _pid; /* which child */ | ||
89 | unsigned int _uid; /* sender's uid */ | ||
90 | int _status; /* exit code */ | ||
91 | compat_clock_t _utime; | ||
92 | compat_clock_t _stime; | ||
93 | } _sigchld; | ||
94 | |||
95 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */ | ||
96 | struct { | ||
97 | u32 _addr; /* faulting insn/memory ref. */ | ||
98 | int _trapno; | ||
99 | } _sigfault; | ||
100 | |||
101 | /* SIGPOLL */ | ||
102 | struct { | ||
103 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
104 | int _fd; | ||
105 | } _sigpoll; | ||
106 | } _sifields; | ||
107 | }compat_siginfo_t; | ||
108 | |||
109 | struct rt_signal_frame32 { | 57 | struct rt_signal_frame32 { |
110 | struct sparc_stackf32 ss; | 58 | struct sparc_stackf32 ss; |
111 | compat_siginfo_t info; | 59 | compat_siginfo_t info; |
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h index 6e74450ff0a1..3063e6fc8daa 100644 --- a/arch/tile/include/asm/compat.h +++ b/arch/tile/include/asm/compat.h | |||
@@ -110,6 +110,68 @@ struct compat_flock64 { | |||
110 | 110 | ||
111 | typedef u32 compat_sigset_word; | 111 | typedef u32 compat_sigset_word; |
112 | 112 | ||
113 | typedef union compat_sigval { | ||
114 | compat_int_t sival_int; | ||
115 | compat_uptr_t sival_ptr; | ||
116 | } compat_sigval_t; | ||
117 | |||
118 | #define COMPAT_SI_PAD_SIZE (128/sizeof(int) - 3) | ||
119 | |||
120 | typedef struct compat_siginfo { | ||
121 | int si_signo; | ||
122 | int si_errno; | ||
123 | int si_code; | ||
124 | |||
125 | union { | ||
126 | int _pad[COMPAT_SI_PAD_SIZE]; | ||
127 | |||
128 | /* kill() */ | ||
129 | struct { | ||
130 | unsigned int _pid; /* sender's pid */ | ||
131 | unsigned int _uid; /* sender's uid */ | ||
132 | } _kill; | ||
133 | |||
134 | /* POSIX.1b timers */ | ||
135 | struct { | ||
136 | compat_timer_t _tid; /* timer id */ | ||
137 | int _overrun; /* overrun count */ | ||
138 | compat_sigval_t _sigval; /* same as below */ | ||
139 | int _sys_private; /* not to be passed to user */ | ||
140 | int _overrun_incr; /* amount to add to overrun */ | ||
141 | } _timer; | ||
142 | |||
143 | /* POSIX.1b signals */ | ||
144 | struct { | ||
145 | unsigned int _pid; /* sender's pid */ | ||
146 | unsigned int _uid; /* sender's uid */ | ||
147 | compat_sigval_t _sigval; | ||
148 | } _rt; | ||
149 | |||
150 | /* SIGCHLD */ | ||
151 | struct { | ||
152 | unsigned int _pid; /* which child */ | ||
153 | unsigned int _uid; /* sender's uid */ | ||
154 | int _status; /* exit code */ | ||
155 | compat_clock_t _utime; | ||
156 | compat_clock_t _stime; | ||
157 | } _sigchld; | ||
158 | |||
159 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
160 | struct { | ||
161 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
162 | #ifdef __ARCH_SI_TRAPNO | ||
163 | int _trapno; /* TRAP # which caused the signal */ | ||
164 | #endif | ||
165 | } _sigfault; | ||
166 | |||
167 | /* SIGPOLL */ | ||
168 | struct { | ||
169 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
170 | int _fd; | ||
171 | } _sigpoll; | ||
172 | } _sifields; | ||
173 | } compat_siginfo_t; | ||
174 | |||
113 | #define COMPAT_OFF_T_MAX 0x7fffffff | 175 | #define COMPAT_OFF_T_MAX 0x7fffffff |
114 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 176 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
115 | 177 | ||
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h index d16d006d660e..f8ccf08f6934 100644 --- a/arch/tile/include/asm/elf.h +++ b/arch/tile/include/asm/elf.h | |||
@@ -156,12 +156,12 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, | |||
156 | #undef SET_PERSONALITY | 156 | #undef SET_PERSONALITY |
157 | #define SET_PERSONALITY(ex) \ | 157 | #define SET_PERSONALITY(ex) \ |
158 | do { \ | 158 | do { \ |
159 | current->personality = PER_LINUX; \ | 159 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \ |
160 | current_thread_info()->status &= ~TS_COMPAT; \ | 160 | current_thread_info()->status &= ~TS_COMPAT; \ |
161 | } while (0) | 161 | } while (0) |
162 | #define COMPAT_SET_PERSONALITY(ex) \ | 162 | #define COMPAT_SET_PERSONALITY(ex) \ |
163 | do { \ | 163 | do { \ |
164 | current->personality = PER_LINUX_32BIT; \ | 164 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \ |
165 | current_thread_info()->status |= TS_COMPAT; \ | 165 | current_thread_info()->status |= TS_COMPAT; \ |
166 | } while (0) | 166 | } while (0) |
167 | 167 | ||
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 474571b84085..7bc0859a9f5e 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c | |||
@@ -55,63 +55,6 @@ struct compat_ucontext { | |||
55 | sigset_t uc_sigmask; /* mask last for extensibility */ | 55 | sigset_t uc_sigmask; /* mask last for extensibility */ |
56 | }; | 56 | }; |
57 | 57 | ||
58 | #define COMPAT_SI_PAD_SIZE ((SI_MAX_SIZE - 3 * sizeof(int)) / sizeof(int)) | ||
59 | |||
60 | struct compat_siginfo { | ||
61 | int si_signo; | ||
62 | int si_errno; | ||
63 | int si_code; | ||
64 | |||
65 | union { | ||
66 | int _pad[COMPAT_SI_PAD_SIZE]; | ||
67 | |||
68 | /* kill() */ | ||
69 | struct { | ||
70 | unsigned int _pid; /* sender's pid */ | ||
71 | unsigned int _uid; /* sender's uid */ | ||
72 | } _kill; | ||
73 | |||
74 | /* POSIX.1b timers */ | ||
75 | struct { | ||
76 | compat_timer_t _tid; /* timer id */ | ||
77 | int _overrun; /* overrun count */ | ||
78 | compat_sigval_t _sigval; /* same as below */ | ||
79 | int _sys_private; /* not to be passed to user */ | ||
80 | int _overrun_incr; /* amount to add to overrun */ | ||
81 | } _timer; | ||
82 | |||
83 | /* POSIX.1b signals */ | ||
84 | struct { | ||
85 | unsigned int _pid; /* sender's pid */ | ||
86 | unsigned int _uid; /* sender's uid */ | ||
87 | compat_sigval_t _sigval; | ||
88 | } _rt; | ||
89 | |||
90 | /* SIGCHLD */ | ||
91 | struct { | ||
92 | unsigned int _pid; /* which child */ | ||
93 | unsigned int _uid; /* sender's uid */ | ||
94 | int _status; /* exit code */ | ||
95 | compat_clock_t _utime; | ||
96 | compat_clock_t _stime; | ||
97 | } _sigchld; | ||
98 | |||
99 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
100 | struct { | ||
101 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
102 | #ifdef __ARCH_SI_TRAPNO | ||
103 | int _trapno; /* TRAP # which caused the signal */ | ||
104 | #endif | ||
105 | } _sigfault; | ||
106 | |||
107 | /* SIGPOLL */ | ||
108 | struct { | ||
109 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
110 | int _fd; | ||
111 | } _sigpoll; | ||
112 | } _sifields; | ||
113 | }; | ||
114 | |||
115 | struct compat_rt_sigframe { | 58 | struct compat_rt_sigframe { |
116 | unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */ | 59 | unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */ |
117 | struct compat_siginfo info; | 60 | struct compat_siginfo info; |
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index b0a47433341e..1e638e75a6b7 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig | |||
@@ -6,6 +6,7 @@ config UNICORE32 | |||
6 | select HAVE_DMA_ATTRS | 6 | select HAVE_DMA_ATTRS |
7 | select HAVE_KERNEL_GZIP | 7 | select HAVE_KERNEL_GZIP |
8 | select HAVE_KERNEL_BZIP2 | 8 | select HAVE_KERNEL_BZIP2 |
9 | select GENERIC_ATOMIC64 | ||
9 | select HAVE_KERNEL_LZO | 10 | select HAVE_KERNEL_LZO |
10 | select HAVE_KERNEL_LZMA | 11 | select HAVE_KERNEL_LZMA |
11 | select ARCH_HAVE_CUSTOM_GPIO_H | 12 | select ARCH_HAVE_CUSTOM_GPIO_H |
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index f34261296ffb..338803422239 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h | |||
@@ -409,7 +409,7 @@ extern struct apic *apic; | |||
409 | * to enforce the order with in them. | 409 | * to enforce the order with in them. |
410 | */ | 410 | */ |
411 | #define apic_driver(sym) \ | 411 | #define apic_driver(sym) \ |
412 | static struct apic *__apicdrivers_##sym __used \ | 412 | static const struct apic *__apicdrivers_##sym __used \ |
413 | __aligned(sizeof(struct apic *)) \ | 413 | __aligned(sizeof(struct apic *)) \ |
414 | __section(.apicdrivers) = { &sym } | 414 | __section(.apicdrivers) = { &sym } |
415 | 415 | ||
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index fedf32b73e65..59c6c401f79f 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h | |||
@@ -41,6 +41,7 @@ typedef s64 __attribute__((aligned(4))) compat_s64; | |||
41 | typedef u32 compat_uint_t; | 41 | typedef u32 compat_uint_t; |
42 | typedef u32 compat_ulong_t; | 42 | typedef u32 compat_ulong_t; |
43 | typedef u64 __attribute__((aligned(4))) compat_u64; | 43 | typedef u64 __attribute__((aligned(4))) compat_u64; |
44 | typedef u32 compat_uptr_t; | ||
44 | 45 | ||
45 | struct compat_timespec { | 46 | struct compat_timespec { |
46 | compat_time_t tv_sec; | 47 | compat_time_t tv_sec; |
@@ -124,6 +125,78 @@ typedef u32 compat_old_sigset_t; /* at least 32 bits */ | |||
124 | 125 | ||
125 | typedef u32 compat_sigset_word; | 126 | typedef u32 compat_sigset_word; |
126 | 127 | ||
128 | typedef union compat_sigval { | ||
129 | compat_int_t sival_int; | ||
130 | compat_uptr_t sival_ptr; | ||
131 | } compat_sigval_t; | ||
132 | |||
133 | typedef struct compat_siginfo { | ||
134 | int si_signo; | ||
135 | int si_errno; | ||
136 | int si_code; | ||
137 | |||
138 | union { | ||
139 | int _pad[128/sizeof(int) - 3]; | ||
140 | |||
141 | /* kill() */ | ||
142 | struct { | ||
143 | unsigned int _pid; /* sender's pid */ | ||
144 | unsigned int _uid; /* sender's uid */ | ||
145 | } _kill; | ||
146 | |||
147 | /* POSIX.1b timers */ | ||
148 | struct { | ||
149 | compat_timer_t _tid; /* timer id */ | ||
150 | int _overrun; /* overrun count */ | ||
151 | compat_sigval_t _sigval; /* same as below */ | ||
152 | int _sys_private; /* not to be passed to user */ | ||
153 | int _overrun_incr; /* amount to add to overrun */ | ||
154 | } _timer; | ||
155 | |||
156 | /* POSIX.1b signals */ | ||
157 | struct { | ||
158 | unsigned int _pid; /* sender's pid */ | ||
159 | unsigned int _uid; /* sender's uid */ | ||
160 | compat_sigval_t _sigval; | ||
161 | } _rt; | ||
162 | |||
163 | /* SIGCHLD */ | ||
164 | struct { | ||
165 | unsigned int _pid; /* which child */ | ||
166 | unsigned int _uid; /* sender's uid */ | ||
167 | int _status; /* exit code */ | ||
168 | compat_clock_t _utime; | ||
169 | compat_clock_t _stime; | ||
170 | } _sigchld; | ||
171 | |||
172 | /* SIGCHLD (x32 version) */ | ||
173 | struct { | ||
174 | unsigned int _pid; /* which child */ | ||
175 | unsigned int _uid; /* sender's uid */ | ||
176 | int _status; /* exit code */ | ||
177 | compat_s64 _utime; | ||
178 | compat_s64 _stime; | ||
179 | } _sigchld_x32; | ||
180 | |||
181 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
182 | struct { | ||
183 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
184 | } _sigfault; | ||
185 | |||
186 | /* SIGPOLL */ | ||
187 | struct { | ||
188 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
189 | int _fd; | ||
190 | } _sigpoll; | ||
191 | |||
192 | struct { | ||
193 | unsigned int _call_addr; /* calling insn */ | ||
194 | int _syscall; /* triggering system call number */ | ||
195 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ | ||
196 | } _sigsys; | ||
197 | } _sifields; | ||
198 | } compat_siginfo_t; | ||
199 | |||
127 | #define COMPAT_OFF_T_MAX 0x7fffffff | 200 | #define COMPAT_OFF_T_MAX 0x7fffffff |
128 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | 201 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL |
129 | 202 | ||
@@ -209,7 +282,6 @@ typedef struct user_regs_struct32 compat_elf_gregset_t; | |||
209 | * as pointers because the syscall entry code will have | 282 | * as pointers because the syscall entry code will have |
210 | * appropriately converted them already. | 283 | * appropriately converted them already. |
211 | */ | 284 | */ |
212 | typedef u32 compat_uptr_t; | ||
213 | 285 | ||
214 | static inline void __user *compat_ptr(compat_uptr_t uptr) | 286 | static inline void __user *compat_ptr(compat_uptr_t uptr) |
215 | { | 287 | { |
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h index b04cbdb138cd..e6232773ce49 100644 --- a/arch/x86/include/asm/ia32.h +++ b/arch/x86/include/asm/ia32.h | |||
@@ -86,73 +86,6 @@ struct stat64 { | |||
86 | unsigned long long st_ino; | 86 | unsigned long long st_ino; |
87 | } __attribute__((packed)); | 87 | } __attribute__((packed)); |
88 | 88 | ||
89 | typedef struct compat_siginfo { | ||
90 | int si_signo; | ||
91 | int si_errno; | ||
92 | int si_code; | ||
93 | |||
94 | union { | ||
95 | int _pad[((128 / sizeof(int)) - 3)]; | ||
96 | |||
97 | /* kill() */ | ||
98 | struct { | ||
99 | unsigned int _pid; /* sender's pid */ | ||
100 | unsigned int _uid; /* sender's uid */ | ||
101 | } _kill; | ||
102 | |||
103 | /* POSIX.1b timers */ | ||
104 | struct { | ||
105 | compat_timer_t _tid; /* timer id */ | ||
106 | int _overrun; /* overrun count */ | ||
107 | compat_sigval_t _sigval; /* same as below */ | ||
108 | int _sys_private; /* not to be passed to user */ | ||
109 | int _overrun_incr; /* amount to add to overrun */ | ||
110 | } _timer; | ||
111 | |||
112 | /* POSIX.1b signals */ | ||
113 | struct { | ||
114 | unsigned int _pid; /* sender's pid */ | ||
115 | unsigned int _uid; /* sender's uid */ | ||
116 | compat_sigval_t _sigval; | ||
117 | } _rt; | ||
118 | |||
119 | /* SIGCHLD */ | ||
120 | struct { | ||
121 | unsigned int _pid; /* which child */ | ||
122 | unsigned int _uid; /* sender's uid */ | ||
123 | int _status; /* exit code */ | ||
124 | compat_clock_t _utime; | ||
125 | compat_clock_t _stime; | ||
126 | } _sigchld; | ||
127 | |||
128 | /* SIGCHLD (x32 version) */ | ||
129 | struct { | ||
130 | unsigned int _pid; /* which child */ | ||
131 | unsigned int _uid; /* sender's uid */ | ||
132 | int _status; /* exit code */ | ||
133 | compat_s64 _utime; | ||
134 | compat_s64 _stime; | ||
135 | } _sigchld_x32; | ||
136 | |||
137 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
138 | struct { | ||
139 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
140 | } _sigfault; | ||
141 | |||
142 | /* SIGPOLL */ | ||
143 | struct { | ||
144 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
145 | int _fd; | ||
146 | } _sigpoll; | ||
147 | |||
148 | struct { | ||
149 | unsigned int _call_addr; /* calling insn */ | ||
150 | int _syscall; /* triggering system call number */ | ||
151 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ | ||
152 | } _sigsys; | ||
153 | } _sifields; | ||
154 | } compat_siginfo_t; | ||
155 | |||
156 | #define IA32_STACK_TOP IA32_PAGE_OFFSET | 89 | #define IA32_STACK_TOP IA32_PAGE_OFFSET |
157 | 90 | ||
158 | #ifdef __KERNEL__ | 91 | #ifdef __KERNEL__ |
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index bc552cff2578..a65829ac2b9a 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | static int numachip_system __read_mostly; | 31 | static int numachip_system __read_mostly; |
32 | 32 | ||
33 | static struct apic apic_numachip __read_mostly; | 33 | static const struct apic apic_numachip __read_mostly; |
34 | 34 | ||
35 | static unsigned int get_apic_id(unsigned long x) | 35 | static unsigned int get_apic_id(unsigned long x) |
36 | { | 36 | { |
@@ -199,7 +199,7 @@ static int numachip_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
199 | return 0; | 199 | return 0; |
200 | } | 200 | } |
201 | 201 | ||
202 | static struct apic apic_numachip __refconst = { | 202 | static const struct apic apic_numachip __refconst = { |
203 | 203 | ||
204 | .name = "NumaConnect system", | 204 | .name = "NumaConnect system", |
205 | .probe = numachip_probe, | 205 | .probe = numachip_probe, |
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index af6db6ec5b2a..4929c1be0ac0 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c | |||
@@ -225,7 +225,7 @@ static struct platform_device rtc_device = { | |||
225 | static __init int add_rtc_cmos(void) | 225 | static __init int add_rtc_cmos(void) |
226 | { | 226 | { |
227 | #ifdef CONFIG_PNP | 227 | #ifdef CONFIG_PNP |
228 | static const char *ids[] __initconst = | 228 | static const char * const const ids[] __initconst = |
229 | { "PNP0b00", "PNP0b01", "PNP0b02", }; | 229 | { "PNP0b00", "PNP0b01", "PNP0b02", }; |
230 | struct pnp_dev *dev; | 230 | struct pnp_dev *dev; |
231 | struct pnp_id *id; | 231 | struct pnp_id *id; |
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h index 6e65eadaae14..5293312bc6a4 100644 --- a/arch/xtensa/include/asm/elf.h +++ b/arch/xtensa/include/asm/elf.h | |||
@@ -189,7 +189,8 @@ typedef struct { | |||
189 | #endif | 189 | #endif |
190 | } elf_xtregs_t; | 190 | } elf_xtregs_t; |
191 | 191 | ||
192 | #define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT) | 192 | #define SET_PERSONALITY(ex) \ |
193 | set_personality(PER_LINUX_32BIT | (current->personality & (~PER_MASK))) | ||
193 | 194 | ||
194 | struct task_struct; | 195 | struct task_struct; |
195 | 196 | ||
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 2059ee460b0c..81e44f7b0ab6 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c | |||
@@ -1567,7 +1567,7 @@ tx_complete++; | |||
1567 | /*--------------------------------- entries ---------------------------------*/ | 1567 | /*--------------------------------- entries ---------------------------------*/ |
1568 | 1568 | ||
1569 | 1569 | ||
1570 | static const char *media_name[] __devinitdata = { | 1570 | static char * const media_name[] __devinitconst = { |
1571 | "MMF", "SMF", "MMF", "03?", /* 0- 3 */ | 1571 | "MMF", "SMF", "MMF", "03?", /* 0- 3 */ |
1572 | "UTP", "05?", "06?", "07?", /* 4- 7 */ | 1572 | "UTP", "05?", "06?", "07?", /* 4- 7 */ |
1573 | "TAXI","09?", "10?", "11?", /* 8-11 */ | 1573 | "TAXI","09?", "10?", "11?", /* 8-11 */ |
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index db195abad698..d2ed7f18d1ac 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ |
2 | #define VERSION "47" | 2 | #define VERSION "50" |
3 | #define AOE_MAJOR 152 | 3 | #define AOE_MAJOR 152 |
4 | #define DEVICE_NAME "aoe" | 4 | #define DEVICE_NAME "aoe" |
5 | 5 | ||
@@ -10,9 +10,6 @@ | |||
10 | #define AOE_PARTITIONS (16) | 10 | #define AOE_PARTITIONS (16) |
11 | #endif | 11 | #endif |
12 | 12 | ||
13 | #define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * NPERSHELF + (aoeminor)) | ||
14 | #define AOEMAJOR(sysminor) ((sysminor) / NPERSHELF) | ||
15 | #define AOEMINOR(sysminor) ((sysminor) % NPERSHELF) | ||
16 | #define WHITESPACE " \t\v\f\n" | 13 | #define WHITESPACE " \t\v\f\n" |
17 | 14 | ||
18 | enum { | 15 | enum { |
@@ -75,72 +72,67 @@ enum { | |||
75 | DEVFL_UP = 1, /* device is installed in system and ready for AoE->ATA commands */ | 72 | DEVFL_UP = 1, /* device is installed in system and ready for AoE->ATA commands */ |
76 | DEVFL_TKILL = (1<<1), /* flag for timer to know when to kill self */ | 73 | DEVFL_TKILL = (1<<1), /* flag for timer to know when to kill self */ |
77 | DEVFL_EXT = (1<<2), /* device accepts lba48 commands */ | 74 | DEVFL_EXT = (1<<2), /* device accepts lba48 commands */ |
78 | DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */ | 75 | DEVFL_GDALLOC = (1<<3), /* need to alloc gendisk */ |
79 | DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */ | 76 | DEVFL_KICKME = (1<<4), /* slow polling network card catch */ |
80 | DEVFL_KICKME = (1<<5), /* slow polling network card catch */ | 77 | DEVFL_NEWSIZE = (1<<5), /* need to update dev size in block layer */ |
81 | DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */ | ||
82 | |||
83 | BUFFL_FAIL = 1, | ||
84 | }; | 78 | }; |
85 | 79 | ||
86 | enum { | 80 | enum { |
87 | DEFAULTBCNT = 2 * 512, /* 2 sectors */ | 81 | DEFAULTBCNT = 2 * 512, /* 2 sectors */ |
88 | NPERSHELF = 16, /* number of slots per shelf address */ | ||
89 | FREETAG = -1, | ||
90 | MIN_BUFS = 16, | 82 | MIN_BUFS = 16, |
91 | NTARGETS = 8, | 83 | NTARGETS = 8, |
92 | NAOEIFS = 8, | 84 | NAOEIFS = 8, |
93 | NSKBPOOLMAX = 128, | 85 | NSKBPOOLMAX = 256, |
86 | NFACTIVE = 61, | ||
94 | 87 | ||
95 | TIMERTICK = HZ / 10, | 88 | TIMERTICK = HZ / 10, |
96 | MINTIMER = HZ >> 2, | 89 | MINTIMER = HZ >> 2, |
97 | MAXTIMER = HZ << 1, | 90 | MAXTIMER = HZ << 1, |
98 | HELPWAIT = 20, | ||
99 | }; | 91 | }; |
100 | 92 | ||
101 | struct buf { | 93 | struct buf { |
102 | struct list_head bufs; | ||
103 | ulong stime; /* for disk stats */ | ||
104 | ulong flags; | ||
105 | ulong nframesout; | 94 | ulong nframesout; |
106 | ulong resid; | 95 | ulong resid; |
107 | ulong bv_resid; | 96 | ulong bv_resid; |
108 | ulong bv_off; | ||
109 | sector_t sector; | 97 | sector_t sector; |
110 | struct bio *bio; | 98 | struct bio *bio; |
111 | struct bio_vec *bv; | 99 | struct bio_vec *bv; |
100 | struct request *rq; | ||
112 | }; | 101 | }; |
113 | 102 | ||
114 | struct frame { | 103 | struct frame { |
115 | int tag; | 104 | struct list_head head; |
105 | u32 tag; | ||
116 | ulong waited; | 106 | ulong waited; |
107 | struct aoetgt *t; /* parent target I belong to */ | ||
108 | sector_t lba; | ||
109 | struct sk_buff *skb; /* command skb freed on module exit */ | ||
110 | struct sk_buff *r_skb; /* response skb for async processing */ | ||
117 | struct buf *buf; | 111 | struct buf *buf; |
118 | char *bufaddr; | 112 | struct bio_vec *bv; |
119 | ulong bcnt; | 113 | ulong bcnt; |
120 | sector_t lba; | 114 | ulong bv_off; |
121 | struct sk_buff *skb; | ||
122 | }; | 115 | }; |
123 | 116 | ||
124 | struct aoeif { | 117 | struct aoeif { |
125 | struct net_device *nd; | 118 | struct net_device *nd; |
126 | unsigned char lost; | 119 | ulong lost; |
127 | unsigned char lostjumbo; | 120 | int bcnt; |
128 | ushort maxbcnt; | ||
129 | }; | 121 | }; |
130 | 122 | ||
131 | struct aoetgt { | 123 | struct aoetgt { |
132 | unsigned char addr[6]; | 124 | unsigned char addr[6]; |
133 | ushort nframes; | 125 | ushort nframes; |
134 | struct frame *frames; | 126 | struct aoedev *d; /* parent device I belong to */ |
127 | struct list_head ffree; /* list of free frames */ | ||
135 | struct aoeif ifs[NAOEIFS]; | 128 | struct aoeif ifs[NAOEIFS]; |
136 | struct aoeif *ifp; /* current aoeif in use */ | 129 | struct aoeif *ifp; /* current aoeif in use */ |
137 | ushort nout; | 130 | ushort nout; |
138 | ushort maxout; | 131 | ushort maxout; |
139 | u16 lasttag; /* last tag sent */ | 132 | ulong falloc; |
140 | u16 useme; | ||
141 | ulong lastwadj; /* last window adjustment */ | 133 | ulong lastwadj; /* last window adjustment */ |
134 | int minbcnt; | ||
142 | int wpkts, rpkts; | 135 | int wpkts, rpkts; |
143 | int dataref; | ||
144 | }; | 136 | }; |
145 | 137 | ||
146 | struct aoedev { | 138 | struct aoedev { |
@@ -153,6 +145,9 @@ struct aoedev { | |||
153 | u16 rttavg; /* round trip average of requests/responses */ | 145 | u16 rttavg; /* round trip average of requests/responses */ |
154 | u16 mintimer; | 146 | u16 mintimer; |
155 | u16 fw_ver; /* version of blade's firmware */ | 147 | u16 fw_ver; /* version of blade's firmware */ |
148 | u16 lasttag; /* last tag sent */ | ||
149 | u16 useme; | ||
150 | ulong ref; | ||
156 | struct work_struct work;/* disk create work struct */ | 151 | struct work_struct work;/* disk create work struct */ |
157 | struct gendisk *gd; | 152 | struct gendisk *gd; |
158 | struct request_queue *blkq; | 153 | struct request_queue *blkq; |
@@ -160,16 +155,31 @@ struct aoedev { | |||
160 | sector_t ssize; | 155 | sector_t ssize; |
161 | struct timer_list timer; | 156 | struct timer_list timer; |
162 | spinlock_t lock; | 157 | spinlock_t lock; |
163 | struct sk_buff_head sendq; | ||
164 | struct sk_buff_head skbpool; | 158 | struct sk_buff_head skbpool; |
165 | mempool_t *bufpool; /* for deadlock-free Buf allocation */ | 159 | mempool_t *bufpool; /* for deadlock-free Buf allocation */ |
166 | struct list_head bufq; /* queue of bios to work on */ | 160 | struct { /* pointers to work in progress */ |
167 | struct buf *inprocess; /* the one we're currently working on */ | 161 | struct buf *buf; |
162 | struct bio *nxbio; | ||
163 | struct request *rq; | ||
164 | } ip; | ||
165 | ulong maxbcnt; | ||
166 | struct list_head factive[NFACTIVE]; /* hash of active frames */ | ||
168 | struct aoetgt *targets[NTARGETS]; | 167 | struct aoetgt *targets[NTARGETS]; |
169 | struct aoetgt **tgt; /* target in use when working */ | 168 | struct aoetgt **tgt; /* target in use when working */ |
170 | struct aoetgt **htgt; /* target needing rexmit assistance */ | 169 | struct aoetgt *htgt; /* target needing rexmit assistance */ |
170 | ulong ntargets; | ||
171 | ulong kicked; | ||
171 | }; | 172 | }; |
172 | 173 | ||
174 | /* kthread tracking */ | ||
175 | struct ktstate { | ||
176 | struct completion rendez; | ||
177 | struct task_struct *task; | ||
178 | wait_queue_head_t *waitq; | ||
179 | int (*fn) (void); | ||
180 | char *name; | ||
181 | spinlock_t *lock; | ||
182 | }; | ||
173 | 183 | ||
174 | int aoeblk_init(void); | 184 | int aoeblk_init(void); |
175 | void aoeblk_exit(void); | 185 | void aoeblk_exit(void); |
@@ -182,22 +192,29 @@ void aoechr_error(char *); | |||
182 | 192 | ||
183 | void aoecmd_work(struct aoedev *d); | 193 | void aoecmd_work(struct aoedev *d); |
184 | void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); | 194 | void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); |
185 | void aoecmd_ata_rsp(struct sk_buff *); | 195 | struct sk_buff *aoecmd_ata_rsp(struct sk_buff *); |
186 | void aoecmd_cfg_rsp(struct sk_buff *); | 196 | void aoecmd_cfg_rsp(struct sk_buff *); |
187 | void aoecmd_sleepwork(struct work_struct *); | 197 | void aoecmd_sleepwork(struct work_struct *); |
188 | void aoecmd_cleanslate(struct aoedev *); | 198 | void aoecmd_cleanslate(struct aoedev *); |
199 | void aoecmd_exit(void); | ||
200 | int aoecmd_init(void); | ||
189 | struct sk_buff *aoecmd_ata_id(struct aoedev *); | 201 | struct sk_buff *aoecmd_ata_id(struct aoedev *); |
202 | void aoe_freetframe(struct frame *); | ||
203 | void aoe_flush_iocq(void); | ||
204 | void aoe_end_request(struct aoedev *, struct request *, int); | ||
205 | int aoe_ktstart(struct ktstate *k); | ||
206 | void aoe_ktstop(struct ktstate *k); | ||
190 | 207 | ||
191 | int aoedev_init(void); | 208 | int aoedev_init(void); |
192 | void aoedev_exit(void); | 209 | void aoedev_exit(void); |
193 | struct aoedev *aoedev_by_aoeaddr(int maj, int min); | 210 | struct aoedev *aoedev_by_aoeaddr(ulong maj, int min, int do_alloc); |
194 | struct aoedev *aoedev_by_sysminor_m(ulong sysminor); | ||
195 | void aoedev_downdev(struct aoedev *d); | 211 | void aoedev_downdev(struct aoedev *d); |
196 | int aoedev_flush(const char __user *str, size_t size); | 212 | int aoedev_flush(const char __user *str, size_t size); |
213 | void aoe_failbuf(struct aoedev *, struct buf *); | ||
214 | void aoedev_put(struct aoedev *); | ||
197 | 215 | ||
198 | int aoenet_init(void); | 216 | int aoenet_init(void); |
199 | void aoenet_exit(void); | 217 | void aoenet_exit(void); |
200 | void aoenet_xmit(struct sk_buff_head *); | 218 | void aoenet_xmit(struct sk_buff_head *); |
201 | int is_aoe_netif(struct net_device *ifp); | 219 | int is_aoe_netif(struct net_device *ifp); |
202 | int set_aoe_iflist(const char __user *str, size_t size); | 220 | int set_aoe_iflist(const char __user *str, size_t size); |
203 | |||
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 321de7b6c442..00dfc5008ad4 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoeblk.c | 3 | * aoeblk.c |
4 | * block device routines | 4 | * block device routines |
@@ -161,68 +161,22 @@ aoeblk_release(struct gendisk *disk, fmode_t mode) | |||
161 | } | 161 | } |
162 | 162 | ||
163 | static void | 163 | static void |
164 | aoeblk_make_request(struct request_queue *q, struct bio *bio) | 164 | aoeblk_request(struct request_queue *q) |
165 | { | 165 | { |
166 | struct sk_buff_head queue; | ||
167 | struct aoedev *d; | 166 | struct aoedev *d; |
168 | struct buf *buf; | 167 | struct request *rq; |
169 | ulong flags; | ||
170 | |||
171 | blk_queue_bounce(q, &bio); | ||
172 | |||
173 | if (bio == NULL) { | ||
174 | printk(KERN_ERR "aoe: bio is NULL\n"); | ||
175 | BUG(); | ||
176 | return; | ||
177 | } | ||
178 | d = bio->bi_bdev->bd_disk->private_data; | ||
179 | if (d == NULL) { | ||
180 | printk(KERN_ERR "aoe: bd_disk->private_data is NULL\n"); | ||
181 | BUG(); | ||
182 | bio_endio(bio, -ENXIO); | ||
183 | return; | ||
184 | } else if (bio->bi_io_vec == NULL) { | ||
185 | printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); | ||
186 | BUG(); | ||
187 | bio_endio(bio, -ENXIO); | ||
188 | return; | ||
189 | } | ||
190 | buf = mempool_alloc(d->bufpool, GFP_NOIO); | ||
191 | if (buf == NULL) { | ||
192 | printk(KERN_INFO "aoe: buf allocation failure\n"); | ||
193 | bio_endio(bio, -ENOMEM); | ||
194 | return; | ||
195 | } | ||
196 | memset(buf, 0, sizeof(*buf)); | ||
197 | INIT_LIST_HEAD(&buf->bufs); | ||
198 | buf->stime = jiffies; | ||
199 | buf->bio = bio; | ||
200 | buf->resid = bio->bi_size; | ||
201 | buf->sector = bio->bi_sector; | ||
202 | buf->bv = &bio->bi_io_vec[bio->bi_idx]; | ||
203 | buf->bv_resid = buf->bv->bv_len; | ||
204 | WARN_ON(buf->bv_resid == 0); | ||
205 | buf->bv_off = buf->bv->bv_offset; | ||
206 | |||
207 | spin_lock_irqsave(&d->lock, flags); | ||
208 | 168 | ||
169 | d = q->queuedata; | ||
209 | if ((d->flags & DEVFL_UP) == 0) { | 170 | if ((d->flags & DEVFL_UP) == 0) { |
210 | pr_info_ratelimited("aoe: device %ld.%d is not up\n", | 171 | pr_info_ratelimited("aoe: device %ld.%d is not up\n", |
211 | d->aoemajor, d->aoeminor); | 172 | d->aoemajor, d->aoeminor); |
212 | spin_unlock_irqrestore(&d->lock, flags); | 173 | while ((rq = blk_peek_request(q))) { |
213 | mempool_free(buf, d->bufpool); | 174 | blk_start_request(rq); |
214 | bio_endio(bio, -ENXIO); | 175 | aoe_end_request(d, rq, 1); |
176 | } | ||
215 | return; | 177 | return; |
216 | } | 178 | } |
217 | |||
218 | list_add_tail(&buf->bufs, &d->bufq); | ||
219 | |||
220 | aoecmd_work(d); | 179 | aoecmd_work(d); |
221 | __skb_queue_head_init(&queue); | ||
222 | skb_queue_splice_init(&d->sendq, &queue); | ||
223 | |||
224 | spin_unlock_irqrestore(&d->lock, flags); | ||
225 | aoenet_xmit(&queue); | ||
226 | } | 180 | } |
227 | 181 | ||
228 | static int | 182 | static int |
@@ -254,41 +208,54 @@ aoeblk_gdalloc(void *vp) | |||
254 | { | 208 | { |
255 | struct aoedev *d = vp; | 209 | struct aoedev *d = vp; |
256 | struct gendisk *gd; | 210 | struct gendisk *gd; |
211 | mempool_t *mp; | ||
212 | struct request_queue *q; | ||
213 | enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, }; | ||
257 | ulong flags; | 214 | ulong flags; |
258 | 215 | ||
259 | gd = alloc_disk(AOE_PARTITIONS); | 216 | gd = alloc_disk(AOE_PARTITIONS); |
260 | if (gd == NULL) { | 217 | if (gd == NULL) { |
261 | printk(KERN_ERR | 218 | pr_err("aoe: cannot allocate disk structure for %ld.%d\n", |
262 | "aoe: cannot allocate disk structure for %ld.%d\n", | ||
263 | d->aoemajor, d->aoeminor); | 219 | d->aoemajor, d->aoeminor); |
264 | goto err; | 220 | goto err; |
265 | } | 221 | } |
266 | 222 | ||
267 | d->bufpool = mempool_create_slab_pool(MIN_BUFS, buf_pool_cache); | 223 | mp = mempool_create(MIN_BUFS, mempool_alloc_slab, mempool_free_slab, |
268 | if (d->bufpool == NULL) { | 224 | buf_pool_cache); |
225 | if (mp == NULL) { | ||
269 | printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%d\n", | 226 | printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%d\n", |
270 | d->aoemajor, d->aoeminor); | 227 | d->aoemajor, d->aoeminor); |
271 | goto err_disk; | 228 | goto err_disk; |
272 | } | 229 | } |
230 | q = blk_init_queue(aoeblk_request, &d->lock); | ||
231 | if (q == NULL) { | ||
232 | pr_err("aoe: cannot allocate block queue for %ld.%d\n", | ||
233 | d->aoemajor, d->aoeminor); | ||
234 | mempool_destroy(mp); | ||
235 | goto err_disk; | ||
236 | } | ||
273 | 237 | ||
274 | d->blkq = blk_alloc_queue(GFP_KERNEL); | 238 | d->blkq = blk_alloc_queue(GFP_KERNEL); |
275 | if (!d->blkq) | 239 | if (!d->blkq) |
276 | goto err_mempool; | 240 | goto err_mempool; |
277 | blk_queue_make_request(d->blkq, aoeblk_make_request); | ||
278 | d->blkq->backing_dev_info.name = "aoe"; | 241 | d->blkq->backing_dev_info.name = "aoe"; |
279 | if (bdi_init(&d->blkq->backing_dev_info)) | 242 | if (bdi_init(&d->blkq->backing_dev_info)) |
280 | goto err_blkq; | 243 | goto err_blkq; |
281 | spin_lock_irqsave(&d->lock, flags); | 244 | spin_lock_irqsave(&d->lock, flags); |
245 | blk_queue_max_hw_sectors(d->blkq, BLK_DEF_MAX_SECTORS); | ||
246 | q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_CACHE_SIZE; | ||
247 | d->bufpool = mp; | ||
248 | d->blkq = gd->queue = q; | ||
249 | q->queuedata = d; | ||
250 | d->gd = gd; | ||
282 | gd->major = AOE_MAJOR; | 251 | gd->major = AOE_MAJOR; |
283 | gd->first_minor = d->sysminor * AOE_PARTITIONS; | 252 | gd->first_minor = d->sysminor; |
284 | gd->fops = &aoe_bdops; | 253 | gd->fops = &aoe_bdops; |
285 | gd->private_data = d; | 254 | gd->private_data = d; |
286 | set_capacity(gd, d->ssize); | 255 | set_capacity(gd, d->ssize); |
287 | snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", | 256 | snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", |
288 | d->aoemajor, d->aoeminor); | 257 | d->aoemajor, d->aoeminor); |
289 | 258 | ||
290 | gd->queue = d->blkq; | ||
291 | d->gd = gd; | ||
292 | d->flags &= ~DEVFL_GDALLOC; | 259 | d->flags &= ~DEVFL_GDALLOC; |
293 | d->flags |= DEVFL_UP; | 260 | d->flags |= DEVFL_UP; |
294 | 261 | ||
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index e86d2062a164..ed57a890c643 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoechr.c | 3 | * aoechr.c |
4 | * AoE character device driver | 4 | * AoE character device driver |
@@ -86,34 +86,34 @@ revalidate(const char __user *str, size_t size) | |||
86 | if (copy_from_user(buf, str, size)) | 86 | if (copy_from_user(buf, str, size)) |
87 | return -EFAULT; | 87 | return -EFAULT; |
88 | 88 | ||
89 | /* should be e%d.%d format */ | ||
90 | n = sscanf(buf, "e%d.%d", &major, &minor); | 89 | n = sscanf(buf, "e%d.%d", &major, &minor); |
91 | if (n != 2) { | 90 | if (n != 2) { |
92 | printk(KERN_ERR "aoe: invalid device specification\n"); | 91 | pr_err("aoe: invalid device specification %s\n", buf); |
93 | return -EINVAL; | 92 | return -EINVAL; |
94 | } | 93 | } |
95 | d = aoedev_by_aoeaddr(major, minor); | 94 | d = aoedev_by_aoeaddr(major, minor, 0); |
96 | if (!d) | 95 | if (!d) |
97 | return -EINVAL; | 96 | return -EINVAL; |
98 | spin_lock_irqsave(&d->lock, flags); | 97 | spin_lock_irqsave(&d->lock, flags); |
99 | aoecmd_cleanslate(d); | 98 | aoecmd_cleanslate(d); |
99 | aoecmd_cfg(major, minor); | ||
100 | loop: | 100 | loop: |
101 | skb = aoecmd_ata_id(d); | 101 | skb = aoecmd_ata_id(d); |
102 | spin_unlock_irqrestore(&d->lock, flags); | 102 | spin_unlock_irqrestore(&d->lock, flags); |
103 | /* try again if we are able to sleep a bit, | 103 | /* try again if we are able to sleep a bit, |
104 | * otherwise give up this revalidation | 104 | * otherwise give up this revalidation |
105 | */ | 105 | */ |
106 | if (!skb && !msleep_interruptible(200)) { | 106 | if (!skb && !msleep_interruptible(250)) { |
107 | spin_lock_irqsave(&d->lock, flags); | 107 | spin_lock_irqsave(&d->lock, flags); |
108 | goto loop; | 108 | goto loop; |
109 | } | 109 | } |
110 | aoedev_put(d); | ||
110 | if (skb) { | 111 | if (skb) { |
111 | struct sk_buff_head queue; | 112 | struct sk_buff_head queue; |
112 | __skb_queue_head_init(&queue); | 113 | __skb_queue_head_init(&queue); |
113 | __skb_queue_tail(&queue, skb); | 114 | __skb_queue_tail(&queue, skb); |
114 | aoenet_xmit(&queue); | 115 | aoenet_xmit(&queue); |
115 | } | 116 | } |
116 | aoecmd_cfg(major, minor); | ||
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
@@ -174,6 +174,7 @@ aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp | |||
174 | break; | 174 | break; |
175 | case MINOR_FLUSH: | 175 | case MINOR_FLUSH: |
176 | ret = aoedev_flush(buf, cnt); | 176 | ret = aoedev_flush(buf, cnt); |
177 | break; | ||
177 | } | 178 | } |
178 | if (ret == 0) | 179 | if (ret == 0) |
179 | ret = cnt; | 180 | ret = cnt; |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 887f68f6d79a..3804a0af3ef1 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoecmd.c | 3 | * aoecmd.c |
4 | * Filesystem request handling methods | 4 | * Filesystem request handling methods |
@@ -12,10 +12,19 @@ | |||
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <linux/genhd.h> | 13 | #include <linux/genhd.h> |
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/workqueue.h> | ||
16 | #include <linux/kthread.h> | ||
15 | #include <net/net_namespace.h> | 17 | #include <net/net_namespace.h> |
16 | #include <asm/unaligned.h> | 18 | #include <asm/unaligned.h> |
19 | #include <linux/uio.h> | ||
17 | #include "aoe.h" | 20 | #include "aoe.h" |
18 | 21 | ||
22 | #define MAXIOC (8192) /* default meant to avoid most soft lockups */ | ||
23 | |||
24 | static void ktcomplete(struct frame *, struct sk_buff *); | ||
25 | |||
26 | static struct buf *nextbuf(struct aoedev *); | ||
27 | |||
19 | static int aoe_deadsecs = 60 * 3; | 28 | static int aoe_deadsecs = 60 * 3; |
20 | module_param(aoe_deadsecs, int, 0644); | 29 | module_param(aoe_deadsecs, int, 0644); |
21 | MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev."); | 30 | MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev."); |
@@ -25,6 +34,15 @@ module_param(aoe_maxout, int, 0644); | |||
25 | MODULE_PARM_DESC(aoe_maxout, | 34 | MODULE_PARM_DESC(aoe_maxout, |
26 | "Only aoe_maxout outstanding packets for every MAC on eX.Y."); | 35 | "Only aoe_maxout outstanding packets for every MAC on eX.Y."); |
27 | 36 | ||
37 | static wait_queue_head_t ktiowq; | ||
38 | static struct ktstate kts; | ||
39 | |||
40 | /* io completion queue */ | ||
41 | static struct { | ||
42 | struct list_head head; | ||
43 | spinlock_t lock; | ||
44 | } iocq; | ||
45 | |||
28 | static struct sk_buff * | 46 | static struct sk_buff * |
29 | new_skb(ulong len) | 47 | new_skb(ulong len) |
30 | { | 48 | { |
@@ -41,15 +59,21 @@ new_skb(ulong len) | |||
41 | } | 59 | } |
42 | 60 | ||
43 | static struct frame * | 61 | static struct frame * |
44 | getframe(struct aoetgt *t, int tag) | 62 | getframe(struct aoedev *d, u32 tag) |
45 | { | 63 | { |
46 | struct frame *f, *e; | 64 | struct frame *f; |
65 | struct list_head *head, *pos, *nx; | ||
66 | u32 n; | ||
47 | 67 | ||
48 | f = t->frames; | 68 | n = tag % NFACTIVE; |
49 | e = f + t->nframes; | 69 | head = &d->factive[n]; |
50 | for (; f<e; f++) | 70 | list_for_each_safe(pos, nx, head) { |
51 | if (f->tag == tag) | 71 | f = list_entry(pos, struct frame, head); |
72 | if (f->tag == tag) { | ||
73 | list_del(pos); | ||
52 | return f; | 74 | return f; |
75 | } | ||
76 | } | ||
53 | return NULL; | 77 | return NULL; |
54 | } | 78 | } |
55 | 79 | ||
@@ -59,18 +83,18 @@ getframe(struct aoetgt *t, int tag) | |||
59 | * This driver reserves tag -1 to mean "unused frame." | 83 | * This driver reserves tag -1 to mean "unused frame." |
60 | */ | 84 | */ |
61 | static int | 85 | static int |
62 | newtag(struct aoetgt *t) | 86 | newtag(struct aoedev *d) |
63 | { | 87 | { |
64 | register ulong n; | 88 | register ulong n; |
65 | 89 | ||
66 | n = jiffies & 0xffff; | 90 | n = jiffies & 0xffff; |
67 | return n |= (++t->lasttag & 0x7fff) << 16; | 91 | return n |= (++d->lasttag & 0x7fff) << 16; |
68 | } | 92 | } |
69 | 93 | ||
70 | static int | 94 | static u32 |
71 | aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h) | 95 | aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h) |
72 | { | 96 | { |
73 | u32 host_tag = newtag(t); | 97 | u32 host_tag = newtag(d); |
74 | 98 | ||
75 | memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); | 99 | memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); |
76 | memcpy(h->dst, t->addr, sizeof h->dst); | 100 | memcpy(h->dst, t->addr, sizeof h->dst); |
@@ -95,16 +119,18 @@ put_lba(struct aoe_atahdr *ah, sector_t lba) | |||
95 | ah->lba5 = lba >>= 8; | 119 | ah->lba5 = lba >>= 8; |
96 | } | 120 | } |
97 | 121 | ||
98 | static void | 122 | static struct aoeif * |
99 | ifrotate(struct aoetgt *t) | 123 | ifrotate(struct aoetgt *t) |
100 | { | 124 | { |
101 | t->ifp++; | 125 | struct aoeif *ifp; |
102 | if (t->ifp >= &t->ifs[NAOEIFS] || t->ifp->nd == NULL) | 126 | |
103 | t->ifp = t->ifs; | 127 | ifp = t->ifp; |
104 | if (t->ifp->nd == NULL) { | 128 | ifp++; |
105 | printk(KERN_INFO "aoe: no interface to rotate to\n"); | 129 | if (ifp >= &t->ifs[NAOEIFS] || ifp->nd == NULL) |
106 | BUG(); | 130 | ifp = t->ifs; |
107 | } | 131 | if (ifp->nd == NULL) |
132 | return NULL; | ||
133 | return t->ifp = ifp; | ||
108 | } | 134 | } |
109 | 135 | ||
110 | static void | 136 | static void |
@@ -129,78 +155,128 @@ skb_pool_get(struct aoedev *d) | |||
129 | return NULL; | 155 | return NULL; |
130 | } | 156 | } |
131 | 157 | ||
132 | /* freeframe is where we do our load balancing so it's a little hairy. */ | 158 | void |
159 | aoe_freetframe(struct frame *f) | ||
160 | { | ||
161 | struct aoetgt *t; | ||
162 | |||
163 | t = f->t; | ||
164 | f->buf = NULL; | ||
165 | f->bv = NULL; | ||
166 | f->r_skb = NULL; | ||
167 | list_add(&f->head, &t->ffree); | ||
168 | } | ||
169 | |||
133 | static struct frame * | 170 | static struct frame * |
134 | freeframe(struct aoedev *d) | 171 | newtframe(struct aoedev *d, struct aoetgt *t) |
135 | { | 172 | { |
136 | struct frame *f, *e, *rf; | 173 | struct frame *f; |
137 | struct aoetgt **t; | ||
138 | struct sk_buff *skb; | 174 | struct sk_buff *skb; |
175 | struct list_head *pos; | ||
176 | |||
177 | if (list_empty(&t->ffree)) { | ||
178 | if (t->falloc >= NSKBPOOLMAX*2) | ||
179 | return NULL; | ||
180 | f = kcalloc(1, sizeof(*f), GFP_ATOMIC); | ||
181 | if (f == NULL) | ||
182 | return NULL; | ||
183 | t->falloc++; | ||
184 | f->t = t; | ||
185 | } else { | ||
186 | pos = t->ffree.next; | ||
187 | list_del(pos); | ||
188 | f = list_entry(pos, struct frame, head); | ||
189 | } | ||
190 | |||
191 | skb = f->skb; | ||
192 | if (skb == NULL) { | ||
193 | f->skb = skb = new_skb(ETH_ZLEN); | ||
194 | if (!skb) { | ||
195 | bail: aoe_freetframe(f); | ||
196 | return NULL; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | if (atomic_read(&skb_shinfo(skb)->dataref) != 1) { | ||
201 | skb = skb_pool_get(d); | ||
202 | if (skb == NULL) | ||
203 | goto bail; | ||
204 | skb_pool_put(d, f->skb); | ||
205 | f->skb = skb; | ||
206 | } | ||
207 | |||
208 | skb->truesize -= skb->data_len; | ||
209 | skb_shinfo(skb)->nr_frags = skb->data_len = 0; | ||
210 | skb_trim(skb, 0); | ||
211 | return f; | ||
212 | } | ||
213 | |||
214 | static struct frame * | ||
215 | newframe(struct aoedev *d) | ||
216 | { | ||
217 | struct frame *f; | ||
218 | struct aoetgt *t, **tt; | ||
219 | int totout = 0; | ||
139 | 220 | ||
140 | if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */ | 221 | if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */ |
141 | printk(KERN_ERR "aoe: NULL TARGETS!\n"); | 222 | printk(KERN_ERR "aoe: NULL TARGETS!\n"); |
142 | return NULL; | 223 | return NULL; |
143 | } | 224 | } |
144 | t = d->tgt; | 225 | tt = d->tgt; /* last used target */ |
145 | t++; | ||
146 | if (t >= &d->targets[NTARGETS] || !*t) | ||
147 | t = d->targets; | ||
148 | for (;;) { | 226 | for (;;) { |
149 | if ((*t)->nout < (*t)->maxout | 227 | tt++; |
228 | if (tt >= &d->targets[NTARGETS] || !*tt) | ||
229 | tt = d->targets; | ||
230 | t = *tt; | ||
231 | totout += t->nout; | ||
232 | if (t->nout < t->maxout | ||
150 | && t != d->htgt | 233 | && t != d->htgt |
151 | && (*t)->ifp->nd) { | 234 | && t->ifp->nd) { |
152 | rf = NULL; | 235 | f = newtframe(d, t); |
153 | f = (*t)->frames; | 236 | if (f) { |
154 | e = f + (*t)->nframes; | 237 | ifrotate(t); |
155 | for (; f < e; f++) { | 238 | d->tgt = tt; |
156 | if (f->tag != FREETAG) | ||
157 | continue; | ||
158 | skb = f->skb; | ||
159 | if (!skb | ||
160 | && !(f->skb = skb = new_skb(ETH_ZLEN))) | ||
161 | continue; | ||
162 | if (atomic_read(&skb_shinfo(skb)->dataref) | ||
163 | != 1) { | ||
164 | if (!rf) | ||
165 | rf = f; | ||
166 | continue; | ||
167 | } | ||
168 | gotone: skb_shinfo(skb)->nr_frags = skb->data_len = 0; | ||
169 | skb_trim(skb, 0); | ||
170 | d->tgt = t; | ||
171 | ifrotate(*t); | ||
172 | return f; | 239 | return f; |
173 | } | 240 | } |
174 | /* Work can be done, but the network layer is | ||
175 | holding our precious packets. Try to grab | ||
176 | one from the pool. */ | ||
177 | f = rf; | ||
178 | if (f == NULL) { /* more paranoia */ | ||
179 | printk(KERN_ERR | ||
180 | "aoe: freeframe: %s.\n", | ||
181 | "unexpected null rf"); | ||
182 | d->flags |= DEVFL_KICKME; | ||
183 | return NULL; | ||
184 | } | ||
185 | skb = skb_pool_get(d); | ||
186 | if (skb) { | ||
187 | skb_pool_put(d, f->skb); | ||
188 | f->skb = skb; | ||
189 | goto gotone; | ||
190 | } | ||
191 | (*t)->dataref++; | ||
192 | if ((*t)->nout == 0) | ||
193 | d->flags |= DEVFL_KICKME; | ||
194 | } | 241 | } |
195 | if (t == d->tgt) /* we've looped and found nada */ | 242 | if (tt == d->tgt) /* we've looped and found nada */ |
196 | break; | 243 | break; |
197 | t++; | 244 | } |
198 | if (t >= &d->targets[NTARGETS] || !*t) | 245 | if (totout == 0) { |
199 | t = d->targets; | 246 | d->kicked++; |
247 | d->flags |= DEVFL_KICKME; | ||
200 | } | 248 | } |
201 | return NULL; | 249 | return NULL; |
202 | } | 250 | } |
203 | 251 | ||
252 | static void | ||
253 | skb_fillup(struct sk_buff *skb, struct bio_vec *bv, ulong off, ulong cnt) | ||
254 | { | ||
255 | int frag = 0; | ||
256 | ulong fcnt; | ||
257 | loop: | ||
258 | fcnt = bv->bv_len - (off - bv->bv_offset); | ||
259 | if (fcnt > cnt) | ||
260 | fcnt = cnt; | ||
261 | skb_fill_page_desc(skb, frag++, bv->bv_page, off, fcnt); | ||
262 | cnt -= fcnt; | ||
263 | if (cnt <= 0) | ||
264 | return; | ||
265 | bv++; | ||
266 | off = bv->bv_offset; | ||
267 | goto loop; | ||
268 | } | ||
269 | |||
270 | static void | ||
271 | fhash(struct frame *f) | ||
272 | { | ||
273 | struct aoedev *d = f->t->d; | ||
274 | u32 n; | ||
275 | |||
276 | n = f->tag % NFACTIVE; | ||
277 | list_add_tail(&f->head, &d->factive[n]); | ||
278 | } | ||
279 | |||
204 | static int | 280 | static int |
205 | aoecmd_ata_rw(struct aoedev *d) | 281 | aoecmd_ata_rw(struct aoedev *d) |
206 | { | 282 | { |
@@ -208,26 +284,47 @@ aoecmd_ata_rw(struct aoedev *d) | |||
208 | struct aoe_hdr *h; | 284 | struct aoe_hdr *h; |
209 | struct aoe_atahdr *ah; | 285 | struct aoe_atahdr *ah; |
210 | struct buf *buf; | 286 | struct buf *buf; |
211 | struct bio_vec *bv; | ||
212 | struct aoetgt *t; | 287 | struct aoetgt *t; |
213 | struct sk_buff *skb; | 288 | struct sk_buff *skb; |
214 | ulong bcnt; | 289 | struct sk_buff_head queue; |
290 | ulong bcnt, fbcnt; | ||
215 | char writebit, extbit; | 291 | char writebit, extbit; |
216 | 292 | ||
217 | writebit = 0x10; | 293 | writebit = 0x10; |
218 | extbit = 0x4; | 294 | extbit = 0x4; |
219 | 295 | ||
220 | f = freeframe(d); | 296 | buf = nextbuf(d); |
297 | if (buf == NULL) | ||
298 | return 0; | ||
299 | f = newframe(d); | ||
221 | if (f == NULL) | 300 | if (f == NULL) |
222 | return 0; | 301 | return 0; |
223 | t = *d->tgt; | 302 | t = *d->tgt; |
224 | buf = d->inprocess; | 303 | bcnt = d->maxbcnt; |
225 | bv = buf->bv; | ||
226 | bcnt = t->ifp->maxbcnt; | ||
227 | if (bcnt == 0) | 304 | if (bcnt == 0) |
228 | bcnt = DEFAULTBCNT; | 305 | bcnt = DEFAULTBCNT; |
229 | if (bcnt > buf->bv_resid) | 306 | if (bcnt > buf->resid) |
230 | bcnt = buf->bv_resid; | 307 | bcnt = buf->resid; |
308 | fbcnt = bcnt; | ||
309 | f->bv = buf->bv; | ||
310 | f->bv_off = f->bv->bv_offset + (f->bv->bv_len - buf->bv_resid); | ||
311 | do { | ||
312 | if (fbcnt < buf->bv_resid) { | ||
313 | buf->bv_resid -= fbcnt; | ||
314 | buf->resid -= fbcnt; | ||
315 | break; | ||
316 | } | ||
317 | fbcnt -= buf->bv_resid; | ||
318 | buf->resid -= buf->bv_resid; | ||
319 | if (buf->resid == 0) { | ||
320 | d->ip.buf = NULL; | ||
321 | break; | ||
322 | } | ||
323 | buf->bv++; | ||
324 | buf->bv_resid = buf->bv->bv_len; | ||
325 | WARN_ON(buf->bv_resid == 0); | ||
326 | } while (fbcnt); | ||
327 | |||
231 | /* initialize the headers & frame */ | 328 | /* initialize the headers & frame */ |
232 | skb = f->skb; | 329 | skb = f->skb; |
233 | h = (struct aoe_hdr *) skb_mac_header(skb); | 330 | h = (struct aoe_hdr *) skb_mac_header(skb); |
@@ -235,10 +332,10 @@ aoecmd_ata_rw(struct aoedev *d) | |||
235 | skb_put(skb, sizeof *h + sizeof *ah); | 332 | skb_put(skb, sizeof *h + sizeof *ah); |
236 | memset(h, 0, skb->len); | 333 | memset(h, 0, skb->len); |
237 | f->tag = aoehdr_atainit(d, t, h); | 334 | f->tag = aoehdr_atainit(d, t, h); |
335 | fhash(f); | ||
238 | t->nout++; | 336 | t->nout++; |
239 | f->waited = 0; | 337 | f->waited = 0; |
240 | f->buf = buf; | 338 | f->buf = buf; |
241 | f->bufaddr = page_address(bv->bv_page) + buf->bv_off; | ||
242 | f->bcnt = bcnt; | 339 | f->bcnt = bcnt; |
243 | f->lba = buf->sector; | 340 | f->lba = buf->sector; |
244 | 341 | ||
@@ -253,10 +350,11 @@ aoecmd_ata_rw(struct aoedev *d) | |||
253 | ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */ | 350 | ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */ |
254 | } | 351 | } |
255 | if (bio_data_dir(buf->bio) == WRITE) { | 352 | if (bio_data_dir(buf->bio) == WRITE) { |
256 | skb_fill_page_desc(skb, 0, bv->bv_page, buf->bv_off, bcnt); | 353 | skb_fillup(skb, f->bv, f->bv_off, bcnt); |
257 | ah->aflags |= AOEAFL_WRITE; | 354 | ah->aflags |= AOEAFL_WRITE; |
258 | skb->len += bcnt; | 355 | skb->len += bcnt; |
259 | skb->data_len = bcnt; | 356 | skb->data_len = bcnt; |
357 | skb->truesize += bcnt; | ||
260 | t->wpkts++; | 358 | t->wpkts++; |
261 | } else { | 359 | } else { |
262 | t->rpkts++; | 360 | t->rpkts++; |
@@ -267,23 +365,15 @@ aoecmd_ata_rw(struct aoedev *d) | |||
267 | 365 | ||
268 | /* mark all tracking fields and load out */ | 366 | /* mark all tracking fields and load out */ |
269 | buf->nframesout += 1; | 367 | buf->nframesout += 1; |
270 | buf->bv_off += bcnt; | ||
271 | buf->bv_resid -= bcnt; | ||
272 | buf->resid -= bcnt; | ||
273 | buf->sector += bcnt >> 9; | 368 | buf->sector += bcnt >> 9; |
274 | if (buf->resid == 0) { | ||
275 | d->inprocess = NULL; | ||
276 | } else if (buf->bv_resid == 0) { | ||
277 | buf->bv = ++bv; | ||
278 | buf->bv_resid = bv->bv_len; | ||
279 | WARN_ON(buf->bv_resid == 0); | ||
280 | buf->bv_off = bv->bv_offset; | ||
281 | } | ||
282 | 369 | ||
283 | skb->dev = t->ifp->nd; | 370 | skb->dev = t->ifp->nd; |
284 | skb = skb_clone(skb, GFP_ATOMIC); | 371 | skb = skb_clone(skb, GFP_ATOMIC); |
285 | if (skb) | 372 | if (skb) { |
286 | __skb_queue_tail(&d->sendq, skb); | 373 | __skb_queue_head_init(&queue); |
374 | __skb_queue_tail(&queue, skb); | ||
375 | aoenet_xmit(&queue); | ||
376 | } | ||
287 | return 1; | 377 | return 1; |
288 | } | 378 | } |
289 | 379 | ||
@@ -330,17 +420,25 @@ cont: | |||
330 | } | 420 | } |
331 | 421 | ||
332 | static void | 422 | static void |
333 | resend(struct aoedev *d, struct aoetgt *t, struct frame *f) | 423 | resend(struct aoedev *d, struct frame *f) |
334 | { | 424 | { |
335 | struct sk_buff *skb; | 425 | struct sk_buff *skb; |
426 | struct sk_buff_head queue; | ||
336 | struct aoe_hdr *h; | 427 | struct aoe_hdr *h; |
337 | struct aoe_atahdr *ah; | 428 | struct aoe_atahdr *ah; |
429 | struct aoetgt *t; | ||
338 | char buf[128]; | 430 | char buf[128]; |
339 | u32 n; | 431 | u32 n; |
340 | 432 | ||
341 | ifrotate(t); | 433 | t = f->t; |
342 | n = newtag(t); | 434 | n = newtag(d); |
343 | skb = f->skb; | 435 | skb = f->skb; |
436 | if (ifrotate(t) == NULL) { | ||
437 | /* probably can't happen, but set it up to fail anyway */ | ||
438 | pr_info("aoe: resend: no interfaces to rotate to.\n"); | ||
439 | ktcomplete(f, NULL); | ||
440 | return; | ||
441 | } | ||
344 | h = (struct aoe_hdr *) skb_mac_header(skb); | 442 | h = (struct aoe_hdr *) skb_mac_header(skb); |
345 | ah = (struct aoe_atahdr *) (h+1); | 443 | ah = (struct aoe_atahdr *) (h+1); |
346 | 444 | ||
@@ -351,39 +449,22 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f) | |||
351 | aoechr_error(buf); | 449 | aoechr_error(buf); |
352 | 450 | ||
353 | f->tag = n; | 451 | f->tag = n; |
452 | fhash(f); | ||
354 | h->tag = cpu_to_be32(n); | 453 | h->tag = cpu_to_be32(n); |
355 | memcpy(h->dst, t->addr, sizeof h->dst); | 454 | memcpy(h->dst, t->addr, sizeof h->dst); |
356 | memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); | 455 | memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); |
357 | 456 | ||
358 | switch (ah->cmdstat) { | ||
359 | default: | ||
360 | break; | ||
361 | case ATA_CMD_PIO_READ: | ||
362 | case ATA_CMD_PIO_READ_EXT: | ||
363 | case ATA_CMD_PIO_WRITE: | ||
364 | case ATA_CMD_PIO_WRITE_EXT: | ||
365 | put_lba(ah, f->lba); | ||
366 | |||
367 | n = f->bcnt; | ||
368 | if (n > DEFAULTBCNT) | ||
369 | n = DEFAULTBCNT; | ||
370 | ah->scnt = n >> 9; | ||
371 | if (ah->aflags & AOEAFL_WRITE) { | ||
372 | skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), | ||
373 | offset_in_page(f->bufaddr), n); | ||
374 | skb->len = sizeof *h + sizeof *ah + n; | ||
375 | skb->data_len = n; | ||
376 | } | ||
377 | } | ||
378 | skb->dev = t->ifp->nd; | 457 | skb->dev = t->ifp->nd; |
379 | skb = skb_clone(skb, GFP_ATOMIC); | 458 | skb = skb_clone(skb, GFP_ATOMIC); |
380 | if (skb == NULL) | 459 | if (skb == NULL) |
381 | return; | 460 | return; |
382 | __skb_queue_tail(&d->sendq, skb); | 461 | __skb_queue_head_init(&queue); |
462 | __skb_queue_tail(&queue, skb); | ||
463 | aoenet_xmit(&queue); | ||
383 | } | 464 | } |
384 | 465 | ||
385 | static int | 466 | static int |
386 | tsince(int tag) | 467 | tsince(u32 tag) |
387 | { | 468 | { |
388 | int n; | 469 | int n; |
389 | 470 | ||
@@ -407,58 +488,65 @@ getif(struct aoetgt *t, struct net_device *nd) | |||
407 | return NULL; | 488 | return NULL; |
408 | } | 489 | } |
409 | 490 | ||
410 | static struct aoeif * | ||
411 | addif(struct aoetgt *t, struct net_device *nd) | ||
412 | { | ||
413 | struct aoeif *p; | ||
414 | |||
415 | p = getif(t, NULL); | ||
416 | if (!p) | ||
417 | return NULL; | ||
418 | p->nd = nd; | ||
419 | p->maxbcnt = DEFAULTBCNT; | ||
420 | p->lost = 0; | ||
421 | p->lostjumbo = 0; | ||
422 | return p; | ||
423 | } | ||
424 | |||
425 | static void | 491 | static void |
426 | ejectif(struct aoetgt *t, struct aoeif *ifp) | 492 | ejectif(struct aoetgt *t, struct aoeif *ifp) |
427 | { | 493 | { |
428 | struct aoeif *e; | 494 | struct aoeif *e; |
495 | struct net_device *nd; | ||
429 | ulong n; | 496 | ulong n; |
430 | 497 | ||
498 | nd = ifp->nd; | ||
431 | e = t->ifs + NAOEIFS - 1; | 499 | e = t->ifs + NAOEIFS - 1; |
432 | n = (e - ifp) * sizeof *ifp; | 500 | n = (e - ifp) * sizeof *ifp; |
433 | memmove(ifp, ifp+1, n); | 501 | memmove(ifp, ifp+1, n); |
434 | e->nd = NULL; | 502 | e->nd = NULL; |
503 | dev_put(nd); | ||
435 | } | 504 | } |
436 | 505 | ||
437 | static int | 506 | static int |
438 | sthtith(struct aoedev *d) | 507 | sthtith(struct aoedev *d) |
439 | { | 508 | { |
440 | struct frame *f, *e, *nf; | 509 | struct frame *f, *nf; |
510 | struct list_head *nx, *pos, *head; | ||
441 | struct sk_buff *skb; | 511 | struct sk_buff *skb; |
442 | struct aoetgt *ht = *d->htgt; | 512 | struct aoetgt *ht = d->htgt; |
443 | 513 | int i; | |
444 | f = ht->frames; | 514 | |
445 | e = f + ht->nframes; | 515 | for (i = 0; i < NFACTIVE; i++) { |
446 | for (; f < e; f++) { | 516 | head = &d->factive[i]; |
447 | if (f->tag == FREETAG) | 517 | list_for_each_safe(pos, nx, head) { |
448 | continue; | 518 | f = list_entry(pos, struct frame, head); |
449 | nf = freeframe(d); | 519 | if (f->t != ht) |
450 | if (!nf) | 520 | continue; |
451 | return 0; | 521 | |
452 | skb = nf->skb; | 522 | nf = newframe(d); |
453 | *nf = *f; | 523 | if (!nf) |
454 | f->skb = skb; | 524 | return 0; |
455 | f->tag = FREETAG; | 525 | |
456 | nf->waited = 0; | 526 | /* remove frame from active list */ |
457 | ht->nout--; | 527 | list_del(pos); |
458 | (*d->tgt)->nout++; | 528 | |
459 | resend(d, *d->tgt, nf); | 529 | /* reassign all pertinent bits to new outbound frame */ |
530 | skb = nf->skb; | ||
531 | nf->skb = f->skb; | ||
532 | nf->buf = f->buf; | ||
533 | nf->bcnt = f->bcnt; | ||
534 | nf->lba = f->lba; | ||
535 | nf->bv = f->bv; | ||
536 | nf->bv_off = f->bv_off; | ||
537 | nf->waited = 0; | ||
538 | f->skb = skb; | ||
539 | aoe_freetframe(f); | ||
540 | ht->nout--; | ||
541 | nf->t->nout++; | ||
542 | resend(d, nf); | ||
543 | } | ||
460 | } | 544 | } |
461 | /* he's clean, he's useless. take away his interfaces */ | 545 | /* We've cleaned up the outstanding so take away his |
546 | * interfaces so he won't be used. We should remove him from | ||
547 | * the target array here, but cleaning up a target is | ||
548 | * involved. PUNT! | ||
549 | */ | ||
462 | memset(ht->ifs, 0, sizeof ht->ifs); | 550 | memset(ht->ifs, 0, sizeof ht->ifs); |
463 | d->htgt = NULL; | 551 | d->htgt = NULL; |
464 | return 1; | 552 | return 1; |
@@ -477,13 +565,15 @@ ata_scnt(unsigned char *packet) { | |||
477 | static void | 565 | static void |
478 | rexmit_timer(ulong vp) | 566 | rexmit_timer(ulong vp) |
479 | { | 567 | { |
480 | struct sk_buff_head queue; | ||
481 | struct aoedev *d; | 568 | struct aoedev *d; |
482 | struct aoetgt *t, **tt, **te; | 569 | struct aoetgt *t, **tt, **te; |
483 | struct aoeif *ifp; | 570 | struct aoeif *ifp; |
484 | struct frame *f, *e; | 571 | struct frame *f; |
572 | struct list_head *head, *pos, *nx; | ||
573 | LIST_HEAD(flist); | ||
485 | register long timeout; | 574 | register long timeout; |
486 | ulong flags, n; | 575 | ulong flags, n; |
576 | int i; | ||
487 | 577 | ||
488 | d = (struct aoedev *) vp; | 578 | d = (struct aoedev *) vp; |
489 | 579 | ||
@@ -497,58 +587,22 @@ rexmit_timer(ulong vp) | |||
497 | spin_unlock_irqrestore(&d->lock, flags); | 587 | spin_unlock_irqrestore(&d->lock, flags); |
498 | return; | 588 | return; |
499 | } | 589 | } |
500 | tt = d->targets; | ||
501 | te = tt + NTARGETS; | ||
502 | for (; tt < te && *tt; tt++) { | ||
503 | t = *tt; | ||
504 | f = t->frames; | ||
505 | e = f + t->nframes; | ||
506 | for (; f < e; f++) { | ||
507 | if (f->tag == FREETAG | ||
508 | || tsince(f->tag) < timeout) | ||
509 | continue; | ||
510 | n = f->waited += timeout; | ||
511 | n /= HZ; | ||
512 | if (n > aoe_deadsecs) { | ||
513 | /* waited too long. device failure. */ | ||
514 | aoedev_downdev(d); | ||
515 | break; | ||
516 | } | ||
517 | |||
518 | if (n > HELPWAIT /* see if another target can help */ | ||
519 | && (tt != d->targets || d->targets[1])) | ||
520 | d->htgt = tt; | ||
521 | |||
522 | if (t->nout == t->maxout) { | ||
523 | if (t->maxout > 1) | ||
524 | t->maxout--; | ||
525 | t->lastwadj = jiffies; | ||
526 | } | ||
527 | |||
528 | ifp = getif(t, f->skb->dev); | ||
529 | if (ifp && ++ifp->lost > (t->nframes << 1) | ||
530 | && (ifp != t->ifs || t->ifs[1].nd)) { | ||
531 | ejectif(t, ifp); | ||
532 | ifp = NULL; | ||
533 | } | ||
534 | 590 | ||
535 | if (ata_scnt(skb_mac_header(f->skb)) > DEFAULTBCNT / 512 | 591 | /* collect all frames to rexmit into flist */ |
536 | && ifp && ++ifp->lostjumbo > (t->nframes << 1) | 592 | for (i = 0; i < NFACTIVE; i++) { |
537 | && ifp->maxbcnt != DEFAULTBCNT) { | 593 | head = &d->factive[i]; |
538 | printk(KERN_INFO | 594 | list_for_each_safe(pos, nx, head) { |
539 | "aoe: e%ld.%d: " | 595 | f = list_entry(pos, struct frame, head); |
540 | "too many lost jumbo on " | 596 | if (tsince(f->tag) < timeout) |
541 | "%s:%pm - " | 597 | break; /* end of expired frames */ |
542 | "falling back to %d frames.\n", | 598 | /* move to flist for later processing */ |
543 | d->aoemajor, d->aoeminor, | 599 | list_move_tail(pos, &flist); |
544 | ifp->nd->name, t->addr, | ||
545 | DEFAULTBCNT); | ||
546 | ifp->maxbcnt = 0; | ||
547 | } | ||
548 | resend(d, t, f); | ||
549 | } | 600 | } |
550 | 601 | } | |
551 | /* window check */ | 602 | /* window check */ |
603 | tt = d->targets; | ||
604 | te = tt + d->ntargets; | ||
605 | for (; tt < te && (t = *tt); tt++) { | ||
552 | if (t->nout == t->maxout | 606 | if (t->nout == t->maxout |
553 | && t->maxout < t->nframes | 607 | && t->maxout < t->nframes |
554 | && (jiffies - t->lastwadj)/HZ > 10) { | 608 | && (jiffies - t->lastwadj)/HZ > 10) { |
@@ -557,45 +611,173 @@ rexmit_timer(ulong vp) | |||
557 | } | 611 | } |
558 | } | 612 | } |
559 | 613 | ||
560 | if (!skb_queue_empty(&d->sendq)) { | 614 | if (!list_empty(&flist)) { /* retransmissions necessary */ |
561 | n = d->rttavg <<= 1; | 615 | n = d->rttavg <<= 1; |
562 | if (n > MAXTIMER) | 616 | if (n > MAXTIMER) |
563 | d->rttavg = MAXTIMER; | 617 | d->rttavg = MAXTIMER; |
564 | } | 618 | } |
565 | 619 | ||
566 | if (d->flags & DEVFL_KICKME || d->htgt) { | 620 | /* process expired frames */ |
567 | d->flags &= ~DEVFL_KICKME; | 621 | while (!list_empty(&flist)) { |
568 | aoecmd_work(d); | 622 | pos = flist.next; |
623 | f = list_entry(pos, struct frame, head); | ||
624 | n = f->waited += timeout; | ||
625 | n /= HZ; | ||
626 | if (n > aoe_deadsecs) { | ||
627 | /* Waited too long. Device failure. | ||
628 | * Hang all frames on first hash bucket for downdev | ||
629 | * to clean up. | ||
630 | */ | ||
631 | list_splice(&flist, &d->factive[0]); | ||
632 | aoedev_downdev(d); | ||
633 | break; | ||
634 | } | ||
635 | list_del(pos); | ||
636 | |||
637 | t = f->t; | ||
638 | if (n > aoe_deadsecs/2) | ||
639 | d->htgt = t; /* see if another target can help */ | ||
640 | |||
641 | if (t->nout == t->maxout) { | ||
642 | if (t->maxout > 1) | ||
643 | t->maxout--; | ||
644 | t->lastwadj = jiffies; | ||
645 | } | ||
646 | |||
647 | ifp = getif(t, f->skb->dev); | ||
648 | if (ifp && ++ifp->lost > (t->nframes << 1) | ||
649 | && (ifp != t->ifs || t->ifs[1].nd)) { | ||
650 | ejectif(t, ifp); | ||
651 | ifp = NULL; | ||
652 | } | ||
653 | resend(d, f); | ||
569 | } | 654 | } |
570 | 655 | ||
571 | __skb_queue_head_init(&queue); | 656 | if ((d->flags & DEVFL_KICKME || d->htgt) && d->blkq) { |
572 | skb_queue_splice_init(&d->sendq, &queue); | 657 | d->flags &= ~DEVFL_KICKME; |
658 | d->blkq->request_fn(d->blkq); | ||
659 | } | ||
573 | 660 | ||
574 | d->timer.expires = jiffies + TIMERTICK; | 661 | d->timer.expires = jiffies + TIMERTICK; |
575 | add_timer(&d->timer); | 662 | add_timer(&d->timer); |
576 | 663 | ||
577 | spin_unlock_irqrestore(&d->lock, flags); | 664 | spin_unlock_irqrestore(&d->lock, flags); |
665 | } | ||
578 | 666 | ||
579 | aoenet_xmit(&queue); | 667 | static unsigned long |
668 | rqbiocnt(struct request *r) | ||
669 | { | ||
670 | struct bio *bio; | ||
671 | unsigned long n = 0; | ||
672 | |||
673 | __rq_for_each_bio(bio, r) | ||
674 | n++; | ||
675 | return n; | ||
676 | } | ||
677 | |||
678 | /* This can be removed if we are certain that no users of the block | ||
679 | * layer will ever use zero-count pages in bios. Otherwise we have to | ||
680 | * protect against the put_page sometimes done by the network layer. | ||
681 | * | ||
682 | * See http://oss.sgi.com/archives/xfs/2007-01/msg00594.html for | ||
683 | * discussion. | ||
684 | * | ||
685 | * We cannot use get_page in the workaround, because it insists on a | ||
686 | * positive page count as a precondition. So we use _count directly. | ||
687 | */ | ||
688 | static void | ||
689 | bio_pageinc(struct bio *bio) | ||
690 | { | ||
691 | struct bio_vec *bv; | ||
692 | struct page *page; | ||
693 | int i; | ||
694 | |||
695 | bio_for_each_segment(bv, bio, i) { | ||
696 | page = bv->bv_page; | ||
697 | /* Non-zero page count for non-head members of | ||
698 | * compound pages is no longer allowed by the kernel, | ||
699 | * but this has never been seen here. | ||
700 | */ | ||
701 | if (unlikely(PageCompound(page))) | ||
702 | if (compound_trans_head(page) != page) { | ||
703 | pr_crit("page tail used for block I/O\n"); | ||
704 | BUG(); | ||
705 | } | ||
706 | atomic_inc(&page->_count); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | static void | ||
711 | bio_pagedec(struct bio *bio) | ||
712 | { | ||
713 | struct bio_vec *bv; | ||
714 | int i; | ||
715 | |||
716 | bio_for_each_segment(bv, bio, i) | ||
717 | atomic_dec(&bv->bv_page->_count); | ||
718 | } | ||
719 | |||
720 | static void | ||
721 | bufinit(struct buf *buf, struct request *rq, struct bio *bio) | ||
722 | { | ||
723 | struct bio_vec *bv; | ||
724 | |||
725 | memset(buf, 0, sizeof(*buf)); | ||
726 | buf->rq = rq; | ||
727 | buf->bio = bio; | ||
728 | buf->resid = bio->bi_size; | ||
729 | buf->sector = bio->bi_sector; | ||
730 | bio_pageinc(bio); | ||
731 | buf->bv = bv = &bio->bi_io_vec[bio->bi_idx]; | ||
732 | buf->bv_resid = bv->bv_len; | ||
733 | WARN_ON(buf->bv_resid == 0); | ||
734 | } | ||
735 | |||
736 | static struct buf * | ||
737 | nextbuf(struct aoedev *d) | ||
738 | { | ||
739 | struct request *rq; | ||
740 | struct request_queue *q; | ||
741 | struct buf *buf; | ||
742 | struct bio *bio; | ||
743 | |||
744 | q = d->blkq; | ||
745 | if (q == NULL) | ||
746 | return NULL; /* initializing */ | ||
747 | if (d->ip.buf) | ||
748 | return d->ip.buf; | ||
749 | rq = d->ip.rq; | ||
750 | if (rq == NULL) { | ||
751 | rq = blk_peek_request(q); | ||
752 | if (rq == NULL) | ||
753 | return NULL; | ||
754 | blk_start_request(rq); | ||
755 | d->ip.rq = rq; | ||
756 | d->ip.nxbio = rq->bio; | ||
757 | rq->special = (void *) rqbiocnt(rq); | ||
758 | } | ||
759 | buf = mempool_alloc(d->bufpool, GFP_ATOMIC); | ||
760 | if (buf == NULL) { | ||
761 | pr_err("aoe: nextbuf: unable to mempool_alloc!\n"); | ||
762 | return NULL; | ||
763 | } | ||
764 | bio = d->ip.nxbio; | ||
765 | bufinit(buf, rq, bio); | ||
766 | bio = bio->bi_next; | ||
767 | d->ip.nxbio = bio; | ||
768 | if (bio == NULL) | ||
769 | d->ip.rq = NULL; | ||
770 | return d->ip.buf = buf; | ||
580 | } | 771 | } |
581 | 772 | ||
582 | /* enters with d->lock held */ | 773 | /* enters with d->lock held */ |
583 | void | 774 | void |
584 | aoecmd_work(struct aoedev *d) | 775 | aoecmd_work(struct aoedev *d) |
585 | { | 776 | { |
586 | struct buf *buf; | ||
587 | loop: | ||
588 | if (d->htgt && !sthtith(d)) | 777 | if (d->htgt && !sthtith(d)) |
589 | return; | 778 | return; |
590 | if (d->inprocess == NULL) { | 779 | while (aoecmd_ata_rw(d)) |
591 | if (list_empty(&d->bufq)) | 780 | ; |
592 | return; | ||
593 | buf = container_of(d->bufq.next, struct buf, bufs); | ||
594 | list_del(d->bufq.next); | ||
595 | d->inprocess = buf; | ||
596 | } | ||
597 | if (aoecmd_ata_rw(d)) | ||
598 | goto loop; | ||
599 | } | 781 | } |
600 | 782 | ||
601 | /* this function performs work that has been deferred until sleeping is OK | 783 | /* this function performs work that has been deferred until sleeping is OK |
@@ -604,28 +786,25 @@ void | |||
604 | aoecmd_sleepwork(struct work_struct *work) | 786 | aoecmd_sleepwork(struct work_struct *work) |
605 | { | 787 | { |
606 | struct aoedev *d = container_of(work, struct aoedev, work); | 788 | struct aoedev *d = container_of(work, struct aoedev, work); |
789 | struct block_device *bd; | ||
790 | u64 ssize; | ||
607 | 791 | ||
608 | if (d->flags & DEVFL_GDALLOC) | 792 | if (d->flags & DEVFL_GDALLOC) |
609 | aoeblk_gdalloc(d); | 793 | aoeblk_gdalloc(d); |
610 | 794 | ||
611 | if (d->flags & DEVFL_NEWSIZE) { | 795 | if (d->flags & DEVFL_NEWSIZE) { |
612 | struct block_device *bd; | ||
613 | unsigned long flags; | ||
614 | u64 ssize; | ||
615 | |||
616 | ssize = get_capacity(d->gd); | 796 | ssize = get_capacity(d->gd); |
617 | bd = bdget_disk(d->gd, 0); | 797 | bd = bdget_disk(d->gd, 0); |
618 | |||
619 | if (bd) { | 798 | if (bd) { |
620 | mutex_lock(&bd->bd_inode->i_mutex); | 799 | mutex_lock(&bd->bd_inode->i_mutex); |
621 | i_size_write(bd->bd_inode, (loff_t)ssize<<9); | 800 | i_size_write(bd->bd_inode, (loff_t)ssize<<9); |
622 | mutex_unlock(&bd->bd_inode->i_mutex); | 801 | mutex_unlock(&bd->bd_inode->i_mutex); |
623 | bdput(bd); | 802 | bdput(bd); |
624 | } | 803 | } |
625 | spin_lock_irqsave(&d->lock, flags); | 804 | spin_lock_irq(&d->lock); |
626 | d->flags |= DEVFL_UP; | 805 | d->flags |= DEVFL_UP; |
627 | d->flags &= ~DEVFL_NEWSIZE; | 806 | d->flags &= ~DEVFL_NEWSIZE; |
628 | spin_unlock_irqrestore(&d->lock, flags); | 807 | spin_unlock_irq(&d->lock); |
629 | } | 808 | } |
630 | } | 809 | } |
631 | 810 | ||
@@ -718,163 +897,299 @@ gettgt(struct aoedev *d, char *addr) | |||
718 | return NULL; | 897 | return NULL; |
719 | } | 898 | } |
720 | 899 | ||
721 | static inline void | 900 | static void |
722 | diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector) | 901 | bvcpy(struct bio_vec *bv, ulong off, struct sk_buff *skb, long cnt) |
902 | { | ||
903 | ulong fcnt; | ||
904 | char *p; | ||
905 | int soff = 0; | ||
906 | loop: | ||
907 | fcnt = bv->bv_len - (off - bv->bv_offset); | ||
908 | if (fcnt > cnt) | ||
909 | fcnt = cnt; | ||
910 | p = page_address(bv->bv_page) + off; | ||
911 | skb_copy_bits(skb, soff, p, fcnt); | ||
912 | soff += fcnt; | ||
913 | cnt -= fcnt; | ||
914 | if (cnt <= 0) | ||
915 | return; | ||
916 | bv++; | ||
917 | off = bv->bv_offset; | ||
918 | goto loop; | ||
919 | } | ||
920 | |||
921 | void | ||
922 | aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) | ||
923 | { | ||
924 | struct bio *bio; | ||
925 | int bok; | ||
926 | struct request_queue *q; | ||
927 | |||
928 | q = d->blkq; | ||
929 | if (rq == d->ip.rq) | ||
930 | d->ip.rq = NULL; | ||
931 | do { | ||
932 | bio = rq->bio; | ||
933 | bok = !fastfail && test_bit(BIO_UPTODATE, &bio->bi_flags); | ||
934 | } while (__blk_end_request(rq, bok ? 0 : -EIO, bio->bi_size)); | ||
935 | |||
936 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ | ||
937 | if (!fastfail) | ||
938 | q->request_fn(q); | ||
939 | } | ||
940 | |||
941 | static void | ||
942 | aoe_end_buf(struct aoedev *d, struct buf *buf) | ||
943 | { | ||
944 | struct request *rq; | ||
945 | unsigned long n; | ||
946 | |||
947 | if (buf == d->ip.buf) | ||
948 | d->ip.buf = NULL; | ||
949 | rq = buf->rq; | ||
950 | bio_pagedec(buf->bio); | ||
951 | mempool_free(buf, d->bufpool); | ||
952 | n = (unsigned long) rq->special; | ||
953 | rq->special = (void *) --n; | ||
954 | if (n == 0) | ||
955 | aoe_end_request(d, rq, 0); | ||
956 | } | ||
957 | |||
958 | static void | ||
959 | ktiocomplete(struct frame *f) | ||
723 | { | 960 | { |
724 | unsigned long n_sect = bio->bi_size >> 9; | 961 | struct aoe_hdr *hin, *hout; |
725 | const int rw = bio_data_dir(bio); | 962 | struct aoe_atahdr *ahin, *ahout; |
726 | struct hd_struct *part; | 963 | struct buf *buf; |
727 | int cpu; | 964 | struct sk_buff *skb; |
965 | struct aoetgt *t; | ||
966 | struct aoeif *ifp; | ||
967 | struct aoedev *d; | ||
968 | long n; | ||
969 | |||
970 | if (f == NULL) | ||
971 | return; | ||
972 | |||
973 | t = f->t; | ||
974 | d = t->d; | ||
975 | |||
976 | hout = (struct aoe_hdr *) skb_mac_header(f->skb); | ||
977 | ahout = (struct aoe_atahdr *) (hout+1); | ||
978 | buf = f->buf; | ||
979 | skb = f->r_skb; | ||
980 | if (skb == NULL) | ||
981 | goto noskb; /* just fail the buf. */ | ||
982 | |||
983 | hin = (struct aoe_hdr *) skb->data; | ||
984 | skb_pull(skb, sizeof(*hin)); | ||
985 | ahin = (struct aoe_atahdr *) skb->data; | ||
986 | skb_pull(skb, sizeof(*ahin)); | ||
987 | if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */ | ||
988 | pr_err("aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n", | ||
989 | ahout->cmdstat, ahin->cmdstat, | ||
990 | d->aoemajor, d->aoeminor); | ||
991 | noskb: if (buf) | ||
992 | clear_bit(BIO_UPTODATE, &buf->bio->bi_flags); | ||
993 | goto badrsp; | ||
994 | } | ||
728 | 995 | ||
729 | cpu = part_stat_lock(); | 996 | n = ahout->scnt << 9; |
730 | part = disk_map_sector_rcu(disk, sector); | 997 | switch (ahout->cmdstat) { |
998 | case ATA_CMD_PIO_READ: | ||
999 | case ATA_CMD_PIO_READ_EXT: | ||
1000 | if (skb->len < n) { | ||
1001 | pr_err("aoe: runt data size in read. skb->len=%d need=%ld\n", | ||
1002 | skb->len, n); | ||
1003 | clear_bit(BIO_UPTODATE, &buf->bio->bi_flags); | ||
1004 | break; | ||
1005 | } | ||
1006 | bvcpy(f->bv, f->bv_off, skb, n); | ||
1007 | case ATA_CMD_PIO_WRITE: | ||
1008 | case ATA_CMD_PIO_WRITE_EXT: | ||
1009 | spin_lock_irq(&d->lock); | ||
1010 | ifp = getif(t, skb->dev); | ||
1011 | if (ifp) | ||
1012 | ifp->lost = 0; | ||
1013 | if (d->htgt == t) /* I'll help myself, thank you. */ | ||
1014 | d->htgt = NULL; | ||
1015 | spin_unlock_irq(&d->lock); | ||
1016 | break; | ||
1017 | case ATA_CMD_ID_ATA: | ||
1018 | if (skb->len < 512) { | ||
1019 | pr_info("aoe: runt data size in ataid. skb->len=%d\n", | ||
1020 | skb->len); | ||
1021 | break; | ||
1022 | } | ||
1023 | if (skb_linearize(skb)) | ||
1024 | break; | ||
1025 | spin_lock_irq(&d->lock); | ||
1026 | ataid_complete(d, t, skb->data); | ||
1027 | spin_unlock_irq(&d->lock); | ||
1028 | break; | ||
1029 | default: | ||
1030 | pr_info("aoe: unrecognized ata command %2.2Xh for %d.%d\n", | ||
1031 | ahout->cmdstat, | ||
1032 | be16_to_cpu(get_unaligned(&hin->major)), | ||
1033 | hin->minor); | ||
1034 | } | ||
1035 | badrsp: | ||
1036 | spin_lock_irq(&d->lock); | ||
1037 | |||
1038 | aoe_freetframe(f); | ||
1039 | |||
1040 | if (buf && --buf->nframesout == 0 && buf->resid == 0) | ||
1041 | aoe_end_buf(d, buf); | ||
1042 | |||
1043 | aoecmd_work(d); | ||
1044 | |||
1045 | spin_unlock_irq(&d->lock); | ||
1046 | aoedev_put(d); | ||
1047 | dev_kfree_skb(skb); | ||
1048 | } | ||
1049 | |||
1050 | /* Enters with iocq.lock held. | ||
1051 | * Returns true iff responses needing processing remain. | ||
1052 | */ | ||
1053 | static int | ||
1054 | ktio(void) | ||
1055 | { | ||
1056 | struct frame *f; | ||
1057 | struct list_head *pos; | ||
1058 | int i; | ||
731 | 1059 | ||
732 | part_stat_inc(cpu, part, ios[rw]); | 1060 | for (i = 0; ; ++i) { |
733 | part_stat_add(cpu, part, ticks[rw], duration); | 1061 | if (i == MAXIOC) |
734 | part_stat_add(cpu, part, sectors[rw], n_sect); | 1062 | return 1; |
735 | part_stat_add(cpu, part, io_ticks, duration); | 1063 | if (list_empty(&iocq.head)) |
1064 | return 0; | ||
1065 | pos = iocq.head.next; | ||
1066 | list_del(pos); | ||
1067 | spin_unlock_irq(&iocq.lock); | ||
1068 | f = list_entry(pos, struct frame, head); | ||
1069 | ktiocomplete(f); | ||
1070 | spin_lock_irq(&iocq.lock); | ||
1071 | } | ||
1072 | } | ||
736 | 1073 | ||
737 | part_stat_unlock(); | 1074 | static int |
1075 | kthread(void *vp) | ||
1076 | { | ||
1077 | struct ktstate *k; | ||
1078 | DECLARE_WAITQUEUE(wait, current); | ||
1079 | int more; | ||
1080 | |||
1081 | k = vp; | ||
1082 | current->flags |= PF_NOFREEZE; | ||
1083 | set_user_nice(current, -10); | ||
1084 | complete(&k->rendez); /* tell spawner we're running */ | ||
1085 | do { | ||
1086 | spin_lock_irq(k->lock); | ||
1087 | more = k->fn(); | ||
1088 | if (!more) { | ||
1089 | add_wait_queue(k->waitq, &wait); | ||
1090 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1091 | } | ||
1092 | spin_unlock_irq(k->lock); | ||
1093 | if (!more) { | ||
1094 | schedule(); | ||
1095 | remove_wait_queue(k->waitq, &wait); | ||
1096 | } else | ||
1097 | cond_resched(); | ||
1098 | } while (!kthread_should_stop()); | ||
1099 | complete(&k->rendez); /* tell spawner we're stopping */ | ||
1100 | return 0; | ||
738 | } | 1101 | } |
739 | 1102 | ||
740 | void | 1103 | void |
1104 | aoe_ktstop(struct ktstate *k) | ||
1105 | { | ||
1106 | kthread_stop(k->task); | ||
1107 | wait_for_completion(&k->rendez); | ||
1108 | } | ||
1109 | |||
1110 | int | ||
1111 | aoe_ktstart(struct ktstate *k) | ||
1112 | { | ||
1113 | struct task_struct *task; | ||
1114 | |||
1115 | init_completion(&k->rendez); | ||
1116 | task = kthread_run(kthread, k, k->name); | ||
1117 | if (task == NULL || IS_ERR(task)) | ||
1118 | return -ENOMEM; | ||
1119 | k->task = task; | ||
1120 | wait_for_completion(&k->rendez); /* allow kthread to start */ | ||
1121 | init_completion(&k->rendez); /* for waiting for exit later */ | ||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1125 | /* pass it off to kthreads for processing */ | ||
1126 | static void | ||
1127 | ktcomplete(struct frame *f, struct sk_buff *skb) | ||
1128 | { | ||
1129 | ulong flags; | ||
1130 | |||
1131 | f->r_skb = skb; | ||
1132 | spin_lock_irqsave(&iocq.lock, flags); | ||
1133 | list_add_tail(&f->head, &iocq.head); | ||
1134 | spin_unlock_irqrestore(&iocq.lock, flags); | ||
1135 | wake_up(&ktiowq); | ||
1136 | } | ||
1137 | |||
1138 | struct sk_buff * | ||
741 | aoecmd_ata_rsp(struct sk_buff *skb) | 1139 | aoecmd_ata_rsp(struct sk_buff *skb) |
742 | { | 1140 | { |
743 | struct sk_buff_head queue; | ||
744 | struct aoedev *d; | 1141 | struct aoedev *d; |
745 | struct aoe_hdr *hin, *hout; | 1142 | struct aoe_hdr *h; |
746 | struct aoe_atahdr *ahin, *ahout; | ||
747 | struct frame *f; | 1143 | struct frame *f; |
748 | struct buf *buf; | ||
749 | struct aoetgt *t; | 1144 | struct aoetgt *t; |
750 | struct aoeif *ifp; | 1145 | u32 n; |
751 | register long n; | ||
752 | ulong flags; | 1146 | ulong flags; |
753 | char ebuf[128]; | 1147 | char ebuf[128]; |
754 | u16 aoemajor; | 1148 | u16 aoemajor; |
755 | 1149 | ||
756 | hin = (struct aoe_hdr *) skb_mac_header(skb); | 1150 | h = (struct aoe_hdr *) skb->data; |
757 | aoemajor = get_unaligned_be16(&hin->major); | 1151 | aoemajor = be16_to_cpu(get_unaligned(&h->major)); |
758 | d = aoedev_by_aoeaddr(aoemajor, hin->minor); | 1152 | d = aoedev_by_aoeaddr(aoemajor, h->minor, 0); |
759 | if (d == NULL) { | 1153 | if (d == NULL) { |
760 | snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response " | 1154 | snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response " |
761 | "for unknown device %d.%d\n", | 1155 | "for unknown device %d.%d\n", |
762 | aoemajor, hin->minor); | 1156 | aoemajor, h->minor); |
763 | aoechr_error(ebuf); | 1157 | aoechr_error(ebuf); |
764 | return; | 1158 | return skb; |
765 | } | 1159 | } |
766 | 1160 | ||
767 | spin_lock_irqsave(&d->lock, flags); | 1161 | spin_lock_irqsave(&d->lock, flags); |
768 | 1162 | ||
769 | n = get_unaligned_be32(&hin->tag); | 1163 | n = be32_to_cpu(get_unaligned(&h->tag)); |
770 | t = gettgt(d, hin->src); | 1164 | f = getframe(d, n); |
771 | if (t == NULL) { | ||
772 | printk(KERN_INFO "aoe: can't find target e%ld.%d:%pm\n", | ||
773 | d->aoemajor, d->aoeminor, hin->src); | ||
774 | spin_unlock_irqrestore(&d->lock, flags); | ||
775 | return; | ||
776 | } | ||
777 | f = getframe(t, n); | ||
778 | if (f == NULL) { | 1165 | if (f == NULL) { |
779 | calc_rttavg(d, -tsince(n)); | 1166 | calc_rttavg(d, -tsince(n)); |
780 | spin_unlock_irqrestore(&d->lock, flags); | 1167 | spin_unlock_irqrestore(&d->lock, flags); |
1168 | aoedev_put(d); | ||
781 | snprintf(ebuf, sizeof ebuf, | 1169 | snprintf(ebuf, sizeof ebuf, |
782 | "%15s e%d.%d tag=%08x@%08lx\n", | 1170 | "%15s e%d.%d tag=%08x@%08lx\n", |
783 | "unexpected rsp", | 1171 | "unexpected rsp", |
784 | get_unaligned_be16(&hin->major), | 1172 | get_unaligned_be16(&h->major), |
785 | hin->minor, | 1173 | h->minor, |
786 | get_unaligned_be32(&hin->tag), | 1174 | get_unaligned_be32(&h->tag), |
787 | jiffies); | 1175 | jiffies); |
788 | aoechr_error(ebuf); | 1176 | aoechr_error(ebuf); |
789 | return; | 1177 | return skb; |
790 | } | 1178 | } |
791 | 1179 | t = f->t; | |
792 | calc_rttavg(d, tsince(f->tag)); | 1180 | calc_rttavg(d, tsince(f->tag)); |
793 | |||
794 | ahin = (struct aoe_atahdr *) (hin+1); | ||
795 | hout = (struct aoe_hdr *) skb_mac_header(f->skb); | ||
796 | ahout = (struct aoe_atahdr *) (hout+1); | ||
797 | buf = f->buf; | ||
798 | |||
799 | if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */ | ||
800 | printk(KERN_ERR | ||
801 | "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n", | ||
802 | ahout->cmdstat, ahin->cmdstat, | ||
803 | d->aoemajor, d->aoeminor); | ||
804 | if (buf) | ||
805 | buf->flags |= BUFFL_FAIL; | ||
806 | } else { | ||
807 | if (d->htgt && t == *d->htgt) /* I'll help myself, thank you. */ | ||
808 | d->htgt = NULL; | ||
809 | n = ahout->scnt << 9; | ||
810 | switch (ahout->cmdstat) { | ||
811 | case ATA_CMD_PIO_READ: | ||
812 | case ATA_CMD_PIO_READ_EXT: | ||
813 | if (skb->len - sizeof *hin - sizeof *ahin < n) { | ||
814 | printk(KERN_ERR | ||
815 | "aoe: %s. skb->len=%d need=%ld\n", | ||
816 | "runt data size in read", skb->len, n); | ||
817 | /* fail frame f? just returning will rexmit. */ | ||
818 | spin_unlock_irqrestore(&d->lock, flags); | ||
819 | return; | ||
820 | } | ||
821 | memcpy(f->bufaddr, ahin+1, n); | ||
822 | case ATA_CMD_PIO_WRITE: | ||
823 | case ATA_CMD_PIO_WRITE_EXT: | ||
824 | ifp = getif(t, skb->dev); | ||
825 | if (ifp) { | ||
826 | ifp->lost = 0; | ||
827 | if (n > DEFAULTBCNT) | ||
828 | ifp->lostjumbo = 0; | ||
829 | } | ||
830 | if (f->bcnt -= n) { | ||
831 | f->lba += n >> 9; | ||
832 | f->bufaddr += n; | ||
833 | resend(d, t, f); | ||
834 | goto xmit; | ||
835 | } | ||
836 | break; | ||
837 | case ATA_CMD_ID_ATA: | ||
838 | if (skb->len - sizeof *hin - sizeof *ahin < 512) { | ||
839 | printk(KERN_INFO | ||
840 | "aoe: runt data size in ataid. skb->len=%d\n", | ||
841 | skb->len); | ||
842 | spin_unlock_irqrestore(&d->lock, flags); | ||
843 | return; | ||
844 | } | ||
845 | ataid_complete(d, t, (char *) (ahin+1)); | ||
846 | break; | ||
847 | default: | ||
848 | printk(KERN_INFO | ||
849 | "aoe: unrecognized ata command %2.2Xh for %d.%d\n", | ||
850 | ahout->cmdstat, | ||
851 | get_unaligned_be16(&hin->major), | ||
852 | hin->minor); | ||
853 | } | ||
854 | } | ||
855 | |||
856 | if (buf && --buf->nframesout == 0 && buf->resid == 0) { | ||
857 | diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector); | ||
858 | if (buf->flags & BUFFL_FAIL) | ||
859 | bio_endio(buf->bio, -EIO); | ||
860 | else { | ||
861 | bio_flush_dcache_pages(buf->bio); | ||
862 | bio_endio(buf->bio, 0); | ||
863 | } | ||
864 | mempool_free(buf, d->bufpool); | ||
865 | } | ||
866 | |||
867 | f->buf = NULL; | ||
868 | f->tag = FREETAG; | ||
869 | t->nout--; | 1181 | t->nout--; |
870 | |||
871 | aoecmd_work(d); | 1182 | aoecmd_work(d); |
872 | xmit: | ||
873 | __skb_queue_head_init(&queue); | ||
874 | skb_queue_splice_init(&d->sendq, &queue); | ||
875 | 1183 | ||
876 | spin_unlock_irqrestore(&d->lock, flags); | 1184 | spin_unlock_irqrestore(&d->lock, flags); |
877 | aoenet_xmit(&queue); | 1185 | |
1186 | ktcomplete(f, skb); | ||
1187 | |||
1188 | /* | ||
1189 | * Note here that we do not perform an aoedev_put, as we are | ||
1190 | * leaving this reference for the ktio to release. | ||
1191 | */ | ||
1192 | return NULL; | ||
878 | } | 1193 | } |
879 | 1194 | ||
880 | void | 1195 | void |
@@ -896,7 +1211,7 @@ aoecmd_ata_id(struct aoedev *d) | |||
896 | struct sk_buff *skb; | 1211 | struct sk_buff *skb; |
897 | struct aoetgt *t; | 1212 | struct aoetgt *t; |
898 | 1213 | ||
899 | f = freeframe(d); | 1214 | f = newframe(d); |
900 | if (f == NULL) | 1215 | if (f == NULL) |
901 | return NULL; | 1216 | return NULL; |
902 | 1217 | ||
@@ -909,6 +1224,7 @@ aoecmd_ata_id(struct aoedev *d) | |||
909 | skb_put(skb, sizeof *h + sizeof *ah); | 1224 | skb_put(skb, sizeof *h + sizeof *ah); |
910 | memset(h, 0, skb->len); | 1225 | memset(h, 0, skb->len); |
911 | f->tag = aoehdr_atainit(d, t, h); | 1226 | f->tag = aoehdr_atainit(d, t, h); |
1227 | fhash(f); | ||
912 | t->nout++; | 1228 | t->nout++; |
913 | f->waited = 0; | 1229 | f->waited = 0; |
914 | 1230 | ||
@@ -929,7 +1245,6 @@ static struct aoetgt * | |||
929 | addtgt(struct aoedev *d, char *addr, ulong nframes) | 1245 | addtgt(struct aoedev *d, char *addr, ulong nframes) |
930 | { | 1246 | { |
931 | struct aoetgt *t, **tt, **te; | 1247 | struct aoetgt *t, **tt, **te; |
932 | struct frame *f, *e; | ||
933 | 1248 | ||
934 | tt = d->targets; | 1249 | tt = d->targets; |
935 | te = tt + NTARGETS; | 1250 | te = tt + NTARGETS; |
@@ -941,26 +1256,73 @@ addtgt(struct aoedev *d, char *addr, ulong nframes) | |||
941 | "aoe: device addtgt failure; too many targets\n"); | 1256 | "aoe: device addtgt failure; too many targets\n"); |
942 | return NULL; | 1257 | return NULL; |
943 | } | 1258 | } |
944 | t = kcalloc(1, sizeof *t, GFP_ATOMIC); | 1259 | t = kzalloc(sizeof(*t), GFP_ATOMIC); |
945 | f = kcalloc(nframes, sizeof *f, GFP_ATOMIC); | 1260 | if (!t) { |
946 | if (!t || !f) { | ||
947 | kfree(f); | ||
948 | kfree(t); | ||
949 | printk(KERN_INFO "aoe: cannot allocate memory to add target\n"); | 1261 | printk(KERN_INFO "aoe: cannot allocate memory to add target\n"); |
950 | return NULL; | 1262 | return NULL; |
951 | } | 1263 | } |
952 | 1264 | ||
1265 | d->ntargets++; | ||
953 | t->nframes = nframes; | 1266 | t->nframes = nframes; |
954 | t->frames = f; | 1267 | t->d = d; |
955 | e = f + nframes; | ||
956 | for (; f < e; f++) | ||
957 | f->tag = FREETAG; | ||
958 | memcpy(t->addr, addr, sizeof t->addr); | 1268 | memcpy(t->addr, addr, sizeof t->addr); |
959 | t->ifp = t->ifs; | 1269 | t->ifp = t->ifs; |
960 | t->maxout = t->nframes; | 1270 | t->maxout = t->nframes; |
1271 | INIT_LIST_HEAD(&t->ffree); | ||
961 | return *tt = t; | 1272 | return *tt = t; |
962 | } | 1273 | } |
963 | 1274 | ||
1275 | static void | ||
1276 | setdbcnt(struct aoedev *d) | ||
1277 | { | ||
1278 | struct aoetgt **t, **e; | ||
1279 | int bcnt = 0; | ||
1280 | |||
1281 | t = d->targets; | ||
1282 | e = t + NTARGETS; | ||
1283 | for (; t < e && *t; t++) | ||
1284 | if (bcnt == 0 || bcnt > (*t)->minbcnt) | ||
1285 | bcnt = (*t)->minbcnt; | ||
1286 | if (bcnt != d->maxbcnt) { | ||
1287 | d->maxbcnt = bcnt; | ||
1288 | pr_info("aoe: e%ld.%d: setting %d byte data frames\n", | ||
1289 | d->aoemajor, d->aoeminor, bcnt); | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | static void | ||
1294 | setifbcnt(struct aoetgt *t, struct net_device *nd, int bcnt) | ||
1295 | { | ||
1296 | struct aoedev *d; | ||
1297 | struct aoeif *p, *e; | ||
1298 | int minbcnt; | ||
1299 | |||
1300 | d = t->d; | ||
1301 | minbcnt = bcnt; | ||
1302 | p = t->ifs; | ||
1303 | e = p + NAOEIFS; | ||
1304 | for (; p < e; p++) { | ||
1305 | if (p->nd == NULL) | ||
1306 | break; /* end of the valid interfaces */ | ||
1307 | if (p->nd == nd) { | ||
1308 | p->bcnt = bcnt; /* we're updating */ | ||
1309 | nd = NULL; | ||
1310 | } else if (minbcnt > p->bcnt) | ||
1311 | minbcnt = p->bcnt; /* find the min interface */ | ||
1312 | } | ||
1313 | if (nd) { | ||
1314 | if (p == e) { | ||
1315 | pr_err("aoe: device setifbcnt failure; too many interfaces.\n"); | ||
1316 | return; | ||
1317 | } | ||
1318 | dev_hold(nd); | ||
1319 | p->nd = nd; | ||
1320 | p->bcnt = bcnt; | ||
1321 | } | ||
1322 | t->minbcnt = minbcnt; | ||
1323 | setdbcnt(d); | ||
1324 | } | ||
1325 | |||
964 | void | 1326 | void |
965 | aoecmd_cfg_rsp(struct sk_buff *skb) | 1327 | aoecmd_cfg_rsp(struct sk_buff *skb) |
966 | { | 1328 | { |
@@ -968,11 +1330,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
968 | struct aoe_hdr *h; | 1330 | struct aoe_hdr *h; |
969 | struct aoe_cfghdr *ch; | 1331 | struct aoe_cfghdr *ch; |
970 | struct aoetgt *t; | 1332 | struct aoetgt *t; |
971 | struct aoeif *ifp; | 1333 | ulong flags, aoemajor; |
972 | ulong flags, sysminor, aoemajor; | ||
973 | struct sk_buff *sl; | 1334 | struct sk_buff *sl; |
1335 | struct sk_buff_head queue; | ||
974 | u16 n; | 1336 | u16 n; |
975 | 1337 | ||
1338 | sl = NULL; | ||
976 | h = (struct aoe_hdr *) skb_mac_header(skb); | 1339 | h = (struct aoe_hdr *) skb_mac_header(skb); |
977 | ch = (struct aoe_cfghdr *) (h+1); | 1340 | ch = (struct aoe_cfghdr *) (h+1); |
978 | 1341 | ||
@@ -986,10 +1349,13 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
986 | "Check shelf dip switches.\n"); | 1349 | "Check shelf dip switches.\n"); |
987 | return; | 1350 | return; |
988 | } | 1351 | } |
989 | 1352 | if (aoemajor == 0xffff) { | |
990 | sysminor = SYSMINOR(aoemajor, h->minor); | 1353 | pr_info("aoe: e%ld.%d: broadcast shelf number invalid\n", |
991 | if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) { | 1354 | aoemajor, (int) h->minor); |
992 | printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n", | 1355 | return; |
1356 | } | ||
1357 | if (h->minor == 0xff) { | ||
1358 | pr_info("aoe: e%ld.%d: broadcast slot number invalid\n", | ||
993 | aoemajor, (int) h->minor); | 1359 | aoemajor, (int) h->minor); |
994 | return; | 1360 | return; |
995 | } | 1361 | } |
@@ -998,9 +1364,9 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
998 | if (n > aoe_maxout) /* keep it reasonable */ | 1364 | if (n > aoe_maxout) /* keep it reasonable */ |
999 | n = aoe_maxout; | 1365 | n = aoe_maxout; |
1000 | 1366 | ||
1001 | d = aoedev_by_sysminor_m(sysminor); | 1367 | d = aoedev_by_aoeaddr(aoemajor, h->minor, 1); |
1002 | if (d == NULL) { | 1368 | if (d == NULL) { |
1003 | printk(KERN_INFO "aoe: device sysminor_m failure\n"); | 1369 | pr_info("aoe: device allocation failure\n"); |
1004 | return; | 1370 | return; |
1005 | } | 1371 | } |
1006 | 1372 | ||
@@ -1009,52 +1375,26 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
1009 | t = gettgt(d, h->src); | 1375 | t = gettgt(d, h->src); |
1010 | if (!t) { | 1376 | if (!t) { |
1011 | t = addtgt(d, h->src, n); | 1377 | t = addtgt(d, h->src, n); |
1012 | if (!t) { | 1378 | if (!t) |
1013 | spin_unlock_irqrestore(&d->lock, flags); | 1379 | goto bail; |
1014 | return; | ||
1015 | } | ||
1016 | } | ||
1017 | ifp = getif(t, skb->dev); | ||
1018 | if (!ifp) { | ||
1019 | ifp = addif(t, skb->dev); | ||
1020 | if (!ifp) { | ||
1021 | printk(KERN_INFO | ||
1022 | "aoe: device addif failure; " | ||
1023 | "too many interfaces?\n"); | ||
1024 | spin_unlock_irqrestore(&d->lock, flags); | ||
1025 | return; | ||
1026 | } | ||
1027 | } | ||
1028 | if (ifp->maxbcnt) { | ||
1029 | n = ifp->nd->mtu; | ||
1030 | n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr); | ||
1031 | n /= 512; | ||
1032 | if (n > ch->scnt) | ||
1033 | n = ch->scnt; | ||
1034 | n = n ? n * 512 : DEFAULTBCNT; | ||
1035 | if (n != ifp->maxbcnt) { | ||
1036 | printk(KERN_INFO | ||
1037 | "aoe: e%ld.%d: setting %d%s%s:%pm\n", | ||
1038 | d->aoemajor, d->aoeminor, n, | ||
1039 | " byte data frames on ", ifp->nd->name, | ||
1040 | t->addr); | ||
1041 | ifp->maxbcnt = n; | ||
1042 | } | ||
1043 | } | 1380 | } |
1381 | n = skb->dev->mtu; | ||
1382 | n -= sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr); | ||
1383 | n /= 512; | ||
1384 | if (n > ch->scnt) | ||
1385 | n = ch->scnt; | ||
1386 | n = n ? n * 512 : DEFAULTBCNT; | ||
1387 | setifbcnt(t, skb->dev, n); | ||
1044 | 1388 | ||
1045 | /* don't change users' perspective */ | 1389 | /* don't change users' perspective */ |
1046 | if (d->nopen) { | 1390 | if (d->nopen == 0) { |
1047 | spin_unlock_irqrestore(&d->lock, flags); | 1391 | d->fw_ver = be16_to_cpu(ch->fwver); |
1048 | return; | 1392 | sl = aoecmd_ata_id(d); |
1049 | } | 1393 | } |
1050 | d->fw_ver = be16_to_cpu(ch->fwver); | 1394 | bail: |
1051 | |||
1052 | sl = aoecmd_ata_id(d); | ||
1053 | |||
1054 | spin_unlock_irqrestore(&d->lock, flags); | 1395 | spin_unlock_irqrestore(&d->lock, flags); |
1055 | 1396 | aoedev_put(d); | |
1056 | if (sl) { | 1397 | if (sl) { |
1057 | struct sk_buff_head queue; | ||
1058 | __skb_queue_head_init(&queue); | 1398 | __skb_queue_head_init(&queue); |
1059 | __skb_queue_tail(&queue, sl); | 1399 | __skb_queue_tail(&queue, sl); |
1060 | aoenet_xmit(&queue); | 1400 | aoenet_xmit(&queue); |
@@ -1065,20 +1405,74 @@ void | |||
1065 | aoecmd_cleanslate(struct aoedev *d) | 1405 | aoecmd_cleanslate(struct aoedev *d) |
1066 | { | 1406 | { |
1067 | struct aoetgt **t, **te; | 1407 | struct aoetgt **t, **te; |
1068 | struct aoeif *p, *e; | ||
1069 | 1408 | ||
1070 | d->mintimer = MINTIMER; | 1409 | d->mintimer = MINTIMER; |
1410 | d->maxbcnt = 0; | ||
1071 | 1411 | ||
1072 | t = d->targets; | 1412 | t = d->targets; |
1073 | te = t + NTARGETS; | 1413 | te = t + NTARGETS; |
1074 | for (; t < te && *t; t++) { | 1414 | for (; t < te && *t; t++) |
1075 | (*t)->maxout = (*t)->nframes; | 1415 | (*t)->maxout = (*t)->nframes; |
1076 | p = (*t)->ifs; | 1416 | } |
1077 | e = p + NAOEIFS; | 1417 | |
1078 | for (; p < e; p++) { | 1418 | void |
1079 | p->lostjumbo = 0; | 1419 | aoe_failbuf(struct aoedev *d, struct buf *buf) |
1080 | p->lost = 0; | 1420 | { |
1081 | p->maxbcnt = DEFAULTBCNT; | 1421 | if (buf == NULL) |
1422 | return; | ||
1423 | buf->resid = 0; | ||
1424 | clear_bit(BIO_UPTODATE, &buf->bio->bi_flags); | ||
1425 | if (buf->nframesout == 0) | ||
1426 | aoe_end_buf(d, buf); | ||
1427 | } | ||
1428 | |||
1429 | void | ||
1430 | aoe_flush_iocq(void) | ||
1431 | { | ||
1432 | struct frame *f; | ||
1433 | struct aoedev *d; | ||
1434 | LIST_HEAD(flist); | ||
1435 | struct list_head *pos; | ||
1436 | struct sk_buff *skb; | ||
1437 | ulong flags; | ||
1438 | |||
1439 | spin_lock_irqsave(&iocq.lock, flags); | ||
1440 | list_splice_init(&iocq.head, &flist); | ||
1441 | spin_unlock_irqrestore(&iocq.lock, flags); | ||
1442 | while (!list_empty(&flist)) { | ||
1443 | pos = flist.next; | ||
1444 | list_del(pos); | ||
1445 | f = list_entry(pos, struct frame, head); | ||
1446 | d = f->t->d; | ||
1447 | skb = f->r_skb; | ||
1448 | spin_lock_irqsave(&d->lock, flags); | ||
1449 | if (f->buf) { | ||
1450 | f->buf->nframesout--; | ||
1451 | aoe_failbuf(d, f->buf); | ||
1082 | } | 1452 | } |
1453 | aoe_freetframe(f); | ||
1454 | spin_unlock_irqrestore(&d->lock, flags); | ||
1455 | dev_kfree_skb(skb); | ||
1456 | aoedev_put(d); | ||
1083 | } | 1457 | } |
1084 | } | 1458 | } |
1459 | |||
1460 | int __init | ||
1461 | aoecmd_init(void) | ||
1462 | { | ||
1463 | INIT_LIST_HEAD(&iocq.head); | ||
1464 | spin_lock_init(&iocq.lock); | ||
1465 | init_waitqueue_head(&ktiowq); | ||
1466 | kts.name = "aoe_ktio"; | ||
1467 | kts.fn = ktio; | ||
1468 | kts.waitq = &ktiowq; | ||
1469 | kts.lock = &iocq.lock; | ||
1470 | return aoe_ktstart(&kts); | ||
1471 | } | ||
1472 | |||
1473 | void | ||
1474 | aoecmd_exit(void) | ||
1475 | { | ||
1476 | aoe_ktstop(&kts); | ||
1477 | aoe_flush_iocq(); | ||
1478 | } | ||
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index 6b5110a47458..90e5b537f94b 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoedev.c | 3 | * aoedev.c |
4 | * AoE device utility functions; maintains device list. | 4 | * AoE device utility functions; maintains device list. |
@@ -9,6 +9,9 @@ | |||
9 | #include <linux/netdevice.h> | 9 | #include <linux/netdevice.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/bitmap.h> | ||
13 | #include <linux/kdev_t.h> | ||
14 | #include <linux/moduleparam.h> | ||
12 | #include "aoe.h" | 15 | #include "aoe.h" |
13 | 16 | ||
14 | static void dummy_timer(ulong); | 17 | static void dummy_timer(ulong); |
@@ -16,23 +19,121 @@ static void aoedev_freedev(struct aoedev *); | |||
16 | static void freetgt(struct aoedev *d, struct aoetgt *t); | 19 | static void freetgt(struct aoedev *d, struct aoetgt *t); |
17 | static void skbpoolfree(struct aoedev *d); | 20 | static void skbpoolfree(struct aoedev *d); |
18 | 21 | ||
22 | static int aoe_dyndevs = 1; | ||
23 | module_param(aoe_dyndevs, int, 0644); | ||
24 | MODULE_PARM_DESC(aoe_dyndevs, "Use dynamic minor numbers for devices."); | ||
25 | |||
19 | static struct aoedev *devlist; | 26 | static struct aoedev *devlist; |
20 | static DEFINE_SPINLOCK(devlist_lock); | 27 | static DEFINE_SPINLOCK(devlist_lock); |
21 | 28 | ||
22 | struct aoedev * | 29 | /* Because some systems will have one, many, or no |
23 | aoedev_by_aoeaddr(int maj, int min) | 30 | * - partitions, |
31 | * - slots per shelf, | ||
32 | * - or shelves, | ||
33 | * we need some flexibility in the way the minor numbers | ||
34 | * are allocated. So they are dynamic. | ||
35 | */ | ||
36 | #define N_DEVS ((1U<<MINORBITS)/AOE_PARTITIONS) | ||
37 | |||
38 | static DEFINE_SPINLOCK(used_minors_lock); | ||
39 | static DECLARE_BITMAP(used_minors, N_DEVS); | ||
40 | |||
41 | static int | ||
42 | minor_get_dyn(ulong *sysminor) | ||
24 | { | 43 | { |
25 | struct aoedev *d; | ||
26 | ulong flags; | 44 | ulong flags; |
45 | ulong n; | ||
46 | int error = 0; | ||
47 | |||
48 | spin_lock_irqsave(&used_minors_lock, flags); | ||
49 | n = find_first_zero_bit(used_minors, N_DEVS); | ||
50 | if (n < N_DEVS) | ||
51 | set_bit(n, used_minors); | ||
52 | else | ||
53 | error = -1; | ||
54 | spin_unlock_irqrestore(&used_minors_lock, flags); | ||
55 | |||
56 | *sysminor = n * AOE_PARTITIONS; | ||
57 | return error; | ||
58 | } | ||
27 | 59 | ||
28 | spin_lock_irqsave(&devlist_lock, flags); | 60 | static int |
61 | minor_get_static(ulong *sysminor, ulong aoemaj, int aoemin) | ||
62 | { | ||
63 | ulong flags; | ||
64 | ulong n; | ||
65 | int error = 0; | ||
66 | enum { | ||
67 | /* for backwards compatibility when !aoe_dyndevs, | ||
68 | * a static number of supported slots per shelf */ | ||
69 | NPERSHELF = 16, | ||
70 | }; | ||
71 | |||
72 | n = aoemaj * NPERSHELF + aoemin; | ||
73 | if (aoemin >= NPERSHELF || n >= N_DEVS) { | ||
74 | pr_err("aoe: %s with e%ld.%d\n", | ||
75 | "cannot use static minor device numbers", | ||
76 | aoemaj, aoemin); | ||
77 | error = -1; | ||
78 | } else { | ||
79 | spin_lock_irqsave(&used_minors_lock, flags); | ||
80 | if (test_bit(n, used_minors)) { | ||
81 | pr_err("aoe: %s %lu\n", | ||
82 | "existing device already has static minor number", | ||
83 | n); | ||
84 | error = -1; | ||
85 | } else | ||
86 | set_bit(n, used_minors); | ||
87 | spin_unlock_irqrestore(&used_minors_lock, flags); | ||
88 | } | ||
29 | 89 | ||
30 | for (d=devlist; d; d=d->next) | 90 | *sysminor = n; |
31 | if (d->aoemajor == maj && d->aoeminor == min) | 91 | return error; |
32 | break; | 92 | } |
93 | |||
94 | static int | ||
95 | minor_get(ulong *sysminor, ulong aoemaj, int aoemin) | ||
96 | { | ||
97 | if (aoe_dyndevs) | ||
98 | return minor_get_dyn(sysminor); | ||
99 | else | ||
100 | return minor_get_static(sysminor, aoemaj, aoemin); | ||
101 | } | ||
102 | |||
103 | static void | ||
104 | minor_free(ulong minor) | ||
105 | { | ||
106 | ulong flags; | ||
107 | |||
108 | minor /= AOE_PARTITIONS; | ||
109 | BUG_ON(minor >= N_DEVS); | ||
110 | |||
111 | spin_lock_irqsave(&used_minors_lock, flags); | ||
112 | BUG_ON(!test_bit(minor, used_minors)); | ||
113 | clear_bit(minor, used_minors); | ||
114 | spin_unlock_irqrestore(&used_minors_lock, flags); | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Users who grab a pointer to the device with aoedev_by_aoeaddr | ||
119 | * automatically get a reference count and must be responsible | ||
120 | * for performing a aoedev_put. With the addition of async | ||
121 | * kthread processing I'm no longer confident that we can | ||
122 | * guarantee consistency in the face of device flushes. | ||
123 | * | ||
124 | * For the time being, we only bother to add extra references for | ||
125 | * frames sitting on the iocq. When the kthreads finish processing | ||
126 | * these frames, they will aoedev_put the device. | ||
127 | */ | ||
128 | |||
129 | void | ||
130 | aoedev_put(struct aoedev *d) | ||
131 | { | ||
132 | ulong flags; | ||
33 | 133 | ||
134 | spin_lock_irqsave(&devlist_lock, flags); | ||
135 | d->ref--; | ||
34 | spin_unlock_irqrestore(&devlist_lock, flags); | 136 | spin_unlock_irqrestore(&devlist_lock, flags); |
35 | return d; | ||
36 | } | 137 | } |
37 | 138 | ||
38 | static void | 139 | static void |
@@ -47,54 +148,74 @@ dummy_timer(ulong vp) | |||
47 | add_timer(&d->timer); | 148 | add_timer(&d->timer); |
48 | } | 149 | } |
49 | 150 | ||
151 | static void | ||
152 | aoe_failip(struct aoedev *d) | ||
153 | { | ||
154 | struct request *rq; | ||
155 | struct bio *bio; | ||
156 | unsigned long n; | ||
157 | |||
158 | aoe_failbuf(d, d->ip.buf); | ||
159 | |||
160 | rq = d->ip.rq; | ||
161 | if (rq == NULL) | ||
162 | return; | ||
163 | while ((bio = d->ip.nxbio)) { | ||
164 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | ||
165 | d->ip.nxbio = bio->bi_next; | ||
166 | n = (unsigned long) rq->special; | ||
167 | rq->special = (void *) --n; | ||
168 | } | ||
169 | if ((unsigned long) rq->special == 0) | ||
170 | aoe_end_request(d, rq, 0); | ||
171 | } | ||
172 | |||
50 | void | 173 | void |
51 | aoedev_downdev(struct aoedev *d) | 174 | aoedev_downdev(struct aoedev *d) |
52 | { | 175 | { |
53 | struct aoetgt **t, **te; | 176 | struct aoetgt *t, **tt, **te; |
54 | struct frame *f, *e; | 177 | struct frame *f; |
55 | struct buf *buf; | 178 | struct list_head *head, *pos, *nx; |
56 | struct bio *bio; | 179 | struct request *rq; |
180 | int i; | ||
57 | 181 | ||
58 | t = d->targets; | 182 | d->flags &= ~DEVFL_UP; |
59 | te = t + NTARGETS; | 183 | |
60 | for (; t < te && *t; t++) { | 184 | /* clean out active buffers */ |
61 | f = (*t)->frames; | 185 | for (i = 0; i < NFACTIVE; i++) { |
62 | e = f + (*t)->nframes; | 186 | head = &d->factive[i]; |
63 | for (; f < e; f->tag = FREETAG, f->buf = NULL, f++) { | 187 | list_for_each_safe(pos, nx, head) { |
64 | if (f->tag == FREETAG || f->buf == NULL) | 188 | f = list_entry(pos, struct frame, head); |
65 | continue; | 189 | list_del(pos); |
66 | buf = f->buf; | 190 | if (f->buf) { |
67 | bio = buf->bio; | 191 | f->buf->nframesout--; |
68 | if (--buf->nframesout == 0 | 192 | aoe_failbuf(d, f->buf); |
69 | && buf != d->inprocess) { | ||
70 | mempool_free(buf, d->bufpool); | ||
71 | bio_endio(bio, -EIO); | ||
72 | } | 193 | } |
194 | aoe_freetframe(f); | ||
73 | } | 195 | } |
74 | (*t)->maxout = (*t)->nframes; | ||
75 | (*t)->nout = 0; | ||
76 | } | 196 | } |
77 | buf = d->inprocess; | 197 | /* reset window dressings */ |
78 | if (buf) { | 198 | tt = d->targets; |
79 | bio = buf->bio; | 199 | te = tt + NTARGETS; |
80 | mempool_free(buf, d->bufpool); | 200 | for (; tt < te && (t = *tt); tt++) { |
81 | bio_endio(bio, -EIO); | 201 | t->maxout = t->nframes; |
202 | t->nout = 0; | ||
82 | } | 203 | } |
83 | d->inprocess = NULL; | 204 | |
205 | /* clean out the in-process request (if any) */ | ||
206 | aoe_failip(d); | ||
84 | d->htgt = NULL; | 207 | d->htgt = NULL; |
85 | 208 | ||
86 | while (!list_empty(&d->bufq)) { | 209 | /* fast fail all pending I/O */ |
87 | buf = container_of(d->bufq.next, struct buf, bufs); | 210 | if (d->blkq) { |
88 | list_del(d->bufq.next); | 211 | while ((rq = blk_peek_request(d->blkq))) { |
89 | bio = buf->bio; | 212 | blk_start_request(rq); |
90 | mempool_free(buf, d->bufpool); | 213 | aoe_end_request(d, rq, 1); |
91 | bio_endio(bio, -EIO); | 214 | } |
92 | } | 215 | } |
93 | 216 | ||
94 | if (d->gd) | 217 | if (d->gd) |
95 | set_capacity(d->gd, 0); | 218 | set_capacity(d->gd, 0); |
96 | |||
97 | d->flags &= ~DEVFL_UP; | ||
98 | } | 219 | } |
99 | 220 | ||
100 | static void | 221 | static void |
@@ -107,6 +228,7 @@ aoedev_freedev(struct aoedev *d) | |||
107 | aoedisk_rm_sysfs(d); | 228 | aoedisk_rm_sysfs(d); |
108 | del_gendisk(d->gd); | 229 | del_gendisk(d->gd); |
109 | put_disk(d->gd); | 230 | put_disk(d->gd); |
231 | blk_cleanup_queue(d->blkq); | ||
110 | } | 232 | } |
111 | t = d->targets; | 233 | t = d->targets; |
112 | e = t + NTARGETS; | 234 | e = t + NTARGETS; |
@@ -115,7 +237,7 @@ aoedev_freedev(struct aoedev *d) | |||
115 | if (d->bufpool) | 237 | if (d->bufpool) |
116 | mempool_destroy(d->bufpool); | 238 | mempool_destroy(d->bufpool); |
117 | skbpoolfree(d); | 239 | skbpoolfree(d); |
118 | blk_cleanup_queue(d->blkq); | 240 | minor_free(d->sysminor); |
119 | kfree(d); | 241 | kfree(d); |
120 | } | 242 | } |
121 | 243 | ||
@@ -142,7 +264,8 @@ aoedev_flush(const char __user *str, size_t cnt) | |||
142 | spin_lock(&d->lock); | 264 | spin_lock(&d->lock); |
143 | if ((!all && (d->flags & DEVFL_UP)) | 265 | if ((!all && (d->flags & DEVFL_UP)) |
144 | || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE)) | 266 | || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE)) |
145 | || d->nopen) { | 267 | || d->nopen |
268 | || d->ref) { | ||
146 | spin_unlock(&d->lock); | 269 | spin_unlock(&d->lock); |
147 | dd = &d->next; | 270 | dd = &d->next; |
148 | continue; | 271 | continue; |
@@ -163,12 +286,15 @@ aoedev_flush(const char __user *str, size_t cnt) | |||
163 | return 0; | 286 | return 0; |
164 | } | 287 | } |
165 | 288 | ||
166 | /* I'm not really sure that this is a realistic problem, but if the | 289 | /* This has been confirmed to occur once with Tms=3*1000 due to the |
167 | network driver goes gonzo let's just leak memory after complaining. */ | 290 | * driver changing link and not processing its transmit ring. The |
291 | * problem is hard enough to solve by returning an error that I'm | ||
292 | * still punting on "solving" this. | ||
293 | */ | ||
168 | static void | 294 | static void |
169 | skbfree(struct sk_buff *skb) | 295 | skbfree(struct sk_buff *skb) |
170 | { | 296 | { |
171 | enum { Sms = 100, Tms = 3*1000}; | 297 | enum { Sms = 250, Tms = 30 * 1000}; |
172 | int i = Tms / Sms; | 298 | int i = Tms / Sms; |
173 | 299 | ||
174 | if (skb == NULL) | 300 | if (skb == NULL) |
@@ -182,6 +308,7 @@ skbfree(struct sk_buff *skb) | |||
182 | "cannot free skb -- memory leaked."); | 308 | "cannot free skb -- memory leaked."); |
183 | return; | 309 | return; |
184 | } | 310 | } |
311 | skb->truesize -= skb->data_len; | ||
185 | skb_shinfo(skb)->nr_frags = skb->data_len = 0; | 312 | skb_shinfo(skb)->nr_frags = skb->data_len = 0; |
186 | skb_trim(skb, 0); | 313 | skb_trim(skb, 0); |
187 | dev_kfree_skb(skb); | 314 | dev_kfree_skb(skb); |
@@ -198,26 +325,29 @@ skbpoolfree(struct aoedev *d) | |||
198 | __skb_queue_head_init(&d->skbpool); | 325 | __skb_queue_head_init(&d->skbpool); |
199 | } | 326 | } |
200 | 327 | ||
201 | /* find it or malloc it */ | 328 | /* find it or allocate it */ |
202 | struct aoedev * | 329 | struct aoedev * |
203 | aoedev_by_sysminor_m(ulong sysminor) | 330 | aoedev_by_aoeaddr(ulong maj, int min, int do_alloc) |
204 | { | 331 | { |
205 | struct aoedev *d; | 332 | struct aoedev *d; |
333 | int i; | ||
206 | ulong flags; | 334 | ulong flags; |
335 | ulong sysminor; | ||
207 | 336 | ||
208 | spin_lock_irqsave(&devlist_lock, flags); | 337 | spin_lock_irqsave(&devlist_lock, flags); |
209 | 338 | ||
210 | for (d=devlist; d; d=d->next) | 339 | for (d=devlist; d; d=d->next) |
211 | if (d->sysminor == sysminor) | 340 | if (d->aoemajor == maj && d->aoeminor == min) { |
341 | d->ref++; | ||
212 | break; | 342 | break; |
213 | if (d) | 343 | } |
344 | if (d || !do_alloc || minor_get(&sysminor, maj, min) < 0) | ||
214 | goto out; | 345 | goto out; |
215 | d = kcalloc(1, sizeof *d, GFP_ATOMIC); | 346 | d = kcalloc(1, sizeof *d, GFP_ATOMIC); |
216 | if (!d) | 347 | if (!d) |
217 | goto out; | 348 | goto out; |
218 | INIT_WORK(&d->work, aoecmd_sleepwork); | 349 | INIT_WORK(&d->work, aoecmd_sleepwork); |
219 | spin_lock_init(&d->lock); | 350 | spin_lock_init(&d->lock); |
220 | skb_queue_head_init(&d->sendq); | ||
221 | skb_queue_head_init(&d->skbpool); | 351 | skb_queue_head_init(&d->skbpool); |
222 | init_timer(&d->timer); | 352 | init_timer(&d->timer); |
223 | d->timer.data = (ulong) d; | 353 | d->timer.data = (ulong) d; |
@@ -226,10 +356,12 @@ aoedev_by_sysminor_m(ulong sysminor) | |||
226 | add_timer(&d->timer); | 356 | add_timer(&d->timer); |
227 | d->bufpool = NULL; /* defer to aoeblk_gdalloc */ | 357 | d->bufpool = NULL; /* defer to aoeblk_gdalloc */ |
228 | d->tgt = d->targets; | 358 | d->tgt = d->targets; |
229 | INIT_LIST_HEAD(&d->bufq); | 359 | d->ref = 1; |
360 | for (i = 0; i < NFACTIVE; i++) | ||
361 | INIT_LIST_HEAD(&d->factive[i]); | ||
230 | d->sysminor = sysminor; | 362 | d->sysminor = sysminor; |
231 | d->aoemajor = AOEMAJOR(sysminor); | 363 | d->aoemajor = maj; |
232 | d->aoeminor = AOEMINOR(sysminor); | 364 | d->aoeminor = min; |
233 | d->mintimer = MINTIMER; | 365 | d->mintimer = MINTIMER; |
234 | d->next = devlist; | 366 | d->next = devlist; |
235 | devlist = d; | 367 | devlist = d; |
@@ -241,13 +373,23 @@ aoedev_by_sysminor_m(ulong sysminor) | |||
241 | static void | 373 | static void |
242 | freetgt(struct aoedev *d, struct aoetgt *t) | 374 | freetgt(struct aoedev *d, struct aoetgt *t) |
243 | { | 375 | { |
244 | struct frame *f, *e; | 376 | struct frame *f; |
377 | struct list_head *pos, *nx, *head; | ||
378 | struct aoeif *ifp; | ||
245 | 379 | ||
246 | f = t->frames; | 380 | for (ifp = t->ifs; ifp < &t->ifs[NAOEIFS]; ++ifp) { |
247 | e = f + t->nframes; | 381 | if (!ifp->nd) |
248 | for (; f < e; f++) | 382 | break; |
383 | dev_put(ifp->nd); | ||
384 | } | ||
385 | |||
386 | head = &t->ffree; | ||
387 | list_for_each_safe(pos, nx, head) { | ||
388 | list_del(pos); | ||
389 | f = list_entry(pos, struct frame, head); | ||
249 | skbfree(f->skb); | 390 | skbfree(f->skb); |
250 | kfree(t->frames); | 391 | kfree(f); |
392 | } | ||
251 | kfree(t); | 393 | kfree(t); |
252 | } | 394 | } |
253 | 395 | ||
@@ -257,6 +399,7 @@ aoedev_exit(void) | |||
257 | struct aoedev *d; | 399 | struct aoedev *d; |
258 | ulong flags; | 400 | ulong flags; |
259 | 401 | ||
402 | aoe_flush_iocq(); | ||
260 | while ((d = devlist)) { | 403 | while ((d = devlist)) { |
261 | devlist = d->next; | 404 | devlist = d->next; |
262 | 405 | ||
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c index 7f83ad90e76f..04793c2c701b 100644 --- a/drivers/block/aoe/aoemain.c +++ b/drivers/block/aoe/aoemain.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoemain.c | 3 | * aoemain.c |
4 | * Module initialization routines, discover timer | 4 | * Module initialization routines, discover timer |
@@ -61,6 +61,7 @@ aoe_exit(void) | |||
61 | 61 | ||
62 | aoenet_exit(); | 62 | aoenet_exit(); |
63 | unregister_blkdev(AOE_MAJOR, DEVICE_NAME); | 63 | unregister_blkdev(AOE_MAJOR, DEVICE_NAME); |
64 | aoecmd_exit(); | ||
64 | aoechr_exit(); | 65 | aoechr_exit(); |
65 | aoedev_exit(); | 66 | aoedev_exit(); |
66 | aoeblk_exit(); /* free cache after de-allocating bufs */ | 67 | aoeblk_exit(); /* free cache after de-allocating bufs */ |
@@ -83,17 +84,20 @@ aoe_init(void) | |||
83 | ret = aoenet_init(); | 84 | ret = aoenet_init(); |
84 | if (ret) | 85 | if (ret) |
85 | goto net_fail; | 86 | goto net_fail; |
87 | ret = aoecmd_init(); | ||
88 | if (ret) | ||
89 | goto cmd_fail; | ||
86 | ret = register_blkdev(AOE_MAJOR, DEVICE_NAME); | 90 | ret = register_blkdev(AOE_MAJOR, DEVICE_NAME); |
87 | if (ret < 0) { | 91 | if (ret < 0) { |
88 | printk(KERN_ERR "aoe: can't register major\n"); | 92 | printk(KERN_ERR "aoe: can't register major\n"); |
89 | goto blkreg_fail; | 93 | goto blkreg_fail; |
90 | } | 94 | } |
91 | |||
92 | printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION); | 95 | printk(KERN_INFO "aoe: AoE v%s initialised.\n", VERSION); |
93 | discover_timer(TINIT); | 96 | discover_timer(TINIT); |
94 | return 0; | 97 | return 0; |
95 | |||
96 | blkreg_fail: | 98 | blkreg_fail: |
99 | aoecmd_exit(); | ||
100 | cmd_fail: | ||
97 | aoenet_exit(); | 101 | aoenet_exit(); |
98 | net_fail: | 102 | net_fail: |
99 | aoeblk_exit(); | 103 | aoeblk_exit(); |
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index 4d3bc0d49df5..162c6471275c 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ |
2 | /* | 2 | /* |
3 | * aoenet.c | 3 | * aoenet.c |
4 | * Ethernet portion of AoE driver | 4 | * Ethernet portion of AoE driver |
@@ -33,6 +33,9 @@ static char aoe_iflist[IFLISTSZ]; | |||
33 | module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600); | 33 | module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600); |
34 | MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\""); | 34 | MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\""); |
35 | 35 | ||
36 | static wait_queue_head_t txwq; | ||
37 | static struct ktstate kts; | ||
38 | |||
36 | #ifndef MODULE | 39 | #ifndef MODULE |
37 | static int __init aoe_iflist_setup(char *str) | 40 | static int __init aoe_iflist_setup(char *str) |
38 | { | 41 | { |
@@ -44,6 +47,23 @@ static int __init aoe_iflist_setup(char *str) | |||
44 | __setup("aoe_iflist=", aoe_iflist_setup); | 47 | __setup("aoe_iflist=", aoe_iflist_setup); |
45 | #endif | 48 | #endif |
46 | 49 | ||
50 | static spinlock_t txlock; | ||
51 | static struct sk_buff_head skbtxq; | ||
52 | |||
53 | /* enters with txlock held */ | ||
54 | static int | ||
55 | tx(void) | ||
56 | { | ||
57 | struct sk_buff *skb; | ||
58 | |||
59 | while ((skb = skb_dequeue(&skbtxq))) { | ||
60 | spin_unlock_irq(&txlock); | ||
61 | dev_queue_xmit(skb); | ||
62 | spin_lock_irq(&txlock); | ||
63 | } | ||
64 | return 0; | ||
65 | } | ||
66 | |||
47 | int | 67 | int |
48 | is_aoe_netif(struct net_device *ifp) | 68 | is_aoe_netif(struct net_device *ifp) |
49 | { | 69 | { |
@@ -88,10 +108,14 @@ void | |||
88 | aoenet_xmit(struct sk_buff_head *queue) | 108 | aoenet_xmit(struct sk_buff_head *queue) |
89 | { | 109 | { |
90 | struct sk_buff *skb, *tmp; | 110 | struct sk_buff *skb, *tmp; |
111 | ulong flags; | ||
91 | 112 | ||
92 | skb_queue_walk_safe(queue, skb, tmp) { | 113 | skb_queue_walk_safe(queue, skb, tmp) { |
93 | __skb_unlink(skb, queue); | 114 | __skb_unlink(skb, queue); |
94 | dev_queue_xmit(skb); | 115 | spin_lock_irqsave(&txlock, flags); |
116 | skb_queue_tail(&skbtxq, skb); | ||
117 | spin_unlock_irqrestore(&txlock, flags); | ||
118 | wake_up(&txwq); | ||
95 | } | 119 | } |
96 | } | 120 | } |
97 | 121 | ||
@@ -102,7 +126,9 @@ static int | |||
102 | aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev) | 126 | aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev) |
103 | { | 127 | { |
104 | struct aoe_hdr *h; | 128 | struct aoe_hdr *h; |
129 | struct aoe_atahdr *ah; | ||
105 | u32 n; | 130 | u32 n; |
131 | int sn; | ||
106 | 132 | ||
107 | if (dev_net(ifp) != &init_net) | 133 | if (dev_net(ifp) != &init_net) |
108 | goto exit; | 134 | goto exit; |
@@ -110,13 +136,16 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, | |||
110 | skb = skb_share_check(skb, GFP_ATOMIC); | 136 | skb = skb_share_check(skb, GFP_ATOMIC); |
111 | if (skb == NULL) | 137 | if (skb == NULL) |
112 | return 0; | 138 | return 0; |
113 | if (skb_linearize(skb)) | ||
114 | goto exit; | ||
115 | if (!is_aoe_netif(ifp)) | 139 | if (!is_aoe_netif(ifp)) |
116 | goto exit; | 140 | goto exit; |
117 | skb_push(skb, ETH_HLEN); /* (1) */ | 141 | skb_push(skb, ETH_HLEN); /* (1) */ |
118 | 142 | sn = sizeof(*h) + sizeof(*ah); | |
119 | h = (struct aoe_hdr *) skb_mac_header(skb); | 143 | if (skb->len >= sn) { |
144 | sn -= skb_headlen(skb); | ||
145 | if (sn > 0 && !__pskb_pull_tail(skb, sn)) | ||
146 | goto exit; | ||
147 | } | ||
148 | h = (struct aoe_hdr *) skb->data; | ||
120 | n = get_unaligned_be32(&h->tag); | 149 | n = get_unaligned_be32(&h->tag); |
121 | if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31)) | 150 | if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31)) |
122 | goto exit; | 151 | goto exit; |
@@ -137,7 +166,8 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, | |||
137 | 166 | ||
138 | switch (h->cmd) { | 167 | switch (h->cmd) { |
139 | case AOECMD_ATA: | 168 | case AOECMD_ATA: |
140 | aoecmd_ata_rsp(skb); | 169 | /* ata_rsp may keep skb for later processing or give it back */ |
170 | skb = aoecmd_ata_rsp(skb); | ||
141 | break; | 171 | break; |
142 | case AOECMD_CFG: | 172 | case AOECMD_CFG: |
143 | aoecmd_cfg_rsp(skb); | 173 | aoecmd_cfg_rsp(skb); |
@@ -145,8 +175,12 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, | |||
145 | default: | 175 | default: |
146 | if (h->cmd >= AOECMD_VEND_MIN) | 176 | if (h->cmd >= AOECMD_VEND_MIN) |
147 | break; /* don't complain about vendor commands */ | 177 | break; /* don't complain about vendor commands */ |
148 | printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); | 178 | pr_info("aoe: unknown AoE command type 0x%02x\n", h->cmd); |
179 | break; | ||
149 | } | 180 | } |
181 | |||
182 | if (!skb) | ||
183 | return 0; | ||
150 | exit: | 184 | exit: |
151 | dev_kfree_skb(skb); | 185 | dev_kfree_skb(skb); |
152 | return 0; | 186 | return 0; |
@@ -160,6 +194,15 @@ static struct packet_type aoe_pt __read_mostly = { | |||
160 | int __init | 194 | int __init |
161 | aoenet_init(void) | 195 | aoenet_init(void) |
162 | { | 196 | { |
197 | skb_queue_head_init(&skbtxq); | ||
198 | init_waitqueue_head(&txwq); | ||
199 | spin_lock_init(&txlock); | ||
200 | kts.lock = &txlock; | ||
201 | kts.fn = tx; | ||
202 | kts.waitq = &txwq; | ||
203 | kts.name = "aoe_tx"; | ||
204 | if (aoe_ktstart(&kts)) | ||
205 | return -EAGAIN; | ||
163 | dev_add_pack(&aoe_pt); | 206 | dev_add_pack(&aoe_pt); |
164 | return 0; | 207 | return 0; |
165 | } | 208 | } |
@@ -167,6 +210,8 @@ aoenet_init(void) | |||
167 | void | 210 | void |
168 | aoenet_exit(void) | 211 | aoenet_exit(void) |
169 | { | 212 | { |
213 | aoe_ktstop(&kts); | ||
214 | skb_queue_purge(&skbtxq); | ||
170 | dev_remove_pack(&aoe_pt); | 215 | dev_remove_pack(&aoe_pt); |
171 | } | 216 | } |
172 | 217 | ||
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 0c03411c59eb..043ddcca4abf 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -78,6 +78,8 @@ static const char *ioctl_cmd_to_ascii(int cmd) | |||
78 | case NBD_SET_SOCK: return "set-sock"; | 78 | case NBD_SET_SOCK: return "set-sock"; |
79 | case NBD_SET_BLKSIZE: return "set-blksize"; | 79 | case NBD_SET_BLKSIZE: return "set-blksize"; |
80 | case NBD_SET_SIZE: return "set-size"; | 80 | case NBD_SET_SIZE: return "set-size"; |
81 | case NBD_SET_TIMEOUT: return "set-timeout"; | ||
82 | case NBD_SET_FLAGS: return "set-flags"; | ||
81 | case NBD_DO_IT: return "do-it"; | 83 | case NBD_DO_IT: return "do-it"; |
82 | case NBD_CLEAR_SOCK: return "clear-sock"; | 84 | case NBD_CLEAR_SOCK: return "clear-sock"; |
83 | case NBD_CLEAR_QUE: return "clear-que"; | 85 | case NBD_CLEAR_QUE: return "clear-que"; |
@@ -96,6 +98,7 @@ static const char *nbdcmd_to_ascii(int cmd) | |||
96 | case NBD_CMD_READ: return "read"; | 98 | case NBD_CMD_READ: return "read"; |
97 | case NBD_CMD_WRITE: return "write"; | 99 | case NBD_CMD_WRITE: return "write"; |
98 | case NBD_CMD_DISC: return "disconnect"; | 100 | case NBD_CMD_DISC: return "disconnect"; |
101 | case NBD_CMD_TRIM: return "trim/discard"; | ||
99 | } | 102 | } |
100 | return "invalid"; | 103 | return "invalid"; |
101 | } | 104 | } |
@@ -467,8 +470,12 @@ static void nbd_handle_req(struct nbd_device *nbd, struct request *req) | |||
467 | 470 | ||
468 | nbd_cmd(req) = NBD_CMD_READ; | 471 | nbd_cmd(req) = NBD_CMD_READ; |
469 | if (rq_data_dir(req) == WRITE) { | 472 | if (rq_data_dir(req) == WRITE) { |
470 | nbd_cmd(req) = NBD_CMD_WRITE; | 473 | if ((req->cmd_flags & REQ_DISCARD)) { |
471 | if (nbd->flags & NBD_READ_ONLY) { | 474 | WARN_ON(!(nbd->flags & NBD_FLAG_SEND_TRIM)); |
475 | nbd_cmd(req) = NBD_CMD_TRIM; | ||
476 | } else | ||
477 | nbd_cmd(req) = NBD_CMD_WRITE; | ||
478 | if (nbd->flags & NBD_FLAG_READ_ONLY) { | ||
472 | dev_err(disk_to_dev(nbd->disk), | 479 | dev_err(disk_to_dev(nbd->disk), |
473 | "Write on read-only\n"); | 480 | "Write on read-only\n"); |
474 | goto error_out; | 481 | goto error_out; |
@@ -651,6 +658,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, | |||
651 | nbd->xmit_timeout = arg * HZ; | 658 | nbd->xmit_timeout = arg * HZ; |
652 | return 0; | 659 | return 0; |
653 | 660 | ||
661 | case NBD_SET_FLAGS: | ||
662 | nbd->flags = arg; | ||
663 | return 0; | ||
664 | |||
654 | case NBD_SET_SIZE_BLOCKS: | 665 | case NBD_SET_SIZE_BLOCKS: |
655 | nbd->bytesize = ((u64) arg) * nbd->blksize; | 666 | nbd->bytesize = ((u64) arg) * nbd->blksize; |
656 | bdev->bd_inode->i_size = nbd->bytesize; | 667 | bdev->bd_inode->i_size = nbd->bytesize; |
@@ -670,6 +681,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, | |||
670 | 681 | ||
671 | mutex_unlock(&nbd->tx_lock); | 682 | mutex_unlock(&nbd->tx_lock); |
672 | 683 | ||
684 | if (nbd->flags & NBD_FLAG_SEND_TRIM) | ||
685 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, | ||
686 | nbd->disk->queue); | ||
687 | |||
673 | thread = kthread_create(nbd_thread, nbd, nbd->disk->disk_name); | 688 | thread = kthread_create(nbd_thread, nbd, nbd->disk->disk_name); |
674 | if (IS_ERR(thread)) { | 689 | if (IS_ERR(thread)) { |
675 | mutex_lock(&nbd->tx_lock); | 690 | mutex_lock(&nbd->tx_lock); |
@@ -687,6 +702,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, | |||
687 | nbd->file = NULL; | 702 | nbd->file = NULL; |
688 | nbd_clear_que(nbd); | 703 | nbd_clear_que(nbd); |
689 | dev_warn(disk_to_dev(nbd->disk), "queue cleared\n"); | 704 | dev_warn(disk_to_dev(nbd->disk), "queue cleared\n"); |
705 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue); | ||
690 | if (file) | 706 | if (file) |
691 | fput(file); | 707 | fput(file); |
692 | nbd->bytesize = 0; | 708 | nbd->bytesize = 0; |
@@ -805,6 +821,9 @@ static int __init nbd_init(void) | |||
805 | * Tell the block layer that we are not a rotational device | 821 | * Tell the block layer that we are not a rotational device |
806 | */ | 822 | */ |
807 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue); | 823 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue); |
824 | disk->queue->limits.discard_granularity = 512; | ||
825 | disk->queue->limits.max_discard_sectors = UINT_MAX; | ||
826 | disk->queue->limits.discard_zeroes_data = 0; | ||
808 | } | 827 | } |
809 | 828 | ||
810 | if (register_blkdev(NBD_MAJOR, "nbd")) { | 829 | if (register_blkdev(NBD_MAJOR, "nbd")) { |
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index 47ff7e470d87..0c7d340b9ab9 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c | |||
@@ -799,7 +799,7 @@ static int mbcs_remove(struct cx_dev *dev) | |||
799 | return 0; | 799 | return 0; |
800 | } | 800 | } |
801 | 801 | ||
802 | static const struct cx_device_id __devinitdata mbcs_id_table[] = { | 802 | static const struct cx_device_id __devinitconst mbcs_id_table[] = { |
803 | { | 803 | { |
804 | .part_num = MBCS_PART_NUM, | 804 | .part_num = MBCS_PART_NUM, |
805 | .mfg_num = MBCS_MFG_NUM, | 805 | .mfg_num = MBCS_MFG_NUM, |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 3491654cdf7b..a815d44c70a4 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -582,7 +582,7 @@ void dmaengine_get(void) | |||
582 | list_del_rcu(&device->global_node); | 582 | list_del_rcu(&device->global_node); |
583 | break; | 583 | break; |
584 | } else if (err) | 584 | } else if (err) |
585 | pr_err("%s: failed to get %s: (%d)\n", | 585 | pr_debug("%s: failed to get %s: (%d)\n", |
586 | __func__, dma_chan_name(chan), err); | 586 | __func__, dma_chan_name(chan), err); |
587 | } | 587 | } |
588 | } | 588 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2091ae8f539a..2421d95130d4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -982,7 +982,7 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adap) | |||
982 | 982 | ||
983 | if (adap->nr == -1) /* -1 means dynamically assign bus id */ | 983 | if (adap->nr == -1) /* -1 means dynamically assign bus id */ |
984 | return i2c_add_adapter(adap); | 984 | return i2c_add_adapter(adap); |
985 | if (adap->nr & ~MAX_ID_MASK) | 985 | if (adap->nr & ~MAX_IDR_MASK) |
986 | return -EINVAL; | 986 | return -EINVAL; |
987 | 987 | ||
988 | retry: | 988 | retry: |
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index 57d00caefc86..01451940393b 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c | |||
@@ -181,7 +181,7 @@ static const struct ide_port_ops atp86x_port_ops = { | |||
181 | .cable_detect = atp86x_cable_detect, | 181 | .cable_detect = atp86x_cable_detect, |
182 | }; | 182 | }; |
183 | 183 | ||
184 | static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | 184 | static const struct ide_port_info aec62xx_chipsets[] __devinitconst = { |
185 | { /* 0: AEC6210 */ | 185 | { /* 0: AEC6210 */ |
186 | .name = DRV_NAME, | 186 | .name = DRV_NAME, |
187 | .init_chipset = init_chipset_aec62xx, | 187 | .init_chipset = init_chipset_aec62xx, |
diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c index d3be99fb4154..8f3570ee64c3 100644 --- a/drivers/ide/ali14xx.c +++ b/drivers/ide/ali14xx.c | |||
@@ -52,13 +52,13 @@ | |||
52 | 52 | ||
53 | /* port addresses for auto-detection */ | 53 | /* port addresses for auto-detection */ |
54 | #define ALI_NUM_PORTS 4 | 54 | #define ALI_NUM_PORTS 4 |
55 | static const int ports[ALI_NUM_PORTS] __initdata = | 55 | static const int ports[ALI_NUM_PORTS] __initconst = |
56 | { 0x074, 0x0f4, 0x034, 0x0e4 }; | 56 | { 0x074, 0x0f4, 0x034, 0x0e4 }; |
57 | 57 | ||
58 | /* register initialization data */ | 58 | /* register initialization data */ |
59 | typedef struct { u8 reg, data; } RegInitializer; | 59 | typedef struct { u8 reg, data; } RegInitializer; |
60 | 60 | ||
61 | static const RegInitializer initData[] __initdata = { | 61 | static const RegInitializer initData[] __initconst = { |
62 | {0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00}, | 62 | {0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00}, |
63 | {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f}, | 63 | {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f}, |
64 | {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00}, | 64 | {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00}, |
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 2c8016ad0e26..911a27ca356b 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c | |||
@@ -512,7 +512,7 @@ static const struct ide_dma_ops ali_dma_ops = { | |||
512 | .dma_sff_read_status = ide_dma_sff_read_status, | 512 | .dma_sff_read_status = ide_dma_sff_read_status, |
513 | }; | 513 | }; |
514 | 514 | ||
515 | static const struct ide_port_info ali15x3_chipset __devinitdata = { | 515 | static const struct ide_port_info ali15x3_chipset __devinitconst = { |
516 | .name = DRV_NAME, | 516 | .name = DRV_NAME, |
517 | .init_chipset = init_chipset_ali15x3, | 517 | .init_chipset = init_chipset_ali15x3, |
518 | .init_hwif = init_hwif_ali15x3, | 518 | .init_hwif = init_hwif_ali15x3, |
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 3747b2561f09..56fc99557ba2 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c | |||
@@ -223,7 +223,7 @@ static const struct ide_port_ops amd_port_ops = { | |||
223 | .udma_mask = udma, \ | 223 | .udma_mask = udma, \ |
224 | } | 224 | } |
225 | 225 | ||
226 | static const struct ide_port_info amd74xx_chipsets[] __devinitdata = { | 226 | static const struct ide_port_info amd74xx_chipsets[] __devinitconst = { |
227 | /* 0: AMD7401 */ DECLARE_AMD_DEV(0x00, ATA_UDMA2), | 227 | /* 0: AMD7401 */ DECLARE_AMD_DEV(0x00, ATA_UDMA2), |
228 | /* 1: AMD7409 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA4), | 228 | /* 1: AMD7409 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA4), |
229 | /* 2: AMD7411/7441 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA5), | 229 | /* 2: AMD7411/7441 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA5), |
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c index 15f0ead89f5c..cb43480b1bd5 100644 --- a/drivers/ide/atiixp.c +++ b/drivers/ide/atiixp.c | |||
@@ -139,7 +139,7 @@ static const struct ide_port_ops atiixp_port_ops = { | |||
139 | .cable_detect = atiixp_cable_detect, | 139 | .cable_detect = atiixp_cable_detect, |
140 | }; | 140 | }; |
141 | 141 | ||
142 | static const struct ide_port_info atiixp_pci_info[] __devinitdata = { | 142 | static const struct ide_port_info atiixp_pci_info[] __devinitconst = { |
143 | { /* 0: IXP200/300/400/700 */ | 143 | { /* 0: IXP200/300/400/700 */ |
144 | .name = DRV_NAME, | 144 | .name = DRV_NAME, |
145 | .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, | 145 | .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, |
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index 14717304b388..70f0a2754c13 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c | |||
@@ -685,7 +685,7 @@ static int pci_conf2(void) | |||
685 | return 0; | 685 | return 0; |
686 | } | 686 | } |
687 | 687 | ||
688 | static const struct ide_port_info cmd640_port_info __initdata = { | 688 | static const struct ide_port_info cmd640_port_info __initconst = { |
689 | .chipset = ide_cmd640, | 689 | .chipset = ide_cmd640, |
690 | .host_flags = IDE_HFLAG_SERIALIZE | | 690 | .host_flags = IDE_HFLAG_SERIALIZE | |
691 | IDE_HFLAG_NO_DMA | | 691 | IDE_HFLAG_NO_DMA | |
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 5f80312e636b..d1fc43802f5d 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c | |||
@@ -327,7 +327,7 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = { | |||
327 | .dma_sff_read_status = ide_dma_sff_read_status, | 327 | .dma_sff_read_status = ide_dma_sff_read_status, |
328 | }; | 328 | }; |
329 | 329 | ||
330 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | 330 | static const struct ide_port_info cmd64x_chipsets[] __devinitconst = { |
331 | { /* 0: CMD643 */ | 331 | { /* 0: CMD643 */ |
332 | .name = DRV_NAME, | 332 | .name = DRV_NAME, |
333 | .init_chipset = init_chipset_cmd64x, | 333 | .init_chipset = init_chipset_cmd64x, |
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c index 2c1e5f7cd261..14447621e60b 100644 --- a/drivers/ide/cs5520.c +++ b/drivers/ide/cs5520.c | |||
@@ -94,7 +94,7 @@ static const struct ide_port_ops cs5520_port_ops = { | |||
94 | .set_dma_mode = cs5520_set_dma_mode, | 94 | .set_dma_mode = cs5520_set_dma_mode, |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static const struct ide_port_info cyrix_chipset __devinitdata = { | 97 | static const struct ide_port_info cyrix_chipset __devinitconst = { |
98 | .name = DRV_NAME, | 98 | .name = DRV_NAME, |
99 | .enablebits = { { 0x60, 0x01, 0x01 }, { 0x60, 0x02, 0x02 } }, | 99 | .enablebits = { { 0x60, 0x01, 0x01 }, { 0x60, 0x02, 0x02 } }, |
100 | .port_ops = &cs5520_port_ops, | 100 | .port_ops = &cs5520_port_ops, |
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c index 4dc4eb92b076..49b40ad59d1a 100644 --- a/drivers/ide/cs5530.c +++ b/drivers/ide/cs5530.c | |||
@@ -245,7 +245,7 @@ static const struct ide_port_ops cs5530_port_ops = { | |||
245 | .udma_filter = cs5530_udma_filter, | 245 | .udma_filter = cs5530_udma_filter, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | static const struct ide_port_info cs5530_chipset __devinitdata = { | 248 | static const struct ide_port_info cs5530_chipset __devinitconst = { |
249 | .name = DRV_NAME, | 249 | .name = DRV_NAME, |
250 | .init_chipset = init_chipset_cs5530, | 250 | .init_chipset = init_chipset_cs5530, |
251 | .init_hwif = init_hwif_cs5530, | 251 | .init_hwif = init_hwif_cs5530, |
diff --git a/drivers/ide/cs5535.c b/drivers/ide/cs5535.c index 5059fafadf29..18d4c852602b 100644 --- a/drivers/ide/cs5535.c +++ b/drivers/ide/cs5535.c | |||
@@ -170,7 +170,7 @@ static const struct ide_port_ops cs5535_port_ops = { | |||
170 | .cable_detect = cs5535_cable_detect, | 170 | .cable_detect = cs5535_cable_detect, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | static const struct ide_port_info cs5535_chipset __devinitdata = { | 173 | static const struct ide_port_info cs5535_chipset __devinitconst = { |
174 | .name = DRV_NAME, | 174 | .name = DRV_NAME, |
175 | .port_ops = &cs5535_port_ops, | 175 | .port_ops = &cs5535_port_ops, |
176 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE, | 176 | .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE, |
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 847553fd8b96..3ffb49dab574 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c | |||
@@ -163,7 +163,7 @@ static const struct ide_port_ops cy82c693_port_ops = { | |||
163 | .set_dma_mode = cy82c693_set_dma_mode, | 163 | .set_dma_mode = cy82c693_set_dma_mode, |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static const struct ide_port_info cy82c693_chipset __devinitdata = { | 166 | static const struct ide_port_info cy82c693_chipset __devinitconst = { |
167 | .name = DRV_NAME, | 167 | .name = DRV_NAME, |
168 | .init_iops = init_iops_cy82c693, | 168 | .init_iops = init_iops_cy82c693, |
169 | .port_ops = &cy82c693_port_ops, | 169 | .port_ops = &cy82c693_port_ops, |
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c index 46af4743b3e6..8722df329cbe 100644 --- a/drivers/ide/dtc2278.c +++ b/drivers/ide/dtc2278.c | |||
@@ -91,7 +91,7 @@ static const struct ide_port_ops dtc2278_port_ops = { | |||
91 | .set_pio_mode = dtc2278_set_pio_mode, | 91 | .set_pio_mode = dtc2278_set_pio_mode, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static const struct ide_port_info dtc2278_port_info __initdata = { | 94 | static const struct ide_port_info dtc2278_port_info __initconst = { |
95 | .name = DRV_NAME, | 95 | .name = DRV_NAME, |
96 | .chipset = ide_dtc2278, | 96 | .chipset = ide_dtc2278, |
97 | .port_ops = &dtc2278_port_ops, | 97 | .port_ops = &dtc2278_port_ops, |
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index 58c51cddc100..4aec3b87ff91 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c | |||
@@ -443,7 +443,7 @@ static struct hpt_timings hpt37x_timings = { | |||
443 | } | 443 | } |
444 | }; | 444 | }; |
445 | 445 | ||
446 | static const struct hpt_info hpt36x __devinitdata = { | 446 | static const struct hpt_info hpt36x __devinitconst = { |
447 | .chip_name = "HPT36x", | 447 | .chip_name = "HPT36x", |
448 | .chip_type = HPT36x, | 448 | .chip_type = HPT36x, |
449 | .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, | 449 | .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, |
@@ -451,7 +451,7 @@ static const struct hpt_info hpt36x __devinitdata = { | |||
451 | .timings = &hpt36x_timings | 451 | .timings = &hpt36x_timings |
452 | }; | 452 | }; |
453 | 453 | ||
454 | static const struct hpt_info hpt370 __devinitdata = { | 454 | static const struct hpt_info hpt370 __devinitconst = { |
455 | .chip_name = "HPT370", | 455 | .chip_name = "HPT370", |
456 | .chip_type = HPT370, | 456 | .chip_type = HPT370, |
457 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, | 457 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, |
@@ -459,7 +459,7 @@ static const struct hpt_info hpt370 __devinitdata = { | |||
459 | .timings = &hpt37x_timings | 459 | .timings = &hpt37x_timings |
460 | }; | 460 | }; |
461 | 461 | ||
462 | static const struct hpt_info hpt370a __devinitdata = { | 462 | static const struct hpt_info hpt370a __devinitconst = { |
463 | .chip_name = "HPT370A", | 463 | .chip_name = "HPT370A", |
464 | .chip_type = HPT370A, | 464 | .chip_type = HPT370A, |
465 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, | 465 | .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, |
@@ -467,7 +467,7 @@ static const struct hpt_info hpt370a __devinitdata = { | |||
467 | .timings = &hpt37x_timings | 467 | .timings = &hpt37x_timings |
468 | }; | 468 | }; |
469 | 469 | ||
470 | static const struct hpt_info hpt374 __devinitdata = { | 470 | static const struct hpt_info hpt374 __devinitconst = { |
471 | .chip_name = "HPT374", | 471 | .chip_name = "HPT374", |
472 | .chip_type = HPT374, | 472 | .chip_type = HPT374, |
473 | .udma_mask = ATA_UDMA5, | 473 | .udma_mask = ATA_UDMA5, |
@@ -475,7 +475,7 @@ static const struct hpt_info hpt374 __devinitdata = { | |||
475 | .timings = &hpt37x_timings | 475 | .timings = &hpt37x_timings |
476 | }; | 476 | }; |
477 | 477 | ||
478 | static const struct hpt_info hpt372 __devinitdata = { | 478 | static const struct hpt_info hpt372 __devinitconst = { |
479 | .chip_name = "HPT372", | 479 | .chip_name = "HPT372", |
480 | .chip_type = HPT372, | 480 | .chip_type = HPT372, |
481 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 481 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
@@ -483,7 +483,7 @@ static const struct hpt_info hpt372 __devinitdata = { | |||
483 | .timings = &hpt37x_timings | 483 | .timings = &hpt37x_timings |
484 | }; | 484 | }; |
485 | 485 | ||
486 | static const struct hpt_info hpt372a __devinitdata = { | 486 | static const struct hpt_info hpt372a __devinitconst = { |
487 | .chip_name = "HPT372A", | 487 | .chip_name = "HPT372A", |
488 | .chip_type = HPT372A, | 488 | .chip_type = HPT372A, |
489 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 489 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
@@ -491,7 +491,7 @@ static const struct hpt_info hpt372a __devinitdata = { | |||
491 | .timings = &hpt37x_timings | 491 | .timings = &hpt37x_timings |
492 | }; | 492 | }; |
493 | 493 | ||
494 | static const struct hpt_info hpt302 __devinitdata = { | 494 | static const struct hpt_info hpt302 __devinitconst = { |
495 | .chip_name = "HPT302", | 495 | .chip_name = "HPT302", |
496 | .chip_type = HPT302, | 496 | .chip_type = HPT302, |
497 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 497 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
@@ -499,7 +499,7 @@ static const struct hpt_info hpt302 __devinitdata = { | |||
499 | .timings = &hpt37x_timings | 499 | .timings = &hpt37x_timings |
500 | }; | 500 | }; |
501 | 501 | ||
502 | static const struct hpt_info hpt371 __devinitdata = { | 502 | static const struct hpt_info hpt371 __devinitconst = { |
503 | .chip_name = "HPT371", | 503 | .chip_name = "HPT371", |
504 | .chip_type = HPT371, | 504 | .chip_type = HPT371, |
505 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 505 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
@@ -507,7 +507,7 @@ static const struct hpt_info hpt371 __devinitdata = { | |||
507 | .timings = &hpt37x_timings | 507 | .timings = &hpt37x_timings |
508 | }; | 508 | }; |
509 | 509 | ||
510 | static const struct hpt_info hpt372n __devinitdata = { | 510 | static const struct hpt_info hpt372n __devinitconst = { |
511 | .chip_name = "HPT372N", | 511 | .chip_name = "HPT372N", |
512 | .chip_type = HPT372N, | 512 | .chip_type = HPT372N, |
513 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 513 | .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
@@ -515,7 +515,7 @@ static const struct hpt_info hpt372n __devinitdata = { | |||
515 | .timings = &hpt37x_timings | 515 | .timings = &hpt37x_timings |
516 | }; | 516 | }; |
517 | 517 | ||
518 | static const struct hpt_info hpt302n __devinitdata = { | 518 | static const struct hpt_info hpt302n __devinitconst = { |
519 | .chip_name = "HPT302N", | 519 | .chip_name = "HPT302N", |
520 | .chip_type = HPT302N, | 520 | .chip_type = HPT302N, |
521 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 521 | .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
@@ -523,7 +523,7 @@ static const struct hpt_info hpt302n __devinitdata = { | |||
523 | .timings = &hpt37x_timings | 523 | .timings = &hpt37x_timings |
524 | }; | 524 | }; |
525 | 525 | ||
526 | static const struct hpt_info hpt371n __devinitdata = { | 526 | static const struct hpt_info hpt371n __devinitconst = { |
527 | .chip_name = "HPT371N", | 527 | .chip_name = "HPT371N", |
528 | .chip_type = HPT371N, | 528 | .chip_type = HPT371N, |
529 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, | 529 | .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, |
@@ -1361,7 +1361,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = { | |||
1361 | .dma_sff_read_status = ide_dma_sff_read_status, | 1361 | .dma_sff_read_status = ide_dma_sff_read_status, |
1362 | }; | 1362 | }; |
1363 | 1363 | ||
1364 | static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | 1364 | static const struct ide_port_info hpt366_chipsets[] __devinitconst = { |
1365 | { /* 0: HPT36x */ | 1365 | { /* 0: HPT36x */ |
1366 | .name = DRV_NAME, | 1366 | .name = DRV_NAME, |
1367 | .init_chipset = init_chipset_hpt366, | 1367 | .init_chipset = init_chipset_hpt366, |
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c index 986f2513eab4..1e0fd3aa962d 100644 --- a/drivers/ide/ht6560b.c +++ b/drivers/ide/ht6560b.c | |||
@@ -341,7 +341,7 @@ static const struct ide_port_ops ht6560b_port_ops = { | |||
341 | .set_pio_mode = ht6560b_set_pio_mode, | 341 | .set_pio_mode = ht6560b_set_pio_mode, |
342 | }; | 342 | }; |
343 | 343 | ||
344 | static const struct ide_port_info ht6560b_port_info __initdata = { | 344 | static const struct ide_port_info ht6560b_port_info __initconst = { |
345 | .name = DRV_NAME, | 345 | .name = DRV_NAME, |
346 | .chipset = ide_ht6560b, | 346 | .chipset = ide_ht6560b, |
347 | .tp_ops = &ht6560b_tp_ops, | 347 | .tp_ops = &ht6560b_tp_ops, |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index bcb507b0cfd4..e640d0ac3af6 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c | |||
@@ -451,7 +451,7 @@ err_free: | |||
451 | return ret; | 451 | return ret; |
452 | } | 452 | } |
453 | 453 | ||
454 | static const struct ide_port_info icside_v6_port_info __initdata = { | 454 | static const struct ide_port_info icside_v6_port_info __initconst = { |
455 | .init_dma = icside_dma_off_init, | 455 | .init_dma = icside_dma_off_init, |
456 | .port_ops = &icside_v6_no_dma_port_ops, | 456 | .port_ops = &icside_v6_no_dma_port_ops, |
457 | .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, | 457 | .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, |
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c index 7f56b738d762..dab5b670bfbf 100644 --- a/drivers/ide/ide-pci-generic.c +++ b/drivers/ide/ide-pci-generic.c | |||
@@ -53,7 +53,7 @@ static const struct ide_port_ops netcell_port_ops = { | |||
53 | .udma_mask = ATA_UDMA6, \ | 53 | .udma_mask = ATA_UDMA6, \ |
54 | } | 54 | } |
55 | 55 | ||
56 | static const struct ide_port_info generic_chipsets[] __devinitdata = { | 56 | static const struct ide_port_info generic_chipsets[] __devinitconst = { |
57 | /* 0: Unknown */ | 57 | /* 0: Unknown */ |
58 | DECLARE_GENERIC_PCI_DEV(0), | 58 | DECLARE_GENERIC_PCI_DEV(0), |
59 | 59 | ||
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c index 560e66d07659..d5dd180c4b85 100644 --- a/drivers/ide/it8172.c +++ b/drivers/ide/it8172.c | |||
@@ -115,7 +115,7 @@ static const struct ide_port_ops it8172_port_ops = { | |||
115 | .set_dma_mode = it8172_set_dma_mode, | 115 | .set_dma_mode = it8172_set_dma_mode, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static const struct ide_port_info it8172_port_info __devinitdata = { | 118 | static const struct ide_port_info it8172_port_info __devinitconst = { |
119 | .name = DRV_NAME, | 119 | .name = DRV_NAME, |
120 | .port_ops = &it8172_port_ops, | 120 | .port_ops = &it8172_port_ops, |
121 | .enablebits = { {0x41, 0x80, 0x80}, {0x00, 0x00, 0x00} }, | 121 | .enablebits = { {0x41, 0x80, 0x80}, {0x00, 0x00, 0x00} }, |
diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c index 46816ba26416..1847aeb5450a 100644 --- a/drivers/ide/it8213.c +++ b/drivers/ide/it8213.c | |||
@@ -156,7 +156,7 @@ static const struct ide_port_ops it8213_port_ops = { | |||
156 | .cable_detect = it8213_cable_detect, | 156 | .cable_detect = it8213_cable_detect, |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static const struct ide_port_info it8213_chipset __devinitdata = { | 159 | static const struct ide_port_info it8213_chipset __devinitconst = { |
160 | .name = DRV_NAME, | 160 | .name = DRV_NAME, |
161 | .enablebits = { {0x41, 0x80, 0x80} }, | 161 | .enablebits = { {0x41, 0x80, 0x80} }, |
162 | .port_ops = &it8213_port_ops, | 162 | .port_ops = &it8213_port_ops, |
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index 2e3169f2acda..c5611dbca342 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c | |||
@@ -630,7 +630,7 @@ static const struct ide_port_ops it821x_port_ops = { | |||
630 | .cable_detect = it821x_cable_detect, | 630 | .cable_detect = it821x_cable_detect, |
631 | }; | 631 | }; |
632 | 632 | ||
633 | static const struct ide_port_info it821x_chipset __devinitdata = { | 633 | static const struct ide_port_info it821x_chipset __devinitconst = { |
634 | .name = DRV_NAME, | 634 | .name = DRV_NAME, |
635 | .init_chipset = init_chipset_it821x, | 635 | .init_chipset = init_chipset_it821x, |
636 | .init_hwif = init_hwif_it821x, | 636 | .init_hwif = init_hwif_it821x, |
diff --git a/drivers/ide/jmicron.c b/drivers/ide/jmicron.c index 74c2c4a6d909..efddd7d9f92d 100644 --- a/drivers/ide/jmicron.c +++ b/drivers/ide/jmicron.c | |||
@@ -102,7 +102,7 @@ static const struct ide_port_ops jmicron_port_ops = { | |||
102 | .cable_detect = jmicron_cable_detect, | 102 | .cable_detect = jmicron_cable_detect, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static const struct ide_port_info jmicron_chipset __devinitdata = { | 105 | static const struct ide_port_info jmicron_chipset __devinitconst = { |
106 | .name = DRV_NAME, | 106 | .name = DRV_NAME, |
107 | .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } }, | 107 | .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } }, |
108 | .port_ops = &jmicron_port_ops, | 108 | .port_ops = &jmicron_port_ops, |
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 95327a2c2422..73f78d872d55 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c | |||
@@ -293,7 +293,7 @@ static const struct ide_dma_ops ns87415_dma_ops = { | |||
293 | .dma_sff_read_status = superio_dma_sff_read_status, | 293 | .dma_sff_read_status = superio_dma_sff_read_status, |
294 | }; | 294 | }; |
295 | 295 | ||
296 | static const struct ide_port_info ns87415_chipset __devinitdata = { | 296 | static const struct ide_port_info ns87415_chipset __devinitconst = { |
297 | .name = DRV_NAME, | 297 | .name = DRV_NAME, |
298 | .init_hwif = init_hwif_ns87415, | 298 | .init_hwif = init_hwif_ns87415, |
299 | .tp_ops = &ns87415_tp_ops, | 299 | .tp_ops = &ns87415_tp_ops, |
diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c index 1a53a4c375ed..39edc66cb96c 100644 --- a/drivers/ide/opti621.c +++ b/drivers/ide/opti621.c | |||
@@ -131,7 +131,7 @@ static const struct ide_port_ops opti621_port_ops = { | |||
131 | .set_pio_mode = opti621_set_pio_mode, | 131 | .set_pio_mode = opti621_set_pio_mode, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static const struct ide_port_info opti621_chipset __devinitdata = { | 134 | static const struct ide_port_info opti621_chipset __devinitconst = { |
135 | .name = DRV_NAME, | 135 | .name = DRV_NAME, |
136 | .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} }, | 136 | .enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} }, |
137 | .port_ops = &opti621_port_ops, | 137 | .port_ops = &opti621_port_ops, |
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c index 9546fe2a93f7..2e5ceb62fb3b 100644 --- a/drivers/ide/pdc202xx_new.c +++ b/drivers/ide/pdc202xx_new.c | |||
@@ -465,7 +465,7 @@ static const struct ide_port_ops pdcnew_port_ops = { | |||
465 | .udma_mask = udma, \ | 465 | .udma_mask = udma, \ |
466 | } | 466 | } |
467 | 467 | ||
468 | static const struct ide_port_info pdcnew_chipsets[] __devinitdata = { | 468 | static const struct ide_port_info pdcnew_chipsets[] __devinitconst = { |
469 | /* 0: PDC202{68,70} */ DECLARE_PDCNEW_DEV(ATA_UDMA5), | 469 | /* 0: PDC202{68,70} */ DECLARE_PDCNEW_DEV(ATA_UDMA5), |
470 | /* 1: PDC202{69,71,75,76,77} */ DECLARE_PDCNEW_DEV(ATA_UDMA6), | 470 | /* 1: PDC202{69,71,75,76,77} */ DECLARE_PDCNEW_DEV(ATA_UDMA6), |
471 | }; | 471 | }; |
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index 3a35ec6193d2..563451096812 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c | |||
@@ -270,7 +270,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = { | |||
270 | .max_sectors = sectors, \ | 270 | .max_sectors = sectors, \ |
271 | } | 271 | } |
272 | 272 | ||
273 | static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = { | 273 | static const struct ide_port_info pdc202xx_chipsets[] __devinitconst = { |
274 | { /* 0: PDC20246 */ | 274 | { /* 0: PDC20246 */ |
275 | .name = DRV_NAME, | 275 | .name = DRV_NAME, |
276 | .init_chipset = init_chipset_pdc202xx, | 276 | .init_chipset = init_chipset_pdc202xx, |
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 1892e81fb00f..fe0fd60cfc09 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c | |||
@@ -344,7 +344,7 @@ static const struct ide_port_ops ich_port_ops = { | |||
344 | .udma_mask = udma, \ | 344 | .udma_mask = udma, \ |
345 | } | 345 | } |
346 | 346 | ||
347 | static const struct ide_port_info piix_pci_info[] __devinitdata = { | 347 | static const struct ide_port_info piix_pci_info[] __devinitconst = { |
348 | /* 0: MPIIX */ | 348 | /* 0: MPIIX */ |
349 | { /* | 349 | { /* |
350 | * MPIIX actually has only a single IDE channel mapped to | 350 | * MPIIX actually has only a single IDE channel mapped to |
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c index e03f4f19c1d6..a6fb6a894c7b 100644 --- a/drivers/ide/qd65xx.c +++ b/drivers/ide/qd65xx.c | |||
@@ -335,7 +335,7 @@ static const struct ide_port_ops qd6580_port_ops = { | |||
335 | .set_pio_mode = qd6580_set_pio_mode, | 335 | .set_pio_mode = qd6580_set_pio_mode, |
336 | }; | 336 | }; |
337 | 337 | ||
338 | static const struct ide_port_info qd65xx_port_info __initdata = { | 338 | static const struct ide_port_info qd65xx_port_info __initconst = { |
339 | .name = DRV_NAME, | 339 | .name = DRV_NAME, |
340 | .tp_ops = &qd65xx_tp_ops, | 340 | .tp_ops = &qd65xx_tp_ops, |
341 | .chipset = ide_qd65xx, | 341 | .chipset = ide_qd65xx, |
diff --git a/drivers/ide/rz1000.c b/drivers/ide/rz1000.c index a6414a884eb1..c04173e9fc38 100644 --- a/drivers/ide/rz1000.c +++ b/drivers/ide/rz1000.c | |||
@@ -38,7 +38,7 @@ static int __devinit rz1000_disable_readahead(struct pci_dev *dev) | |||
38 | } | 38 | } |
39 | } | 39 | } |
40 | 40 | ||
41 | static const struct ide_port_info rz1000_chipset __devinitdata = { | 41 | static const struct ide_port_info rz1000_chipset __devinitconst = { |
42 | .name = DRV_NAME, | 42 | .name = DRV_NAME, |
43 | .host_flags = IDE_HFLAG_NO_DMA, | 43 | .host_flags = IDE_HFLAG_NO_DMA, |
44 | }; | 44 | }; |
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c index 356b9b504ffd..d4758ebe77da 100644 --- a/drivers/ide/sc1200.c +++ b/drivers/ide/sc1200.c | |||
@@ -291,7 +291,7 @@ static const struct ide_dma_ops sc1200_dma_ops = { | |||
291 | .dma_sff_read_status = ide_dma_sff_read_status, | 291 | .dma_sff_read_status = ide_dma_sff_read_status, |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static const struct ide_port_info sc1200_chipset __devinitdata = { | 294 | static const struct ide_port_info sc1200_chipset __devinitconst = { |
295 | .name = DRV_NAME, | 295 | .name = DRV_NAME, |
296 | .port_ops = &sc1200_port_ops, | 296 | .port_ops = &sc1200_port_ops, |
297 | .dma_ops = &sc1200_dma_ops, | 297 | .dma_ops = &sc1200_dma_ops, |
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c index b7f5b0c4310c..970103810021 100644 --- a/drivers/ide/scc_pata.c +++ b/drivers/ide/scc_pata.c | |||
@@ -811,7 +811,7 @@ static const struct ide_dma_ops scc_dma_ops = { | |||
811 | .dma_sff_read_status = scc_dma_sff_read_status, | 811 | .dma_sff_read_status = scc_dma_sff_read_status, |
812 | }; | 812 | }; |
813 | 813 | ||
814 | static const struct ide_port_info scc_chipset __devinitdata = { | 814 | static const struct ide_port_info scc_chipset __devinitconst = { |
815 | .name = "sccIDE", | 815 | .name = "sccIDE", |
816 | .init_iops = init_iops_scc, | 816 | .init_iops = init_iops_scc, |
817 | .init_dma = scc_init_dma, | 817 | .init_dma = scc_init_dma, |
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c index 35fb8dabb55d..24d72ef23df7 100644 --- a/drivers/ide/serverworks.c +++ b/drivers/ide/serverworks.c | |||
@@ -337,7 +337,7 @@ static const struct ide_port_ops svwks_port_ops = { | |||
337 | .cable_detect = svwks_cable_detect, | 337 | .cable_detect = svwks_cable_detect, |
338 | }; | 338 | }; |
339 | 339 | ||
340 | static const struct ide_port_info serverworks_chipsets[] __devinitdata = { | 340 | static const struct ide_port_info serverworks_chipsets[] __devinitconst = { |
341 | { /* 0: OSB4 */ | 341 | { /* 0: OSB4 */ |
342 | .name = DRV_NAME, | 342 | .name = DRV_NAME, |
343 | .init_chipset = init_chipset_svwks, | 343 | .init_chipset = init_chipset_svwks, |
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c index ddeda444a27a..46f7e30d3790 100644 --- a/drivers/ide/siimage.c +++ b/drivers/ide/siimage.c | |||
@@ -719,7 +719,7 @@ static const struct ide_dma_ops sil_dma_ops = { | |||
719 | .udma_mask = ATA_UDMA6, \ | 719 | .udma_mask = ATA_UDMA6, \ |
720 | } | 720 | } |
721 | 721 | ||
722 | static const struct ide_port_info siimage_chipsets[] __devinitdata = { | 722 | static const struct ide_port_info siimage_chipsets[] __devinitconst = { |
723 | /* 0: SiI680 */ DECLARE_SII_DEV(&sil_pata_port_ops), | 723 | /* 0: SiI680 */ DECLARE_SII_DEV(&sil_pata_port_ops), |
724 | /* 1: SiI3112 */ DECLARE_SII_DEV(&sil_sata_port_ops) | 724 | /* 1: SiI3112 */ DECLARE_SII_DEV(&sil_sata_port_ops) |
725 | }; | 725 | }; |
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c index 4a0022567758..09e61b4c5e94 100644 --- a/drivers/ide/sis5513.c +++ b/drivers/ide/sis5513.c | |||
@@ -563,7 +563,7 @@ static const struct ide_port_ops sis_ata133_port_ops = { | |||
563 | .cable_detect = sis_cable_detect, | 563 | .cable_detect = sis_cable_detect, |
564 | }; | 564 | }; |
565 | 565 | ||
566 | static const struct ide_port_info sis5513_chipset __devinitdata = { | 566 | static const struct ide_port_info sis5513_chipset __devinitconst = { |
567 | .name = DRV_NAME, | 567 | .name = DRV_NAME, |
568 | .init_chipset = init_chipset_sis5513, | 568 | .init_chipset = init_chipset_sis5513, |
569 | .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} }, | 569 | .enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} }, |
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index f21dc2ad7682..d051cd224bdb 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c | |||
@@ -299,7 +299,7 @@ static const struct ide_dma_ops sl82c105_dma_ops = { | |||
299 | .dma_sff_read_status = ide_dma_sff_read_status, | 299 | .dma_sff_read_status = ide_dma_sff_read_status, |
300 | }; | 300 | }; |
301 | 301 | ||
302 | static const struct ide_port_info sl82c105_chipset __devinitdata = { | 302 | static const struct ide_port_info sl82c105_chipset __devinitconst = { |
303 | .name = DRV_NAME, | 303 | .name = DRV_NAME, |
304 | .init_chipset = init_chipset_sl82c105, | 304 | .init_chipset = init_chipset_sl82c105, |
305 | .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, | 305 | .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, |
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c index 864ffe0e26d9..863a5e9283ca 100644 --- a/drivers/ide/slc90e66.c +++ b/drivers/ide/slc90e66.c | |||
@@ -132,7 +132,7 @@ static const struct ide_port_ops slc90e66_port_ops = { | |||
132 | .cable_detect = slc90e66_cable_detect, | 132 | .cable_detect = slc90e66_cable_detect, |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static const struct ide_port_info slc90e66_chipset __devinitdata = { | 135 | static const struct ide_port_info slc90e66_chipset __devinitconst = { |
136 | .name = DRV_NAME, | 136 | .name = DRV_NAME, |
137 | .enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} }, | 137 | .enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} }, |
138 | .port_ops = &slc90e66_port_ops, | 138 | .port_ops = &slc90e66_port_ops, |
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c index 4799d5c384e7..17946785ebf6 100644 --- a/drivers/ide/tc86c001.c +++ b/drivers/ide/tc86c001.c | |||
@@ -192,7 +192,7 @@ static const struct ide_dma_ops tc86c001_dma_ops = { | |||
192 | .dma_sff_read_status = ide_dma_sff_read_status, | 192 | .dma_sff_read_status = ide_dma_sff_read_status, |
193 | }; | 193 | }; |
194 | 194 | ||
195 | static const struct ide_port_info tc86c001_chipset __devinitdata = { | 195 | static const struct ide_port_info tc86c001_chipset __devinitconst = { |
196 | .name = DRV_NAME, | 196 | .name = DRV_NAME, |
197 | .init_hwif = init_hwif_tc86c001, | 197 | .init_hwif = init_hwif_tc86c001, |
198 | .port_ops = &tc86c001_port_ops, | 198 | .port_ops = &tc86c001_port_ops, |
diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c index 281c91426345..55ce1b80efcb 100644 --- a/drivers/ide/triflex.c +++ b/drivers/ide/triflex.c | |||
@@ -92,7 +92,7 @@ static const struct ide_port_ops triflex_port_ops = { | |||
92 | .set_dma_mode = triflex_set_mode, | 92 | .set_dma_mode = triflex_set_mode, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static const struct ide_port_info triflex_device __devinitdata = { | 95 | static const struct ide_port_info triflex_device __devinitconst = { |
96 | .name = DRV_NAME, | 96 | .name = DRV_NAME, |
97 | .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, | 97 | .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, |
98 | .port_ops = &triflex_port_ops, | 98 | .port_ops = &triflex_port_ops, |
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c index 4b42ca091534..e494a98a43a9 100644 --- a/drivers/ide/trm290.c +++ b/drivers/ide/trm290.c | |||
@@ -324,7 +324,7 @@ static struct ide_dma_ops trm290_dma_ops = { | |||
324 | .dma_check = trm290_dma_check, | 324 | .dma_check = trm290_dma_check, |
325 | }; | 325 | }; |
326 | 326 | ||
327 | static const struct ide_port_info trm290_chipset __devinitdata = { | 327 | static const struct ide_port_info trm290_chipset __devinitconst = { |
328 | .name = DRV_NAME, | 328 | .name = DRV_NAME, |
329 | .init_hwif = init_hwif_trm290, | 329 | .init_hwif = init_hwif_trm290, |
330 | .tp_ops = &trm290_tp_ops, | 330 | .tp_ops = &trm290_tp_ops, |
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c index 7002765b593c..91d49dd957ef 100644 --- a/drivers/ide/tx4938ide.c +++ b/drivers/ide/tx4938ide.c | |||
@@ -117,7 +117,7 @@ static const struct ide_port_ops tx4938ide_port_ops = { | |||
117 | .set_pio_mode = tx4938ide_set_pio_mode, | 117 | .set_pio_mode = tx4938ide_set_pio_mode, |
118 | }; | 118 | }; |
119 | 119 | ||
120 | static const struct ide_port_info tx4938ide_port_info __initdata = { | 120 | static const struct ide_port_info tx4938ide_port_info __initconst = { |
121 | .port_ops = &tx4938ide_port_ops, | 121 | .port_ops = &tx4938ide_port_ops, |
122 | #ifdef __BIG_ENDIAN | 122 | #ifdef __BIG_ENDIAN |
123 | .tp_ops = &tx4938ide_tp_ops, | 123 | .tp_ops = &tx4938ide_tp_ops, |
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 71c231954972..c0ab800b7bb3 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c | |||
@@ -522,7 +522,7 @@ static const struct ide_dma_ops tx4939ide_dma_ops = { | |||
522 | .dma_sff_read_status = tx4939ide_dma_sff_read_status, | 522 | .dma_sff_read_status = tx4939ide_dma_sff_read_status, |
523 | }; | 523 | }; |
524 | 524 | ||
525 | static const struct ide_port_info tx4939ide_port_info __initdata = { | 525 | static const struct ide_port_info tx4939ide_port_info __initconst = { |
526 | .init_hwif = tx4939ide_init_hwif, | 526 | .init_hwif = tx4939ide_init_hwif, |
527 | .init_dma = tx4939ide_init_dma, | 527 | .init_dma = tx4939ide_init_dma, |
528 | .port_ops = &tx4939ide_port_ops, | 528 | .port_ops = &tx4939ide_port_ops, |
diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c index 5cfb78120669..3aa0fea0f3d9 100644 --- a/drivers/ide/umc8672.c +++ b/drivers/ide/umc8672.c | |||
@@ -128,7 +128,7 @@ static const struct ide_port_ops umc8672_port_ops = { | |||
128 | .set_pio_mode = umc_set_pio_mode, | 128 | .set_pio_mode = umc_set_pio_mode, |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static const struct ide_port_info umc8672_port_info __initdata = { | 131 | static const struct ide_port_info umc8672_port_info __initconst = { |
132 | .name = DRV_NAME, | 132 | .name = DRV_NAME, |
133 | .chipset = ide_umc8672, | 133 | .chipset = ide_umc8672, |
134 | .port_ops = &umc8672_port_ops, | 134 | .port_ops = &umc8672_port_ops, |
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index f46f49cfcc28..eb7767864d10 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c | |||
@@ -403,7 +403,7 @@ static const struct ide_port_ops via_port_ops = { | |||
403 | .cable_detect = via82cxxx_cable_detect, | 403 | .cable_detect = via82cxxx_cable_detect, |
404 | }; | 404 | }; |
405 | 405 | ||
406 | static const struct ide_port_info via82cxxx_chipset __devinitdata = { | 406 | static const struct ide_port_info via82cxxx_chipset __devinitconst = { |
407 | .name = DRV_NAME, | 407 | .name = DRV_NAME, |
408 | .init_chipset = init_chipset_via82cxxx, | 408 | .init_chipset = init_chipset_via82cxxx, |
409 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, | 409 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index d67999f6e34a..394fea2ba1bc 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -390,7 +390,7 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv) | |||
390 | ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, | 390 | ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, |
391 | next_id, &id); | 391 | next_id, &id); |
392 | if (!ret) | 392 | if (!ret) |
393 | next_id = ((unsigned) id + 1) & MAX_ID_MASK; | 393 | next_id = ((unsigned) id + 1) & MAX_IDR_MASK; |
394 | spin_unlock_irqrestore(&cm.lock, flags); | 394 | spin_unlock_irqrestore(&cm.lock, flags); |
395 | } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); | 395 | } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); |
396 | 396 | ||
diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c index e25e4dafb8a8..80079e5a2e30 100644 --- a/drivers/infiniband/hw/mlx4/cm.c +++ b/drivers/infiniband/hw/mlx4/cm.c | |||
@@ -225,7 +225,7 @@ id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id) | |||
225 | ret = idr_get_new_above(&sriov->pv_id_table, ent, | 225 | ret = idr_get_new_above(&sriov->pv_id_table, ent, |
226 | next_id, &id); | 226 | next_id, &id); |
227 | if (!ret) { | 227 | if (!ret) { |
228 | next_id = ((unsigned) id + 1) & MAX_ID_MASK; | 228 | next_id = ((unsigned) id + 1) & MAX_IDR_MASK; |
229 | ent->pv_cm_id = (u32)id; | 229 | ent->pv_cm_id = (u32)id; |
230 | sl_id_map_add(ibdev, ent); | 230 | sl_id_map_add(ibdev, ent); |
231 | } | 231 | } |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 20e5c2cda430..ef87310b7662 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -748,7 +748,7 @@ static void __devexit macio_pci_remove(struct pci_dev* pdev) | |||
748 | * MacIO is matched against any Apple ID, it's probe() function | 748 | * MacIO is matched against any Apple ID, it's probe() function |
749 | * will then decide wether it applies or not | 749 | * will then decide wether it applies or not |
750 | */ | 750 | */ |
751 | static const struct pci_device_id __devinitdata pci_ids [] = { { | 751 | static const struct pci_device_id __devinitconst pci_ids[] = { { |
752 | .vendor = PCI_VENDOR_ID_APPLE, | 752 | .vendor = PCI_VENDOR_ID_APPLE, |
753 | .device = PCI_ANY_ID, | 753 | .device = PCI_ANY_ID, |
754 | .subvendor = PCI_ANY_ID, | 754 | .subvendor = PCI_ANY_ID, |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 3d6d9beb18d4..8fefc961ec06 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -374,21 +374,21 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) | |||
374 | } | 374 | } |
375 | #endif | 375 | #endif |
376 | 376 | ||
377 | static const __devinitdata struct reg_default wm8994_revc_patch[] = { | 377 | static const __devinitconst struct reg_default wm8994_revc_patch[] = { |
378 | { 0x102, 0x3 }, | 378 | { 0x102, 0x3 }, |
379 | { 0x56, 0x3 }, | 379 | { 0x56, 0x3 }, |
380 | { 0x817, 0x0 }, | 380 | { 0x817, 0x0 }, |
381 | { 0x102, 0x0 }, | 381 | { 0x102, 0x0 }, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | static const __devinitdata struct reg_default wm8958_reva_patch[] = { | 384 | static const __devinitconst struct reg_default wm8958_reva_patch[] = { |
385 | { 0x102, 0x3 }, | 385 | { 0x102, 0x3 }, |
386 | { 0xcb, 0x81 }, | 386 | { 0xcb, 0x81 }, |
387 | { 0x817, 0x0 }, | 387 | { 0x817, 0x0 }, |
388 | { 0x102, 0x0 }, | 388 | { 0x102, 0x0 }, |
389 | }; | 389 | }; |
390 | 390 | ||
391 | static const __devinitdata struct reg_default wm1811_reva_patch[] = { | 391 | static const __devinitconst struct reg_default wm1811_reva_patch[] = { |
392 | { 0x102, 0x3 }, | 392 | { 0x102, 0x3 }, |
393 | { 0x56, 0xc07 }, | 393 | { 0x56, 0xc07 }, |
394 | { 0x5d, 0x7e }, | 394 | { 0x5d, 0x7e }, |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 504da715a41a..9722d43d6140 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -653,7 +653,7 @@ static const struct sdhci_pci_fixes sdhci_via = { | |||
653 | .probe = via_probe, | 653 | .probe = via_probe, |
654 | }; | 654 | }; |
655 | 655 | ||
656 | static const struct pci_device_id pci_ids[] __devinitdata = { | 656 | static const struct pci_device_id pci_ids[] __devinitconst = { |
657 | { | 657 | { |
658 | .vendor = PCI_VENDOR_ID_RICOH, | 658 | .vendor = PCI_VENDOR_ID_RICOH, |
659 | .device = PCI_DEVICE_ID_RICOH_R5C822, | 659 | .device = PCI_DEVICE_ID_RICOH_R5C822, |
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 034c16b60e96..adc3708d8829 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <linux/kernel.h> | 56 | #include <linux/kernel.h> |
57 | #include <linux/can.h> | 57 | #include <linux/can.h> |
58 | 58 | ||
59 | static __initdata const char banner[] = | 59 | static __initconst const char banner[] = |
60 | KERN_INFO "slcan: serial line CAN interface driver\n"; | 60 | KERN_INFO "slcan: serial line CAN interface driver\n"; |
61 | 61 | ||
62 | MODULE_ALIAS_LDISC(N_SLCAN); | 62 | MODULE_ALIAS_LDISC(N_SLCAN); |
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 4f93c0be0053..0a2a5ee79a17 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c | |||
@@ -49,7 +49,7 @@ | |||
49 | #include <linux/slab.h> | 49 | #include <linux/slab.h> |
50 | #include <net/rtnetlink.h> | 50 | #include <net/rtnetlink.h> |
51 | 51 | ||
52 | static __initdata const char banner[] = | 52 | static __initconst const char banner[] = |
53 | KERN_INFO "vcan: Virtual CAN interface driver\n"; | 53 | KERN_INFO "vcan: Virtual CAN interface driver\n"; |
54 | 54 | ||
55 | MODULE_DESCRIPTION("virtual CAN interface"); | 55 | MODULE_DESCRIPTION("virtual CAN interface"); |
diff --git a/drivers/net/ethernet/8390/ne3210.c b/drivers/net/ethernet/8390/ne3210.c index a2f8b2b8e27c..e3f57427d5c5 100644 --- a/drivers/net/ethernet/8390/ne3210.c +++ b/drivers/net/ethernet/8390/ne3210.c | |||
@@ -81,7 +81,7 @@ static void ne3210_block_output(struct net_device *dev, int count, const unsigne | |||
81 | 81 | ||
82 | static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; | 82 | static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; |
83 | static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0}; | 83 | static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0}; |
84 | static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"}; | 84 | static const char * const ifmap[] __initconst = {"UTP", "?", "BNC", "AUI"}; |
85 | static int ifmap_val[] __initdata = { | 85 | static int ifmap_val[] __initdata = { |
86 | IF_PORT_10BASET, | 86 | IF_PORT_10BASET, |
87 | IF_PORT_UNKNOWN, | 87 | IF_PORT_UNKNOWN, |
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c index d920a529ba22..5b65992c2a0a 100644 --- a/drivers/net/ethernet/adaptec/starfire.c +++ b/drivers/net/ethernet/adaptec/starfire.c | |||
@@ -295,7 +295,7 @@ MODULE_DEVICE_TABLE(pci, starfire_pci_tbl); | |||
295 | static const struct chip_info { | 295 | static const struct chip_info { |
296 | const char *name; | 296 | const char *name; |
297 | int drv_flags; | 297 | int drv_flags; |
298 | } netdrv_tbl[] __devinitdata = { | 298 | } netdrv_tbl[] __devinitconst = { |
299 | { "Adaptec Starfire 6915", CanHaveMII }, | 299 | { "Adaptec Starfire 6915", CanHaveMII }, |
300 | }; | 300 | }; |
301 | 301 | ||
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 55a2e3795055..d19f82f7597a 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c | |||
@@ -702,7 +702,7 @@ struct atl1c_platform_patch { | |||
702 | u32 patch_flag; | 702 | u32 patch_flag; |
703 | #define ATL1C_LINK_PATCH 0x1 | 703 | #define ATL1C_LINK_PATCH 0x1 |
704 | }; | 704 | }; |
705 | static const struct atl1c_platform_patch plats[] __devinitdata = { | 705 | static const struct atl1c_platform_patch plats[] __devinitconst = { |
706 | {0x2060, 0xC1, 0x1019, 0x8152, 0x1}, | 706 | {0x2060, 0xC1, 0x1019, 0x8152, 0x1}, |
707 | {0x2060, 0xC1, 0x1019, 0x2060, 0x1}, | 707 | {0x2060, 0xC1, 0x1019, 0x2060, 0x1}, |
708 | {0x2060, 0xC1, 0x1019, 0xE000, 0x1}, | 708 | {0x2060, 0xC1, 0x1019, 0xE000, 0x1}, |
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c index 57d64b80fd72..623dd8635c46 100644 --- a/drivers/net/ethernet/atheros/atlx/atl2.c +++ b/drivers/net/ethernet/atheros/atlx/atl2.c | |||
@@ -2845,7 +2845,7 @@ static void atl2_force_ps(struct atl2_hw *hw) | |||
2845 | */ | 2845 | */ |
2846 | 2846 | ||
2847 | #define ATL2_PARAM(X, desc) \ | 2847 | #define ATL2_PARAM(X, desc) \ |
2848 | static const int __devinitdata X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \ | 2848 | static const int __devinitconst X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \ |
2849 | MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \ | 2849 | MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \ |
2850 | MODULE_PARM_DESC(X, desc); | 2850 | MODULE_PARM_DESC(X, desc); |
2851 | #else | 2851 | #else |
diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c index 61cc09342865..77335853ac36 100644 --- a/drivers/net/ethernet/dec/tulip/de2104x.c +++ b/drivers/net/ethernet/dec/tulip/de2104x.c | |||
@@ -661,9 +661,6 @@ static netdev_tx_t de_start_xmit (struct sk_buff *skb, | |||
661 | new frame, not around filling de->setup_frame. This is non-deterministic | 661 | new frame, not around filling de->setup_frame. This is non-deterministic |
662 | when re-entered but still correct. */ | 662 | when re-entered but still correct. */ |
663 | 663 | ||
664 | #undef set_bit_le | ||
665 | #define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0) | ||
666 | |||
667 | static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) | 664 | static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) |
668 | { | 665 | { |
669 | struct de_private *de = netdev_priv(dev); | 666 | struct de_private *de = netdev_priv(dev); |
@@ -673,12 +670,12 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) | |||
673 | u16 *eaddrs; | 670 | u16 *eaddrs; |
674 | 671 | ||
675 | memset(hash_table, 0, sizeof(hash_table)); | 672 | memset(hash_table, 0, sizeof(hash_table)); |
676 | set_bit_le(255, hash_table); /* Broadcast entry */ | 673 | __set_bit_le(255, hash_table); /* Broadcast entry */ |
677 | /* This should work on big-endian machines as well. */ | 674 | /* This should work on big-endian machines as well. */ |
678 | netdev_for_each_mc_addr(ha, dev) { | 675 | netdev_for_each_mc_addr(ha, dev) { |
679 | int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff; | 676 | int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff; |
680 | 677 | ||
681 | set_bit_le(index, hash_table); | 678 | __set_bit_le(index, hash_table); |
682 | } | 679 | } |
683 | 680 | ||
684 | for (i = 0; i < 32; i++) { | 681 | for (i = 0; i < 32; i++) { |
diff --git a/drivers/net/ethernet/dec/tulip/eeprom.c b/drivers/net/ethernet/dec/tulip/eeprom.c index ed7d1dcd9566..44f7e8e82d85 100644 --- a/drivers/net/ethernet/dec/tulip/eeprom.c +++ b/drivers/net/ethernet/dec/tulip/eeprom.c | |||
@@ -79,7 +79,7 @@ static struct eeprom_fixup eeprom_fixups[] __devinitdata = { | |||
79 | {NULL}}; | 79 | {NULL}}; |
80 | 80 | ||
81 | 81 | ||
82 | static const char *block_name[] __devinitdata = { | 82 | static const char *const block_name[] __devinitconst = { |
83 | "21140 non-MII", | 83 | "21140 non-MII", |
84 | "21140 MII PHY", | 84 | "21140 MII PHY", |
85 | "21142 Serial PHY", | 85 | "21142 Serial PHY", |
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index c4f37aca2269..885700a19978 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c | |||
@@ -1010,9 +1010,6 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) | |||
1010 | new frame, not around filling tp->setup_frame. This is non-deterministic | 1010 | new frame, not around filling tp->setup_frame. This is non-deterministic |
1011 | when re-entered but still correct. */ | 1011 | when re-entered but still correct. */ |
1012 | 1012 | ||
1013 | #undef set_bit_le | ||
1014 | #define set_bit_le(i,p) do { ((char *)(p))[(i)/8] |= (1<<((i)%8)); } while(0) | ||
1015 | |||
1016 | static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) | 1013 | static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) |
1017 | { | 1014 | { |
1018 | struct tulip_private *tp = netdev_priv(dev); | 1015 | struct tulip_private *tp = netdev_priv(dev); |
@@ -1022,12 +1019,12 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev) | |||
1022 | u16 *eaddrs; | 1019 | u16 *eaddrs; |
1023 | 1020 | ||
1024 | memset(hash_table, 0, sizeof(hash_table)); | 1021 | memset(hash_table, 0, sizeof(hash_table)); |
1025 | set_bit_le(255, hash_table); /* Broadcast entry */ | 1022 | __set_bit_le(255, hash_table); /* Broadcast entry */ |
1026 | /* This should work on big-endian machines as well. */ | 1023 | /* This should work on big-endian machines as well. */ |
1027 | netdev_for_each_mc_addr(ha, dev) { | 1024 | netdev_for_each_mc_addr(ha, dev) { |
1028 | int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff; | 1025 | int index = ether_crc_le(ETH_ALEN, ha->addr) & 0x1ff; |
1029 | 1026 | ||
1030 | set_bit_le(index, hash_table); | 1027 | __set_bit_le(index, hash_table); |
1031 | } | 1028 | } |
1032 | for (i = 0; i < 32; i++) { | 1029 | for (i = 0; i < 32; i++) { |
1033 | *setup_frm++ = hash_table[i]; | 1030 | *setup_frm++ = hash_table[i]; |
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c index 4d1ffca83c82..7c1ec4d7920b 100644 --- a/drivers/net/ethernet/dec/tulip/winbond-840.c +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c | |||
@@ -236,7 +236,7 @@ struct pci_id_info { | |||
236 | int drv_flags; /* Driver use, intended as capability flags. */ | 236 | int drv_flags; /* Driver use, intended as capability flags. */ |
237 | }; | 237 | }; |
238 | 238 | ||
239 | static const struct pci_id_info pci_id_tbl[] __devinitdata = { | 239 | static const struct pci_id_info pci_id_tbl[] __devinitconst = { |
240 | { /* Sometime a Level-One switch card. */ | 240 | { /* Sometime a Level-One switch card. */ |
241 | "Winbond W89c840", CanHaveMII | HasBrokenTx | FDXOnNoMII}, | 241 | "Winbond W89c840", CanHaveMII | HasBrokenTx | FDXOnNoMII}, |
242 | { "Winbond W89c840", CanHaveMII | HasBrokenTx}, | 242 | { "Winbond W89c840", CanHaveMII | HasBrokenTx}, |
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c index d7bb52a7bda1..3b83588e51f6 100644 --- a/drivers/net/ethernet/dlink/sundance.c +++ b/drivers/net/ethernet/dlink/sundance.c | |||
@@ -218,7 +218,7 @@ enum { | |||
218 | struct pci_id_info { | 218 | struct pci_id_info { |
219 | const char *name; | 219 | const char *name; |
220 | }; | 220 | }; |
221 | static const struct pci_id_info pci_id_tbl[] __devinitdata = { | 221 | static const struct pci_id_info pci_id_tbl[] __devinitconst = { |
222 | {"D-Link DFE-550TX FAST Ethernet Adapter"}, | 222 | {"D-Link DFE-550TX FAST Ethernet Adapter"}, |
223 | {"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"}, | 223 | {"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"}, |
224 | {"D-Link DFE-580TX 4 port Server Adapter"}, | 224 | {"D-Link DFE-580TX 4 port Server Adapter"}, |
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c index 9d71c9cc300b..0e4a0ac86aa8 100644 --- a/drivers/net/ethernet/fealnx.c +++ b/drivers/net/ethernet/fealnx.c | |||
@@ -150,7 +150,7 @@ struct chip_info { | |||
150 | int flags; | 150 | int flags; |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static const struct chip_info skel_netdrv_tbl[] __devinitdata = { | 153 | static const struct chip_info skel_netdrv_tbl[] __devinitconst = { |
154 | { "100/10M Ethernet PCI Adapter", HAS_MII_XCVR }, | 154 | { "100/10M Ethernet PCI Adapter", HAS_MII_XCVR }, |
155 | { "100/10M Ethernet PCI Adapter", HAS_CHIP_XCVR }, | 155 | { "100/10M Ethernet PCI Adapter", HAS_CHIP_XCVR }, |
156 | { "1000/100/10M Ethernet PCI Adapter", HAS_MII_XCVR }, | 156 | { "1000/100/10M Ethernet PCI Adapter", HAS_MII_XCVR }, |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index b528e52a8ee1..2a0c9dc48eb3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |||
@@ -38,7 +38,7 @@ static inline void writeq(u64 val, void __iomem *addr) | |||
38 | } | 38 | } |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | static const struct crb_128M_2M_block_map | 41 | static struct crb_128M_2M_block_map |
42 | crb_128M_2M_map[64] __cacheline_aligned_in_smp = { | 42 | crb_128M_2M_map[64] __cacheline_aligned_in_smp = { |
43 | {{{0, 0, 0, 0} } }, /* 0: PCI */ | 43 | {{{0, 0, 0, 0} } }, /* 0: PCI */ |
44 | {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */ | 44 | {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */ |
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 1d83565cc6af..3ed7add23c12 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c | |||
@@ -228,7 +228,7 @@ typedef enum { | |||
228 | static const struct { | 228 | static const struct { |
229 | const char *name; | 229 | const char *name; |
230 | u32 hw_flags; | 230 | u32 hw_flags; |
231 | } board_info[] __devinitdata = { | 231 | } board_info[] __devinitconst = { |
232 | { "RealTek RTL8139", RTL8139_CAPS }, | 232 | { "RealTek RTL8139", RTL8139_CAPS }, |
233 | { "RealTek RTL8129", RTL8129_CAPS }, | 233 | { "RealTek RTL8129", RTL8129_CAPS }, |
234 | }; | 234 | }; |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 96bd980e828d..4f86d0cd516a 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -2019,14 +2019,14 @@ static void efx_set_rx_mode(struct net_device *net_dev) | |||
2019 | netdev_for_each_mc_addr(ha, net_dev) { | 2019 | netdev_for_each_mc_addr(ha, net_dev) { |
2020 | crc = ether_crc_le(ETH_ALEN, ha->addr); | 2020 | crc = ether_crc_le(ETH_ALEN, ha->addr); |
2021 | bit = crc & (EFX_MCAST_HASH_ENTRIES - 1); | 2021 | bit = crc & (EFX_MCAST_HASH_ENTRIES - 1); |
2022 | set_bit_le(bit, mc_hash->byte); | 2022 | __set_bit_le(bit, mc_hash); |
2023 | } | 2023 | } |
2024 | 2024 | ||
2025 | /* Broadcast packets go through the multicast hash filter. | 2025 | /* Broadcast packets go through the multicast hash filter. |
2026 | * ether_crc_le() of the broadcast address is 0xbe2612ff | 2026 | * ether_crc_le() of the broadcast address is 0xbe2612ff |
2027 | * so we always add bit 0xff to the mask. | 2027 | * so we always add bit 0xff to the mask. |
2028 | */ | 2028 | */ |
2029 | set_bit_le(0xff, mc_hash->byte); | 2029 | __set_bit_le(0xff, mc_hash); |
2030 | } | 2030 | } |
2031 | 2031 | ||
2032 | if (efx->port_enabled) | 2032 | if (efx->port_enabled) |
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index c1a010cda89b..576a31091165 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h | |||
@@ -1101,18 +1101,6 @@ static inline struct efx_rx_buffer *efx_rx_buffer(struct efx_rx_queue *rx_queue, | |||
1101 | return &rx_queue->buffer[index]; | 1101 | return &rx_queue->buffer[index]; |
1102 | } | 1102 | } |
1103 | 1103 | ||
1104 | /* Set bit in a little-endian bitfield */ | ||
1105 | static inline void set_bit_le(unsigned nr, unsigned char *addr) | ||
1106 | { | ||
1107 | addr[nr / 8] |= (1 << (nr % 8)); | ||
1108 | } | ||
1109 | |||
1110 | /* Clear bit in a little-endian bitfield */ | ||
1111 | static inline void clear_bit_le(unsigned nr, unsigned char *addr) | ||
1112 | { | ||
1113 | addr[nr / 8] &= ~(1 << (nr % 8)); | ||
1114 | } | ||
1115 | |||
1116 | 1104 | ||
1117 | /** | 1105 | /** |
1118 | * EFX_MAX_FRAME_LEN - calculate maximum frame length | 1106 | * EFX_MAX_FRAME_LEN - calculate maximum frame length |
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index cdff40b65729..aab7cacb2e34 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c | |||
@@ -472,9 +472,9 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue) | |||
472 | 472 | ||
473 | efx_reado(efx, ®, FR_AA_TX_CHKSM_CFG); | 473 | efx_reado(efx, ®, FR_AA_TX_CHKSM_CFG); |
474 | if (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD) | 474 | if (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD) |
475 | clear_bit_le(tx_queue->queue, (void *)®); | 475 | __clear_bit_le(tx_queue->queue, ®); |
476 | else | 476 | else |
477 | set_bit_le(tx_queue->queue, (void *)®); | 477 | __set_bit_le(tx_queue->queue, ®); |
478 | efx_writeo(efx, ®, FR_AA_TX_CHKSM_CFG); | 478 | efx_writeo(efx, ®, FR_AA_TX_CHKSM_CFG); |
479 | } | 479 | } |
480 | 480 | ||
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c index 4613591b43e7..d8166012b7d4 100644 --- a/drivers/net/ethernet/sis/sis190.c +++ b/drivers/net/ethernet/sis/sis190.c | |||
@@ -1618,7 +1618,7 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, | |||
1618 | static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev, | 1618 | static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev, |
1619 | struct net_device *dev) | 1619 | struct net_device *dev) |
1620 | { | 1620 | { |
1621 | static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 }; | 1621 | static const u16 __devinitconst ids[] = { 0x0965, 0x0966, 0x0968 }; |
1622 | struct sis190_private *tp = netdev_priv(dev); | 1622 | struct sis190_private *tp = netdev_priv(dev); |
1623 | struct pci_dev *isa_bridge; | 1623 | struct pci_dev *isa_bridge; |
1624 | u8 reg, tmp8; | 1624 | u8 reg, tmp8; |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 64783a0d545a..1450e33fc250 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -811,9 +811,9 @@ static struct tty_ldisc_ops sp_ldisc = { | |||
811 | 811 | ||
812 | /* Initialize 6pack control device -- register 6pack line discipline */ | 812 | /* Initialize 6pack control device -- register 6pack line discipline */ |
813 | 813 | ||
814 | static const char msg_banner[] __initdata = KERN_INFO \ | 814 | static const char msg_banner[] __initconst = KERN_INFO \ |
815 | "AX.25: 6pack driver, " SIXPACK_VERSION "\n"; | 815 | "AX.25: 6pack driver, " SIXPACK_VERSION "\n"; |
816 | static const char msg_regfail[] __initdata = KERN_ERR \ | 816 | static const char msg_regfail[] __initconst = KERN_ERR \ |
817 | "6pack: can't register line discipline (err = %d)\n"; | 817 | "6pack: can't register line discipline (err = %d)\n"; |
818 | 818 | ||
819 | static int __init sixpack_init_driver(void) | 819 | static int __init sixpack_init_driver(void) |
@@ -829,7 +829,7 @@ static int __init sixpack_init_driver(void) | |||
829 | return status; | 829 | return status; |
830 | } | 830 | } |
831 | 831 | ||
832 | static const char msg_unregfail[] __exitdata = KERN_ERR \ | 832 | static const char msg_unregfail[] = KERN_ERR \ |
833 | "6pack: can't unregister line discipline (err = %d)\n"; | 833 | "6pack: can't unregister line discipline (err = %d)\n"; |
834 | 834 | ||
835 | static void __exit sixpack_exit_driver(void) | 835 | static void __exit sixpack_exit_driver(void) |
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 76d54774ba82..c2e5497397d5 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c | |||
@@ -87,7 +87,7 @@ | |||
87 | 87 | ||
88 | #include <linux/bpqether.h> | 88 | #include <linux/bpqether.h> |
89 | 89 | ||
90 | static const char banner[] __initdata = KERN_INFO \ | 90 | static const char banner[] __initconst = KERN_INFO \ |
91 | "AX.25: bpqether driver version 004\n"; | 91 | "AX.25: bpqether driver version 004\n"; |
92 | 92 | ||
93 | static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; | 93 | static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 2c0894a92abd..8e01c457015b 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -997,9 +997,9 @@ static struct tty_ldisc_ops ax_ldisc = { | |||
997 | .write_wakeup = mkiss_write_wakeup | 997 | .write_wakeup = mkiss_write_wakeup |
998 | }; | 998 | }; |
999 | 999 | ||
1000 | static const char banner[] __initdata = KERN_INFO \ | 1000 | static const char banner[] __initconst = KERN_INFO \ |
1001 | "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; | 1001 | "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; |
1002 | static const char msg_regfail[] __initdata = KERN_ERR \ | 1002 | static const char msg_regfail[] __initconst = KERN_ERR \ |
1003 | "mkiss: can't register line discipline (err = %d)\n"; | 1003 | "mkiss: can't register line discipline (err = %d)\n"; |
1004 | 1004 | ||
1005 | static int __init mkiss_init_driver(void) | 1005 | static int __init mkiss_init_driver(void) |
@@ -1015,7 +1015,7 @@ static int __init mkiss_init_driver(void) | |||
1015 | return status; | 1015 | return status; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | static const char msg_unregfail[] __exitdata = KERN_ERR \ | 1018 | static const char msg_unregfail[] = KERN_ERR \ |
1019 | "mkiss: can't unregister line discipline (err = %d)\n"; | 1019 | "mkiss: can't unregister line discipline (err = %d)\n"; |
1020 | 1020 | ||
1021 | static void __exit mkiss_exit_driver(void) | 1021 | static void __exit mkiss_exit_driver(void) |
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index efc6c97163a7..1b4a47bd32b7 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
@@ -182,7 +182,7 @@ | |||
182 | 182 | ||
183 | #include "z8530.h" | 183 | #include "z8530.h" |
184 | 184 | ||
185 | static const char banner[] __initdata = KERN_INFO \ | 185 | static const char banner[] __initconst = KERN_INFO \ |
186 | "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n"; | 186 | "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n"; |
187 | 187 | ||
188 | static void t_dwait(unsigned long); | 188 | static void t_dwait(unsigned long); |
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 5a6412ecce73..c6645f1017af 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c | |||
@@ -76,7 +76,7 @@ | |||
76 | /* --------------------------------------------------------------------- */ | 76 | /* --------------------------------------------------------------------- */ |
77 | 77 | ||
78 | static const char yam_drvname[] = "yam"; | 78 | static const char yam_drvname[] = "yam"; |
79 | static const char yam_drvinfo[] __initdata = KERN_INFO \ | 79 | static const char yam_drvinfo[] __initconst = KERN_INFO \ |
80 | "YAM driver version 0.8 by F1OAT/F6FBB\n"; | 80 | "YAM driver version 0.8 by F1OAT/F6FBB\n"; |
81 | 81 | ||
82 | /* --------------------------------------------------------------------- */ | 82 | /* --------------------------------------------------------------------- */ |
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 91d25888a1b9..d8b9b1e8ee02 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/ethtool.h> | 26 | #include <linux/ethtool.h> |
27 | 27 | ||
28 | #define DRV_NAME "rionet" | 28 | #define DRV_NAME "rionet" |
29 | #define DRV_VERSION "0.2" | 29 | #define DRV_VERSION "0.3" |
30 | #define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>" | 30 | #define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>" |
31 | #define DRV_DESC "Ethernet over RapidIO" | 31 | #define DRV_DESC "Ethernet over RapidIO" |
32 | 32 | ||
@@ -47,8 +47,7 @@ MODULE_LICENSE("GPL"); | |||
47 | 47 | ||
48 | #define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE | 48 | #define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE |
49 | #define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE | 49 | #define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE |
50 | 50 | #define RIONET_MAX_NETS 8 | |
51 | static LIST_HEAD(rionet_peers); | ||
52 | 51 | ||
53 | struct rionet_private { | 52 | struct rionet_private { |
54 | struct rio_mport *mport; | 53 | struct rio_mport *mport; |
@@ -69,16 +68,14 @@ struct rionet_peer { | |||
69 | struct resource *res; | 68 | struct resource *res; |
70 | }; | 69 | }; |
71 | 70 | ||
72 | static int rionet_check = 0; | 71 | struct rionet_net { |
73 | static int rionet_capable = 1; | 72 | struct net_device *ndev; |
73 | struct list_head peers; | ||
74 | struct rio_dev **active; | ||
75 | int nact; /* number of active peers */ | ||
76 | }; | ||
74 | 77 | ||
75 | /* | 78 | static struct rionet_net nets[RIONET_MAX_NETS]; |
76 | * This is a fast lookup table for translating TX | ||
77 | * Ethernet packets into a destination RIO device. It | ||
78 | * could be made into a hash table to save memory depending | ||
79 | * on system trade-offs. | ||
80 | */ | ||
81 | static struct rio_dev **rionet_active; | ||
82 | 79 | ||
83 | #define is_rionet_capable(src_ops, dst_ops) \ | 80 | #define is_rionet_capable(src_ops, dst_ops) \ |
84 | ((src_ops & RIO_SRC_OPS_DATA_MSG) && \ | 81 | ((src_ops & RIO_SRC_OPS_DATA_MSG) && \ |
@@ -175,6 +172,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
175 | struct ethhdr *eth = (struct ethhdr *)skb->data; | 172 | struct ethhdr *eth = (struct ethhdr *)skb->data; |
176 | u16 destid; | 173 | u16 destid; |
177 | unsigned long flags; | 174 | unsigned long flags; |
175 | int add_num = 1; | ||
178 | 176 | ||
179 | local_irq_save(flags); | 177 | local_irq_save(flags); |
180 | if (!spin_trylock(&rnet->tx_lock)) { | 178 | if (!spin_trylock(&rnet->tx_lock)) { |
@@ -182,7 +180,10 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
182 | return NETDEV_TX_LOCKED; | 180 | return NETDEV_TX_LOCKED; |
183 | } | 181 | } |
184 | 182 | ||
185 | if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) { | 183 | if (is_multicast_ether_addr(eth->h_dest)) |
184 | add_num = nets[rnet->mport->id].nact; | ||
185 | |||
186 | if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) { | ||
186 | netif_stop_queue(ndev); | 187 | netif_stop_queue(ndev); |
187 | spin_unlock_irqrestore(&rnet->tx_lock, flags); | 188 | spin_unlock_irqrestore(&rnet->tx_lock, flags); |
188 | printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n", | 189 | printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n", |
@@ -191,15 +192,22 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
191 | } | 192 | } |
192 | 193 | ||
193 | if (is_multicast_ether_addr(eth->h_dest)) { | 194 | if (is_multicast_ether_addr(eth->h_dest)) { |
195 | int count = 0; | ||
196 | |||
194 | for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size); | 197 | for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size); |
195 | i++) | 198 | i++) |
196 | if (rionet_active[i]) | 199 | if (nets[rnet->mport->id].active[i]) { |
197 | rionet_queue_tx_msg(skb, ndev, | 200 | rionet_queue_tx_msg(skb, ndev, |
198 | rionet_active[i]); | 201 | nets[rnet->mport->id].active[i]); |
202 | if (count) | ||
203 | atomic_inc(&skb->users); | ||
204 | count++; | ||
205 | } | ||
199 | } else if (RIONET_MAC_MATCH(eth->h_dest)) { | 206 | } else if (RIONET_MAC_MATCH(eth->h_dest)) { |
200 | destid = RIONET_GET_DESTID(eth->h_dest); | 207 | destid = RIONET_GET_DESTID(eth->h_dest); |
201 | if (rionet_active[destid]) | 208 | if (nets[rnet->mport->id].active[destid]) |
202 | rionet_queue_tx_msg(skb, ndev, rionet_active[destid]); | 209 | rionet_queue_tx_msg(skb, ndev, |
210 | nets[rnet->mport->id].active[destid]); | ||
203 | } | 211 | } |
204 | 212 | ||
205 | spin_unlock_irqrestore(&rnet->tx_lock, flags); | 213 | spin_unlock_irqrestore(&rnet->tx_lock, flags); |
@@ -218,16 +226,21 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u | |||
218 | printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x", | 226 | printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x", |
219 | DRV_NAME, sid, tid, info); | 227 | DRV_NAME, sid, tid, info); |
220 | if (info == RIONET_DOORBELL_JOIN) { | 228 | if (info == RIONET_DOORBELL_JOIN) { |
221 | if (!rionet_active[sid]) { | 229 | if (!nets[rnet->mport->id].active[sid]) { |
222 | list_for_each_entry(peer, &rionet_peers, node) { | 230 | list_for_each_entry(peer, |
223 | if (peer->rdev->destid == sid) | 231 | &nets[rnet->mport->id].peers, node) { |
224 | rionet_active[sid] = peer->rdev; | 232 | if (peer->rdev->destid == sid) { |
233 | nets[rnet->mport->id].active[sid] = | ||
234 | peer->rdev; | ||
235 | nets[rnet->mport->id].nact++; | ||
236 | } | ||
225 | } | 237 | } |
226 | rio_mport_send_doorbell(mport, sid, | 238 | rio_mport_send_doorbell(mport, sid, |
227 | RIONET_DOORBELL_JOIN); | 239 | RIONET_DOORBELL_JOIN); |
228 | } | 240 | } |
229 | } else if (info == RIONET_DOORBELL_LEAVE) { | 241 | } else if (info == RIONET_DOORBELL_LEAVE) { |
230 | rionet_active[sid] = NULL; | 242 | nets[rnet->mport->id].active[sid] = NULL; |
243 | nets[rnet->mport->id].nact--; | ||
231 | } else { | 244 | } else { |
232 | if (netif_msg_intr(rnet)) | 245 | if (netif_msg_intr(rnet)) |
233 | printk(KERN_WARNING "%s: unhandled doorbell\n", | 246 | printk(KERN_WARNING "%s: unhandled doorbell\n", |
@@ -321,7 +334,8 @@ static int rionet_open(struct net_device *ndev) | |||
321 | netif_carrier_on(ndev); | 334 | netif_carrier_on(ndev); |
322 | netif_start_queue(ndev); | 335 | netif_start_queue(ndev); |
323 | 336 | ||
324 | list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { | 337 | list_for_each_entry_safe(peer, tmp, |
338 | &nets[rnet->mport->id].peers, node) { | ||
325 | if (!(peer->res = rio_request_outb_dbell(peer->rdev, | 339 | if (!(peer->res = rio_request_outb_dbell(peer->rdev, |
326 | RIONET_DOORBELL_JOIN, | 340 | RIONET_DOORBELL_JOIN, |
327 | RIONET_DOORBELL_LEAVE))) | 341 | RIONET_DOORBELL_LEAVE))) |
@@ -346,7 +360,7 @@ static int rionet_close(struct net_device *ndev) | |||
346 | int i; | 360 | int i; |
347 | 361 | ||
348 | if (netif_msg_ifup(rnet)) | 362 | if (netif_msg_ifup(rnet)) |
349 | printk(KERN_INFO "%s: close\n", DRV_NAME); | 363 | printk(KERN_INFO "%s: close %s\n", DRV_NAME, ndev->name); |
350 | 364 | ||
351 | netif_stop_queue(ndev); | 365 | netif_stop_queue(ndev); |
352 | netif_carrier_off(ndev); | 366 | netif_carrier_off(ndev); |
@@ -354,10 +368,11 @@ static int rionet_close(struct net_device *ndev) | |||
354 | for (i = 0; i < RIONET_RX_RING_SIZE; i++) | 368 | for (i = 0; i < RIONET_RX_RING_SIZE; i++) |
355 | kfree_skb(rnet->rx_skb[i]); | 369 | kfree_skb(rnet->rx_skb[i]); |
356 | 370 | ||
357 | list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { | 371 | list_for_each_entry_safe(peer, tmp, |
358 | if (rionet_active[peer->rdev->destid]) { | 372 | &nets[rnet->mport->id].peers, node) { |
373 | if (nets[rnet->mport->id].active[peer->rdev->destid]) { | ||
359 | rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE); | 374 | rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE); |
360 | rionet_active[peer->rdev->destid] = NULL; | 375 | nets[rnet->mport->id].active[peer->rdev->destid] = NULL; |
361 | } | 376 | } |
362 | rio_release_outb_dbell(peer->rdev, peer->res); | 377 | rio_release_outb_dbell(peer->rdev, peer->res); |
363 | } | 378 | } |
@@ -373,17 +388,21 @@ static int rionet_close(struct net_device *ndev) | |||
373 | static void rionet_remove(struct rio_dev *rdev) | 388 | static void rionet_remove(struct rio_dev *rdev) |
374 | { | 389 | { |
375 | struct net_device *ndev = rio_get_drvdata(rdev); | 390 | struct net_device *ndev = rio_get_drvdata(rdev); |
391 | unsigned char netid = rdev->net->hport->id; | ||
376 | struct rionet_peer *peer, *tmp; | 392 | struct rionet_peer *peer, *tmp; |
377 | 393 | ||
378 | free_pages((unsigned long)rionet_active, get_order(sizeof(void *) * | ||
379 | RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size))); | ||
380 | unregister_netdev(ndev); | 394 | unregister_netdev(ndev); |
381 | free_netdev(ndev); | ||
382 | 395 | ||
383 | list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { | 396 | free_pages((unsigned long)nets[netid].active, get_order(sizeof(void *) * |
397 | RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size))); | ||
398 | nets[netid].active = NULL; | ||
399 | |||
400 | list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) { | ||
384 | list_del(&peer->node); | 401 | list_del(&peer->node); |
385 | kfree(peer); | 402 | kfree(peer); |
386 | } | 403 | } |
404 | |||
405 | free_netdev(ndev); | ||
387 | } | 406 | } |
388 | 407 | ||
389 | static void rionet_get_drvinfo(struct net_device *ndev, | 408 | static void rionet_get_drvinfo(struct net_device *ndev, |
@@ -435,13 +454,13 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) | |||
435 | const size_t rionet_active_bytes = sizeof(void *) * | 454 | const size_t rionet_active_bytes = sizeof(void *) * |
436 | RIO_MAX_ROUTE_ENTRIES(mport->sys_size); | 455 | RIO_MAX_ROUTE_ENTRIES(mport->sys_size); |
437 | 456 | ||
438 | rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, | 457 | nets[mport->id].active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, |
439 | get_order(rionet_active_bytes)); | 458 | get_order(rionet_active_bytes)); |
440 | if (!rionet_active) { | 459 | if (!nets[mport->id].active) { |
441 | rc = -ENOMEM; | 460 | rc = -ENOMEM; |
442 | goto out; | 461 | goto out; |
443 | } | 462 | } |
444 | memset((void *)rionet_active, 0, rionet_active_bytes); | 463 | memset((void *)nets[mport->id].active, 0, rionet_active_bytes); |
445 | 464 | ||
446 | /* Set up private area */ | 465 | /* Set up private area */ |
447 | rnet = netdev_priv(ndev); | 466 | rnet = netdev_priv(ndev); |
@@ -470,60 +489,62 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) | |||
470 | if (rc != 0) | 489 | if (rc != 0) |
471 | goto out; | 490 | goto out; |
472 | 491 | ||
473 | printk("%s: %s %s Version %s, MAC %pM\n", | 492 | printk(KERN_INFO "%s: %s %s Version %s, MAC %pM, %s\n", |
474 | ndev->name, | 493 | ndev->name, |
475 | DRV_NAME, | 494 | DRV_NAME, |
476 | DRV_DESC, | 495 | DRV_DESC, |
477 | DRV_VERSION, | 496 | DRV_VERSION, |
478 | ndev->dev_addr); | 497 | ndev->dev_addr, |
498 | mport->name); | ||
479 | 499 | ||
480 | out: | 500 | out: |
481 | return rc; | 501 | return rc; |
482 | } | 502 | } |
483 | 503 | ||
484 | /* | 504 | static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1]; |
485 | * XXX Make multi-net safe | 505 | |
486 | */ | ||
487 | static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) | 506 | static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) |
488 | { | 507 | { |
489 | int rc = -ENODEV; | 508 | int rc = -ENODEV; |
490 | u32 lsrc_ops, ldst_ops; | 509 | u32 lsrc_ops, ldst_ops; |
491 | struct rionet_peer *peer; | 510 | struct rionet_peer *peer; |
492 | struct net_device *ndev = NULL; | 511 | struct net_device *ndev = NULL; |
512 | unsigned char netid = rdev->net->hport->id; | ||
513 | int oldnet; | ||
493 | 514 | ||
494 | /* If local device is not rionet capable, give up quickly */ | 515 | if (netid >= RIONET_MAX_NETS) |
495 | if (!rionet_capable) | 516 | return rc; |
496 | goto out; | ||
497 | 517 | ||
498 | /* Allocate our net_device structure */ | 518 | oldnet = test_and_set_bit(netid, net_table); |
499 | ndev = alloc_etherdev(sizeof(struct rionet_private)); | ||
500 | if (ndev == NULL) { | ||
501 | rc = -ENOMEM; | ||
502 | goto out; | ||
503 | } | ||
504 | 519 | ||
505 | /* | 520 | /* |
506 | * First time through, make sure local device is rionet | 521 | * First time through, make sure local device is rionet |
507 | * capable, setup netdev, and set flags so this is skipped | 522 | * capable, setup netdev (will be skipped on later probes) |
508 | * on later probes | ||
509 | */ | 523 | */ |
510 | if (!rionet_check) { | 524 | if (!oldnet) { |
511 | rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, | 525 | rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, |
512 | &lsrc_ops); | 526 | &lsrc_ops); |
513 | rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR, | 527 | rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR, |
514 | &ldst_ops); | 528 | &ldst_ops); |
515 | if (!is_rionet_capable(lsrc_ops, ldst_ops)) { | 529 | if (!is_rionet_capable(lsrc_ops, ldst_ops)) { |
516 | printk(KERN_ERR | 530 | printk(KERN_ERR |
517 | "%s: local device is not network capable\n", | 531 | "%s: local device %s is not network capable\n", |
518 | DRV_NAME); | 532 | DRV_NAME, rdev->net->hport->name); |
519 | rionet_check = 1; | ||
520 | rionet_capable = 0; | ||
521 | goto out; | 533 | goto out; |
522 | } | 534 | } |
523 | 535 | ||
536 | /* Allocate our net_device structure */ | ||
537 | ndev = alloc_etherdev(sizeof(struct rionet_private)); | ||
538 | if (ndev == NULL) { | ||
539 | rc = -ENOMEM; | ||
540 | goto out; | ||
541 | } | ||
542 | nets[netid].ndev = ndev; | ||
524 | rc = rionet_setup_netdev(rdev->net->hport, ndev); | 543 | rc = rionet_setup_netdev(rdev->net->hport, ndev); |
525 | rionet_check = 1; | 544 | INIT_LIST_HEAD(&nets[netid].peers); |
526 | } | 545 | nets[netid].nact = 0; |
546 | } else if (nets[netid].ndev == NULL) | ||
547 | goto out; | ||
527 | 548 | ||
528 | /* | 549 | /* |
529 | * If the remote device has mailbox/doorbell capabilities, | 550 | * If the remote device has mailbox/doorbell capabilities, |
@@ -535,10 +556,10 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) | |||
535 | goto out; | 556 | goto out; |
536 | } | 557 | } |
537 | peer->rdev = rdev; | 558 | peer->rdev = rdev; |
538 | list_add_tail(&peer->node, &rionet_peers); | 559 | list_add_tail(&peer->node, &nets[netid].peers); |
539 | } | 560 | } |
540 | 561 | ||
541 | rio_set_drvdata(rdev, ndev); | 562 | rio_set_drvdata(rdev, nets[netid].ndev); |
542 | 563 | ||
543 | out: | 564 | out: |
544 | return rc; | 565 | return rc; |
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index 0e5769061702..feacc3b994b7 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c | |||
@@ -1775,7 +1775,7 @@ EXPORT_SYMBOL(z8530_queue_xmit); | |||
1775 | /* | 1775 | /* |
1776 | * Module support | 1776 | * Module support |
1777 | */ | 1777 | */ |
1778 | static const char banner[] __initdata = | 1778 | static const char banner[] __initconst = |
1779 | KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n"; | 1779 | KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n"; |
1780 | 1780 | ||
1781 | static int __init z85230_init_driver(void) | 1781 | static int __init z85230_init_driver(void) |
diff --git a/drivers/platform/x86/amilo-rfkill.c b/drivers/platform/x86/amilo-rfkill.c index a514bf66fdd7..1deca7f6c4ea 100644 --- a/drivers/platform/x86/amilo-rfkill.c +++ b/drivers/platform/x86/amilo-rfkill.c | |||
@@ -74,7 +74,7 @@ static const struct rfkill_ops amilo_m7440_rfkill_ops = { | |||
74 | .set_block = amilo_m7440_rfkill_set_block | 74 | .set_block = amilo_m7440_rfkill_set_block |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static const struct dmi_system_id __devinitdata amilo_rfkill_id_table[] = { | 77 | static const struct dmi_system_id __devinitconst amilo_rfkill_id_table[] = { |
78 | { | 78 | { |
79 | .matches = { | 79 | .matches = { |
80 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 80 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index 7acae3f85f3b..f77484528b1b 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c | |||
@@ -52,7 +52,7 @@ struct fujitsu_config { | |||
52 | unsigned int quirks; | 52 | unsigned int quirks; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initconst = { | 55 | static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initdata = { |
56 | KEY_RESERVED, | 56 | KEY_RESERVED, |
57 | KEY_RESERVED, | 57 | KEY_RESERVED, |
58 | KEY_RESERVED, | 58 | KEY_RESERVED, |
@@ -71,7 +71,7 @@ static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initconst = { | |||
71 | KEY_LEFTALT | 71 | KEY_LEFTALT |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initconst = { | 74 | static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initdata = { |
75 | KEY_RESERVED, | 75 | KEY_RESERVED, |
76 | KEY_RESERVED, | 76 | KEY_RESERVED, |
77 | KEY_RESERVED, | 77 | KEY_RESERVED, |
@@ -90,7 +90,7 @@ static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initconst = { | |||
90 | KEY_LEFTALT | 90 | KEY_LEFTALT |
91 | }; | 91 | }; |
92 | 92 | ||
93 | static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initconst = { | 93 | static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initdata = { |
94 | KEY_RESERVED, | 94 | KEY_RESERVED, |
95 | KEY_RESERVED, | 95 | KEY_RESERVED, |
96 | KEY_RESERVED, | 96 | KEY_RESERVED, |
@@ -109,7 +109,7 @@ static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initconst = { | |||
109 | KEY_LEFTALT | 109 | KEY_LEFTALT |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initconst = { | 112 | static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initdata = { |
113 | KEY_RESERVED, | 113 | KEY_RESERVED, |
114 | KEY_RESERVED, | 114 | KEY_RESERVED, |
115 | KEY_RESERVED, | 115 | KEY_RESERVED, |
@@ -299,7 +299,7 @@ static int __devinit fujitsu_dmi_stylistic(const struct dmi_system_id *dmi) | |||
299 | return 1; | 299 | return 1; |
300 | } | 300 | } |
301 | 301 | ||
302 | static struct dmi_system_id dmi_ids[] __initconst = { | 302 | static const struct dmi_system_id dmi_ids[] __initconst = { |
303 | { | 303 | { |
304 | .callback = fujitsu_dmi_lifebook, | 304 | .callback = fujitsu_dmi_lifebook, |
305 | .ident = "Fujitsu Siemens P/T Series", | 305 | .ident = "Fujitsu Siemens P/T Series", |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 9da5fe715e6a..75dd651664ae 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -522,7 +522,7 @@ static acpi_handle ec_handle; | |||
522 | 522 | ||
523 | #define TPACPI_HANDLE(object, parent, paths...) \ | 523 | #define TPACPI_HANDLE(object, parent, paths...) \ |
524 | static acpi_handle object##_handle; \ | 524 | static acpi_handle object##_handle; \ |
525 | static const acpi_handle *object##_parent __initdata = \ | 525 | static const acpi_handle * const object##_parent __initconst = \ |
526 | &parent##_handle; \ | 526 | &parent##_handle; \ |
527 | static char *object##_paths[] __initdata = { paths } | 527 | static char *object##_paths[] __initdata = { paths } |
528 | 528 | ||
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index e771487132f7..2420d5af0583 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
@@ -306,7 +306,7 @@ int pps_register_cdev(struct pps_device *pps) | |||
306 | if (err < 0) | 306 | if (err < 0) |
307 | return err; | 307 | return err; |
308 | 308 | ||
309 | pps->id &= MAX_ID_MASK; | 309 | pps->id &= MAX_IDR_MASK; |
310 | if (pps->id >= PPS_MAX_SOURCES) { | 310 | if (pps->id >= PPS_MAX_SOURCES) { |
311 | pr_err("%s: too many PPS sources in the system\n", | 311 | pr_err("%s: too many PPS sources in the system\n", |
312 | pps->info.name); | 312 | pps->info.name); |
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index d5e1625bbac2..38ecd8f4d60e 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -862,6 +862,90 @@ static void tsi721_init_pc2sr_mapping(struct tsi721_device *priv) | |||
862 | } | 862 | } |
863 | 863 | ||
864 | /** | 864 | /** |
865 | * tsi721_rio_map_inb_mem -- Mapping inbound memory region. | ||
866 | * @mport: RapidIO master port | ||
867 | * @lstart: Local memory space start address. | ||
868 | * @rstart: RapidIO space start address. | ||
869 | * @size: The mapping region size. | ||
870 | * @flags: Flags for mapping. 0 for using default flags. | ||
871 | * | ||
872 | * Return: 0 -- Success. | ||
873 | * | ||
874 | * This function will create the inbound mapping | ||
875 | * from rstart to lstart. | ||
876 | */ | ||
877 | static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart, | ||
878 | u64 rstart, u32 size, u32 flags) | ||
879 | { | ||
880 | struct tsi721_device *priv = mport->priv; | ||
881 | int i; | ||
882 | u32 regval; | ||
883 | |||
884 | if (!is_power_of_2(size) || size < 0x1000 || | ||
885 | ((u64)lstart & (size - 1)) || (rstart & (size - 1))) | ||
886 | return -EINVAL; | ||
887 | |||
888 | /* Search for free inbound translation window */ | ||
889 | for (i = 0; i < TSI721_IBWIN_NUM; i++) { | ||
890 | regval = ioread32(priv->regs + TSI721_IBWIN_LB(i)); | ||
891 | if (!(regval & TSI721_IBWIN_LB_WEN)) | ||
892 | break; | ||
893 | } | ||
894 | |||
895 | if (i >= TSI721_IBWIN_NUM) { | ||
896 | dev_err(&priv->pdev->dev, | ||
897 | "Unable to find free inbound window\n"); | ||
898 | return -EBUSY; | ||
899 | } | ||
900 | |||
901 | iowrite32(TSI721_IBWIN_SIZE(size) << 8, | ||
902 | priv->regs + TSI721_IBWIN_SZ(i)); | ||
903 | |||
904 | iowrite32(((u64)lstart >> 32), priv->regs + TSI721_IBWIN_TUA(i)); | ||
905 | iowrite32(((u64)lstart & TSI721_IBWIN_TLA_ADD), | ||
906 | priv->regs + TSI721_IBWIN_TLA(i)); | ||
907 | |||
908 | iowrite32(rstart >> 32, priv->regs + TSI721_IBWIN_UB(i)); | ||
909 | iowrite32((rstart & TSI721_IBWIN_LB_BA) | TSI721_IBWIN_LB_WEN, | ||
910 | priv->regs + TSI721_IBWIN_LB(i)); | ||
911 | dev_dbg(&priv->pdev->dev, | ||
912 | "Configured IBWIN%d mapping (RIO_0x%llx -> PCIe_0x%llx)\n", | ||
913 | i, rstart, (unsigned long long)lstart); | ||
914 | |||
915 | return 0; | ||
916 | } | ||
917 | |||
918 | /** | ||
919 | * fsl_rio_unmap_inb_mem -- Unmapping inbound memory region. | ||
920 | * @mport: RapidIO master port | ||
921 | * @lstart: Local memory space start address. | ||
922 | */ | ||
923 | static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport, | ||
924 | dma_addr_t lstart) | ||
925 | { | ||
926 | struct tsi721_device *priv = mport->priv; | ||
927 | int i; | ||
928 | u64 addr; | ||
929 | u32 regval; | ||
930 | |||
931 | /* Search for matching active inbound translation window */ | ||
932 | for (i = 0; i < TSI721_IBWIN_NUM; i++) { | ||
933 | regval = ioread32(priv->regs + TSI721_IBWIN_LB(i)); | ||
934 | if (regval & TSI721_IBWIN_LB_WEN) { | ||
935 | regval = ioread32(priv->regs + TSI721_IBWIN_TUA(i)); | ||
936 | addr = (u64)regval << 32; | ||
937 | regval = ioread32(priv->regs + TSI721_IBWIN_TLA(i)); | ||
938 | addr |= regval & TSI721_IBWIN_TLA_ADD; | ||
939 | |||
940 | if (addr == (u64)lstart) { | ||
941 | iowrite32(0, priv->regs + TSI721_IBWIN_LB(i)); | ||
942 | break; | ||
943 | } | ||
944 | } | ||
945 | } | ||
946 | } | ||
947 | |||
948 | /** | ||
865 | * tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe) | 949 | * tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe) |
866 | * translation regions. | 950 | * translation regions. |
867 | * @priv: pointer to tsi721 private data | 951 | * @priv: pointer to tsi721 private data |
@@ -874,7 +958,7 @@ static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv) | |||
874 | 958 | ||
875 | /* Disable all SR2PC inbound windows */ | 959 | /* Disable all SR2PC inbound windows */ |
876 | for (i = 0; i < TSI721_IBWIN_NUM; i++) | 960 | for (i = 0; i < TSI721_IBWIN_NUM; i++) |
877 | iowrite32(0, priv->regs + TSI721_IBWINLB(i)); | 961 | iowrite32(0, priv->regs + TSI721_IBWIN_LB(i)); |
878 | } | 962 | } |
879 | 963 | ||
880 | /** | 964 | /** |
@@ -2144,6 +2228,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
2144 | ops->add_outb_message = tsi721_add_outb_message; | 2228 | ops->add_outb_message = tsi721_add_outb_message; |
2145 | ops->add_inb_buffer = tsi721_add_inb_buffer; | 2229 | ops->add_inb_buffer = tsi721_add_inb_buffer; |
2146 | ops->get_inb_message = tsi721_get_inb_message; | 2230 | ops->get_inb_message = tsi721_get_inb_message; |
2231 | ops->map_inb = tsi721_rio_map_inb_mem; | ||
2232 | ops->unmap_inb = tsi721_rio_unmap_inb_mem; | ||
2147 | 2233 | ||
2148 | mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); | 2234 | mport = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); |
2149 | if (!mport) { | 2235 | if (!mport) { |
@@ -2165,7 +2251,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
2165 | rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); | 2251 | rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); |
2166 | rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3); | 2252 | rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3); |
2167 | rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3); | 2253 | rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3); |
2168 | strcpy(mport->name, "Tsi721 mport"); | 2254 | snprintf(mport->name, RIO_MAX_MPORT_NAME, "%s(%s)", |
2255 | dev_driver_string(&pdev->dev), dev_name(&pdev->dev)); | ||
2169 | 2256 | ||
2170 | /* Hook up interrupt handler */ | 2257 | /* Hook up interrupt handler */ |
2171 | 2258 | ||
@@ -2315,7 +2402,8 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2315 | 2402 | ||
2316 | /* Configure DMA attributes. */ | 2403 | /* Configure DMA attributes. */ |
2317 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | 2404 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
2318 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { | 2405 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
2406 | if (err) { | ||
2319 | dev_info(&pdev->dev, "Unable to set DMA mask\n"); | 2407 | dev_info(&pdev->dev, "Unable to set DMA mask\n"); |
2320 | goto err_unmap_bars; | 2408 | goto err_unmap_bars; |
2321 | } | 2409 | } |
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index 59de9d7be346..7d5b13ba8d4f 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
@@ -156,9 +156,18 @@ | |||
156 | 156 | ||
157 | #define TSI721_IBWIN_NUM 8 | 157 | #define TSI721_IBWIN_NUM 8 |
158 | 158 | ||
159 | #define TSI721_IBWINLB(x) (0x29000 + (x) * 0x20) | 159 | #define TSI721_IBWIN_LB(x) (0x29000 + (x) * 0x20) |
160 | #define TSI721_IBWINLB_BA 0xfffff000 | 160 | #define TSI721_IBWIN_LB_BA 0xfffff000 |
161 | #define TSI721_IBWINLB_WEN 0x00000001 | 161 | #define TSI721_IBWIN_LB_WEN 0x00000001 |
162 | |||
163 | #define TSI721_IBWIN_UB(x) (0x29004 + (x) * 0x20) | ||
164 | #define TSI721_IBWIN_SZ(x) (0x29008 + (x) * 0x20) | ||
165 | #define TSI721_IBWIN_SZ_SIZE 0x00001f00 | ||
166 | #define TSI721_IBWIN_SIZE(size) (__fls(size) - 12) | ||
167 | |||
168 | #define TSI721_IBWIN_TLA(x) (0x2900c + (x) * 0x20) | ||
169 | #define TSI721_IBWIN_TLA_ADD 0xfffff000 | ||
170 | #define TSI721_IBWIN_TUA(x) (0x29010 + (x) * 0x20) | ||
162 | 171 | ||
163 | #define TSI721_SR2PC_GEN_INTE 0x29800 | 172 | #define TSI721_SR2PC_GEN_INTE 0x29800 |
164 | #define TSI721_SR2PC_PWE 0x29804 | 173 | #define TSI721_SR2PC_PWE 0x29804 |
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 2bebd791a092..48e9041dd1e2 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -31,27 +31,21 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
34 | #include <linux/sched.h> | ||
34 | #include <linux/jiffies.h> | 35 | #include <linux/jiffies.h> |
35 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
36 | 37 | ||
37 | #include "rio.h" | 38 | #include "rio.h" |
38 | 39 | ||
39 | LIST_HEAD(rio_devices); | 40 | LIST_HEAD(rio_devices); |
40 | static LIST_HEAD(rio_switches); | ||
41 | |||
42 | static void rio_enum_timeout(unsigned long); | ||
43 | 41 | ||
44 | static void rio_init_em(struct rio_dev *rdev); | 42 | static void rio_init_em(struct rio_dev *rdev); |
45 | 43 | ||
46 | DEFINE_SPINLOCK(rio_global_list_lock); | 44 | DEFINE_SPINLOCK(rio_global_list_lock); |
47 | 45 | ||
48 | static int next_destid = 0; | 46 | static int next_destid = 0; |
49 | static int next_net = 0; | ||
50 | static int next_comptag = 1; | 47 | static int next_comptag = 1; |
51 | 48 | ||
52 | static struct timer_list rio_enum_timer = | ||
53 | TIMER_INITIALIZER(rio_enum_timeout, 0, 0); | ||
54 | |||
55 | static int rio_mport_phys_table[] = { | 49 | static int rio_mport_phys_table[] = { |
56 | RIO_EFB_PAR_EP_ID, | 50 | RIO_EFB_PAR_EP_ID, |
57 | RIO_EFB_PAR_EP_REC_ID, | 51 | RIO_EFB_PAR_EP_REC_ID, |
@@ -60,6 +54,114 @@ static int rio_mport_phys_table[] = { | |||
60 | -1, | 54 | -1, |
61 | }; | 55 | }; |
62 | 56 | ||
57 | |||
58 | /* | ||
59 | * rio_destid_alloc - Allocate next available destID for given network | ||
60 | * net: RIO network | ||
61 | * | ||
62 | * Returns next available device destination ID for the specified RIO network. | ||
63 | * Marks allocated ID as one in use. | ||
64 | * Returns RIO_INVALID_DESTID if new destID is not available. | ||
65 | */ | ||
66 | static u16 rio_destid_alloc(struct rio_net *net) | ||
67 | { | ||
68 | int destid; | ||
69 | struct rio_id_table *idtab = &net->destid_table; | ||
70 | |||
71 | spin_lock(&idtab->lock); | ||
72 | destid = find_next_zero_bit(idtab->table, idtab->max, idtab->next); | ||
73 | if (destid >= idtab->max) | ||
74 | destid = find_first_zero_bit(idtab->table, idtab->max); | ||
75 | |||
76 | if (destid < idtab->max) { | ||
77 | idtab->next = destid + 1; | ||
78 | if (idtab->next >= idtab->max) | ||
79 | idtab->next = 0; | ||
80 | set_bit(destid, idtab->table); | ||
81 | destid += idtab->start; | ||
82 | } else | ||
83 | destid = RIO_INVALID_DESTID; | ||
84 | |||
85 | spin_unlock(&idtab->lock); | ||
86 | return (u16)destid; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * rio_destid_reserve - Reserve the specivied destID | ||
91 | * net: RIO network | ||
92 | * destid: destID to reserve | ||
93 | * | ||
94 | * Tries to reserve the specified destID. | ||
95 | * Returns 0 if successfull. | ||
96 | */ | ||
97 | static int rio_destid_reserve(struct rio_net *net, u16 destid) | ||
98 | { | ||
99 | int oldbit; | ||
100 | struct rio_id_table *idtab = &net->destid_table; | ||
101 | |||
102 | destid -= idtab->start; | ||
103 | spin_lock(&idtab->lock); | ||
104 | oldbit = test_and_set_bit(destid, idtab->table); | ||
105 | spin_unlock(&idtab->lock); | ||
106 | return oldbit; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * rio_destid_free - free a previously allocated destID | ||
111 | * net: RIO network | ||
112 | * destid: destID to free | ||
113 | * | ||
114 | * Makes the specified destID available for use. | ||
115 | */ | ||
116 | static void rio_destid_free(struct rio_net *net, u16 destid) | ||
117 | { | ||
118 | struct rio_id_table *idtab = &net->destid_table; | ||
119 | |||
120 | destid -= idtab->start; | ||
121 | spin_lock(&idtab->lock); | ||
122 | clear_bit(destid, idtab->table); | ||
123 | spin_unlock(&idtab->lock); | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * rio_destid_first - return first destID in use | ||
128 | * net: RIO network | ||
129 | */ | ||
130 | static u16 rio_destid_first(struct rio_net *net) | ||
131 | { | ||
132 | int destid; | ||
133 | struct rio_id_table *idtab = &net->destid_table; | ||
134 | |||
135 | spin_lock(&idtab->lock); | ||
136 | destid = find_first_bit(idtab->table, idtab->max); | ||
137 | if (destid >= idtab->max) | ||
138 | destid = RIO_INVALID_DESTID; | ||
139 | else | ||
140 | destid += idtab->start; | ||
141 | spin_unlock(&idtab->lock); | ||
142 | return (u16)destid; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * rio_destid_next - return next destID in use | ||
147 | * net: RIO network | ||
148 | * from: destination ID from which search shall continue | ||
149 | */ | ||
150 | static u16 rio_destid_next(struct rio_net *net, u16 from) | ||
151 | { | ||
152 | int destid; | ||
153 | struct rio_id_table *idtab = &net->destid_table; | ||
154 | |||
155 | spin_lock(&idtab->lock); | ||
156 | destid = find_next_bit(idtab->table, idtab->max, from); | ||
157 | if (destid >= idtab->max) | ||
158 | destid = RIO_INVALID_DESTID; | ||
159 | else | ||
160 | destid += idtab->start; | ||
161 | spin_unlock(&idtab->lock); | ||
162 | return (u16)destid; | ||
163 | } | ||
164 | |||
63 | /** | 165 | /** |
64 | * rio_get_device_id - Get the base/extended device id for a device | 166 | * rio_get_device_id - Get the base/extended device id for a device |
65 | * @port: RIO master port | 167 | * @port: RIO master port |
@@ -108,14 +210,15 @@ static void rio_local_set_device_id(struct rio_mport *port, u16 did) | |||
108 | 210 | ||
109 | /** | 211 | /** |
110 | * rio_clear_locks- Release all host locks and signal enumeration complete | 212 | * rio_clear_locks- Release all host locks and signal enumeration complete |
111 | * @port: Master port to issue transaction | 213 | * @net: RIO network to run on |
112 | * | 214 | * |
113 | * Marks the component tag CSR on each device with the enumeration | 215 | * Marks the component tag CSR on each device with the enumeration |
114 | * complete flag. When complete, it then release the host locks on | 216 | * complete flag. When complete, it then release the host locks on |
115 | * each device. Returns 0 on success or %-EINVAL on failure. | 217 | * each device. Returns 0 on success or %-EINVAL on failure. |
116 | */ | 218 | */ |
117 | static int rio_clear_locks(struct rio_mport *port) | 219 | static int rio_clear_locks(struct rio_net *net) |
118 | { | 220 | { |
221 | struct rio_mport *port = net->hport; | ||
119 | struct rio_dev *rdev; | 222 | struct rio_dev *rdev; |
120 | u32 result; | 223 | u32 result; |
121 | int ret = 0; | 224 | int ret = 0; |
@@ -130,7 +233,7 @@ static int rio_clear_locks(struct rio_mport *port) | |||
130 | result); | 233 | result); |
131 | ret = -EINVAL; | 234 | ret = -EINVAL; |
132 | } | 235 | } |
133 | list_for_each_entry(rdev, &rio_devices, global_list) { | 236 | list_for_each_entry(rdev, &net->devices, net_list) { |
134 | rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR, | 237 | rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR, |
135 | port->host_deviceid); | 238 | port->host_deviceid); |
136 | rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result); | 239 | rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result); |
@@ -176,10 +279,6 @@ static int rio_enum_host(struct rio_mport *port) | |||
176 | 279 | ||
177 | /* Set master port destid and init destid ctr */ | 280 | /* Set master port destid and init destid ctr */ |
178 | rio_local_set_device_id(port, port->host_deviceid); | 281 | rio_local_set_device_id(port, port->host_deviceid); |
179 | |||
180 | if (next_destid == port->host_deviceid) | ||
181 | next_destid++; | ||
182 | |||
183 | return 0; | 282 | return 0; |
184 | } | 283 | } |
185 | 284 | ||
@@ -446,9 +545,8 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
446 | if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { | 545 | if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { |
447 | if (do_enum) { | 546 | if (do_enum) { |
448 | rio_set_device_id(port, destid, hopcount, next_destid); | 547 | rio_set_device_id(port, destid, hopcount, next_destid); |
449 | rdev->destid = next_destid++; | 548 | rdev->destid = next_destid; |
450 | if (next_destid == port->host_deviceid) | 549 | next_destid = rio_destid_alloc(net); |
451 | next_destid++; | ||
452 | } else | 550 | } else |
453 | rdev->destid = rio_get_device_id(port, destid, hopcount); | 551 | rdev->destid = rio_get_device_id(port, destid, hopcount); |
454 | 552 | ||
@@ -483,7 +581,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, | |||
483 | rswitch->clr_table(port, destid, hopcount, | 581 | rswitch->clr_table(port, destid, hopcount, |
484 | RIO_GLOBAL_TABLE); | 582 | RIO_GLOBAL_TABLE); |
485 | 583 | ||
486 | list_add_tail(&rswitch->node, &rio_switches); | 584 | list_add_tail(&rswitch->node, &net->switches); |
487 | 585 | ||
488 | } else { | 586 | } else { |
489 | if (do_enum) | 587 | if (do_enum) |
@@ -747,12 +845,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount) | |||
747 | static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | 845 | static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, |
748 | u8 hopcount, struct rio_dev *prev, int prev_port) | 846 | u8 hopcount, struct rio_dev *prev, int prev_port) |
749 | { | 847 | { |
750 | int port_num; | ||
751 | int cur_destid; | ||
752 | int sw_destid; | ||
753 | int sw_inport; | ||
754 | struct rio_dev *rdev; | 848 | struct rio_dev *rdev; |
755 | u16 destid; | ||
756 | u32 regval; | 849 | u32 regval; |
757 | int tmp; | 850 | int tmp; |
758 | 851 | ||
@@ -818,19 +911,26 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
818 | return -1; | 911 | return -1; |
819 | 912 | ||
820 | if (rio_is_switch(rdev)) { | 913 | if (rio_is_switch(rdev)) { |
914 | int sw_destid; | ||
915 | int cur_destid; | ||
916 | int sw_inport; | ||
917 | u16 destid; | ||
918 | int port_num; | ||
919 | |||
821 | sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo); | 920 | sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo); |
822 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, | 921 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, |
823 | port->host_deviceid, sw_inport, 0); | 922 | port->host_deviceid, sw_inport, 0); |
824 | rdev->rswitch->route_table[port->host_deviceid] = sw_inport; | 923 | rdev->rswitch->route_table[port->host_deviceid] = sw_inport; |
825 | 924 | ||
826 | for (destid = 0; destid < next_destid; destid++) { | 925 | destid = rio_destid_first(net); |
827 | if (destid == port->host_deviceid) | 926 | while (destid != RIO_INVALID_DESTID && destid < next_destid) { |
828 | continue; | 927 | if (destid != port->host_deviceid) { |
829 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, | 928 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, |
830 | destid, sw_inport, 0); | 929 | destid, sw_inport, 0); |
831 | rdev->rswitch->route_table[destid] = sw_inport; | 930 | rdev->rswitch->route_table[destid] = sw_inport; |
931 | } | ||
932 | destid = rio_destid_next(net, destid + 1); | ||
832 | } | 933 | } |
833 | |||
834 | pr_debug( | 934 | pr_debug( |
835 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", | 935 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", |
836 | rio_name(rdev), rdev->vid, rdev->did, | 936 | rio_name(rdev), rdev->vid, rdev->did, |
@@ -839,12 +939,10 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
839 | for (port_num = 0; | 939 | for (port_num = 0; |
840 | port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo); | 940 | port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo); |
841 | port_num++) { | 941 | port_num++) { |
842 | /*Enable Input Output Port (transmitter reviever)*/ | 942 | if (sw_inport == port_num) { |
843 | rio_enable_rx_tx_port(port, 0, | 943 | rio_enable_rx_tx_port(port, 0, |
844 | RIO_ANY_DESTID(port->sys_size), | 944 | RIO_ANY_DESTID(port->sys_size), |
845 | hopcount, port_num); | 945 | hopcount, port_num); |
846 | |||
847 | if (sw_inport == port_num) { | ||
848 | rdev->rswitch->port_ok |= (1 << port_num); | 946 | rdev->rswitch->port_ok |= (1 << port_num); |
849 | continue; | 947 | continue; |
850 | } | 948 | } |
@@ -857,6 +955,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
857 | pr_debug( | 955 | pr_debug( |
858 | "RIO: scanning device on port %d\n", | 956 | "RIO: scanning device on port %d\n", |
859 | port_num); | 957 | port_num); |
958 | rio_enable_rx_tx_port(port, 0, | ||
959 | RIO_ANY_DESTID(port->sys_size), | ||
960 | hopcount, port_num); | ||
860 | rdev->rswitch->port_ok |= (1 << port_num); | 961 | rdev->rswitch->port_ok |= (1 << port_num); |
861 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, | 962 | rio_route_add_entry(rdev, RIO_GLOBAL_TABLE, |
862 | RIO_ANY_DESTID(port->sys_size), | 963 | RIO_ANY_DESTID(port->sys_size), |
@@ -867,19 +968,22 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
867 | return -1; | 968 | return -1; |
868 | 969 | ||
869 | /* Update routing tables */ | 970 | /* Update routing tables */ |
870 | if (next_destid > cur_destid) { | 971 | destid = rio_destid_next(net, cur_destid + 1); |
972 | if (destid != RIO_INVALID_DESTID) { | ||
871 | for (destid = cur_destid; | 973 | for (destid = cur_destid; |
872 | destid < next_destid; destid++) { | 974 | destid < next_destid;) { |
873 | if (destid == port->host_deviceid) | 975 | if (destid != port->host_deviceid) { |
874 | continue; | 976 | rio_route_add_entry(rdev, |
875 | rio_route_add_entry(rdev, | ||
876 | RIO_GLOBAL_TABLE, | 977 | RIO_GLOBAL_TABLE, |
877 | destid, | 978 | destid, |
878 | port_num, | 979 | port_num, |
879 | 0); | 980 | 0); |
880 | rdev->rswitch-> | 981 | rdev->rswitch-> |
881 | route_table[destid] = | 982 | route_table[destid] = |
882 | port_num; | 983 | port_num; |
984 | } | ||
985 | destid = rio_destid_next(net, | ||
986 | destid + 1); | ||
883 | } | 987 | } |
884 | } | 988 | } |
885 | } else { | 989 | } else { |
@@ -905,11 +1009,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
905 | rio_init_em(rdev); | 1009 | rio_init_em(rdev); |
906 | 1010 | ||
907 | /* Check for empty switch */ | 1011 | /* Check for empty switch */ |
908 | if (next_destid == sw_destid) { | 1012 | if (next_destid == sw_destid) |
909 | next_destid++; | 1013 | next_destid = rio_destid_alloc(net); |
910 | if (next_destid == port->host_deviceid) | ||
911 | next_destid++; | ||
912 | } | ||
913 | 1014 | ||
914 | rdev->destid = sw_destid; | 1015 | rdev->destid = sw_destid; |
915 | } else | 1016 | } else |
@@ -1047,48 +1148,71 @@ static int rio_mport_is_active(struct rio_mport *port) | |||
1047 | /** | 1148 | /** |
1048 | * rio_alloc_net- Allocate and configure a new RIO network | 1149 | * rio_alloc_net- Allocate and configure a new RIO network |
1049 | * @port: Master port associated with the RIO network | 1150 | * @port: Master port associated with the RIO network |
1151 | * @do_enum: Enumeration/Discovery mode flag | ||
1152 | * @start: logical minimal start id for new net | ||
1050 | * | 1153 | * |
1051 | * Allocates a RIO network structure, initializes per-network | 1154 | * Allocates a RIO network structure, initializes per-network |
1052 | * list heads, and adds the associated master port to the | 1155 | * list heads, and adds the associated master port to the |
1053 | * network list of associated master ports. Returns a | 1156 | * network list of associated master ports. Returns a |
1054 | * RIO network pointer on success or %NULL on failure. | 1157 | * RIO network pointer on success or %NULL on failure. |
1055 | */ | 1158 | */ |
1056 | static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port) | 1159 | static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port, |
1160 | int do_enum, u16 start) | ||
1057 | { | 1161 | { |
1058 | struct rio_net *net; | 1162 | struct rio_net *net; |
1059 | 1163 | ||
1060 | net = kzalloc(sizeof(struct rio_net), GFP_KERNEL); | 1164 | net = kzalloc(sizeof(struct rio_net), GFP_KERNEL); |
1165 | if (net && do_enum) { | ||
1166 | net->destid_table.table = kzalloc( | ||
1167 | BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)) * | ||
1168 | sizeof(long), | ||
1169 | GFP_KERNEL); | ||
1170 | |||
1171 | if (net->destid_table.table == NULL) { | ||
1172 | pr_err("RIO: failed to allocate destID table\n"); | ||
1173 | kfree(net); | ||
1174 | net = NULL; | ||
1175 | } else { | ||
1176 | net->destid_table.start = start; | ||
1177 | net->destid_table.next = 0; | ||
1178 | net->destid_table.max = | ||
1179 | RIO_MAX_ROUTE_ENTRIES(port->sys_size); | ||
1180 | spin_lock_init(&net->destid_table.lock); | ||
1181 | } | ||
1182 | } | ||
1183 | |||
1061 | if (net) { | 1184 | if (net) { |
1062 | INIT_LIST_HEAD(&net->node); | 1185 | INIT_LIST_HEAD(&net->node); |
1063 | INIT_LIST_HEAD(&net->devices); | 1186 | INIT_LIST_HEAD(&net->devices); |
1187 | INIT_LIST_HEAD(&net->switches); | ||
1064 | INIT_LIST_HEAD(&net->mports); | 1188 | INIT_LIST_HEAD(&net->mports); |
1065 | list_add_tail(&port->nnode, &net->mports); | 1189 | list_add_tail(&port->nnode, &net->mports); |
1066 | net->hport = port; | 1190 | net->hport = port; |
1067 | net->id = next_net++; | 1191 | net->id = port->id; |
1068 | } | 1192 | } |
1069 | return net; | 1193 | return net; |
1070 | } | 1194 | } |
1071 | 1195 | ||
1072 | /** | 1196 | /** |
1073 | * rio_update_route_tables- Updates route tables in switches | 1197 | * rio_update_route_tables- Updates route tables in switches |
1074 | * @port: Master port associated with the RIO network | 1198 | * @net: RIO network to run update on |
1075 | * | 1199 | * |
1076 | * For each enumerated device, ensure that each switch in a system | 1200 | * For each enumerated device, ensure that each switch in a system |
1077 | * has correct routing entries. Add routes for devices that where | 1201 | * has correct routing entries. Add routes for devices that where |
1078 | * unknown dirung the first enumeration pass through the switch. | 1202 | * unknown dirung the first enumeration pass through the switch. |
1079 | */ | 1203 | */ |
1080 | static void rio_update_route_tables(struct rio_mport *port) | 1204 | static void rio_update_route_tables(struct rio_net *net) |
1081 | { | 1205 | { |
1082 | struct rio_dev *rdev, *swrdev; | 1206 | struct rio_dev *rdev, *swrdev; |
1083 | struct rio_switch *rswitch; | 1207 | struct rio_switch *rswitch; |
1084 | u8 sport; | 1208 | u8 sport; |
1085 | u16 destid; | 1209 | u16 destid; |
1086 | 1210 | ||
1087 | list_for_each_entry(rdev, &rio_devices, global_list) { | 1211 | list_for_each_entry(rdev, &net->devices, net_list) { |
1088 | 1212 | ||
1089 | destid = rdev->destid; | 1213 | destid = rdev->destid; |
1090 | 1214 | ||
1091 | list_for_each_entry(rswitch, &rio_switches, node) { | 1215 | list_for_each_entry(rswitch, &net->switches, node) { |
1092 | 1216 | ||
1093 | if (rio_is_switch(rdev) && (rdev->rswitch == rswitch)) | 1217 | if (rio_is_switch(rdev) && (rdev->rswitch == rswitch)) |
1094 | continue; | 1218 | continue; |
@@ -1166,12 +1290,16 @@ int __devinit rio_enum_mport(struct rio_mport *mport) | |||
1166 | 1290 | ||
1167 | /* If master port has an active link, allocate net and enum peers */ | 1291 | /* If master port has an active link, allocate net and enum peers */ |
1168 | if (rio_mport_is_active(mport)) { | 1292 | if (rio_mport_is_active(mport)) { |
1169 | if (!(net = rio_alloc_net(mport))) { | 1293 | net = rio_alloc_net(mport, 1, 0); |
1294 | if (!net) { | ||
1170 | printk(KERN_ERR "RIO: failed to allocate new net\n"); | 1295 | printk(KERN_ERR "RIO: failed to allocate new net\n"); |
1171 | rc = -ENOMEM; | 1296 | rc = -ENOMEM; |
1172 | goto out; | 1297 | goto out; |
1173 | } | 1298 | } |
1174 | 1299 | ||
1300 | /* reserve mport destID in new net */ | ||
1301 | rio_destid_reserve(net, mport->host_deviceid); | ||
1302 | |||
1175 | /* Enable Input Output Port (transmitter reviever) */ | 1303 | /* Enable Input Output Port (transmitter reviever) */ |
1176 | rio_enable_rx_tx_port(mport, 1, 0, 0, 0); | 1304 | rio_enable_rx_tx_port(mport, 1, 0, 0, 0); |
1177 | 1305 | ||
@@ -1179,17 +1307,21 @@ int __devinit rio_enum_mport(struct rio_mport *mport) | |||
1179 | rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR, | 1307 | rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR, |
1180 | next_comptag++); | 1308 | next_comptag++); |
1181 | 1309 | ||
1310 | next_destid = rio_destid_alloc(net); | ||
1311 | |||
1182 | if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) { | 1312 | if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) { |
1183 | /* A higher priority host won enumeration, bail. */ | 1313 | /* A higher priority host won enumeration, bail. */ |
1184 | printk(KERN_INFO | 1314 | printk(KERN_INFO |
1185 | "RIO: master port %d device has lost enumeration to a remote host\n", | 1315 | "RIO: master port %d device has lost enumeration to a remote host\n", |
1186 | mport->id); | 1316 | mport->id); |
1187 | rio_clear_locks(mport); | 1317 | rio_clear_locks(net); |
1188 | rc = -EBUSY; | 1318 | rc = -EBUSY; |
1189 | goto out; | 1319 | goto out; |
1190 | } | 1320 | } |
1191 | rio_update_route_tables(mport); | 1321 | /* free the last allocated destID (unused) */ |
1192 | rio_clear_locks(mport); | 1322 | rio_destid_free(net, next_destid); |
1323 | rio_update_route_tables(net); | ||
1324 | rio_clear_locks(net); | ||
1193 | rio_pw_enable(mport, 1); | 1325 | rio_pw_enable(mport, 1); |
1194 | } else { | 1326 | } else { |
1195 | printk(KERN_INFO "RIO: master port %d link inactive\n", | 1327 | printk(KERN_INFO "RIO: master port %d link inactive\n", |
@@ -1203,47 +1335,34 @@ int __devinit rio_enum_mport(struct rio_mport *mport) | |||
1203 | 1335 | ||
1204 | /** | 1336 | /** |
1205 | * rio_build_route_tables- Generate route tables from switch route entries | 1337 | * rio_build_route_tables- Generate route tables from switch route entries |
1338 | * @net: RIO network to run route tables scan on | ||
1206 | * | 1339 | * |
1207 | * For each switch device, generate a route table by copying existing | 1340 | * For each switch device, generate a route table by copying existing |
1208 | * route entries from the switch. | 1341 | * route entries from the switch. |
1209 | */ | 1342 | */ |
1210 | static void rio_build_route_tables(void) | 1343 | static void rio_build_route_tables(struct rio_net *net) |
1211 | { | 1344 | { |
1345 | struct rio_switch *rswitch; | ||
1212 | struct rio_dev *rdev; | 1346 | struct rio_dev *rdev; |
1213 | int i; | 1347 | int i; |
1214 | u8 sport; | 1348 | u8 sport; |
1215 | 1349 | ||
1216 | list_for_each_entry(rdev, &rio_devices, global_list) | 1350 | list_for_each_entry(rswitch, &net->switches, node) { |
1217 | if (rio_is_switch(rdev)) { | 1351 | rdev = sw_to_rio_dev(rswitch); |
1218 | rio_lock_device(rdev->net->hport, rdev->destid, | ||
1219 | rdev->hopcount, 1000); | ||
1220 | for (i = 0; | ||
1221 | i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); | ||
1222 | i++) { | ||
1223 | if (rio_route_get_entry(rdev, | ||
1224 | RIO_GLOBAL_TABLE, i, &sport, 0) < 0) | ||
1225 | continue; | ||
1226 | rdev->rswitch->route_table[i] = sport; | ||
1227 | } | ||
1228 | 1352 | ||
1229 | rio_unlock_device(rdev->net->hport, | 1353 | rio_lock_device(net->hport, rdev->destid, |
1230 | rdev->destid, | 1354 | rdev->hopcount, 1000); |
1231 | rdev->hopcount); | 1355 | for (i = 0; |
1356 | i < RIO_MAX_ROUTE_ENTRIES(net->hport->sys_size); | ||
1357 | i++) { | ||
1358 | if (rio_route_get_entry(rdev, RIO_GLOBAL_TABLE, | ||
1359 | i, &sport, 0) < 0) | ||
1360 | continue; | ||
1361 | rswitch->route_table[i] = sport; | ||
1232 | } | 1362 | } |
1233 | } | ||
1234 | 1363 | ||
1235 | /** | 1364 | rio_unlock_device(net->hport, rdev->destid, rdev->hopcount); |
1236 | * rio_enum_timeout- Signal that enumeration timed out | 1365 | } |
1237 | * @data: Address of timeout flag. | ||
1238 | * | ||
1239 | * When the enumeration complete timer expires, set a flag that | ||
1240 | * signals to the discovery process that enumeration did not | ||
1241 | * complete in a sane amount of time. | ||
1242 | */ | ||
1243 | static void rio_enum_timeout(unsigned long data) | ||
1244 | { | ||
1245 | /* Enumeration timed out, set flag */ | ||
1246 | *(int *)data = 1; | ||
1247 | } | 1366 | } |
1248 | 1367 | ||
1249 | /** | 1368 | /** |
@@ -1259,34 +1378,33 @@ static void rio_enum_timeout(unsigned long data) | |||
1259 | int __devinit rio_disc_mport(struct rio_mport *mport) | 1378 | int __devinit rio_disc_mport(struct rio_mport *mport) |
1260 | { | 1379 | { |
1261 | struct rio_net *net = NULL; | 1380 | struct rio_net *net = NULL; |
1262 | int enum_timeout_flag = 0; | 1381 | unsigned long to_end; |
1263 | 1382 | ||
1264 | printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id, | 1383 | printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id, |
1265 | mport->name); | 1384 | mport->name); |
1266 | 1385 | ||
1267 | /* If master port has an active link, allocate net and discover peers */ | 1386 | /* If master port has an active link, allocate net and discover peers */ |
1268 | if (rio_mport_is_active(mport)) { | 1387 | if (rio_mport_is_active(mport)) { |
1269 | if (!(net = rio_alloc_net(mport))) { | 1388 | pr_debug("RIO: wait for enumeration to complete...\n"); |
1270 | printk(KERN_ERR "RIO: Failed to allocate new net\n"); | ||
1271 | goto bail; | ||
1272 | } | ||
1273 | 1389 | ||
1274 | pr_debug("RIO: wait for enumeration complete..."); | 1390 | to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; |
1275 | 1391 | while (time_before(jiffies, to_end)) { | |
1276 | rio_enum_timer.expires = | 1392 | if (rio_enum_complete(mport)) |
1277 | jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; | 1393 | goto enum_done; |
1278 | rio_enum_timer.data = (unsigned long)&enum_timeout_flag; | 1394 | schedule_timeout_uninterruptible(msecs_to_jiffies(10)); |
1279 | add_timer(&rio_enum_timer); | ||
1280 | while (!rio_enum_complete(mport)) { | ||
1281 | mdelay(1); | ||
1282 | if (enum_timeout_flag) { | ||
1283 | del_timer_sync(&rio_enum_timer); | ||
1284 | goto timeout; | ||
1285 | } | ||
1286 | } | 1395 | } |
1287 | del_timer_sync(&rio_enum_timer); | ||
1288 | 1396 | ||
1289 | pr_debug("done\n"); | 1397 | pr_debug("RIO: discovery timeout on mport %d %s\n", |
1398 | mport->id, mport->name); | ||
1399 | goto bail; | ||
1400 | enum_done: | ||
1401 | pr_debug("RIO: ... enumeration done\n"); | ||
1402 | |||
1403 | net = rio_alloc_net(mport, 0, 0); | ||
1404 | if (!net) { | ||
1405 | printk(KERN_ERR "RIO: Failed to allocate new net\n"); | ||
1406 | goto bail; | ||
1407 | } | ||
1290 | 1408 | ||
1291 | /* Read DestID assigned by enumerator */ | 1409 | /* Read DestID assigned by enumerator */ |
1292 | rio_local_read_config_32(mport, RIO_DID_CSR, | 1410 | rio_local_read_config_32(mport, RIO_DID_CSR, |
@@ -1302,13 +1420,10 @@ int __devinit rio_disc_mport(struct rio_mport *mport) | |||
1302 | goto bail; | 1420 | goto bail; |
1303 | } | 1421 | } |
1304 | 1422 | ||
1305 | rio_build_route_tables(); | 1423 | rio_build_route_tables(net); |
1306 | } | 1424 | } |
1307 | 1425 | ||
1308 | return 0; | 1426 | return 0; |
1309 | 1427 | bail: | |
1310 | timeout: | ||
1311 | pr_debug("timeout\n"); | ||
1312 | bail: | ||
1313 | return -EBUSY; | 1428 | return -EBUSY; |
1314 | } | 1429 | } |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index c40665a4fa33..d4bd69013c50 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | static LIST_HEAD(rio_mports); | 34 | static LIST_HEAD(rio_mports); |
35 | static unsigned char next_portid; | 35 | static unsigned char next_portid; |
36 | static DEFINE_SPINLOCK(rio_mmap_lock); | ||
36 | 37 | ||
37 | /** | 38 | /** |
38 | * rio_local_get_device_id - Get the base/extended device id for a port | 39 | * rio_local_get_device_id - Get the base/extended device id for a port |
@@ -398,6 +399,49 @@ int rio_release_inb_pwrite(struct rio_dev *rdev) | |||
398 | EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); | 399 | EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); |
399 | 400 | ||
400 | /** | 401 | /** |
402 | * rio_map_inb_region -- Map inbound memory region. | ||
403 | * @mport: Master port. | ||
404 | * @lstart: physical address of memory region to be mapped | ||
405 | * @rbase: RIO base address assigned to this window | ||
406 | * @size: Size of the memory region | ||
407 | * @rflags: Flags for mapping. | ||
408 | * | ||
409 | * Return: 0 -- Success. | ||
410 | * | ||
411 | * This function will create the mapping from RIO space to local memory. | ||
412 | */ | ||
413 | int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local, | ||
414 | u64 rbase, u32 size, u32 rflags) | ||
415 | { | ||
416 | int rc = 0; | ||
417 | unsigned long flags; | ||
418 | |||
419 | if (!mport->ops->map_inb) | ||
420 | return -1; | ||
421 | spin_lock_irqsave(&rio_mmap_lock, flags); | ||
422 | rc = mport->ops->map_inb(mport, local, rbase, size, rflags); | ||
423 | spin_unlock_irqrestore(&rio_mmap_lock, flags); | ||
424 | return rc; | ||
425 | } | ||
426 | EXPORT_SYMBOL_GPL(rio_map_inb_region); | ||
427 | |||
428 | /** | ||
429 | * rio_unmap_inb_region -- Unmap the inbound memory region | ||
430 | * @mport: Master port | ||
431 | * @lstart: physical address of memory region to be unmapped | ||
432 | */ | ||
433 | void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart) | ||
434 | { | ||
435 | unsigned long flags; | ||
436 | if (!mport->ops->unmap_inb) | ||
437 | return; | ||
438 | spin_lock_irqsave(&rio_mmap_lock, flags); | ||
439 | mport->ops->unmap_inb(mport, lstart); | ||
440 | spin_unlock_irqrestore(&rio_mmap_lock, flags); | ||
441 | } | ||
442 | EXPORT_SYMBOL_GPL(rio_unmap_inb_region); | ||
443 | |||
444 | /** | ||
401 | * rio_mport_get_physefb - Helper function that returns register offset | 445 | * rio_mport_get_physefb - Helper function that returns register offset |
402 | * for Physical Layer Extended Features Block. | 446 | * for Physical Layer Extended Features Block. |
403 | * @port: Master port to issue transaction | 447 | * @port: Master port to issue transaction |
@@ -1216,15 +1260,62 @@ static int __devinit rio_init(void) | |||
1216 | return 0; | 1260 | return 0; |
1217 | } | 1261 | } |
1218 | 1262 | ||
1263 | static struct workqueue_struct *rio_wq; | ||
1264 | |||
1265 | struct rio_disc_work { | ||
1266 | struct work_struct work; | ||
1267 | struct rio_mport *mport; | ||
1268 | }; | ||
1269 | |||
1270 | static void __devinit disc_work_handler(struct work_struct *_work) | ||
1271 | { | ||
1272 | struct rio_disc_work *work; | ||
1273 | |||
1274 | work = container_of(_work, struct rio_disc_work, work); | ||
1275 | pr_debug("RIO: discovery work for mport %d %s\n", | ||
1276 | work->mport->id, work->mport->name); | ||
1277 | rio_disc_mport(work->mport); | ||
1278 | |||
1279 | kfree(work); | ||
1280 | } | ||
1281 | |||
1219 | int __devinit rio_init_mports(void) | 1282 | int __devinit rio_init_mports(void) |
1220 | { | 1283 | { |
1221 | struct rio_mport *port; | 1284 | struct rio_mport *port; |
1285 | struct rio_disc_work *work; | ||
1286 | int no_disc = 0; | ||
1222 | 1287 | ||
1223 | list_for_each_entry(port, &rio_mports, node) { | 1288 | list_for_each_entry(port, &rio_mports, node) { |
1224 | if (port->host_deviceid >= 0) | 1289 | if (port->host_deviceid >= 0) |
1225 | rio_enum_mport(port); | 1290 | rio_enum_mport(port); |
1226 | else | 1291 | else if (!no_disc) { |
1227 | rio_disc_mport(port); | 1292 | if (!rio_wq) { |
1293 | rio_wq = alloc_workqueue("riodisc", 0, 0); | ||
1294 | if (!rio_wq) { | ||
1295 | pr_err("RIO: unable allocate rio_wq\n"); | ||
1296 | no_disc = 1; | ||
1297 | continue; | ||
1298 | } | ||
1299 | } | ||
1300 | |||
1301 | work = kzalloc(sizeof *work, GFP_KERNEL); | ||
1302 | if (!work) { | ||
1303 | pr_err("RIO: no memory for work struct\n"); | ||
1304 | no_disc = 1; | ||
1305 | continue; | ||
1306 | } | ||
1307 | |||
1308 | work->mport = port; | ||
1309 | INIT_WORK(&work->work, disc_work_handler); | ||
1310 | queue_work(rio_wq, &work->work); | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | if (rio_wq) { | ||
1315 | pr_debug("RIO: flush discovery workqueue\n"); | ||
1316 | flush_workqueue(rio_wq); | ||
1317 | pr_debug("RIO: flush discovery workqueue finished\n"); | ||
1318 | destroy_workqueue(rio_wq); | ||
1228 | } | 1319 | } |
1229 | 1320 | ||
1230 | rio_init(); | 1321 | rio_init(); |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index fabc99a75c65..e069f176a82d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -19,7 +19,6 @@ if RTC_CLASS | |||
19 | 19 | ||
20 | config RTC_HCTOSYS | 20 | config RTC_HCTOSYS |
21 | bool "Set system time from RTC on startup and resume" | 21 | bool "Set system time from RTC on startup and resume" |
22 | depends on RTC_CLASS = y | ||
23 | default y | 22 | default y |
24 | help | 23 | help |
25 | If you say yes here, the system time (wall clock) will be set using | 24 | If you say yes here, the system time (wall clock) will be set using |
@@ -51,7 +50,6 @@ config RTC_HCTOSYS_DEVICE | |||
51 | 50 | ||
52 | config RTC_DEBUG | 51 | config RTC_DEBUG |
53 | bool "RTC debug support" | 52 | bool "RTC debug support" |
54 | depends on RTC_CLASS = y | ||
55 | help | 53 | help |
56 | Say yes here to enable debugging support in the RTC framework | 54 | Say yes here to enable debugging support in the RTC framework |
57 | and individual RTC drivers. | 55 | and individual RTC drivers. |
@@ -61,7 +59,6 @@ comment "RTC interfaces" | |||
61 | config RTC_INTF_SYSFS | 59 | config RTC_INTF_SYSFS |
62 | boolean "/sys/class/rtc/rtcN (sysfs)" | 60 | boolean "/sys/class/rtc/rtcN (sysfs)" |
63 | depends on SYSFS | 61 | depends on SYSFS |
64 | default RTC_CLASS | ||
65 | help | 62 | help |
66 | Say yes here if you want to use your RTCs using sysfs interfaces, | 63 | Say yes here if you want to use your RTCs using sysfs interfaces, |
67 | /sys/class/rtc/rtc0 through /sys/.../rtcN. | 64 | /sys/class/rtc/rtc0 through /sys/.../rtcN. |
@@ -69,19 +66,19 @@ config RTC_INTF_SYSFS | |||
69 | If unsure, say Y. | 66 | If unsure, say Y. |
70 | 67 | ||
71 | config RTC_INTF_PROC | 68 | config RTC_INTF_PROC |
72 | boolean "/proc/driver/rtc (procfs for rtc0)" | 69 | boolean "/proc/driver/rtc (procfs for rtcN)" |
73 | depends on PROC_FS | 70 | depends on PROC_FS |
74 | default RTC_CLASS | ||
75 | help | 71 | help |
76 | Say yes here if you want to use your first RTC through the proc | 72 | Say yes here if you want to use your system clock RTC through |
77 | interface, /proc/driver/rtc. Other RTCs will not be available | 73 | the proc interface, /proc/driver/rtc. |
78 | through that API. | 74 | Other RTCs will not be available through that API. |
75 | If there is no RTC for the system clock, then the first RTC(rtc0) | ||
76 | is used by default. | ||
79 | 77 | ||
80 | If unsure, say Y. | 78 | If unsure, say Y. |
81 | 79 | ||
82 | config RTC_INTF_DEV | 80 | config RTC_INTF_DEV |
83 | boolean "/dev/rtcN (character devices)" | 81 | boolean "/dev/rtcN (character devices)" |
84 | default RTC_CLASS | ||
85 | help | 82 | help |
86 | Say yes here if you want to use your RTCs using the /dev | 83 | Say yes here if you want to use your RTCs using the /dev |
87 | interfaces, which "udev" sets up as /dev/rtc0 through | 84 | interfaces, which "udev" sets up as /dev/rtc0 through |
@@ -127,7 +124,7 @@ if I2C | |||
127 | 124 | ||
128 | config RTC_DRV_88PM860X | 125 | config RTC_DRV_88PM860X |
129 | tristate "Marvell 88PM860x" | 126 | tristate "Marvell 88PM860x" |
130 | depends on RTC_CLASS && I2C && MFD_88PM860X | 127 | depends on I2C && MFD_88PM860X |
131 | help | 128 | help |
132 | If you say yes here you get support for RTC function in Marvell | 129 | If you say yes here you get support for RTC function in Marvell |
133 | 88PM860x chips. | 130 | 88PM860x chips. |
@@ -137,7 +134,7 @@ config RTC_DRV_88PM860X | |||
137 | 134 | ||
138 | config RTC_DRV_88PM80X | 135 | config RTC_DRV_88PM80X |
139 | tristate "Marvell 88PM80x" | 136 | tristate "Marvell 88PM80x" |
140 | depends on RTC_CLASS && I2C && MFD_88PM800 | 137 | depends on I2C && MFD_88PM800 |
141 | help | 138 | help |
142 | If you say yes here you get support for RTC function in Marvell | 139 | If you say yes here you get support for RTC function in Marvell |
143 | 88PM80x chips. | 140 | 88PM80x chips. |
@@ -165,7 +162,7 @@ config RTC_DRV_DS1307 | |||
165 | 162 | ||
166 | config RTC_DRV_DS1374 | 163 | config RTC_DRV_DS1374 |
167 | tristate "Dallas/Maxim DS1374" | 164 | tristate "Dallas/Maxim DS1374" |
168 | depends on RTC_CLASS && I2C | 165 | depends on I2C |
169 | help | 166 | help |
170 | If you say yes here you get support for Dallas Semiconductor | 167 | If you say yes here you get support for Dallas Semiconductor |
171 | DS1374 real-time clock chips. If an interrupt is associated | 168 | DS1374 real-time clock chips. If an interrupt is associated |
@@ -185,7 +182,7 @@ config RTC_DRV_DS1672 | |||
185 | 182 | ||
186 | config RTC_DRV_DS3232 | 183 | config RTC_DRV_DS3232 |
187 | tristate "Dallas/Maxim DS3232" | 184 | tristate "Dallas/Maxim DS3232" |
188 | depends on RTC_CLASS && I2C | 185 | depends on I2C |
189 | help | 186 | help |
190 | If you say yes here you get support for Dallas Semiconductor | 187 | If you say yes here you get support for Dallas Semiconductor |
191 | DS3232 real-time clock chips. If an interrupt is associated | 188 | DS3232 real-time clock chips. If an interrupt is associated |
@@ -203,6 +200,16 @@ config RTC_DRV_MAX6900 | |||
203 | This driver can also be built as a module. If so, the module | 200 | This driver can also be built as a module. If so, the module |
204 | will be called rtc-max6900. | 201 | will be called rtc-max6900. |
205 | 202 | ||
203 | config RTC_DRV_MAX8907 | ||
204 | tristate "Maxim MAX8907" | ||
205 | depends on MFD_MAX8907 | ||
206 | help | ||
207 | If you say yes here you will get support for the | ||
208 | RTC of Maxim MAX8907 PMIC. | ||
209 | |||
210 | This driver can also be built as a module. If so, the module | ||
211 | will be called rtc-max8907. | ||
212 | |||
206 | config RTC_DRV_MAX8925 | 213 | config RTC_DRV_MAX8925 |
207 | tristate "Maxim MAX8925" | 214 | tristate "Maxim MAX8925" |
208 | depends on MFD_MAX8925 | 215 | depends on MFD_MAX8925 |
@@ -325,7 +332,7 @@ config RTC_DRV_TWL92330 | |||
325 | 332 | ||
326 | config RTC_DRV_TWL4030 | 333 | config RTC_DRV_TWL4030 |
327 | tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0" | 334 | tristate "TI TWL4030/TWL5030/TWL6030/TPS659x0" |
328 | depends on RTC_CLASS && TWL4030_CORE | 335 | depends on TWL4030_CORE |
329 | help | 336 | help |
330 | If you say yes here you get support for the RTC on the | 337 | If you say yes here you get support for the RTC on the |
331 | TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms. | 338 | TWL4030/TWL5030/TWL6030 family chips, used mostly with OMAP3 platforms. |
@@ -333,6 +340,26 @@ config RTC_DRV_TWL4030 | |||
333 | This driver can also be built as a module. If so, the module | 340 | This driver can also be built as a module. If so, the module |
334 | will be called rtc-twl. | 341 | will be called rtc-twl. |
335 | 342 | ||
343 | config RTC_DRV_TPS65910 | ||
344 | tristate "TI TPS65910 RTC driver" | ||
345 | depends on RTC_CLASS && MFD_TPS65910 | ||
346 | help | ||
347 | If you say yes here you get support for the RTC on the | ||
348 | TPS65910 chips. | ||
349 | |||
350 | This driver can also be built as a module. If so, the module | ||
351 | will be called rtc-tps65910. | ||
352 | |||
353 | config RTC_DRV_RC5T583 | ||
354 | tristate "RICOH 5T583 RTC driver" | ||
355 | depends on MFD_RC5T583 | ||
356 | help | ||
357 | If you say yes here you get support for the RTC on the | ||
358 | RICOH 5T583 chips. | ||
359 | |||
360 | This driver can also be built as a module. If so, the module | ||
361 | will be called rtc-rc5t583. | ||
362 | |||
336 | config RTC_DRV_S35390A | 363 | config RTC_DRV_S35390A |
337 | tristate "Seiko Instruments S-35390A" | 364 | tristate "Seiko Instruments S-35390A" |
338 | select BITREVERSE | 365 | select BITREVERSE |
@@ -538,7 +565,6 @@ config RTC_DRV_DS1302 | |||
538 | 565 | ||
539 | config RTC_DRV_DS1511 | 566 | config RTC_DRV_DS1511 |
540 | tristate "Dallas DS1511" | 567 | tristate "Dallas DS1511" |
541 | depends on RTC_CLASS | ||
542 | help | 568 | help |
543 | If you say yes here you get support for the | 569 | If you say yes here you get support for the |
544 | Dallas DS1511 timekeeping/watchdog chip. | 570 | Dallas DS1511 timekeeping/watchdog chip. |
@@ -583,7 +609,6 @@ config RTC_DRV_EFI | |||
583 | 609 | ||
584 | config RTC_DRV_STK17TA8 | 610 | config RTC_DRV_STK17TA8 |
585 | tristate "Simtek STK17TA8" | 611 | tristate "Simtek STK17TA8" |
586 | depends on RTC_CLASS | ||
587 | help | 612 | help |
588 | If you say yes here you get support for the | 613 | If you say yes here you get support for the |
589 | Simtek STK17TA8 timekeeping chip. | 614 | Simtek STK17TA8 timekeeping chip. |
@@ -658,6 +683,15 @@ config RTC_DRV_V3020 | |||
658 | This driver can also be built as a module. If so, the module | 683 | This driver can also be built as a module. If so, the module |
659 | will be called rtc-v3020. | 684 | will be called rtc-v3020. |
660 | 685 | ||
686 | config RTC_DRV_DS2404 | ||
687 | tristate "Dallas DS2404" | ||
688 | help | ||
689 | If you say yes here you get support for the | ||
690 | Dallas DS2404 RTC chip. | ||
691 | |||
692 | This driver can also be built as a module. If so, the module | ||
693 | will be called rtc-ds2404. | ||
694 | |||
661 | config RTC_DRV_WM831X | 695 | config RTC_DRV_WM831X |
662 | tristate "Wolfson Microelectronics WM831x RTC" | 696 | tristate "Wolfson Microelectronics WM831x RTC" |
663 | depends on MFD_WM831X | 697 | depends on MFD_WM831X |
@@ -704,6 +738,7 @@ config RTC_DRV_AB3100 | |||
704 | config RTC_DRV_AB8500 | 738 | config RTC_DRV_AB8500 |
705 | tristate "ST-Ericsson AB8500 RTC" | 739 | tristate "ST-Ericsson AB8500 RTC" |
706 | depends on AB8500_CORE | 740 | depends on AB8500_CORE |
741 | select RTC_INTF_DEV | ||
707 | select RTC_INTF_DEV_UIE_EMUL | 742 | select RTC_INTF_DEV_UIE_EMUL |
708 | help | 743 | help |
709 | Select this to enable the ST-Ericsson AB8500 power management IC RTC | 744 | Select this to enable the ST-Ericsson AB8500 power management IC RTC |
@@ -711,7 +746,7 @@ config RTC_DRV_AB8500 | |||
711 | 746 | ||
712 | config RTC_DRV_NUC900 | 747 | config RTC_DRV_NUC900 |
713 | tristate "NUC910/NUC920 RTC driver" | 748 | tristate "NUC910/NUC920 RTC driver" |
714 | depends on RTC_CLASS && ARCH_W90X900 | 749 | depends on ARCH_W90X900 |
715 | help | 750 | help |
716 | If you say yes here you get support for the RTC subsystem of the | 751 | If you say yes here you get support for the RTC subsystem of the |
717 | NUC910/NUC920 used in embedded systems. | 752 | NUC910/NUC920 used in embedded systems. |
@@ -731,7 +766,6 @@ config RTC_DRV_DAVINCI | |||
731 | config RTC_DRV_IMXDI | 766 | config RTC_DRV_IMXDI |
732 | tristate "Freescale IMX DryIce Real Time Clock" | 767 | tristate "Freescale IMX DryIce Real Time Clock" |
733 | depends on SOC_IMX25 | 768 | depends on SOC_IMX25 |
734 | depends on RTC_CLASS | ||
735 | help | 769 | help |
736 | Support for Freescale IMX DryIce RTC | 770 | Support for Freescale IMX DryIce RTC |
737 | 771 | ||
@@ -791,7 +825,7 @@ config RTC_DRV_SA1100 | |||
791 | 825 | ||
792 | config RTC_DRV_SH | 826 | config RTC_DRV_SH |
793 | tristate "SuperH On-Chip RTC" | 827 | tristate "SuperH On-Chip RTC" |
794 | depends on RTC_CLASS && SUPERH && HAVE_CLK | 828 | depends on SUPERH && HAVE_CLK |
795 | help | 829 | help |
796 | Say Y here to enable support for the on-chip RTC found in | 830 | Say Y here to enable support for the on-chip RTC found in |
797 | most SuperH processors. | 831 | most SuperH processors. |
@@ -1023,7 +1057,6 @@ config RTC_DRV_MPC5121 | |||
1023 | 1057 | ||
1024 | config RTC_DRV_JZ4740 | 1058 | config RTC_DRV_JZ4740 |
1025 | tristate "Ingenic JZ4740 SoC" | 1059 | tristate "Ingenic JZ4740 SoC" |
1026 | depends on RTC_CLASS | ||
1027 | depends on MACH_JZ4740 | 1060 | depends on MACH_JZ4740 |
1028 | help | 1061 | help |
1029 | If you say yes here you get support for the Ingenic JZ4740 SoC RTC | 1062 | If you say yes here you get support for the Ingenic JZ4740 SoC RTC |
@@ -1053,7 +1086,7 @@ config RTC_DRV_PM8XXX | |||
1053 | 1086 | ||
1054 | config RTC_DRV_TEGRA | 1087 | config RTC_DRV_TEGRA |
1055 | tristate "NVIDIA Tegra Internal RTC driver" | 1088 | tristate "NVIDIA Tegra Internal RTC driver" |
1056 | depends on RTC_CLASS && ARCH_TEGRA | 1089 | depends on ARCH_TEGRA |
1057 | help | 1090 | help |
1058 | If you say yes here you get support for the | 1091 | If you say yes here you get support for the |
1059 | Tegra 200 series internal RTC module. | 1092 | Tegra 200 series internal RTC module. |
@@ -1090,7 +1123,6 @@ config RTC_DRV_LOONGSON1 | |||
1090 | config RTC_DRV_MXC | 1123 | config RTC_DRV_MXC |
1091 | tristate "Freescale MXC Real Time Clock" | 1124 | tristate "Freescale MXC Real Time Clock" |
1092 | depends on ARCH_MXC | 1125 | depends on ARCH_MXC |
1093 | depends on RTC_CLASS | ||
1094 | help | 1126 | help |
1095 | If you say yes here you get support for the Freescale MXC | 1127 | If you say yes here you get support for the Freescale MXC |
1096 | RTC module. | 1128 | RTC module. |
@@ -1098,4 +1130,15 @@ config RTC_DRV_MXC | |||
1098 | This driver can also be built as a module, if so, the module | 1130 | This driver can also be built as a module, if so, the module |
1099 | will be called "rtc-mxc". | 1131 | will be called "rtc-mxc". |
1100 | 1132 | ||
1133 | config RTC_DRV_SNVS | ||
1134 | tristate "Freescale SNVS RTC support" | ||
1135 | depends on HAS_IOMEM | ||
1136 | depends on OF | ||
1137 | help | ||
1138 | If you say yes here you get support for the Freescale SNVS | ||
1139 | Low Power (LP) RTC module. | ||
1140 | |||
1141 | This driver can also be built as a module, if so, the module | ||
1142 | will be called "rtc-snvs". | ||
1143 | |||
1101 | endif # RTC_CLASS | 1144 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 0d5b2b66f90d..56297f0fd388 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -43,6 +43,7 @@ obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o | |||
43 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 43 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
44 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 44 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
45 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | 45 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o |
46 | obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o | ||
46 | obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o | 47 | obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o |
47 | obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o | 48 | obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o |
48 | obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o | 49 | obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o |
@@ -64,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | |||
64 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 65 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
65 | obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o | 66 | obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o |
66 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 67 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
68 | obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o | ||
67 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o | 69 | obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o |
68 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o | 70 | obj-$(CONFIG_RTC_DRV_MAX8998) += rtc-max8998.o |
69 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 71 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
@@ -85,6 +87,7 @@ obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o | |||
85 | obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o | 87 | obj-$(CONFIG_RTC_DRV_PUV3) += rtc-puv3.o |
86 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o | 88 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o |
87 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 89 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
90 | obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o | ||
88 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o | 91 | obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o |
89 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 92 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
90 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 93 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
@@ -96,6 +99,7 @@ obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | |||
96 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | 99 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o |
97 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 100 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
98 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o | 101 | obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o |
102 | obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o | ||
99 | obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o | 103 | obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o |
100 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o | 104 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o |
101 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o | 105 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o |
@@ -105,6 +109,7 @@ obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o | |||
105 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | 109 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o |
106 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o | 110 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o |
107 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | 111 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o |
112 | obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o | ||
108 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | 113 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o |
109 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 114 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
110 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 115 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index dc4c2748bbc3..f8a0aab218cb 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -31,8 +31,12 @@ static void rtc_device_release(struct device *dev) | |||
31 | kfree(rtc); | 31 | kfree(rtc); |
32 | } | 32 | } |
33 | 33 | ||
34 | #if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE) | 34 | #ifdef CONFIG_RTC_HCTOSYS_DEVICE |
35 | /* Result of the last RTC to system clock attempt. */ | ||
36 | int rtc_hctosys_ret = -ENODEV; | ||
37 | #endif | ||
35 | 38 | ||
39 | #if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE) | ||
36 | /* | 40 | /* |
37 | * On suspend(), measure the delta between one RTC and the | 41 | * On suspend(), measure the delta between one RTC and the |
38 | * system's wall clock; restore it on resume(). | 42 | * system's wall clock; restore it on resume(). |
@@ -84,6 +88,7 @@ static int rtc_resume(struct device *dev) | |||
84 | struct timespec new_system, new_rtc; | 88 | struct timespec new_system, new_rtc; |
85 | struct timespec sleep_time; | 89 | struct timespec sleep_time; |
86 | 90 | ||
91 | rtc_hctosys_ret = -ENODEV; | ||
87 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) | 92 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
88 | return 0; | 93 | return 0; |
89 | 94 | ||
@@ -117,6 +122,7 @@ static int rtc_resume(struct device *dev) | |||
117 | 122 | ||
118 | if (sleep_time.tv_sec >= 0) | 123 | if (sleep_time.tv_sec >= 0) |
119 | timekeeping_inject_sleeptime(&sleep_time); | 124 | timekeeping_inject_sleeptime(&sleep_time); |
125 | rtc_hctosys_ret = 0; | ||
120 | return 0; | 126 | return 0; |
121 | } | 127 | } |
122 | 128 | ||
@@ -238,6 +244,7 @@ void rtc_device_unregister(struct rtc_device *rtc) | |||
238 | rtc_proc_del_device(rtc); | 244 | rtc_proc_del_device(rtc); |
239 | device_unregister(&rtc->dev); | 245 | device_unregister(&rtc->dev); |
240 | rtc->ops = NULL; | 246 | rtc->ops = NULL; |
247 | ida_simple_remove(&rtc_ida, rtc->id); | ||
241 | mutex_unlock(&rtc->ops_lock); | 248 | mutex_unlock(&rtc->ops_lock); |
242 | put_device(&rtc->dev); | 249 | put_device(&rtc->dev); |
243 | } | 250 | } |
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index bc90b091f195..4aa60d74004e 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c | |||
@@ -22,8 +22,6 @@ | |||
22 | * the best guess is to add 0.5s. | 22 | * the best guess is to add 0.5s. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | int rtc_hctosys_ret = -ENODEV; | ||
26 | |||
27 | static int __init rtc_hctosys(void) | 25 | static int __init rtc_hctosys(void) |
28 | { | 26 | { |
29 | int err = -ENODEV; | 27 | int err = -ENODEV; |
@@ -56,7 +54,7 @@ static int __init rtc_hctosys(void) | |||
56 | 54 | ||
57 | rtc_tm_to_time(&tm, &tv.tv_sec); | 55 | rtc_tm_to_time(&tm, &tv.tv_sec); |
58 | 56 | ||
59 | do_settimeofday(&tv); | 57 | err = do_settimeofday(&tv); |
60 | 58 | ||
61 | dev_info(rtc->dev.parent, | 59 | dev_info(rtc->dev.parent, |
62 | "setting system clock to " | 60 | "setting system clock to " |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 1dd61f402b04..2dfe7a2fb998 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -473,18 +473,7 @@ static struct platform_driver at91_rtc_driver = { | |||
473 | }, | 473 | }, |
474 | }; | 474 | }; |
475 | 475 | ||
476 | static int __init at91_rtc_init(void) | 476 | module_platform_driver(at91_rtc_driver); |
477 | { | ||
478 | return platform_driver_register(&at91_rtc_driver); | ||
479 | } | ||
480 | module_init(at91_rtc_init); | ||
481 | |||
482 | static void __exit at91_rtc_exit(void) | ||
483 | { | ||
484 | platform_driver_unregister(&at91_rtc_driver); | ||
485 | } | ||
486 | module_exit(at91_rtc_exit); | ||
487 | |||
488 | 477 | ||
489 | MODULE_AUTHOR("Michel Benoit"); | 478 | MODULE_AUTHOR("Michel Benoit"); |
490 | MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x"); | 479 | MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x"); |
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 76b2156d3c62..c8115b83e5ab 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c | |||
@@ -276,8 +276,7 @@ static void coh901331_shutdown(struct platform_device *pdev) | |||
276 | 276 | ||
277 | clk_enable(rtap->clk); | 277 | clk_enable(rtap->clk); |
278 | writel(0, rtap->virtbase + COH901331_IRQ_MASK); | 278 | writel(0, rtap->virtbase + COH901331_IRQ_MASK); |
279 | clk_disable(rtap->clk); | 279 | clk_disable_unprepare(rtap->clk); |
280 | clk_unprepare(rtap->clk); | ||
281 | } | 280 | } |
282 | 281 | ||
283 | static struct platform_driver coh901331_driver = { | 282 | static struct platform_driver coh901331_driver = { |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 7fa67d0df172..45d65c0b3a85 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -37,8 +37,17 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
37 | unsigned char buf[4]; | 37 | unsigned char buf[4]; |
38 | 38 | ||
39 | struct i2c_msg msgs[] = { | 39 | struct i2c_msg msgs[] = { |
40 | {client->addr, 0, 1, &addr}, /* setup read ptr */ | 40 | {/* setup read ptr */ |
41 | {client->addr, I2C_M_RD, 4, buf}, /* read date */ | 41 | .addr = client->addr, |
42 | .len = 1, | ||
43 | .buf = &addr | ||
44 | }, | ||
45 | {/* read date */ | ||
46 | .addr = client->addr, | ||
47 | .flags = I2C_M_RD, | ||
48 | .len = 4, | ||
49 | .buf = buf | ||
50 | }, | ||
42 | }; | 51 | }; |
43 | 52 | ||
44 | /* read date registers */ | 53 | /* read date registers */ |
@@ -99,8 +108,17 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status) | |||
99 | unsigned char addr = DS1672_REG_CONTROL; | 108 | unsigned char addr = DS1672_REG_CONTROL; |
100 | 109 | ||
101 | struct i2c_msg msgs[] = { | 110 | struct i2c_msg msgs[] = { |
102 | {client->addr, 0, 1, &addr}, /* setup read ptr */ | 111 | {/* setup read ptr */ |
103 | {client->addr, I2C_M_RD, 1, status}, /* read control */ | 112 | .addr = client->addr, |
113 | .len = 1, | ||
114 | .buf = &addr | ||
115 | }, | ||
116 | {/* read control */ | ||
117 | .addr = client->addr, | ||
118 | .flags = I2C_M_RD, | ||
119 | .len = 1, | ||
120 | .buf = status | ||
121 | }, | ||
104 | }; | 122 | }; |
105 | 123 | ||
106 | /* read control register */ | 124 | /* read control register */ |
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c new file mode 100644 index 000000000000..5ea9df7c8c31 --- /dev/null +++ b/drivers/rtc/rtc-ds2404.c | |||
@@ -0,0 +1,303 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 Sven Schnelle <svens@stackframe.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/rtc.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/bcd.h> | ||
16 | #include <linux/rtc-ds2404.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #include <linux/io.h> | ||
22 | |||
23 | #define DS2404_STATUS_REG 0x200 | ||
24 | #define DS2404_CONTROL_REG 0x201 | ||
25 | #define DS2404_RTC_REG 0x202 | ||
26 | |||
27 | #define DS2404_WRITE_SCRATCHPAD_CMD 0x0f | ||
28 | #define DS2404_READ_SCRATCHPAD_CMD 0xaa | ||
29 | #define DS2404_COPY_SCRATCHPAD_CMD 0x55 | ||
30 | #define DS2404_READ_MEMORY_CMD 0xf0 | ||
31 | |||
32 | struct ds2404; | ||
33 | |||
34 | struct ds2404_chip_ops { | ||
35 | int (*map_io)(struct ds2404 *chip, struct platform_device *pdev, | ||
36 | struct ds2404_platform_data *pdata); | ||
37 | void (*unmap_io)(struct ds2404 *chip); | ||
38 | }; | ||
39 | |||
40 | #define DS2404_RST 0 | ||
41 | #define DS2404_CLK 1 | ||
42 | #define DS2404_DQ 2 | ||
43 | |||
44 | struct ds2404_gpio { | ||
45 | const char *name; | ||
46 | unsigned int gpio; | ||
47 | }; | ||
48 | |||
49 | struct ds2404 { | ||
50 | struct ds2404_gpio *gpio; | ||
51 | struct ds2404_chip_ops *ops; | ||
52 | struct rtc_device *rtc; | ||
53 | }; | ||
54 | |||
55 | static struct ds2404_gpio ds2404_gpio[] = { | ||
56 | { "RTC RST", 0 }, | ||
57 | { "RTC CLK", 0 }, | ||
58 | { "RTC DQ", 0 }, | ||
59 | }; | ||
60 | |||
61 | static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev, | ||
62 | struct ds2404_platform_data *pdata) | ||
63 | { | ||
64 | int i, err; | ||
65 | |||
66 | ds2404_gpio[DS2404_RST].gpio = pdata->gpio_rst; | ||
67 | ds2404_gpio[DS2404_CLK].gpio = pdata->gpio_clk; | ||
68 | ds2404_gpio[DS2404_DQ].gpio = pdata->gpio_dq; | ||
69 | |||
70 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) { | ||
71 | err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name); | ||
72 | if (err) { | ||
73 | printk(KERN_ERR "error mapping gpio %s: %d\n", | ||
74 | ds2404_gpio[i].name, err); | ||
75 | goto err_request; | ||
76 | } | ||
77 | if (i != DS2404_DQ) | ||
78 | gpio_direction_output(ds2404_gpio[i].gpio, 1); | ||
79 | } | ||
80 | |||
81 | chip->gpio = ds2404_gpio; | ||
82 | return 0; | ||
83 | |||
84 | err_request: | ||
85 | while (--i >= 0) | ||
86 | gpio_free(ds2404_gpio[i].gpio); | ||
87 | return err; | ||
88 | } | ||
89 | |||
90 | static void ds2404_gpio_unmap(struct ds2404 *chip) | ||
91 | { | ||
92 | int i; | ||
93 | |||
94 | for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) | ||
95 | gpio_free(ds2404_gpio[i].gpio); | ||
96 | } | ||
97 | |||
98 | static struct ds2404_chip_ops ds2404_gpio_ops = { | ||
99 | .map_io = ds2404_gpio_map, | ||
100 | .unmap_io = ds2404_gpio_unmap, | ||
101 | }; | ||
102 | |||
103 | static void ds2404_reset(struct device *dev) | ||
104 | { | ||
105 | gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0); | ||
106 | udelay(1000); | ||
107 | gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 1); | ||
108 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0); | ||
109 | gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 0); | ||
110 | udelay(10); | ||
111 | } | ||
112 | |||
113 | static void ds2404_write_byte(struct device *dev, u8 byte) | ||
114 | { | ||
115 | int i; | ||
116 | |||
117 | gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 1); | ||
118 | for (i = 0; i < 8; i++) { | ||
119 | gpio_set_value(ds2404_gpio[DS2404_DQ].gpio, byte & (1 << i)); | ||
120 | udelay(10); | ||
121 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1); | ||
122 | udelay(10); | ||
123 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0); | ||
124 | udelay(10); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static u8 ds2404_read_byte(struct device *dev) | ||
129 | { | ||
130 | int i; | ||
131 | u8 ret = 0; | ||
132 | |||
133 | gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio); | ||
134 | |||
135 | for (i = 0; i < 8; i++) { | ||
136 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0); | ||
137 | udelay(10); | ||
138 | if (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio)) | ||
139 | ret |= 1 << i; | ||
140 | gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1); | ||
141 | udelay(10); | ||
142 | } | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static void ds2404_read_memory(struct device *dev, u16 offset, | ||
147 | int length, u8 *out) | ||
148 | { | ||
149 | ds2404_reset(dev); | ||
150 | ds2404_write_byte(dev, DS2404_READ_MEMORY_CMD); | ||
151 | ds2404_write_byte(dev, offset & 0xff); | ||
152 | ds2404_write_byte(dev, (offset >> 8) & 0xff); | ||
153 | while (length--) | ||
154 | *out++ = ds2404_read_byte(dev); | ||
155 | } | ||
156 | |||
157 | static void ds2404_write_memory(struct device *dev, u16 offset, | ||
158 | int length, u8 *out) | ||
159 | { | ||
160 | int i; | ||
161 | u8 ta01, ta02, es; | ||
162 | |||
163 | ds2404_reset(dev); | ||
164 | ds2404_write_byte(dev, DS2404_WRITE_SCRATCHPAD_CMD); | ||
165 | ds2404_write_byte(dev, offset & 0xff); | ||
166 | ds2404_write_byte(dev, (offset >> 8) & 0xff); | ||
167 | |||
168 | for (i = 0; i < length; i++) | ||
169 | ds2404_write_byte(dev, out[i]); | ||
170 | |||
171 | ds2404_reset(dev); | ||
172 | ds2404_write_byte(dev, DS2404_READ_SCRATCHPAD_CMD); | ||
173 | |||
174 | ta01 = ds2404_read_byte(dev); | ||
175 | ta02 = ds2404_read_byte(dev); | ||
176 | es = ds2404_read_byte(dev); | ||
177 | |||
178 | for (i = 0; i < length; i++) { | ||
179 | if (out[i] != ds2404_read_byte(dev)) { | ||
180 | printk(KERN_ERR "read invalid data\n"); | ||
181 | return; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | ds2404_reset(dev); | ||
186 | ds2404_write_byte(dev, DS2404_COPY_SCRATCHPAD_CMD); | ||
187 | ds2404_write_byte(dev, ta01); | ||
188 | ds2404_write_byte(dev, ta02); | ||
189 | ds2404_write_byte(dev, es); | ||
190 | |||
191 | gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio); | ||
192 | while (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio)) | ||
193 | ; | ||
194 | } | ||
195 | |||
196 | static void ds2404_enable_osc(struct device *dev) | ||
197 | { | ||
198 | u8 in[1] = { 0x10 }; /* enable oscillator */ | ||
199 | ds2404_write_memory(dev, 0x201, 1, in); | ||
200 | } | ||
201 | |||
202 | static int ds2404_read_time(struct device *dev, struct rtc_time *dt) | ||
203 | { | ||
204 | unsigned long time = 0; | ||
205 | |||
206 | ds2404_read_memory(dev, 0x203, 4, (u8 *)&time); | ||
207 | time = le32_to_cpu(time); | ||
208 | |||
209 | rtc_time_to_tm(time, dt); | ||
210 | return rtc_valid_tm(dt); | ||
211 | } | ||
212 | |||
213 | static int ds2404_set_mmss(struct device *dev, unsigned long secs) | ||
214 | { | ||
215 | u32 time = cpu_to_le32(secs); | ||
216 | ds2404_write_memory(dev, 0x203, 4, (u8 *)&time); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static const struct rtc_class_ops ds2404_rtc_ops = { | ||
221 | .read_time = ds2404_read_time, | ||
222 | .set_mmss = ds2404_set_mmss, | ||
223 | }; | ||
224 | |||
225 | static int rtc_probe(struct platform_device *pdev) | ||
226 | { | ||
227 | struct ds2404_platform_data *pdata = pdev->dev.platform_data; | ||
228 | struct ds2404 *chip; | ||
229 | int retval = -EBUSY; | ||
230 | |||
231 | chip = kzalloc(sizeof(struct ds2404), GFP_KERNEL); | ||
232 | if (!chip) | ||
233 | return -ENOMEM; | ||
234 | |||
235 | chip->ops = &ds2404_gpio_ops; | ||
236 | |||
237 | retval = chip->ops->map_io(chip, pdev, pdata); | ||
238 | if (retval) | ||
239 | goto err_chip; | ||
240 | |||
241 | dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n", | ||
242 | chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio, | ||
243 | chip->gpio[DS2404_DQ].gpio); | ||
244 | |||
245 | platform_set_drvdata(pdev, chip); | ||
246 | |||
247 | chip->rtc = rtc_device_register("ds2404", | ||
248 | &pdev->dev, &ds2404_rtc_ops, THIS_MODULE); | ||
249 | if (IS_ERR(chip->rtc)) { | ||
250 | retval = PTR_ERR(chip->rtc); | ||
251 | goto err_io; | ||
252 | } | ||
253 | |||
254 | ds2404_enable_osc(&pdev->dev); | ||
255 | return 0; | ||
256 | |||
257 | err_io: | ||
258 | chip->ops->unmap_io(chip); | ||
259 | err_chip: | ||
260 | kfree(chip); | ||
261 | return retval; | ||
262 | } | ||
263 | |||
264 | static int rtc_remove(struct platform_device *dev) | ||
265 | { | ||
266 | struct ds2404 *chip = platform_get_drvdata(dev); | ||
267 | struct rtc_device *rtc = chip->rtc; | ||
268 | |||
269 | if (rtc) | ||
270 | rtc_device_unregister(rtc); | ||
271 | |||
272 | chip->ops->unmap_io(chip); | ||
273 | kfree(chip); | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static struct platform_driver rtc_device_driver = { | ||
279 | .probe = rtc_probe, | ||
280 | .remove = rtc_remove, | ||
281 | .driver = { | ||
282 | .name = "ds2404", | ||
283 | .owner = THIS_MODULE, | ||
284 | }, | ||
285 | }; | ||
286 | |||
287 | static __init int ds2404_init(void) | ||
288 | { | ||
289 | return platform_driver_register(&rtc_device_driver); | ||
290 | } | ||
291 | |||
292 | static __exit void ds2404_exit(void) | ||
293 | { | ||
294 | platform_driver_unregister(&rtc_device_driver); | ||
295 | } | ||
296 | |||
297 | module_init(ds2404_init); | ||
298 | module_exit(ds2404_exit); | ||
299 | |||
300 | MODULE_DESCRIPTION("DS2404 RTC"); | ||
301 | MODULE_AUTHOR("Sven Schnelle"); | ||
302 | MODULE_LICENSE("GPL"); | ||
303 | MODULE_ALIAS("platform:ds2404"); | ||
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index 0104ea7ebe50..f6c24ce35d36 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c | |||
@@ -49,8 +49,17 @@ static int em3027_get_time(struct device *dev, struct rtc_time *tm) | |||
49 | unsigned char buf[7]; | 49 | unsigned char buf[7]; |
50 | 50 | ||
51 | struct i2c_msg msgs[] = { | 51 | struct i2c_msg msgs[] = { |
52 | {client->addr, 0, 1, &addr}, /* setup read addr */ | 52 | {/* setup read addr */ |
53 | {client->addr, I2C_M_RD, 7, buf}, /* read time/date */ | 53 | .addr = client->addr, |
54 | .len = 1, | ||
55 | .buf = &addr | ||
56 | }, | ||
57 | {/* read time/date */ | ||
58 | .addr = client->addr, | ||
59 | .flags = I2C_M_RD, | ||
60 | .len = 7, | ||
61 | .buf = buf | ||
62 | }, | ||
54 | }; | 63 | }; |
55 | 64 | ||
56 | /* read time/date registers */ | 65 | /* read time/date registers */ |
@@ -76,7 +85,9 @@ static int em3027_set_time(struct device *dev, struct rtc_time *tm) | |||
76 | unsigned char buf[8]; | 85 | unsigned char buf[8]; |
77 | 86 | ||
78 | struct i2c_msg msg = { | 87 | struct i2c_msg msg = { |
79 | client->addr, 0, 8, buf, /* write time/date */ | 88 | .addr = client->addr, |
89 | .len = 8, | ||
90 | .buf = buf, /* write time/date */ | ||
80 | }; | 91 | }; |
81 | 92 | ||
82 | buf[0] = EM3027_REG_WATCH_SEC; | 93 | buf[0] = EM3027_REG_WATCH_SEC; |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index dd2aeee6c66a..26c81f233606 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -68,9 +68,17 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], | |||
68 | { | 68 | { |
69 | u8 reg_addr[1] = { reg }; | 69 | u8 reg_addr[1] = { reg }; |
70 | struct i2c_msg msgs[2] = { | 70 | struct i2c_msg msgs[2] = { |
71 | {client->addr, 0, sizeof(reg_addr), reg_addr} | 71 | { |
72 | , | 72 | .addr = client->addr, |
73 | {client->addr, I2C_M_RD, len, buf} | 73 | .len = sizeof(reg_addr), |
74 | .buf = reg_addr | ||
75 | }, | ||
76 | { | ||
77 | .addr = client->addr, | ||
78 | .flags = I2C_M_RD, | ||
79 | .len = len, | ||
80 | .buf = buf | ||
81 | } | ||
74 | }; | 82 | }; |
75 | int ret; | 83 | int ret; |
76 | 84 | ||
@@ -90,7 +98,11 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], | |||
90 | { | 98 | { |
91 | u8 i2c_buf[ISL1208_REG_USR2 + 2]; | 99 | u8 i2c_buf[ISL1208_REG_USR2 + 2]; |
92 | struct i2c_msg msgs[1] = { | 100 | struct i2c_msg msgs[1] = { |
93 | {client->addr, 0, len + 1, i2c_buf} | 101 | { |
102 | .addr = client->addr, | ||
103 | .len = len + 1, | ||
104 | .buf = i2c_buf | ||
105 | } | ||
94 | }; | 106 | }; |
95 | int ret; | 107 | int ret; |
96 | 108 | ||
@@ -697,6 +709,7 @@ isl1208_remove(struct i2c_client *client) | |||
697 | 709 | ||
698 | static const struct i2c_device_id isl1208_id[] = { | 710 | static const struct i2c_device_id isl1208_id[] = { |
699 | { "isl1208", 0 }, | 711 | { "isl1208", 0 }, |
712 | { "isl1218", 0 }, | ||
700 | { } | 713 | { } |
701 | }; | 714 | }; |
702 | MODULE_DEVICE_TABLE(i2c, isl1208_id); | 715 | MODULE_DEVICE_TABLE(i2c, isl1208_id); |
diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 05ab227eeff7..1224182d3eab 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c | |||
@@ -42,7 +42,7 @@ struct jz4740_rtc { | |||
42 | 42 | ||
43 | struct rtc_device *rtc; | 43 | struct rtc_device *rtc; |
44 | 44 | ||
45 | unsigned int irq; | 45 | int irq; |
46 | 46 | ||
47 | spinlock_t lock; | 47 | spinlock_t lock; |
48 | }; | 48 | }; |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 4e0f84af99a7..b885bcd08908 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -213,163 +213,14 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
213 | return m41t80_set_datetime(to_i2c_client(dev), tm); | 213 | return m41t80_set_datetime(to_i2c_client(dev), tm); |
214 | } | 214 | } |
215 | 215 | ||
216 | static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 216 | /* |
217 | { | 217 | * XXX - m41t80 alarm functionality is reported broken. |
218 | struct i2c_client *client = to_i2c_client(dev); | 218 | * until it is fixed, don't register alarm functions. |
219 | int rc; | 219 | */ |
220 | |||
221 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); | ||
222 | if (rc < 0) | ||
223 | goto err; | ||
224 | |||
225 | if (enabled) | ||
226 | rc |= M41T80_ALMON_AFE; | ||
227 | else | ||
228 | rc &= ~M41T80_ALMON_AFE; | ||
229 | |||
230 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) | ||
231 | goto err; | ||
232 | |||
233 | return 0; | ||
234 | err: | ||
235 | return -EIO; | ||
236 | } | ||
237 | |||
238 | static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
239 | { | ||
240 | struct i2c_client *client = to_i2c_client(dev); | ||
241 | u8 wbuf[1 + M41T80_ALARM_REG_SIZE]; | ||
242 | u8 *buf = &wbuf[1]; | ||
243 | u8 *reg = buf - M41T80_REG_ALARM_MON; | ||
244 | u8 dt_addr[1] = { M41T80_REG_ALARM_MON }; | ||
245 | struct i2c_msg msgs_in[] = { | ||
246 | { | ||
247 | .addr = client->addr, | ||
248 | .flags = 0, | ||
249 | .len = 1, | ||
250 | .buf = dt_addr, | ||
251 | }, | ||
252 | { | ||
253 | .addr = client->addr, | ||
254 | .flags = I2C_M_RD, | ||
255 | .len = M41T80_ALARM_REG_SIZE, | ||
256 | .buf = buf, | ||
257 | }, | ||
258 | }; | ||
259 | struct i2c_msg msgs[] = { | ||
260 | { | ||
261 | .addr = client->addr, | ||
262 | .flags = 0, | ||
263 | .len = 1 + M41T80_ALARM_REG_SIZE, | ||
264 | .buf = wbuf, | ||
265 | }, | ||
266 | }; | ||
267 | |||
268 | if (i2c_transfer(client->adapter, msgs_in, 2) < 0) { | ||
269 | dev_err(&client->dev, "read error\n"); | ||
270 | return -EIO; | ||
271 | } | ||
272 | reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE); | ||
273 | reg[M41T80_REG_ALARM_DAY] = 0; | ||
274 | reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80); | ||
275 | reg[M41T80_REG_ALARM_MIN] = 0; | ||
276 | reg[M41T80_REG_ALARM_SEC] = 0; | ||
277 | |||
278 | wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */ | ||
279 | reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ? | ||
280 | bin2bcd(t->time.tm_sec) : 0x80; | ||
281 | reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ? | ||
282 | bin2bcd(t->time.tm_min) : 0x80; | ||
283 | reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ? | ||
284 | bin2bcd(t->time.tm_hour) : 0x80; | ||
285 | reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ? | ||
286 | bin2bcd(t->time.tm_mday) : 0x80; | ||
287 | if (t->time.tm_mon >= 0) | ||
288 | reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1); | ||
289 | else | ||
290 | reg[M41T80_REG_ALARM_DAY] |= 0x40; | ||
291 | |||
292 | if (i2c_transfer(client->adapter, msgs, 1) != 1) { | ||
293 | dev_err(&client->dev, "write error\n"); | ||
294 | return -EIO; | ||
295 | } | ||
296 | |||
297 | if (t->enabled) { | ||
298 | reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE; | ||
299 | if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, | ||
300 | reg[M41T80_REG_ALARM_MON]) < 0) { | ||
301 | dev_err(&client->dev, "write error\n"); | ||
302 | return -EIO; | ||
303 | } | ||
304 | } | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) | ||
309 | { | ||
310 | struct i2c_client *client = to_i2c_client(dev); | ||
311 | u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */ | ||
312 | u8 dt_addr[1] = { M41T80_REG_ALARM_MON }; | ||
313 | u8 *reg = buf - M41T80_REG_ALARM_MON; | ||
314 | struct i2c_msg msgs[] = { | ||
315 | { | ||
316 | .addr = client->addr, | ||
317 | .flags = 0, | ||
318 | .len = 1, | ||
319 | .buf = dt_addr, | ||
320 | }, | ||
321 | { | ||
322 | .addr = client->addr, | ||
323 | .flags = I2C_M_RD, | ||
324 | .len = M41T80_ALARM_REG_SIZE + 1, | ||
325 | .buf = buf, | ||
326 | }, | ||
327 | }; | ||
328 | |||
329 | if (i2c_transfer(client->adapter, msgs, 2) < 0) { | ||
330 | dev_err(&client->dev, "read error\n"); | ||
331 | return -EIO; | ||
332 | } | ||
333 | t->time.tm_sec = -1; | ||
334 | t->time.tm_min = -1; | ||
335 | t->time.tm_hour = -1; | ||
336 | t->time.tm_mday = -1; | ||
337 | t->time.tm_mon = -1; | ||
338 | if (!(reg[M41T80_REG_ALARM_SEC] & 0x80)) | ||
339 | t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f); | ||
340 | if (!(reg[M41T80_REG_ALARM_MIN] & 0x80)) | ||
341 | t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f); | ||
342 | if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80)) | ||
343 | t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f); | ||
344 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x80)) | ||
345 | t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f); | ||
346 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x40)) | ||
347 | t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1; | ||
348 | t->time.tm_year = -1; | ||
349 | t->time.tm_wday = -1; | ||
350 | t->time.tm_yday = -1; | ||
351 | t->time.tm_isdst = -1; | ||
352 | t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE); | ||
353 | t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF); | ||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static struct rtc_class_ops m41t80_rtc_ops = { | 220 | static struct rtc_class_ops m41t80_rtc_ops = { |
358 | .read_time = m41t80_rtc_read_time, | 221 | .read_time = m41t80_rtc_read_time, |
359 | .set_time = m41t80_rtc_set_time, | 222 | .set_time = m41t80_rtc_set_time, |
360 | /* | ||
361 | * XXX - m41t80 alarm functionality is reported broken. | ||
362 | * until it is fixed, don't register alarm functions. | ||
363 | * | ||
364 | .read_alarm = m41t80_rtc_read_alarm, | ||
365 | .set_alarm = m41t80_rtc_set_alarm, | ||
366 | */ | ||
367 | .proc = m41t80_rtc_proc, | 223 | .proc = m41t80_rtc_proc, |
368 | /* | ||
369 | * See above comment on broken alarm | ||
370 | * | ||
371 | .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, | ||
372 | */ | ||
373 | }; | 224 | }; |
374 | 225 | ||
375 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) | 226 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) |
diff --git a/drivers/rtc/rtc-max8907.c b/drivers/rtc/rtc-max8907.c new file mode 100644 index 000000000000..e094ffa434f8 --- /dev/null +++ b/drivers/rtc/rtc-max8907.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX8907 | ||
3 | * | ||
4 | * Copyright (c) 2011-2012, NVIDIA Corporation. | ||
5 | * | ||
6 | * Based on drivers/rtc/rtc-max8925.c, | ||
7 | * Copyright (C) 2009-2010 Marvell International Ltd. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/bcd.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/mfd/max8907.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/rtc.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | enum { | ||
24 | RTC_SEC = 0, | ||
25 | RTC_MIN, | ||
26 | RTC_HOUR, | ||
27 | RTC_WEEKDAY, | ||
28 | RTC_DATE, | ||
29 | RTC_MONTH, | ||
30 | RTC_YEAR1, | ||
31 | RTC_YEAR2, | ||
32 | }; | ||
33 | |||
34 | #define TIME_NUM 8 | ||
35 | #define ALARM_1SEC (1 << 7) | ||
36 | #define HOUR_12 (1 << 7) | ||
37 | #define HOUR_AM_PM (1 << 5) | ||
38 | #define ALARM0_IRQ (1 << 3) | ||
39 | #define ALARM1_IRQ (1 << 2) | ||
40 | #define ALARM0_STATUS (1 << 2) | ||
41 | #define ALARM1_STATUS (1 << 1) | ||
42 | |||
43 | struct max8907_rtc { | ||
44 | struct max8907 *max8907; | ||
45 | struct regmap *regmap; | ||
46 | struct rtc_device *rtc_dev; | ||
47 | int irq; | ||
48 | }; | ||
49 | |||
50 | static irqreturn_t max8907_irq_handler(int irq, void *data) | ||
51 | { | ||
52 | struct max8907_rtc *rtc = data; | ||
53 | |||
54 | regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0); | ||
55 | |||
56 | rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
57 | |||
58 | return IRQ_HANDLED; | ||
59 | } | ||
60 | |||
61 | static void regs_to_tm(u8 *regs, struct rtc_time *tm) | ||
62 | { | ||
63 | tm->tm_year = bcd2bin(regs[RTC_YEAR2]) * 100 + | ||
64 | bcd2bin(regs[RTC_YEAR1]) - 1900; | ||
65 | tm->tm_mon = bcd2bin(regs[RTC_MONTH] & 0x1f) - 1; | ||
66 | tm->tm_mday = bcd2bin(regs[RTC_DATE] & 0x3f); | ||
67 | tm->tm_wday = (regs[RTC_WEEKDAY] & 0x07) - 1; | ||
68 | if (regs[RTC_HOUR] & HOUR_12) { | ||
69 | tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x01f); | ||
70 | if (tm->tm_hour == 12) | ||
71 | tm->tm_hour = 0; | ||
72 | if (regs[RTC_HOUR] & HOUR_AM_PM) | ||
73 | tm->tm_hour += 12; | ||
74 | } else { | ||
75 | tm->tm_hour = bcd2bin(regs[RTC_HOUR] & 0x03f); | ||
76 | } | ||
77 | tm->tm_min = bcd2bin(regs[RTC_MIN] & 0x7f); | ||
78 | tm->tm_sec = bcd2bin(regs[RTC_SEC] & 0x7f); | ||
79 | } | ||
80 | |||
81 | static void tm_to_regs(struct rtc_time *tm, u8 *regs) | ||
82 | { | ||
83 | u8 high, low; | ||
84 | |||
85 | high = (tm->tm_year + 1900) / 100; | ||
86 | low = tm->tm_year % 100; | ||
87 | regs[RTC_YEAR2] = bin2bcd(high); | ||
88 | regs[RTC_YEAR1] = bin2bcd(low); | ||
89 | regs[RTC_MONTH] = bin2bcd(tm->tm_mon + 1); | ||
90 | regs[RTC_DATE] = bin2bcd(tm->tm_mday); | ||
91 | regs[RTC_WEEKDAY] = tm->tm_wday + 1; | ||
92 | regs[RTC_HOUR] = bin2bcd(tm->tm_hour); | ||
93 | regs[RTC_MIN] = bin2bcd(tm->tm_min); | ||
94 | regs[RTC_SEC] = bin2bcd(tm->tm_sec); | ||
95 | } | ||
96 | |||
97 | static int max8907_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
98 | { | ||
99 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
100 | u8 regs[TIME_NUM]; | ||
101 | int ret; | ||
102 | |||
103 | ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_RTC_SEC, regs, | ||
104 | TIME_NUM); | ||
105 | if (ret < 0) | ||
106 | return ret; | ||
107 | |||
108 | regs_to_tm(regs, tm); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int max8907_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
114 | { | ||
115 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
116 | u8 regs[TIME_NUM]; | ||
117 | |||
118 | tm_to_regs(tm, regs); | ||
119 | |||
120 | return regmap_bulk_write(rtc->regmap, MAX8907_REG_RTC_SEC, regs, | ||
121 | TIME_NUM); | ||
122 | } | ||
123 | |||
124 | static int max8907_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
125 | { | ||
126 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
127 | u8 regs[TIME_NUM]; | ||
128 | unsigned int val; | ||
129 | int ret; | ||
130 | |||
131 | ret = regmap_bulk_read(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs, | ||
132 | TIME_NUM); | ||
133 | if (ret < 0) | ||
134 | return ret; | ||
135 | |||
136 | regs_to_tm(regs, &alrm->time); | ||
137 | |||
138 | ret = regmap_read(rtc->regmap, MAX8907_REG_ALARM0_CNTL, &val); | ||
139 | if (ret < 0) | ||
140 | return ret; | ||
141 | |||
142 | alrm->enabled = !!(val & 0x7f); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int max8907_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
148 | { | ||
149 | struct max8907_rtc *rtc = dev_get_drvdata(dev); | ||
150 | u8 regs[TIME_NUM]; | ||
151 | int ret; | ||
152 | |||
153 | tm_to_regs(&alrm->time, regs); | ||
154 | |||
155 | /* Disable alarm while we update the target time */ | ||
156 | ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, 0x7f, 0); | ||
157 | if (ret < 0) | ||
158 | return ret; | ||
159 | |||
160 | ret = regmap_bulk_write(rtc->regmap, MAX8907_REG_ALARM0_SEC, regs, | ||
161 | TIME_NUM); | ||
162 | if (ret < 0) | ||
163 | return ret; | ||
164 | |||
165 | if (alrm->enabled) | ||
166 | ret = regmap_update_bits(rtc->regmap, MAX8907_REG_ALARM0_CNTL, | ||
167 | 0x7f, 0x7f); | ||
168 | |||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | static const struct rtc_class_ops max8907_rtc_ops = { | ||
173 | .read_time = max8907_rtc_read_time, | ||
174 | .set_time = max8907_rtc_set_time, | ||
175 | .read_alarm = max8907_rtc_read_alarm, | ||
176 | .set_alarm = max8907_rtc_set_alarm, | ||
177 | }; | ||
178 | |||
179 | static int __devinit max8907_rtc_probe(struct platform_device *pdev) | ||
180 | { | ||
181 | struct max8907 *max8907 = dev_get_drvdata(pdev->dev.parent); | ||
182 | struct max8907_rtc *rtc; | ||
183 | int ret; | ||
184 | |||
185 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
186 | if (!rtc) | ||
187 | return -ENOMEM; | ||
188 | platform_set_drvdata(pdev, rtc); | ||
189 | |||
190 | rtc->max8907 = max8907; | ||
191 | rtc->regmap = max8907->regmap_rtc; | ||
192 | |||
193 | rtc->rtc_dev = rtc_device_register("max8907-rtc", &pdev->dev, | ||
194 | &max8907_rtc_ops, THIS_MODULE); | ||
195 | if (IS_ERR(rtc->rtc_dev)) { | ||
196 | ret = PTR_ERR(rtc->rtc_dev); | ||
197 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | rtc->irq = regmap_irq_get_virq(max8907->irqc_rtc, | ||
202 | MAX8907_IRQ_RTC_ALARM0); | ||
203 | if (rtc->irq < 0) { | ||
204 | ret = rtc->irq; | ||
205 | goto err_unregister; | ||
206 | } | ||
207 | |||
208 | ret = request_threaded_irq(rtc->irq, NULL, max8907_irq_handler, | ||
209 | IRQF_ONESHOT, "max8907-alarm0", rtc); | ||
210 | if (ret < 0) { | ||
211 | dev_err(&pdev->dev, "Failed to request IRQ%d: %d\n", | ||
212 | rtc->irq, ret); | ||
213 | goto err_unregister; | ||
214 | } | ||
215 | |||
216 | return 0; | ||
217 | |||
218 | err_unregister: | ||
219 | rtc_device_unregister(rtc->rtc_dev); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int __devexit max8907_rtc_remove(struct platform_device *pdev) | ||
224 | { | ||
225 | struct max8907_rtc *rtc = platform_get_drvdata(pdev); | ||
226 | |||
227 | free_irq(rtc->irq, rtc); | ||
228 | rtc_device_unregister(rtc->rtc_dev); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static struct platform_driver max8907_rtc_driver = { | ||
234 | .driver = { | ||
235 | .name = "max8907-rtc", | ||
236 | .owner = THIS_MODULE, | ||
237 | }, | ||
238 | .probe = max8907_rtc_probe, | ||
239 | .remove = __devexit_p(max8907_rtc_remove), | ||
240 | }; | ||
241 | module_platform_driver(max8907_rtc_driver); | ||
242 | |||
243 | MODULE_DESCRIPTION("Maxim MAX8907 RTC driver"); | ||
244 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index e3e50d69baf8..cd0106293a49 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c | |||
@@ -343,7 +343,7 @@ static struct rtc_class_ops mxc_rtc_ops = { | |||
343 | .alarm_irq_enable = mxc_rtc_alarm_irq_enable, | 343 | .alarm_irq_enable = mxc_rtc_alarm_irq_enable, |
344 | }; | 344 | }; |
345 | 345 | ||
346 | static int __init mxc_rtc_probe(struct platform_device *pdev) | 346 | static int __devinit mxc_rtc_probe(struct platform_device *pdev) |
347 | { | 347 | { |
348 | struct resource *res; | 348 | struct resource *res; |
349 | struct rtc_device *rtc; | 349 | struct rtc_device *rtc; |
@@ -367,14 +367,14 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
367 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, | 367 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, |
368 | resource_size(res)); | 368 | resource_size(res)); |
369 | 369 | ||
370 | pdata->clk = clk_get(&pdev->dev, "rtc"); | 370 | pdata->clk = devm_clk_get(&pdev->dev, NULL); |
371 | if (IS_ERR(pdata->clk)) { | 371 | if (IS_ERR(pdata->clk)) { |
372 | dev_err(&pdev->dev, "unable to get clock!\n"); | 372 | dev_err(&pdev->dev, "unable to get clock!\n"); |
373 | ret = PTR_ERR(pdata->clk); | 373 | ret = PTR_ERR(pdata->clk); |
374 | goto exit_free_pdata; | 374 | goto exit_free_pdata; |
375 | } | 375 | } |
376 | 376 | ||
377 | clk_enable(pdata->clk); | 377 | clk_prepare_enable(pdata->clk); |
378 | rate = clk_get_rate(pdata->clk); | 378 | rate = clk_get_rate(pdata->clk); |
379 | 379 | ||
380 | if (rate == 32768) | 380 | if (rate == 32768) |
@@ -426,22 +426,20 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
426 | exit_clr_drvdata: | 426 | exit_clr_drvdata: |
427 | platform_set_drvdata(pdev, NULL); | 427 | platform_set_drvdata(pdev, NULL); |
428 | exit_put_clk: | 428 | exit_put_clk: |
429 | clk_disable(pdata->clk); | 429 | clk_disable_unprepare(pdata->clk); |
430 | clk_put(pdata->clk); | ||
431 | 430 | ||
432 | exit_free_pdata: | 431 | exit_free_pdata: |
433 | 432 | ||
434 | return ret; | 433 | return ret; |
435 | } | 434 | } |
436 | 435 | ||
437 | static int __exit mxc_rtc_remove(struct platform_device *pdev) | 436 | static int __devexit mxc_rtc_remove(struct platform_device *pdev) |
438 | { | 437 | { |
439 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 438 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
440 | 439 | ||
441 | rtc_device_unregister(pdata->rtc); | 440 | rtc_device_unregister(pdata->rtc); |
442 | 441 | ||
443 | clk_disable(pdata->clk); | 442 | clk_disable_unprepare(pdata->clk); |
444 | clk_put(pdata->clk); | ||
445 | platform_set_drvdata(pdev, NULL); | 443 | platform_set_drvdata(pdev, NULL); |
446 | 444 | ||
447 | return 0; | 445 | return 0; |
@@ -482,21 +480,11 @@ static struct platform_driver mxc_rtc_driver = { | |||
482 | #endif | 480 | #endif |
483 | .owner = THIS_MODULE, | 481 | .owner = THIS_MODULE, |
484 | }, | 482 | }, |
485 | .remove = __exit_p(mxc_rtc_remove), | 483 | .probe = mxc_rtc_probe, |
484 | .remove = __devexit_p(mxc_rtc_remove), | ||
486 | }; | 485 | }; |
487 | 486 | ||
488 | static int __init mxc_rtc_init(void) | 487 | module_platform_driver(mxc_rtc_driver) |
489 | { | ||
490 | return platform_driver_probe(&mxc_rtc_driver, mxc_rtc_probe); | ||
491 | } | ||
492 | |||
493 | static void __exit mxc_rtc_exit(void) | ||
494 | { | ||
495 | platform_driver_unregister(&mxc_rtc_driver); | ||
496 | } | ||
497 | |||
498 | module_init(mxc_rtc_init); | ||
499 | module_exit(mxc_rtc_exit); | ||
500 | 488 | ||
501 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 489 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
502 | MODULE_DESCRIPTION("RTC driver for Freescale MXC"); | 490 | MODULE_DESCRIPTION("RTC driver for Freescale MXC"); |
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index c2fe426a6ef2..98e3a2b681e6 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -78,8 +78,17 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
78 | unsigned char buf[13] = { PCF8563_REG_ST1 }; | 78 | unsigned char buf[13] = { PCF8563_REG_ST1 }; |
79 | 79 | ||
80 | struct i2c_msg msgs[] = { | 80 | struct i2c_msg msgs[] = { |
81 | { client->addr, 0, 1, buf }, /* setup read ptr */ | 81 | {/* setup read ptr */ |
82 | { client->addr, I2C_M_RD, 13, buf }, /* read status + date */ | 82 | .addr = client->addr, |
83 | .len = 1, | ||
84 | .buf = buf | ||
85 | }, | ||
86 | {/* read status + date */ | ||
87 | .addr = client->addr, | ||
88 | .flags = I2C_M_RD, | ||
89 | .len = 13, | ||
90 | .buf = buf | ||
91 | }, | ||
83 | }; | 92 | }; |
84 | 93 | ||
85 | /* read registers */ | 94 | /* read registers */ |
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 0a59fda5c09d..e96236ac2e78 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -18,6 +18,26 @@ | |||
18 | 18 | ||
19 | #include "rtc-core.h" | 19 | #include "rtc-core.h" |
20 | 20 | ||
21 | #define NAME_SIZE 10 | ||
22 | |||
23 | #if defined(CONFIG_RTC_HCTOSYS_DEVICE) | ||
24 | static bool is_rtc_hctosys(struct rtc_device *rtc) | ||
25 | { | ||
26 | int size; | ||
27 | char name[NAME_SIZE]; | ||
28 | |||
29 | size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id); | ||
30 | if (size > NAME_SIZE) | ||
31 | return false; | ||
32 | |||
33 | return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE); | ||
34 | } | ||
35 | #else | ||
36 | static bool is_rtc_hctosys(struct rtc_device *rtc) | ||
37 | { | ||
38 | return (rtc->id == 0); | ||
39 | } | ||
40 | #endif | ||
21 | 41 | ||
22 | static int rtc_proc_show(struct seq_file *seq, void *offset) | 42 | static int rtc_proc_show(struct seq_file *seq, void *offset) |
23 | { | 43 | { |
@@ -117,12 +137,12 @@ static const struct file_operations rtc_proc_fops = { | |||
117 | 137 | ||
118 | void rtc_proc_add_device(struct rtc_device *rtc) | 138 | void rtc_proc_add_device(struct rtc_device *rtc) |
119 | { | 139 | { |
120 | if (rtc->id == 0) | 140 | if (is_rtc_hctosys(rtc)) |
121 | proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc); | 141 | proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc); |
122 | } | 142 | } |
123 | 143 | ||
124 | void rtc_proc_del_device(struct rtc_device *rtc) | 144 | void rtc_proc_del_device(struct rtc_device *rtc) |
125 | { | 145 | { |
126 | if (rtc->id == 0) | 146 | if (is_rtc_hctosys(rtc)) |
127 | remove_proc_entry("driver/rtc", NULL); | 147 | remove_proc_entry("driver/rtc", NULL); |
128 | } | 148 | } |
diff --git a/drivers/rtc/rtc-rc5t583.c b/drivers/rtc/rtc-rc5t583.c new file mode 100644 index 000000000000..cdb140c29c56 --- /dev/null +++ b/drivers/rtc/rtc-rc5t583.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* | ||
2 | * rtc-rc5t583.c -- RICOH RC5T583 Real Time Clock | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * Author: Venu Byravarasu <vbyravarasu@nvidia.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/rtc.h> | ||
25 | #include <linux/bcd.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/mfd/rc5t583.h> | ||
29 | |||
30 | struct rc5t583_rtc { | ||
31 | struct rtc_device *rtc; | ||
32 | /* To store the list of enabled interrupts, during system suspend */ | ||
33 | u32 irqen; | ||
34 | }; | ||
35 | |||
36 | /* Total number of RTC registers needed to set time*/ | ||
37 | #define NUM_TIME_REGS (RC5T583_RTC_YEAR - RC5T583_RTC_SEC + 1) | ||
38 | |||
39 | /* Total number of RTC registers needed to set Y-Alarm*/ | ||
40 | #define NUM_YAL_REGS (RC5T583_RTC_AY_YEAR - RC5T583_RTC_AY_MIN + 1) | ||
41 | |||
42 | /* Set Y-Alarm interrupt */ | ||
43 | #define SET_YAL BIT(5) | ||
44 | |||
45 | /* Get Y-Alarm interrupt status*/ | ||
46 | #define GET_YAL_STATUS BIT(3) | ||
47 | |||
48 | static int rc5t583_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | ||
49 | { | ||
50 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
51 | u8 val; | ||
52 | |||
53 | /* Set Y-Alarm, based on 'enabled' */ | ||
54 | val = enabled ? SET_YAL : 0; | ||
55 | |||
56 | return regmap_update_bits(rc5t583->regmap, RC5T583_RTC_CTL1, SET_YAL, | ||
57 | val); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * Gets current rc5t583 RTC time and date parameters. | ||
62 | * | ||
63 | * The RTC's time/alarm representation is not what gmtime(3) requires | ||
64 | * Linux to use: | ||
65 | * | ||
66 | * - Months are 1..12 vs Linux 0-11 | ||
67 | * - Years are 0..99 vs Linux 1900..N (we assume 21st century) | ||
68 | */ | ||
69 | static int rc5t583_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
70 | { | ||
71 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
72 | u8 rtc_data[NUM_TIME_REGS]; | ||
73 | int ret; | ||
74 | |||
75 | ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data, | ||
76 | NUM_TIME_REGS); | ||
77 | if (ret < 0) { | ||
78 | dev_err(dev, "RTC read time failed with err:%d\n", ret); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | tm->tm_sec = bcd2bin(rtc_data[0]); | ||
83 | tm->tm_min = bcd2bin(rtc_data[1]); | ||
84 | tm->tm_hour = bcd2bin(rtc_data[2]); | ||
85 | tm->tm_wday = bcd2bin(rtc_data[3]); | ||
86 | tm->tm_mday = bcd2bin(rtc_data[4]); | ||
87 | tm->tm_mon = bcd2bin(rtc_data[5]) - 1; | ||
88 | tm->tm_year = bcd2bin(rtc_data[6]) + 100; | ||
89 | |||
90 | return ret; | ||
91 | } | ||
92 | |||
93 | static int rc5t583_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
94 | { | ||
95 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
96 | unsigned char rtc_data[NUM_TIME_REGS]; | ||
97 | int ret; | ||
98 | |||
99 | rtc_data[0] = bin2bcd(tm->tm_sec); | ||
100 | rtc_data[1] = bin2bcd(tm->tm_min); | ||
101 | rtc_data[2] = bin2bcd(tm->tm_hour); | ||
102 | rtc_data[3] = bin2bcd(tm->tm_wday); | ||
103 | rtc_data[4] = bin2bcd(tm->tm_mday); | ||
104 | rtc_data[5] = bin2bcd(tm->tm_mon + 1); | ||
105 | rtc_data[6] = bin2bcd(tm->tm_year - 100); | ||
106 | |||
107 | ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_SEC, rtc_data, | ||
108 | NUM_TIME_REGS); | ||
109 | if (ret < 0) { | ||
110 | dev_err(dev, "RTC set time failed with error %d\n", ret); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static int rc5t583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
118 | { | ||
119 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
120 | unsigned char alarm_data[NUM_YAL_REGS]; | ||
121 | u32 interrupt_enable; | ||
122 | int ret; | ||
123 | |||
124 | ret = regmap_bulk_read(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data, | ||
125 | NUM_YAL_REGS); | ||
126 | if (ret < 0) { | ||
127 | dev_err(dev, "rtc_read_alarm error %d\n", ret); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | alm->time.tm_min = bcd2bin(alarm_data[0]); | ||
132 | alm->time.tm_hour = bcd2bin(alarm_data[1]); | ||
133 | alm->time.tm_mday = bcd2bin(alarm_data[2]); | ||
134 | alm->time.tm_mon = bcd2bin(alarm_data[3]) - 1; | ||
135 | alm->time.tm_year = bcd2bin(alarm_data[4]) + 100; | ||
136 | |||
137 | ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, &interrupt_enable); | ||
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | |||
141 | /* check if YALE is set */ | ||
142 | if (interrupt_enable & SET_YAL) | ||
143 | alm->enabled = 1; | ||
144 | |||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | static int rc5t583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
149 | { | ||
150 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
151 | unsigned char alarm_data[NUM_YAL_REGS]; | ||
152 | int ret; | ||
153 | |||
154 | ret = rc5t583_rtc_alarm_irq_enable(dev, 0); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
158 | alarm_data[0] = bin2bcd(alm->time.tm_min); | ||
159 | alarm_data[1] = bin2bcd(alm->time.tm_hour); | ||
160 | alarm_data[2] = bin2bcd(alm->time.tm_mday); | ||
161 | alarm_data[3] = bin2bcd(alm->time.tm_mon + 1); | ||
162 | alarm_data[4] = bin2bcd(alm->time.tm_year - 100); | ||
163 | |||
164 | ret = regmap_bulk_write(rc5t583->regmap, RC5T583_RTC_AY_MIN, alarm_data, | ||
165 | NUM_YAL_REGS); | ||
166 | if (ret) { | ||
167 | dev_err(dev, "rtc_set_alarm error %d\n", ret); | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | if (alm->enabled) | ||
172 | ret = rc5t583_rtc_alarm_irq_enable(dev, 1); | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | static irqreturn_t rc5t583_rtc_interrupt(int irq, void *rtc) | ||
178 | { | ||
179 | struct device *dev = rtc; | ||
180 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
181 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); | ||
182 | unsigned long events = 0; | ||
183 | int ret; | ||
184 | u32 rtc_reg; | ||
185 | |||
186 | ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL2, &rtc_reg); | ||
187 | if (ret < 0) | ||
188 | return IRQ_NONE; | ||
189 | |||
190 | if (rtc_reg & GET_YAL_STATUS) { | ||
191 | events = RTC_IRQF | RTC_AF; | ||
192 | /* clear pending Y-alarm interrupt bit */ | ||
193 | rtc_reg &= ~GET_YAL_STATUS; | ||
194 | } | ||
195 | |||
196 | ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, rtc_reg); | ||
197 | if (ret) | ||
198 | return IRQ_NONE; | ||
199 | |||
200 | /* Notify RTC core on event */ | ||
201 | rtc_update_irq(rc5t583_rtc->rtc, 1, events); | ||
202 | |||
203 | return IRQ_HANDLED; | ||
204 | } | ||
205 | |||
206 | static const struct rtc_class_ops rc5t583_rtc_ops = { | ||
207 | .read_time = rc5t583_rtc_read_time, | ||
208 | .set_time = rc5t583_rtc_set_time, | ||
209 | .read_alarm = rc5t583_rtc_read_alarm, | ||
210 | .set_alarm = rc5t583_rtc_set_alarm, | ||
211 | .alarm_irq_enable = rc5t583_rtc_alarm_irq_enable, | ||
212 | }; | ||
213 | |||
214 | static int __devinit rc5t583_rtc_probe(struct platform_device *pdev) | ||
215 | { | ||
216 | struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent); | ||
217 | struct rc5t583_rtc *ricoh_rtc; | ||
218 | struct rc5t583_platform_data *pmic_plat_data; | ||
219 | int ret; | ||
220 | int irq; | ||
221 | |||
222 | ricoh_rtc = devm_kzalloc(&pdev->dev, sizeof(struct rc5t583_rtc), | ||
223 | GFP_KERNEL); | ||
224 | if (!ricoh_rtc) | ||
225 | return -ENOMEM; | ||
226 | |||
227 | platform_set_drvdata(pdev, ricoh_rtc); | ||
228 | |||
229 | /* Clear pending interrupts */ | ||
230 | ret = regmap_write(rc5t583->regmap, RC5T583_RTC_CTL2, 0); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | |||
234 | /* clear RTC Adjust register */ | ||
235 | ret = regmap_write(rc5t583->regmap, RC5T583_RTC_ADJ, 0); | ||
236 | if (ret < 0) { | ||
237 | dev_err(&pdev->dev, "unable to program rtc_adjust reg\n"); | ||
238 | return -EBUSY; | ||
239 | } | ||
240 | |||
241 | pmic_plat_data = dev_get_platdata(rc5t583->dev); | ||
242 | irq = pmic_plat_data->irq_base; | ||
243 | if (irq <= 0) { | ||
244 | dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", | ||
245 | irq); | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | irq += RC5T583_IRQ_YALE; | ||
250 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
251 | rc5t583_rtc_interrupt, IRQF_TRIGGER_LOW, | ||
252 | "rtc-rc5t583", &pdev->dev); | ||
253 | if (ret < 0) { | ||
254 | dev_err(&pdev->dev, "IRQ is not free.\n"); | ||
255 | return ret; | ||
256 | } | ||
257 | device_init_wakeup(&pdev->dev, 1); | ||
258 | |||
259 | ricoh_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
260 | &rc5t583_rtc_ops, THIS_MODULE); | ||
261 | if (IS_ERR(ricoh_rtc->rtc)) { | ||
262 | ret = PTR_ERR(ricoh_rtc->rtc); | ||
263 | dev_err(&pdev->dev, "RTC device register: err %d\n", ret); | ||
264 | return ret; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Disable rc5t583 RTC interrupts. | ||
272 | * Sets status flag to free. | ||
273 | */ | ||
274 | static int __devexit rc5t583_rtc_remove(struct platform_device *pdev) | ||
275 | { | ||
276 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(&pdev->dev); | ||
277 | |||
278 | rc5t583_rtc_alarm_irq_enable(&rc5t583_rtc->rtc->dev, 0); | ||
279 | |||
280 | rtc_device_unregister(rc5t583_rtc->rtc); | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | #ifdef CONFIG_PM_SLEEP | ||
285 | |||
286 | static int rc5t583_rtc_suspend(struct device *dev) | ||
287 | { | ||
288 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
289 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); | ||
290 | int ret; | ||
291 | |||
292 | /* Store current list of enabled interrupts*/ | ||
293 | ret = regmap_read(rc5t583->regmap, RC5T583_RTC_CTL1, | ||
294 | &rc5t583_rtc->irqen); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | static int rc5t583_rtc_resume(struct device *dev) | ||
299 | { | ||
300 | struct rc5t583 *rc5t583 = dev_get_drvdata(dev->parent); | ||
301 | struct rc5t583_rtc *rc5t583_rtc = dev_get_drvdata(dev); | ||
302 | |||
303 | /* Restore list of enabled interrupts before suspend */ | ||
304 | return regmap_write(rc5t583->regmap, RC5T583_RTC_CTL1, | ||
305 | rc5t583_rtc->irqen); | ||
306 | } | ||
307 | |||
308 | static const struct dev_pm_ops rc5t583_rtc_pm_ops = { | ||
309 | .suspend = rc5t583_rtc_suspend, | ||
310 | .resume = rc5t583_rtc_resume, | ||
311 | }; | ||
312 | |||
313 | #define DEV_PM_OPS (&rc5t583_rtc_pm_ops) | ||
314 | #else | ||
315 | #define DEV_PM_OPS NULL | ||
316 | #endif | ||
317 | |||
318 | static struct platform_driver rc5t583_rtc_driver = { | ||
319 | .probe = rc5t583_rtc_probe, | ||
320 | .remove = __devexit_p(rc5t583_rtc_remove), | ||
321 | .driver = { | ||
322 | .owner = THIS_MODULE, | ||
323 | .name = "rtc-rc5t583", | ||
324 | .pm = DEV_PM_OPS, | ||
325 | }, | ||
326 | }; | ||
327 | |||
328 | module_platform_driver(rc5t583_rtc_driver); | ||
329 | MODULE_ALIAS("platform:rtc-rc5t583"); | ||
330 | MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); | ||
331 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index fb4842c3544e..76f565ae384d 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -104,7 +104,12 @@ static int rs5c_get_regs(struct rs5c372 *rs5c) | |||
104 | { | 104 | { |
105 | struct i2c_client *client = rs5c->client; | 105 | struct i2c_client *client = rs5c->client; |
106 | struct i2c_msg msgs[] = { | 106 | struct i2c_msg msgs[] = { |
107 | { client->addr, I2C_M_RD, sizeof rs5c->buf, rs5c->buf }, | 107 | { |
108 | .addr = client->addr, | ||
109 | .flags = I2C_M_RD, | ||
110 | .len = sizeof(rs5c->buf), | ||
111 | .buf = rs5c->buf | ||
112 | }, | ||
108 | }; | 113 | }; |
109 | 114 | ||
110 | /* This implements the third reading method from the datasheet, using | 115 | /* This implements the third reading method from the datasheet, using |
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index c9562ceedef3..8a092325188d 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #define S35390A_CMD_STATUS1 0 | 19 | #define S35390A_CMD_STATUS1 0 |
20 | #define S35390A_CMD_STATUS2 1 | 20 | #define S35390A_CMD_STATUS2 1 |
21 | #define S35390A_CMD_TIME1 2 | 21 | #define S35390A_CMD_TIME1 2 |
22 | #define S35390A_CMD_TIME2 3 | ||
23 | #define S35390A_CMD_INT2_REG1 5 | ||
22 | 24 | ||
23 | #define S35390A_BYTE_YEAR 0 | 25 | #define S35390A_BYTE_YEAR 0 |
24 | #define S35390A_BYTE_MONTH 1 | 26 | #define S35390A_BYTE_MONTH 1 |
@@ -28,12 +30,23 @@ | |||
28 | #define S35390A_BYTE_MINS 5 | 30 | #define S35390A_BYTE_MINS 5 |
29 | #define S35390A_BYTE_SECS 6 | 31 | #define S35390A_BYTE_SECS 6 |
30 | 32 | ||
33 | #define S35390A_ALRM_BYTE_WDAY 0 | ||
34 | #define S35390A_ALRM_BYTE_HOURS 1 | ||
35 | #define S35390A_ALRM_BYTE_MINS 2 | ||
36 | |||
31 | #define S35390A_FLAG_POC 0x01 | 37 | #define S35390A_FLAG_POC 0x01 |
32 | #define S35390A_FLAG_BLD 0x02 | 38 | #define S35390A_FLAG_BLD 0x02 |
33 | #define S35390A_FLAG_24H 0x40 | 39 | #define S35390A_FLAG_24H 0x40 |
34 | #define S35390A_FLAG_RESET 0x80 | 40 | #define S35390A_FLAG_RESET 0x80 |
35 | #define S35390A_FLAG_TEST 0x01 | 41 | #define S35390A_FLAG_TEST 0x01 |
36 | 42 | ||
43 | #define S35390A_INT2_MODE_MASK 0xF0 | ||
44 | |||
45 | #define S35390A_INT2_MODE_NOINTR 0x00 | ||
46 | #define S35390A_INT2_MODE_FREQ 0x10 | ||
47 | #define S35390A_INT2_MODE_ALARM 0x40 | ||
48 | #define S35390A_INT2_MODE_PMIN_EDG 0x20 | ||
49 | |||
37 | static const struct i2c_device_id s35390a_id[] = { | 50 | static const struct i2c_device_id s35390a_id[] = { |
38 | { "s35390a", 0 }, | 51 | { "s35390a", 0 }, |
39 | { } | 52 | { } |
@@ -50,7 +63,11 @@ static int s35390a_set_reg(struct s35390a *s35390a, int reg, char *buf, int len) | |||
50 | { | 63 | { |
51 | struct i2c_client *client = s35390a->client[reg]; | 64 | struct i2c_client *client = s35390a->client[reg]; |
52 | struct i2c_msg msg[] = { | 65 | struct i2c_msg msg[] = { |
53 | { client->addr, 0, len, buf }, | 66 | { |
67 | .addr = client->addr, | ||
68 | .len = len, | ||
69 | .buf = buf | ||
70 | }, | ||
54 | }; | 71 | }; |
55 | 72 | ||
56 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) | 73 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) |
@@ -63,7 +80,12 @@ static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) | |||
63 | { | 80 | { |
64 | struct i2c_client *client = s35390a->client[reg]; | 81 | struct i2c_client *client = s35390a->client[reg]; |
65 | struct i2c_msg msg[] = { | 82 | struct i2c_msg msg[] = { |
66 | { client->addr, I2C_M_RD, len, buf }, | 83 | { |
84 | .addr = client->addr, | ||
85 | .flags = I2C_M_RD, | ||
86 | .len = len, | ||
87 | .buf = buf | ||
88 | }, | ||
67 | }; | 89 | }; |
68 | 90 | ||
69 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) | 91 | if ((i2c_transfer(client->adapter, msg, 1)) != 1) |
@@ -184,6 +206,104 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
184 | return rtc_valid_tm(tm); | 206 | return rtc_valid_tm(tm); |
185 | } | 207 | } |
186 | 208 | ||
209 | static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | ||
210 | { | ||
211 | struct s35390a *s35390a = i2c_get_clientdata(client); | ||
212 | char buf[3], sts = 0; | ||
213 | int err, i; | ||
214 | |||
215 | dev_dbg(&client->dev, "%s: alm is secs=%d, mins=%d, hours=%d mday=%d, "\ | ||
216 | "mon=%d, year=%d, wday=%d\n", __func__, alm->time.tm_sec, | ||
217 | alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, | ||
218 | alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); | ||
219 | |||
220 | /* disable interrupt */ | ||
221 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | ||
222 | if (err < 0) | ||
223 | return err; | ||
224 | |||
225 | /* clear pending interrupt, if any */ | ||
226 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts)); | ||
227 | if (err < 0) | ||
228 | return err; | ||
229 | |||
230 | if (alm->enabled) | ||
231 | sts = S35390A_INT2_MODE_ALARM; | ||
232 | else | ||
233 | sts = S35390A_INT2_MODE_NOINTR; | ||
234 | |||
235 | /* This chip expects the bits of each byte to be in reverse order */ | ||
236 | sts = bitrev8(sts); | ||
237 | |||
238 | /* set interupt mode*/ | ||
239 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | ||
240 | if (err < 0) | ||
241 | return err; | ||
242 | |||
243 | if (alm->time.tm_wday != -1) | ||
244 | buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80; | ||
245 | |||
246 | buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a, | ||
247 | alm->time.tm_hour) | 0x80; | ||
248 | buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80; | ||
249 | |||
250 | if (alm->time.tm_hour >= 12) | ||
251 | buf[S35390A_ALRM_BYTE_HOURS] |= 0x40; | ||
252 | |||
253 | for (i = 0; i < 3; ++i) | ||
254 | buf[i] = bitrev8(buf[i]); | ||
255 | |||
256 | err = s35390a_set_reg(s35390a, S35390A_CMD_INT2_REG1, buf, | ||
257 | sizeof(buf)); | ||
258 | |||
259 | return err; | ||
260 | } | ||
261 | |||
262 | static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) | ||
263 | { | ||
264 | struct s35390a *s35390a = i2c_get_clientdata(client); | ||
265 | char buf[3], sts; | ||
266 | int i, err; | ||
267 | |||
268 | err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); | ||
269 | if (err < 0) | ||
270 | return err; | ||
271 | |||
272 | if (bitrev8(sts) != S35390A_INT2_MODE_ALARM) | ||
273 | return -EINVAL; | ||
274 | |||
275 | err = s35390a_get_reg(s35390a, S35390A_CMD_INT2_REG1, buf, sizeof(buf)); | ||
276 | if (err < 0) | ||
277 | return err; | ||
278 | |||
279 | /* This chip returns the bits of each byte in reverse order */ | ||
280 | for (i = 0; i < 3; ++i) { | ||
281 | buf[i] = bitrev8(buf[i]); | ||
282 | buf[i] &= ~0x80; | ||
283 | } | ||
284 | |||
285 | alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]); | ||
286 | alm->time.tm_hour = s35390a_reg2hr(s35390a, | ||
287 | buf[S35390A_ALRM_BYTE_HOURS]); | ||
288 | alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]); | ||
289 | |||
290 | dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n", | ||
291 | __func__, alm->time.tm_min, alm->time.tm_hour, | ||
292 | alm->time.tm_wday); | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
298 | { | ||
299 | return s35390a_read_alarm(to_i2c_client(dev), alm); | ||
300 | } | ||
301 | |||
302 | static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
303 | { | ||
304 | return s35390a_set_alarm(to_i2c_client(dev), alm); | ||
305 | } | ||
306 | |||
187 | static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) | 307 | static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) |
188 | { | 308 | { |
189 | return s35390a_get_datetime(to_i2c_client(dev), tm); | 309 | return s35390a_get_datetime(to_i2c_client(dev), tm); |
@@ -197,6 +317,9 @@ static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
197 | static const struct rtc_class_ops s35390a_rtc_ops = { | 317 | static const struct rtc_class_ops s35390a_rtc_ops = { |
198 | .read_time = s35390a_rtc_read_time, | 318 | .read_time = s35390a_rtc_read_time, |
199 | .set_time = s35390a_rtc_set_time, | 319 | .set_time = s35390a_rtc_set_time, |
320 | .set_alarm = s35390a_rtc_set_alarm, | ||
321 | .read_alarm = s35390a_rtc_read_alarm, | ||
322 | |||
200 | }; | 323 | }; |
201 | 324 | ||
202 | static struct i2c_driver s35390a_driver; | 325 | static struct i2c_driver s35390a_driver; |
@@ -261,6 +384,8 @@ static int s35390a_probe(struct i2c_client *client, | |||
261 | if (s35390a_get_datetime(client, &tm) < 0) | 384 | if (s35390a_get_datetime(client, &tm) < 0) |
262 | dev_warn(&client->dev, "clock needs to be set\n"); | 385 | dev_warn(&client->dev, "clock needs to be set\n"); |
263 | 386 | ||
387 | device_set_wakeup_capable(&client->dev, 1); | ||
388 | |||
264 | s35390a->rtc = rtc_device_register(s35390a_driver.driver.name, | 389 | s35390a->rtc = rtc_device_register(s35390a_driver.driver.name, |
265 | &client->dev, &s35390a_rtc_ops, THIS_MODULE); | 390 | &client->dev, &s35390a_rtc_ops, THIS_MODULE); |
266 | 391 | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index bfbd92c8d1c9..77823d21d314 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -476,13 +476,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) | |||
476 | s3c_rtc_tickno = platform_get_irq(pdev, 1); | 476 | s3c_rtc_tickno = platform_get_irq(pdev, 1); |
477 | if (s3c_rtc_tickno < 0) { | 477 | if (s3c_rtc_tickno < 0) { |
478 | dev_err(&pdev->dev, "no irq for rtc tick\n"); | 478 | dev_err(&pdev->dev, "no irq for rtc tick\n"); |
479 | return -ENOENT; | 479 | return s3c_rtc_tickno; |
480 | } | 480 | } |
481 | 481 | ||
482 | s3c_rtc_alarmno = platform_get_irq(pdev, 0); | 482 | s3c_rtc_alarmno = platform_get_irq(pdev, 0); |
483 | if (s3c_rtc_alarmno < 0) { | 483 | if (s3c_rtc_alarmno < 0) { |
484 | dev_err(&pdev->dev, "no irq for alarm\n"); | 484 | dev_err(&pdev->dev, "no irq for alarm\n"); |
485 | return -ENOENT; | 485 | return s3c_rtc_alarmno; |
486 | } | 486 | } |
487 | 487 | ||
488 | pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", | 488 | pr_debug("s3c2410_rtc: tick irq %d, alarm irq %d\n", |
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c new file mode 100644 index 000000000000..3c0da333f465 --- /dev/null +++ b/drivers/rtc/rtc-snvs.c | |||
@@ -0,0 +1,350 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * The code contained herein is licensed under the GNU General Public | ||
5 | * License. You may obtain a copy of the GNU General Public License | ||
6 | * Version 2 or later at the following locations: | ||
7 | * | ||
8 | * http://www.opensource.org/licenses/gpl-license.html | ||
9 | * http://www.gnu.org/copyleft/gpl.html | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/rtc.h> | ||
20 | |||
21 | /* These register offsets are relative to LP (Low Power) range */ | ||
22 | #define SNVS_LPCR 0x04 | ||
23 | #define SNVS_LPSR 0x18 | ||
24 | #define SNVS_LPSRTCMR 0x1c | ||
25 | #define SNVS_LPSRTCLR 0x20 | ||
26 | #define SNVS_LPTAR 0x24 | ||
27 | #define SNVS_LPPGDR 0x30 | ||
28 | |||
29 | #define SNVS_LPCR_SRTC_ENV (1 << 0) | ||
30 | #define SNVS_LPCR_LPTA_EN (1 << 1) | ||
31 | #define SNVS_LPCR_LPWUI_EN (1 << 3) | ||
32 | #define SNVS_LPSR_LPTA (1 << 0) | ||
33 | |||
34 | #define SNVS_LPPGDR_INIT 0x41736166 | ||
35 | #define CNTR_TO_SECS_SH 15 | ||
36 | |||
37 | struct snvs_rtc_data { | ||
38 | struct rtc_device *rtc; | ||
39 | void __iomem *ioaddr; | ||
40 | int irq; | ||
41 | spinlock_t lock; | ||
42 | }; | ||
43 | |||
44 | static u32 rtc_read_lp_counter(void __iomem *ioaddr) | ||
45 | { | ||
46 | u64 read1, read2; | ||
47 | |||
48 | do { | ||
49 | read1 = readl(ioaddr + SNVS_LPSRTCMR); | ||
50 | read1 <<= 32; | ||
51 | read1 |= readl(ioaddr + SNVS_LPSRTCLR); | ||
52 | |||
53 | read2 = readl(ioaddr + SNVS_LPSRTCMR); | ||
54 | read2 <<= 32; | ||
55 | read2 |= readl(ioaddr + SNVS_LPSRTCLR); | ||
56 | } while (read1 != read2); | ||
57 | |||
58 | /* Convert 47-bit counter to 32-bit raw second count */ | ||
59 | return (u32) (read1 >> CNTR_TO_SECS_SH); | ||
60 | } | ||
61 | |||
62 | static void rtc_write_sync_lp(void __iomem *ioaddr) | ||
63 | { | ||
64 | u32 count1, count2, count3; | ||
65 | int i; | ||
66 | |||
67 | /* Wait for 3 CKIL cycles */ | ||
68 | for (i = 0; i < 3; i++) { | ||
69 | do { | ||
70 | count1 = readl(ioaddr + SNVS_LPSRTCLR); | ||
71 | count2 = readl(ioaddr + SNVS_LPSRTCLR); | ||
72 | } while (count1 != count2); | ||
73 | |||
74 | /* Now wait until counter value changes */ | ||
75 | do { | ||
76 | do { | ||
77 | count2 = readl(ioaddr + SNVS_LPSRTCLR); | ||
78 | count3 = readl(ioaddr + SNVS_LPSRTCLR); | ||
79 | } while (count2 != count3); | ||
80 | } while (count3 == count1); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) | ||
85 | { | ||
86 | unsigned long flags; | ||
87 | int timeout = 1000; | ||
88 | u32 lpcr; | ||
89 | |||
90 | spin_lock_irqsave(&data->lock, flags); | ||
91 | |||
92 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
93 | if (enable) | ||
94 | lpcr |= SNVS_LPCR_SRTC_ENV; | ||
95 | else | ||
96 | lpcr &= ~SNVS_LPCR_SRTC_ENV; | ||
97 | writel(lpcr, data->ioaddr + SNVS_LPCR); | ||
98 | |||
99 | spin_unlock_irqrestore(&data->lock, flags); | ||
100 | |||
101 | while (--timeout) { | ||
102 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
103 | |||
104 | if (enable) { | ||
105 | if (lpcr & SNVS_LPCR_SRTC_ENV) | ||
106 | break; | ||
107 | } else { | ||
108 | if (!(lpcr & SNVS_LPCR_SRTC_ENV)) | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | if (!timeout) | ||
114 | return -ETIMEDOUT; | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
120 | { | ||
121 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
122 | unsigned long time = rtc_read_lp_counter(data->ioaddr); | ||
123 | |||
124 | rtc_time_to_tm(time, tm); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
130 | { | ||
131 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
132 | unsigned long time; | ||
133 | |||
134 | rtc_tm_to_time(tm, &time); | ||
135 | |||
136 | /* Disable RTC first */ | ||
137 | snvs_rtc_enable(data, false); | ||
138 | |||
139 | /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */ | ||
140 | writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR); | ||
141 | writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR); | ||
142 | |||
143 | /* Enable RTC again */ | ||
144 | snvs_rtc_enable(data, true); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
150 | { | ||
151 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
152 | u32 lptar, lpsr; | ||
153 | |||
154 | lptar = readl(data->ioaddr + SNVS_LPTAR); | ||
155 | rtc_time_to_tm(lptar, &alrm->time); | ||
156 | |||
157 | lpsr = readl(data->ioaddr + SNVS_LPSR); | ||
158 | alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) | ||
164 | { | ||
165 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
166 | u32 lpcr; | ||
167 | unsigned long flags; | ||
168 | |||
169 | spin_lock_irqsave(&data->lock, flags); | ||
170 | |||
171 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
172 | if (enable) | ||
173 | lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); | ||
174 | else | ||
175 | lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); | ||
176 | writel(lpcr, data->ioaddr + SNVS_LPCR); | ||
177 | |||
178 | spin_unlock_irqrestore(&data->lock, flags); | ||
179 | |||
180 | rtc_write_sync_lp(data->ioaddr); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
186 | { | ||
187 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
188 | struct rtc_time *alrm_tm = &alrm->time; | ||
189 | unsigned long time; | ||
190 | unsigned long flags; | ||
191 | u32 lpcr; | ||
192 | |||
193 | rtc_tm_to_time(alrm_tm, &time); | ||
194 | |||
195 | spin_lock_irqsave(&data->lock, flags); | ||
196 | |||
197 | /* Have to clear LPTA_EN before programming new alarm time in LPTAR */ | ||
198 | lpcr = readl(data->ioaddr + SNVS_LPCR); | ||
199 | lpcr &= ~SNVS_LPCR_LPTA_EN; | ||
200 | writel(lpcr, data->ioaddr + SNVS_LPCR); | ||
201 | |||
202 | spin_unlock_irqrestore(&data->lock, flags); | ||
203 | |||
204 | writel(time, data->ioaddr + SNVS_LPTAR); | ||
205 | |||
206 | /* Clear alarm interrupt status bit */ | ||
207 | writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR); | ||
208 | |||
209 | return snvs_rtc_alarm_irq_enable(dev, alrm->enabled); | ||
210 | } | ||
211 | |||
212 | static const struct rtc_class_ops snvs_rtc_ops = { | ||
213 | .read_time = snvs_rtc_read_time, | ||
214 | .set_time = snvs_rtc_set_time, | ||
215 | .read_alarm = snvs_rtc_read_alarm, | ||
216 | .set_alarm = snvs_rtc_set_alarm, | ||
217 | .alarm_irq_enable = snvs_rtc_alarm_irq_enable, | ||
218 | }; | ||
219 | |||
220 | static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id) | ||
221 | { | ||
222 | struct device *dev = dev_id; | ||
223 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
224 | u32 lpsr; | ||
225 | u32 events = 0; | ||
226 | |||
227 | lpsr = readl(data->ioaddr + SNVS_LPSR); | ||
228 | |||
229 | if (lpsr & SNVS_LPSR_LPTA) { | ||
230 | events |= (RTC_AF | RTC_IRQF); | ||
231 | |||
232 | /* RTC alarm should be one-shot */ | ||
233 | snvs_rtc_alarm_irq_enable(dev, 0); | ||
234 | |||
235 | rtc_update_irq(data->rtc, 1, events); | ||
236 | } | ||
237 | |||
238 | /* clear interrupt status */ | ||
239 | writel(lpsr, data->ioaddr + SNVS_LPSR); | ||
240 | |||
241 | return events ? IRQ_HANDLED : IRQ_NONE; | ||
242 | } | ||
243 | |||
244 | static int __devinit snvs_rtc_probe(struct platform_device *pdev) | ||
245 | { | ||
246 | struct snvs_rtc_data *data; | ||
247 | struct resource *res; | ||
248 | int ret; | ||
249 | |||
250 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
251 | if (!data) | ||
252 | return -ENOMEM; | ||
253 | |||
254 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
255 | data->ioaddr = devm_request_and_ioremap(&pdev->dev, res); | ||
256 | if (!data->ioaddr) | ||
257 | return -EADDRNOTAVAIL; | ||
258 | |||
259 | data->irq = platform_get_irq(pdev, 0); | ||
260 | if (data->irq < 0) | ||
261 | return data->irq; | ||
262 | |||
263 | platform_set_drvdata(pdev, data); | ||
264 | |||
265 | spin_lock_init(&data->lock); | ||
266 | |||
267 | /* Initialize glitch detect */ | ||
268 | writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR); | ||
269 | |||
270 | /* Clear interrupt status */ | ||
271 | writel(0xffffffff, data->ioaddr + SNVS_LPSR); | ||
272 | |||
273 | /* Enable RTC */ | ||
274 | snvs_rtc_enable(data, true); | ||
275 | |||
276 | device_init_wakeup(&pdev->dev, true); | ||
277 | |||
278 | ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler, | ||
279 | IRQF_SHARED, "rtc alarm", &pdev->dev); | ||
280 | if (ret) { | ||
281 | dev_err(&pdev->dev, "failed to request irq %d: %d\n", | ||
282 | data->irq, ret); | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | data->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
287 | &snvs_rtc_ops, THIS_MODULE); | ||
288 | if (IS_ERR(data->rtc)) { | ||
289 | ret = PTR_ERR(data->rtc); | ||
290 | dev_err(&pdev->dev, "failed to register rtc: %d\n", ret); | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int __devexit snvs_rtc_remove(struct platform_device *pdev) | ||
298 | { | ||
299 | struct snvs_rtc_data *data = platform_get_drvdata(pdev); | ||
300 | |||
301 | rtc_device_unregister(data->rtc); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | #ifdef CONFIG_PM_SLEEP | ||
307 | static int snvs_rtc_suspend(struct device *dev) | ||
308 | { | ||
309 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
310 | |||
311 | if (device_may_wakeup(dev)) | ||
312 | enable_irq_wake(data->irq); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int snvs_rtc_resume(struct device *dev) | ||
318 | { | ||
319 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | ||
320 | |||
321 | if (device_may_wakeup(dev)) | ||
322 | disable_irq_wake(data->irq); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | #endif | ||
327 | |||
328 | static SIMPLE_DEV_PM_OPS(snvs_rtc_pm_ops, snvs_rtc_suspend, snvs_rtc_resume); | ||
329 | |||
330 | static const struct of_device_id __devinitconst snvs_dt_ids[] = { | ||
331 | { .compatible = "fsl,sec-v4.0-mon-rtc-lp", }, | ||
332 | { /* sentinel */ } | ||
333 | }; | ||
334 | MODULE_DEVICE_TABLE(of, snvs_dt_ids); | ||
335 | |||
336 | static struct platform_driver snvs_rtc_driver = { | ||
337 | .driver = { | ||
338 | .name = "snvs_rtc", | ||
339 | .owner = THIS_MODULE, | ||
340 | .pm = &snvs_rtc_pm_ops, | ||
341 | .of_match_table = snvs_dt_ids, | ||
342 | }, | ||
343 | .probe = snvs_rtc_probe, | ||
344 | .remove = __devexit_p(snvs_rtc_remove), | ||
345 | }; | ||
346 | module_platform_driver(snvs_rtc_driver); | ||
347 | |||
348 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
349 | MODULE_DESCRIPTION("Freescale SNVS RTC Driver"); | ||
350 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index e2785479113c..bb507d23f6ce 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c | |||
@@ -235,7 +235,7 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
235 | static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) | 235 | static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) |
236 | { | 236 | { |
237 | struct spear_rtc_config *config = dev_get_drvdata(dev); | 237 | struct spear_rtc_config *config = dev_get_drvdata(dev); |
238 | unsigned int time, date, err = 0; | 238 | unsigned int time, date; |
239 | 239 | ||
240 | if (tm2bcd(tm) < 0) | 240 | if (tm2bcd(tm) < 0) |
241 | return -EINVAL; | 241 | return -EINVAL; |
@@ -247,11 +247,8 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
247 | (tm->tm_year << YEAR_SHIFT); | 247 | (tm->tm_year << YEAR_SHIFT); |
248 | writel(time, config->ioaddr + TIME_REG); | 248 | writel(time, config->ioaddr + TIME_REG); |
249 | writel(date, config->ioaddr + DATE_REG); | 249 | writel(date, config->ioaddr + DATE_REG); |
250 | err = is_write_complete(config); | ||
251 | if (err < 0) | ||
252 | return err; | ||
253 | 250 | ||
254 | return 0; | 251 | return is_write_complete(config); |
255 | } | 252 | } |
256 | 253 | ||
257 | /* | 254 | /* |
@@ -295,7 +292,8 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
295 | static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | 292 | static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) |
296 | { | 293 | { |
297 | struct spear_rtc_config *config = dev_get_drvdata(dev); | 294 | struct spear_rtc_config *config = dev_get_drvdata(dev); |
298 | unsigned int time, date, err = 0; | 295 | unsigned int time, date; |
296 | int err; | ||
299 | 297 | ||
300 | if (tm2bcd(&alm->time) < 0) | 298 | if (tm2bcd(&alm->time) < 0) |
301 | return -EINVAL; | 299 | return -EINVAL; |
@@ -357,7 +355,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) | |||
357 | { | 355 | { |
358 | struct resource *res; | 356 | struct resource *res; |
359 | struct spear_rtc_config *config; | 357 | struct spear_rtc_config *config; |
360 | unsigned int status = 0; | 358 | int status = 0; |
361 | int irq; | 359 | int irq; |
362 | 360 | ||
363 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 361 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 380083ca572f..b70e2bb63645 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -102,6 +102,12 @@ rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr, | |||
102 | return n; | 102 | return n; |
103 | } | 103 | } |
104 | 104 | ||
105 | /** | ||
106 | * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time | ||
107 | * | ||
108 | * Returns 1 if the system clock was set by this RTC at the last | ||
109 | * boot or resume event. | ||
110 | */ | ||
105 | static ssize_t | 111 | static ssize_t |
106 | rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, | 112 | rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, |
107 | char *buf) | 113 | char *buf) |
diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c new file mode 100644 index 000000000000..7a82337e4dee --- /dev/null +++ b/drivers/rtc/rtc-tps65910.c | |||
@@ -0,0 +1,349 @@ | |||
1 | /* | ||
2 | * rtc-tps65910.c -- TPS65910 Real Time Clock interface | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * Author: Venu Byravarasu <vbyravarasu@nvidia.com> | ||
6 | * | ||
7 | * Based on original TI driver rtc-twl.c | ||
8 | * Copyright (C) 2007 MontaVista Software, Inc | ||
9 | * Author: Alexandre Rusev <source@mvista.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/bcd.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/mfd/tps65910.h> | ||
27 | |||
28 | struct tps65910_rtc { | ||
29 | struct rtc_device *rtc; | ||
30 | /* To store the list of enabled interrupts */ | ||
31 | u32 irqstat; | ||
32 | }; | ||
33 | |||
34 | /* Total number of RTC registers needed to set time*/ | ||
35 | #define NUM_TIME_REGS (TPS65910_YEARS - TPS65910_SECONDS + 1) | ||
36 | |||
37 | static int tps65910_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) | ||
38 | { | ||
39 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
40 | u8 val = 0; | ||
41 | |||
42 | if (enabled) | ||
43 | val = TPS65910_RTC_INTERRUPTS_IT_ALARM; | ||
44 | |||
45 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, val); | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * Gets current tps65910 RTC time and date parameters. | ||
50 | * | ||
51 | * The RTC's time/alarm representation is not what gmtime(3) requires | ||
52 | * Linux to use: | ||
53 | * | ||
54 | * - Months are 1..12 vs Linux 0-11 | ||
55 | * - Years are 0..99 vs Linux 1900..N (we assume 21st century) | ||
56 | */ | ||
57 | static int tps65910_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
58 | { | ||
59 | unsigned char rtc_data[NUM_TIME_REGS]; | ||
60 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
61 | int ret; | ||
62 | |||
63 | /* Copy RTC counting registers to static registers or latches */ | ||
64 | ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL, | ||
65 | TPS65910_RTC_CTRL_GET_TIME, TPS65910_RTC_CTRL_GET_TIME); | ||
66 | if (ret < 0) { | ||
67 | dev_err(dev, "RTC CTRL reg update failed with err:%d\n", ret); | ||
68 | return ret; | ||
69 | } | ||
70 | |||
71 | ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, rtc_data, | ||
72 | NUM_TIME_REGS); | ||
73 | if (ret < 0) { | ||
74 | dev_err(dev, "reading from RTC failed with err:%d\n", ret); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | tm->tm_sec = bcd2bin(rtc_data[0]); | ||
79 | tm->tm_min = bcd2bin(rtc_data[1]); | ||
80 | tm->tm_hour = bcd2bin(rtc_data[2]); | ||
81 | tm->tm_mday = bcd2bin(rtc_data[3]); | ||
82 | tm->tm_mon = bcd2bin(rtc_data[4]) - 1; | ||
83 | tm->tm_year = bcd2bin(rtc_data[5]) + 100; | ||
84 | |||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | static int tps65910_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
89 | { | ||
90 | unsigned char rtc_data[NUM_TIME_REGS]; | ||
91 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
92 | int ret; | ||
93 | |||
94 | rtc_data[0] = bin2bcd(tm->tm_sec); | ||
95 | rtc_data[1] = bin2bcd(tm->tm_min); | ||
96 | rtc_data[2] = bin2bcd(tm->tm_hour); | ||
97 | rtc_data[3] = bin2bcd(tm->tm_mday); | ||
98 | rtc_data[4] = bin2bcd(tm->tm_mon + 1); | ||
99 | rtc_data[5] = bin2bcd(tm->tm_year - 100); | ||
100 | |||
101 | /* Stop RTC while updating the RTC time registers */ | ||
102 | ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL, | ||
103 | TPS65910_RTC_CTRL_STOP_RTC, 0); | ||
104 | if (ret < 0) { | ||
105 | dev_err(dev, "RTC stop failed with err:%d\n", ret); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | /* update all the time registers in one shot */ | ||
110 | ret = regmap_bulk_write(tps->regmap, TPS65910_SECONDS, rtc_data, | ||
111 | NUM_TIME_REGS); | ||
112 | if (ret < 0) { | ||
113 | dev_err(dev, "rtc_set_time error %d\n", ret); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | /* Start back RTC */ | ||
118 | ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL, | ||
119 | TPS65910_RTC_CTRL_STOP_RTC, 1); | ||
120 | if (ret < 0) | ||
121 | dev_err(dev, "RTC start failed with err:%d\n", ret); | ||
122 | |||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Gets current tps65910 RTC alarm time. | ||
128 | */ | ||
129 | static int tps65910_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
130 | { | ||
131 | unsigned char alarm_data[NUM_TIME_REGS]; | ||
132 | u32 int_val; | ||
133 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
134 | int ret; | ||
135 | |||
136 | ret = regmap_bulk_read(tps->regmap, TPS65910_SECONDS, alarm_data, | ||
137 | NUM_TIME_REGS); | ||
138 | if (ret < 0) { | ||
139 | dev_err(dev, "rtc_read_alarm error %d\n", ret); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | alm->time.tm_sec = bcd2bin(alarm_data[0]); | ||
144 | alm->time.tm_min = bcd2bin(alarm_data[1]); | ||
145 | alm->time.tm_hour = bcd2bin(alarm_data[2]); | ||
146 | alm->time.tm_mday = bcd2bin(alarm_data[3]); | ||
147 | alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1; | ||
148 | alm->time.tm_year = bcd2bin(alarm_data[5]) + 100; | ||
149 | |||
150 | ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, &int_val); | ||
151 | if (ret < 0) | ||
152 | return ret; | ||
153 | |||
154 | if (int_val & TPS65910_RTC_INTERRUPTS_IT_ALARM) | ||
155 | alm->enabled = 1; | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | static int tps65910_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
161 | { | ||
162 | unsigned char alarm_data[NUM_TIME_REGS]; | ||
163 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
164 | int ret; | ||
165 | |||
166 | ret = tps65910_rtc_alarm_irq_enable(dev, 0); | ||
167 | if (ret) | ||
168 | return ret; | ||
169 | |||
170 | alarm_data[0] = bin2bcd(alm->time.tm_sec); | ||
171 | alarm_data[1] = bin2bcd(alm->time.tm_min); | ||
172 | alarm_data[2] = bin2bcd(alm->time.tm_hour); | ||
173 | alarm_data[3] = bin2bcd(alm->time.tm_mday); | ||
174 | alarm_data[4] = bin2bcd(alm->time.tm_mon + 1); | ||
175 | alarm_data[5] = bin2bcd(alm->time.tm_year - 100); | ||
176 | |||
177 | /* update all the alarm registers in one shot */ | ||
178 | ret = regmap_bulk_write(tps->regmap, TPS65910_ALARM_SECONDS, | ||
179 | alarm_data, NUM_TIME_REGS); | ||
180 | if (ret) { | ||
181 | dev_err(dev, "rtc_set_alarm error %d\n", ret); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | if (alm->enabled) | ||
186 | ret = tps65910_rtc_alarm_irq_enable(dev, 1); | ||
187 | |||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static irqreturn_t tps65910_rtc_interrupt(int irq, void *rtc) | ||
192 | { | ||
193 | struct device *dev = rtc; | ||
194 | unsigned long events = 0; | ||
195 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
196 | struct tps65910_rtc *tps_rtc = dev_get_drvdata(dev); | ||
197 | int ret; | ||
198 | u32 rtc_reg; | ||
199 | |||
200 | ret = regmap_read(tps->regmap, TPS65910_RTC_STATUS, &rtc_reg); | ||
201 | if (ret) | ||
202 | return IRQ_NONE; | ||
203 | |||
204 | if (rtc_reg & TPS65910_RTC_STATUS_ALARM) | ||
205 | events = RTC_IRQF | RTC_AF; | ||
206 | |||
207 | ret = regmap_write(tps->regmap, TPS65910_RTC_STATUS, rtc_reg); | ||
208 | if (ret) | ||
209 | return IRQ_NONE; | ||
210 | |||
211 | /* Notify RTC core on event */ | ||
212 | rtc_update_irq(tps_rtc->rtc, 1, events); | ||
213 | |||
214 | return IRQ_HANDLED; | ||
215 | } | ||
216 | |||
217 | static const struct rtc_class_ops tps65910_rtc_ops = { | ||
218 | .read_time = tps65910_rtc_read_time, | ||
219 | .set_time = tps65910_rtc_set_time, | ||
220 | .read_alarm = tps65910_rtc_read_alarm, | ||
221 | .set_alarm = tps65910_rtc_set_alarm, | ||
222 | .alarm_irq_enable = tps65910_rtc_alarm_irq_enable, | ||
223 | }; | ||
224 | |||
225 | static int __devinit tps65910_rtc_probe(struct platform_device *pdev) | ||
226 | { | ||
227 | struct tps65910 *tps65910 = NULL; | ||
228 | struct tps65910_rtc *tps_rtc = NULL; | ||
229 | int ret; | ||
230 | int irq; | ||
231 | u32 rtc_reg; | ||
232 | |||
233 | tps65910 = dev_get_drvdata(pdev->dev.parent); | ||
234 | |||
235 | tps_rtc = devm_kzalloc(&pdev->dev, sizeof(struct tps65910_rtc), | ||
236 | GFP_KERNEL); | ||
237 | if (!tps_rtc) | ||
238 | return -ENOMEM; | ||
239 | |||
240 | /* Clear pending interrupts */ | ||
241 | ret = regmap_read(tps65910->regmap, TPS65910_RTC_STATUS, &rtc_reg); | ||
242 | if (ret < 0) | ||
243 | return ret; | ||
244 | |||
245 | ret = regmap_write(tps65910->regmap, TPS65910_RTC_STATUS, rtc_reg); | ||
246 | if (ret < 0) | ||
247 | return ret; | ||
248 | |||
249 | dev_dbg(&pdev->dev, "Enabling rtc-tps65910.\n"); | ||
250 | rtc_reg = TPS65910_RTC_CTRL_STOP_RTC; | ||
251 | ret = regmap_write(tps65910->regmap, TPS65910_RTC_CTRL, rtc_reg); | ||
252 | if (ret < 0) | ||
253 | return ret; | ||
254 | |||
255 | irq = platform_get_irq(pdev, 0); | ||
256 | if (irq <= 0) { | ||
257 | dev_warn(&pdev->dev, "Wake up is not possible as irq = %d\n", | ||
258 | irq); | ||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | ||
263 | tps65910_rtc_interrupt, IRQF_TRIGGER_LOW, | ||
264 | "rtc-tps65910", &pdev->dev); | ||
265 | if (ret < 0) { | ||
266 | dev_err(&pdev->dev, "IRQ is not free.\n"); | ||
267 | return ret; | ||
268 | } | ||
269 | device_init_wakeup(&pdev->dev, 1); | ||
270 | |||
271 | tps_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
272 | &tps65910_rtc_ops, THIS_MODULE); | ||
273 | if (IS_ERR(tps_rtc->rtc)) { | ||
274 | ret = PTR_ERR(tps_rtc->rtc); | ||
275 | dev_err(&pdev->dev, "RTC device register: err %d\n", ret); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | platform_set_drvdata(pdev, tps_rtc); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | /* | ||
285 | * Disable tps65910 RTC interrupts. | ||
286 | * Sets status flag to free. | ||
287 | */ | ||
288 | static int __devexit tps65910_rtc_remove(struct platform_device *pdev) | ||
289 | { | ||
290 | /* leave rtc running, but disable irqs */ | ||
291 | struct rtc_device *rtc = platform_get_drvdata(pdev); | ||
292 | |||
293 | tps65910_rtc_alarm_irq_enable(&rtc->dev, 0); | ||
294 | |||
295 | rtc_device_unregister(rtc); | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | #ifdef CONFIG_PM_SLEEP | ||
300 | |||
301 | static int tps65910_rtc_suspend(struct device *dev) | ||
302 | { | ||
303 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
304 | u8 alarm = TPS65910_RTC_INTERRUPTS_IT_ALARM; | ||
305 | int ret; | ||
306 | |||
307 | /* Store current list of enabled interrupts*/ | ||
308 | ret = regmap_read(tps->regmap, TPS65910_RTC_INTERRUPTS, | ||
309 | &tps->rtc->irqstat); | ||
310 | if (ret < 0) | ||
311 | return ret; | ||
312 | |||
313 | /* Enable RTC ALARM interrupt only */ | ||
314 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, alarm); | ||
315 | } | ||
316 | |||
317 | static int tps65910_rtc_resume(struct device *dev) | ||
318 | { | ||
319 | struct tps65910 *tps = dev_get_drvdata(dev->parent); | ||
320 | |||
321 | /* Restore list of enabled interrupts before suspend */ | ||
322 | return regmap_write(tps->regmap, TPS65910_RTC_INTERRUPTS, | ||
323 | tps->rtc->irqstat); | ||
324 | } | ||
325 | |||
326 | static const struct dev_pm_ops tps65910_rtc_pm_ops = { | ||
327 | .suspend = tps65910_rtc_suspend, | ||
328 | .resume = tps65910_rtc_resume, | ||
329 | }; | ||
330 | |||
331 | #define DEV_PM_OPS (&tps65910_rtc_pm_ops) | ||
332 | #else | ||
333 | #define DEV_PM_OPS NULL | ||
334 | #endif | ||
335 | |||
336 | static struct platform_driver tps65910_rtc_driver = { | ||
337 | .probe = tps65910_rtc_probe, | ||
338 | .remove = __devexit_p(tps65910_rtc_remove), | ||
339 | .driver = { | ||
340 | .owner = THIS_MODULE, | ||
341 | .name = "tps65910-rtc", | ||
342 | .pm = DEV_PM_OPS, | ||
343 | }, | ||
344 | }; | ||
345 | |||
346 | module_platform_driver(tps65910_rtc_driver); | ||
347 | MODULE_ALIAS("platform:rtc-tps65910"); | ||
348 | MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); | ||
349 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 403b3d41d101..f36e59c6bc01 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -97,8 +97,17 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
97 | int i; | 97 | int i; |
98 | 98 | ||
99 | struct i2c_msg msgs[] = { | 99 | struct i2c_msg msgs[] = { |
100 | { client->addr, 0, 2, dt_addr }, /* setup read ptr */ | 100 | {/* setup read ptr */ |
101 | { client->addr, I2C_M_RD, 8, buf }, /* read date */ | 101 | .addr = client->addr, |
102 | .len = 2, | ||
103 | .buf = dt_addr | ||
104 | }, | ||
105 | {/* read date */ | ||
106 | .addr = client->addr, | ||
107 | .flags = I2C_M_RD, | ||
108 | .len = 8, | ||
109 | .buf = buf | ||
110 | }, | ||
102 | }; | 111 | }; |
103 | 112 | ||
104 | /* read date registers */ | 113 | /* read date registers */ |
@@ -142,8 +151,17 @@ static int x1205_get_status(struct i2c_client *client, unsigned char *sr) | |||
142 | static unsigned char sr_addr[2] = { 0, X1205_REG_SR }; | 151 | static unsigned char sr_addr[2] = { 0, X1205_REG_SR }; |
143 | 152 | ||
144 | struct i2c_msg msgs[] = { | 153 | struct i2c_msg msgs[] = { |
145 | { client->addr, 0, 2, sr_addr }, /* setup read ptr */ | 154 | { /* setup read ptr */ |
146 | { client->addr, I2C_M_RD, 1, sr }, /* read status */ | 155 | .addr = client->addr, |
156 | .len = 2, | ||
157 | .buf = sr_addr | ||
158 | }, | ||
159 | { /* read status */ | ||
160 | .addr = client->addr, | ||
161 | .flags = I2C_M_RD, | ||
162 | .len = 1, | ||
163 | .buf = sr | ||
164 | }, | ||
147 | }; | 165 | }; |
148 | 166 | ||
149 | /* read status register */ | 167 | /* read status register */ |
@@ -279,8 +297,17 @@ static int x1205_get_dtrim(struct i2c_client *client, int *trim) | |||
279 | static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR }; | 297 | static unsigned char dtr_addr[2] = { 0, X1205_REG_DTR }; |
280 | 298 | ||
281 | struct i2c_msg msgs[] = { | 299 | struct i2c_msg msgs[] = { |
282 | { client->addr, 0, 2, dtr_addr }, /* setup read ptr */ | 300 | { /* setup read ptr */ |
283 | { client->addr, I2C_M_RD, 1, &dtr }, /* read dtr */ | 301 | .addr = client->addr, |
302 | .len = 2, | ||
303 | .buf = dtr_addr | ||
304 | }, | ||
305 | { /* read dtr */ | ||
306 | .addr = client->addr, | ||
307 | .flags = I2C_M_RD, | ||
308 | .len = 1, | ||
309 | .buf = &dtr | ||
310 | }, | ||
284 | }; | 311 | }; |
285 | 312 | ||
286 | /* read dtr register */ | 313 | /* read dtr register */ |
@@ -311,8 +338,17 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) | |||
311 | static unsigned char atr_addr[2] = { 0, X1205_REG_ATR }; | 338 | static unsigned char atr_addr[2] = { 0, X1205_REG_ATR }; |
312 | 339 | ||
313 | struct i2c_msg msgs[] = { | 340 | struct i2c_msg msgs[] = { |
314 | { client->addr, 0, 2, atr_addr }, /* setup read ptr */ | 341 | {/* setup read ptr */ |
315 | { client->addr, I2C_M_RD, 1, &atr }, /* read atr */ | 342 | .addr = client->addr, |
343 | .len = 2, | ||
344 | .buf = atr_addr | ||
345 | }, | ||
346 | {/* read atr */ | ||
347 | .addr = client->addr, | ||
348 | .flags = I2C_M_RD, | ||
349 | .len = 1, | ||
350 | .buf = &atr | ||
351 | }, | ||
316 | }; | 352 | }; |
317 | 353 | ||
318 | /* read atr register */ | 354 | /* read atr register */ |
@@ -381,8 +417,17 @@ static int x1205_validate_client(struct i2c_client *client) | |||
381 | unsigned char addr[2] = { 0, probe_zero_pattern[i] }; | 417 | unsigned char addr[2] = { 0, probe_zero_pattern[i] }; |
382 | 418 | ||
383 | struct i2c_msg msgs[2] = { | 419 | struct i2c_msg msgs[2] = { |
384 | { client->addr, 0, 2, addr }, | 420 | { |
385 | { client->addr, I2C_M_RD, 1, &buf }, | 421 | .addr = client->addr, |
422 | .len = 2, | ||
423 | .buf = addr | ||
424 | }, | ||
425 | { | ||
426 | .addr = client->addr, | ||
427 | .flags = I2C_M_RD, | ||
428 | .len = 1, | ||
429 | .buf = &buf | ||
430 | }, | ||
386 | }; | 431 | }; |
387 | 432 | ||
388 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 433 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
@@ -409,8 +454,17 @@ static int x1205_validate_client(struct i2c_client *client) | |||
409 | unsigned char addr[2] = { 0, probe_limits_pattern[i].reg }; | 454 | unsigned char addr[2] = { 0, probe_limits_pattern[i].reg }; |
410 | 455 | ||
411 | struct i2c_msg msgs[2] = { | 456 | struct i2c_msg msgs[2] = { |
412 | { client->addr, 0, 2, addr }, | 457 | { |
413 | { client->addr, I2C_M_RD, 1, ® }, | 458 | .addr = client->addr, |
459 | .len = 2, | ||
460 | .buf = addr | ||
461 | }, | ||
462 | { | ||
463 | .addr = client->addr, | ||
464 | .flags = I2C_M_RD, | ||
465 | .len = 1, | ||
466 | .buf = ® | ||
467 | }, | ||
414 | }; | 468 | }; |
415 | 469 | ||
416 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { | 470 | if ((xfer = i2c_transfer(client->adapter, msgs, 2)) != 2) { |
@@ -444,8 +498,18 @@ static int x1205_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
444 | static unsigned char int_addr[2] = { 0, X1205_REG_INT }; | 498 | static unsigned char int_addr[2] = { 0, X1205_REG_INT }; |
445 | struct i2c_client *client = to_i2c_client(dev); | 499 | struct i2c_client *client = to_i2c_client(dev); |
446 | struct i2c_msg msgs[] = { | 500 | struct i2c_msg msgs[] = { |
447 | { client->addr, 0, 2, int_addr }, /* setup read ptr */ | 501 | { /* setup read ptr */ |
448 | { client->addr, I2C_M_RD, 1, &intreg }, /* read INT register */ | 502 | .addr = client->addr, |
503 | .len = 2, | ||
504 | .buf = int_addr | ||
505 | }, | ||
506 | {/* read INT register */ | ||
507 | |||
508 | .addr = client->addr, | ||
509 | .flags = I2C_M_RD, | ||
510 | .len = 1, | ||
511 | .buf = &intreg | ||
512 | }, | ||
449 | }; | 513 | }; |
450 | 514 | ||
451 | /* read interrupt register and status register */ | 515 | /* read interrupt register and status register */ |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 7199534cd07d..cb7f1582a6d1 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -93,7 +93,7 @@ static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = { | |||
93 | #elif defined(__devinitconst) | 93 | #elif defined(__devinitconst) |
94 | static const struct pci_device_id aac_pci_tbl[] __devinitconst = { | 94 | static const struct pci_device_id aac_pci_tbl[] __devinitconst = { |
95 | #else | 95 | #else |
96 | static const struct pci_device_id aac_pci_tbl[] __devinitdata = { | 96 | static const struct pci_device_id aac_pci_tbl[] __devinitconst = { |
97 | #endif | 97 | #endif |
98 | { 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */ | 98 | { 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */ |
99 | { 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */ | 99 | { 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index ff80552ead84..1c4120c3db41 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -1012,7 +1012,7 @@ static struct sas_domain_function_template aic94xx_transport_functions = { | |||
1012 | .lldd_ata_set_dmamode = asd_set_dmamode, | 1012 | .lldd_ata_set_dmamode = asd_set_dmamode, |
1013 | }; | 1013 | }; |
1014 | 1014 | ||
1015 | static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { | 1015 | static const struct pci_device_id aic94xx_pci_table[] __devinitconst = { |
1016 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1}, | 1016 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1}, |
1017 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1}, | 1017 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1}, |
1018 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1}, | 1018 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1}, |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 68ce08552f69..a540162ac59c 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
@@ -1173,7 +1173,16 @@ wait_io1: | |||
1173 | outw(val, tmport); | 1173 | outw(val, tmport); |
1174 | outb(2, 0x80); | 1174 | outb(2, 0x80); |
1175 | TCM_SYNC: | 1175 | TCM_SYNC: |
1176 | udelay(0x800); | 1176 | /* |
1177 | * The funny division into multiple delays is to accomodate | ||
1178 | * arches like ARM where udelay() multiplies its argument by | ||
1179 | * a large number to initialize a loop counter. To avoid | ||
1180 | * overflow, the maximum supported udelay is 2000 microseconds. | ||
1181 | * | ||
1182 | * XXX it would be more polite to find a way to use msleep() | ||
1183 | */ | ||
1184 | mdelay(2); | ||
1185 | udelay(48); | ||
1177 | if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ | 1186 | if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ |
1178 | outw(0, tmport--); | 1187 | outw(0, tmport--); |
1179 | outb(0, tmport); | 1188 | outb(0, tmport); |
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 67789b8345d2..efd81bb25e01 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -78,7 +78,7 @@ again: | |||
78 | else if (unlikely(err)) | 78 | else if (unlikely(err)) |
79 | return err; | 79 | return err; |
80 | 80 | ||
81 | *id = *id & MAX_ID_MASK; | 81 | *id = *id & MAX_IDR_MASK; |
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 747442d2c0f6..0fefa84ed9ae 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -149,7 +149,7 @@ enum { | |||
149 | }; | 149 | }; |
150 | 150 | ||
151 | /* Must match above enum */ | 151 | /* Must match above enum */ |
152 | static const char *r128_family[] __devinitdata = { | 152 | static char * const r128_family[] __devinitconst = { |
153 | "AGP", | 153 | "AGP", |
154 | "PCI", | 154 | "PCI", |
155 | "PRO AGP", | 155 | "PRO AGP", |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 63cee2e9d622..c101697a4ba7 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -229,13 +229,6 @@ config BACKLIGHT_HP700 | |||
229 | If you have an HP Jornada 700 series, | 229 | If you have an HP Jornada 700 series, |
230 | say Y to include backlight control driver. | 230 | say Y to include backlight control driver. |
231 | 231 | ||
232 | config BACKLIGHT_PROGEAR | ||
233 | tristate "Frontpath ProGear Backlight Driver" | ||
234 | depends on PCI && X86 | ||
235 | help | ||
236 | If you have a Frontpath ProGear say Y to enable the | ||
237 | backlight driver. | ||
238 | |||
239 | config BACKLIGHT_CARILLO_RANCH | 232 | config BACKLIGHT_CARILLO_RANCH |
240 | tristate "Intel Carillo Ranch Backlight Driver" | 233 | tristate "Intel Carillo Ranch Backlight Driver" |
241 | depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 | 234 | depends on LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578 |
@@ -352,6 +345,22 @@ config BACKLIGHT_AAT2870 | |||
352 | If you have a AnalogicTech AAT2870 say Y to enable the | 345 | If you have a AnalogicTech AAT2870 say Y to enable the |
353 | backlight driver. | 346 | backlight driver. |
354 | 347 | ||
348 | config BACKLIGHT_LM3630 | ||
349 | tristate "Backlight Driver for LM3630" | ||
350 | depends on BACKLIGHT_CLASS_DEVICE && I2C | ||
351 | select REGMAP_I2C | ||
352 | help | ||
353 | This supports TI LM3630 Backlight Driver | ||
354 | |||
355 | config BACKLIGHT_LM3639 | ||
356 | tristate "Backlight Driver for LM3639" | ||
357 | depends on BACKLIGHT_CLASS_DEVICE && I2C | ||
358 | select REGMAP_I2C | ||
359 | select NEW_LEDS | ||
360 | select LEDS_CLASS | ||
361 | help | ||
362 | This supports TI LM3639 Backlight + 1.5A Flash LED Driver | ||
363 | |||
355 | config BACKLIGHT_LP855X | 364 | config BACKLIGHT_LP855X |
356 | tristate "Backlight driver for TI LP855X" | 365 | tristate "Backlight driver for TI LP855X" |
357 | depends on BACKLIGHT_CLASS_DEVICE && I2C | 366 | depends on BACKLIGHT_CLASS_DEVICE && I2C |
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 00223a62ec12..e7ce7291635d 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile | |||
@@ -23,10 +23,11 @@ obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o | |||
23 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o | 23 | obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o |
24 | obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o | 24 | obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o |
25 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o | 25 | obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o |
26 | obj-$(CONFIG_BACKLIGHT_LM3630) += lm3630_bl.o | ||
27 | obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o | ||
26 | obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o | 28 | obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o |
27 | obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o | 29 | obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o |
28 | obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o | 30 | obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o |
29 | obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o | ||
30 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o | 31 | obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o |
31 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o | 32 | obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o |
32 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o | 33 | obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o |
diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c index b628d68f5162..ac196181fe45 100644 --- a/drivers/video/backlight/da9052_bl.c +++ b/drivers/video/backlight/da9052_bl.c | |||
@@ -72,7 +72,7 @@ static int da9052_adjust_wled_brightness(struct da9052_bl *wleds) | |||
72 | if (ret < 0) | 72 | if (ret < 0) |
73 | return ret; | 73 | return ret; |
74 | 74 | ||
75 | msleep(10); | 75 | usleep_range(10000, 11000); |
76 | 76 | ||
77 | if (wleds->brightness) { | 77 | if (wleds->brightness) { |
78 | ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], | 78 | ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], |
@@ -129,7 +129,6 @@ static int da9052_backlight_probe(struct platform_device *pdev) | |||
129 | &da9052_backlight_ops, &props); | 129 | &da9052_backlight_ops, &props); |
130 | if (IS_ERR(bl)) { | 130 | if (IS_ERR(bl)) { |
131 | dev_err(&pdev->dev, "Failed to register backlight\n"); | 131 | dev_err(&pdev->dev, "Failed to register backlight\n"); |
132 | devm_kfree(&pdev->dev, wleds); | ||
133 | return PTR_ERR(bl); | 132 | return PTR_ERR(bl); |
134 | } | 133 | } |
135 | 134 | ||
@@ -149,7 +148,6 @@ static int da9052_backlight_remove(struct platform_device *pdev) | |||
149 | wleds->state = DA9052_WLEDS_OFF; | 148 | wleds->state = DA9052_WLEDS_OFF; |
150 | da9052_adjust_wled_brightness(wleds); | 149 | da9052_adjust_wled_brightness(wleds); |
151 | backlight_device_unregister(bl); | 150 | backlight_device_unregister(bl); |
152 | devm_kfree(&pdev->dev, wleds); | ||
153 | 151 | ||
154 | return 0; | 152 | return 0; |
155 | } | 153 | } |
diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 72dd5556a35b..6c5ed6b242cc 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c | |||
@@ -34,9 +34,9 @@ static void kb3886_bl_set_intensity(int intensity) | |||
34 | mutex_lock(&bl_mutex); | 34 | mutex_lock(&bl_mutex); |
35 | intensity = intensity&0xff; | 35 | intensity = intensity&0xff; |
36 | outb(KB3886_ADC_DAC_PWM, KB3886_PARENT); | 36 | outb(KB3886_ADC_DAC_PWM, KB3886_PARENT); |
37 | msleep(10); | 37 | usleep_range(10000, 11000); |
38 | outb(KB3886_PWM0_WRITE, KB3886_IO); | 38 | outb(KB3886_PWM0_WRITE, KB3886_IO); |
39 | msleep(10); | 39 | usleep_range(10000, 11000); |
40 | outb(intensity, KB3886_IO); | 40 | outb(intensity, KB3886_IO); |
41 | mutex_unlock(&bl_mutex); | 41 | mutex_unlock(&bl_mutex); |
42 | } | 42 | } |
diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c new file mode 100644 index 000000000000..dc191441796f --- /dev/null +++ b/drivers/video/backlight/lm3630_bl.c | |||
@@ -0,0 +1,475 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3630 Backlight driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/backlight.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/uaccess.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/platform_data/lm3630_bl.h> | ||
20 | |||
21 | #define REG_CTRL 0x00 | ||
22 | #define REG_CONFIG 0x01 | ||
23 | #define REG_BRT_A 0x03 | ||
24 | #define REG_BRT_B 0x04 | ||
25 | #define REG_INT_STATUS 0x09 | ||
26 | #define REG_INT_EN 0x0A | ||
27 | #define REG_FAULT 0x0B | ||
28 | #define REG_PWM_OUTLOW 0x12 | ||
29 | #define REG_PWM_OUTHIGH 0x13 | ||
30 | #define REG_MAX 0x1F | ||
31 | |||
32 | #define INT_DEBOUNCE_MSEC 10 | ||
33 | |||
34 | enum lm3630_leds { | ||
35 | BLED_ALL = 0, | ||
36 | BLED_1, | ||
37 | BLED_2 | ||
38 | }; | ||
39 | |||
40 | static const char *bled_name[] = { | ||
41 | [BLED_ALL] = "lm3630_bled", /*Bank1 controls all string */ | ||
42 | [BLED_1] = "lm3630_bled1", /*Bank1 controls bled1 */ | ||
43 | [BLED_2] = "lm3630_bled2", /*Bank1 or 2 controls bled2 */ | ||
44 | }; | ||
45 | |||
46 | struct lm3630_chip_data { | ||
47 | struct device *dev; | ||
48 | struct delayed_work work; | ||
49 | int irq; | ||
50 | struct workqueue_struct *irqthread; | ||
51 | struct lm3630_platform_data *pdata; | ||
52 | struct backlight_device *bled1; | ||
53 | struct backlight_device *bled2; | ||
54 | struct regmap *regmap; | ||
55 | }; | ||
56 | |||
57 | /* initialize chip */ | ||
58 | static int __devinit lm3630_chip_init(struct lm3630_chip_data *pchip) | ||
59 | { | ||
60 | int ret; | ||
61 | unsigned int reg_val; | ||
62 | struct lm3630_platform_data *pdata = pchip->pdata; | ||
63 | |||
64 | /*pwm control */ | ||
65 | reg_val = ((pdata->pwm_active & 0x01) << 2) | (pdata->pwm_ctrl & 0x03); | ||
66 | ret = regmap_update_bits(pchip->regmap, REG_CONFIG, 0x07, reg_val); | ||
67 | if (ret < 0) | ||
68 | goto out; | ||
69 | |||
70 | /* bank control */ | ||
71 | reg_val = ((pdata->bank_b_ctrl & 0x01) << 1) | | ||
72 | (pdata->bank_a_ctrl & 0x07); | ||
73 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x07, reg_val); | ||
74 | if (ret < 0) | ||
75 | goto out; | ||
76 | |||
77 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
78 | if (ret < 0) | ||
79 | goto out; | ||
80 | |||
81 | /* set initial brightness */ | ||
82 | if (pdata->bank_a_ctrl != BANK_A_CTRL_DISABLE) { | ||
83 | ret = regmap_write(pchip->regmap, | ||
84 | REG_BRT_A, pdata->init_brt_led1); | ||
85 | if (ret < 0) | ||
86 | goto out; | ||
87 | } | ||
88 | |||
89 | if (pdata->bank_b_ctrl != BANK_B_CTRL_DISABLE) { | ||
90 | ret = regmap_write(pchip->regmap, | ||
91 | REG_BRT_B, pdata->init_brt_led2); | ||
92 | if (ret < 0) | ||
93 | goto out; | ||
94 | } | ||
95 | return ret; | ||
96 | |||
97 | out: | ||
98 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* interrupt handling */ | ||
103 | static void lm3630_delayed_func(struct work_struct *work) | ||
104 | { | ||
105 | int ret; | ||
106 | unsigned int reg_val; | ||
107 | struct lm3630_chip_data *pchip; | ||
108 | |||
109 | pchip = container_of(work, struct lm3630_chip_data, work.work); | ||
110 | |||
111 | ret = regmap_read(pchip->regmap, REG_INT_STATUS, ®_val); | ||
112 | if (ret < 0) { | ||
113 | dev_err(pchip->dev, | ||
114 | "i2c failed to access REG_INT_STATUS Register\n"); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", reg_val); | ||
119 | } | ||
120 | |||
121 | static irqreturn_t lm3630_isr_func(int irq, void *chip) | ||
122 | { | ||
123 | int ret; | ||
124 | struct lm3630_chip_data *pchip = chip; | ||
125 | unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); | ||
126 | |||
127 | queue_delayed_work(pchip->irqthread, &pchip->work, delay); | ||
128 | |||
129 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
130 | if (ret < 0) | ||
131 | goto out; | ||
132 | |||
133 | return IRQ_HANDLED; | ||
134 | out: | ||
135 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
136 | return IRQ_HANDLED; | ||
137 | } | ||
138 | |||
139 | static int lm3630_intr_config(struct lm3630_chip_data *pchip) | ||
140 | { | ||
141 | INIT_DELAYED_WORK(&pchip->work, lm3630_delayed_func); | ||
142 | pchip->irqthread = create_singlethread_workqueue("lm3630-irqthd"); | ||
143 | if (!pchip->irqthread) { | ||
144 | dev_err(pchip->dev, "create irq thread fail...\n"); | ||
145 | return -1; | ||
146 | } | ||
147 | if (request_threaded_irq | ||
148 | (pchip->irq, NULL, lm3630_isr_func, | ||
149 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630_irq", pchip)) { | ||
150 | dev_err(pchip->dev, "request threaded irq fail..\n"); | ||
151 | return -1; | ||
152 | } | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static bool | ||
157 | set_intensity(struct backlight_device *bl, struct lm3630_chip_data *pchip) | ||
158 | { | ||
159 | if (!pchip->pdata->pwm_set_intensity) | ||
160 | return false; | ||
161 | pchip->pdata->pwm_set_intensity(bl->props.brightness - 1, | ||
162 | pchip->pdata->pwm_period); | ||
163 | return true; | ||
164 | } | ||
165 | |||
166 | /* update and get brightness */ | ||
167 | static int lm3630_bank_a_update_status(struct backlight_device *bl) | ||
168 | { | ||
169 | int ret; | ||
170 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
171 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
172 | |||
173 | /* brightness 0 means disable */ | ||
174 | if (!bl->props.brightness) { | ||
175 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x04, 0x00); | ||
176 | if (ret < 0) | ||
177 | goto out; | ||
178 | return bl->props.brightness; | ||
179 | } | ||
180 | |||
181 | /* pwm control */ | ||
182 | if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
183 | if (!set_intensity(bl, pchip)) | ||
184 | dev_err(pchip->dev, "No pwm control func. in plat-data\n"); | ||
185 | } else { | ||
186 | |||
187 | /* i2c control */ | ||
188 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
189 | if (ret < 0) | ||
190 | goto out; | ||
191 | mdelay(1); | ||
192 | ret = regmap_write(pchip->regmap, | ||
193 | REG_BRT_A, bl->props.brightness - 1); | ||
194 | if (ret < 0) | ||
195 | goto out; | ||
196 | } | ||
197 | return bl->props.brightness; | ||
198 | out: | ||
199 | dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); | ||
200 | return bl->props.brightness; | ||
201 | } | ||
202 | |||
203 | static int lm3630_bank_a_get_brightness(struct backlight_device *bl) | ||
204 | { | ||
205 | unsigned int reg_val; | ||
206 | int brightness, ret; | ||
207 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
208 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
209 | |||
210 | if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
211 | ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); | ||
212 | if (ret < 0) | ||
213 | goto out; | ||
214 | brightness = reg_val & 0x01; | ||
215 | ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); | ||
216 | if (ret < 0) | ||
217 | goto out; | ||
218 | brightness = ((brightness << 8) | reg_val) + 1; | ||
219 | } else { | ||
220 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
221 | if (ret < 0) | ||
222 | goto out; | ||
223 | mdelay(1); | ||
224 | ret = regmap_read(pchip->regmap, REG_BRT_A, ®_val); | ||
225 | if (ret < 0) | ||
226 | goto out; | ||
227 | brightness = reg_val + 1; | ||
228 | } | ||
229 | bl->props.brightness = brightness; | ||
230 | return bl->props.brightness; | ||
231 | out: | ||
232 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static const struct backlight_ops lm3630_bank_a_ops = { | ||
237 | .options = BL_CORE_SUSPENDRESUME, | ||
238 | .update_status = lm3630_bank_a_update_status, | ||
239 | .get_brightness = lm3630_bank_a_get_brightness, | ||
240 | }; | ||
241 | |||
242 | static int lm3630_bank_b_update_status(struct backlight_device *bl) | ||
243 | { | ||
244 | int ret; | ||
245 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
246 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
247 | |||
248 | if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
249 | if (!set_intensity(bl, pchip)) | ||
250 | dev_err(pchip->dev, | ||
251 | "no pwm control func. in plat-data\n"); | ||
252 | } else { | ||
253 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
254 | if (ret < 0) | ||
255 | goto out; | ||
256 | mdelay(1); | ||
257 | ret = regmap_write(pchip->regmap, | ||
258 | REG_BRT_B, bl->props.brightness - 1); | ||
259 | } | ||
260 | return bl->props.brightness; | ||
261 | out: | ||
262 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
263 | return bl->props.brightness; | ||
264 | } | ||
265 | |||
266 | static int lm3630_bank_b_get_brightness(struct backlight_device *bl) | ||
267 | { | ||
268 | unsigned int reg_val; | ||
269 | int brightness, ret; | ||
270 | struct lm3630_chip_data *pchip = bl_get_data(bl); | ||
271 | enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; | ||
272 | |||
273 | if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { | ||
274 | ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); | ||
275 | if (ret < 0) | ||
276 | goto out; | ||
277 | brightness = reg_val & 0x01; | ||
278 | ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); | ||
279 | if (ret < 0) | ||
280 | goto out; | ||
281 | brightness = ((brightness << 8) | reg_val) + 1; | ||
282 | } else { | ||
283 | ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); | ||
284 | if (ret < 0) | ||
285 | goto out; | ||
286 | mdelay(1); | ||
287 | ret = regmap_read(pchip->regmap, REG_BRT_B, ®_val); | ||
288 | if (ret < 0) | ||
289 | goto out; | ||
290 | brightness = reg_val + 1; | ||
291 | } | ||
292 | bl->props.brightness = brightness; | ||
293 | |||
294 | return bl->props.brightness; | ||
295 | out: | ||
296 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
297 | return bl->props.brightness; | ||
298 | } | ||
299 | |||
300 | static const struct backlight_ops lm3630_bank_b_ops = { | ||
301 | .options = BL_CORE_SUSPENDRESUME, | ||
302 | .update_status = lm3630_bank_b_update_status, | ||
303 | .get_brightness = lm3630_bank_b_get_brightness, | ||
304 | }; | ||
305 | |||
306 | static int lm3630_backlight_register(struct lm3630_chip_data *pchip, | ||
307 | enum lm3630_leds ledno) | ||
308 | { | ||
309 | const char *name = bled_name[ledno]; | ||
310 | struct backlight_properties props; | ||
311 | struct lm3630_platform_data *pdata = pchip->pdata; | ||
312 | |||
313 | props.type = BACKLIGHT_RAW; | ||
314 | switch (ledno) { | ||
315 | case BLED_1: | ||
316 | case BLED_ALL: | ||
317 | props.brightness = pdata->init_brt_led1; | ||
318 | props.max_brightness = pdata->max_brt_led1; | ||
319 | pchip->bled1 = | ||
320 | backlight_device_register(name, pchip->dev, pchip, | ||
321 | &lm3630_bank_a_ops, &props); | ||
322 | if (IS_ERR(pchip->bled1)) | ||
323 | return -EIO; | ||
324 | break; | ||
325 | case BLED_2: | ||
326 | props.brightness = pdata->init_brt_led2; | ||
327 | props.max_brightness = pdata->max_brt_led2; | ||
328 | pchip->bled2 = | ||
329 | backlight_device_register(name, pchip->dev, pchip, | ||
330 | &lm3630_bank_b_ops, &props); | ||
331 | if (IS_ERR(pchip->bled2)) | ||
332 | return -EIO; | ||
333 | break; | ||
334 | } | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static void lm3630_backlight_unregister(struct lm3630_chip_data *pchip) | ||
339 | { | ||
340 | if (pchip->bled1) | ||
341 | backlight_device_unregister(pchip->bled1); | ||
342 | if (pchip->bled2) | ||
343 | backlight_device_unregister(pchip->bled2); | ||
344 | } | ||
345 | |||
346 | static const struct regmap_config lm3630_regmap = { | ||
347 | .reg_bits = 8, | ||
348 | .val_bits = 8, | ||
349 | .max_register = REG_MAX, | ||
350 | }; | ||
351 | |||
352 | static int __devinit lm3630_probe(struct i2c_client *client, | ||
353 | const struct i2c_device_id *id) | ||
354 | { | ||
355 | struct lm3630_platform_data *pdata = client->dev.platform_data; | ||
356 | struct lm3630_chip_data *pchip; | ||
357 | int ret; | ||
358 | |||
359 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
360 | dev_err(&client->dev, "fail : i2c functionality check...\n"); | ||
361 | return -EOPNOTSUPP; | ||
362 | } | ||
363 | |||
364 | if (pdata == NULL) { | ||
365 | dev_err(&client->dev, "fail : no platform data.\n"); | ||
366 | return -ENODATA; | ||
367 | } | ||
368 | |||
369 | pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630_chip_data), | ||
370 | GFP_KERNEL); | ||
371 | if (!pchip) | ||
372 | return -ENOMEM; | ||
373 | pchip->pdata = pdata; | ||
374 | pchip->dev = &client->dev; | ||
375 | |||
376 | pchip->regmap = devm_regmap_init_i2c(client, &lm3630_regmap); | ||
377 | if (IS_ERR(pchip->regmap)) { | ||
378 | ret = PTR_ERR(pchip->regmap); | ||
379 | dev_err(&client->dev, "fail : allocate register map: %d\n", | ||
380 | ret); | ||
381 | return ret; | ||
382 | } | ||
383 | i2c_set_clientdata(client, pchip); | ||
384 | |||
385 | /* chip initialize */ | ||
386 | ret = lm3630_chip_init(pchip); | ||
387 | if (ret < 0) { | ||
388 | dev_err(&client->dev, "fail : init chip\n"); | ||
389 | goto err_chip_init; | ||
390 | } | ||
391 | |||
392 | switch (pdata->bank_a_ctrl) { | ||
393 | case BANK_A_CTRL_ALL: | ||
394 | ret = lm3630_backlight_register(pchip, BLED_ALL); | ||
395 | pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; | ||
396 | break; | ||
397 | case BANK_A_CTRL_LED1: | ||
398 | ret = lm3630_backlight_register(pchip, BLED_1); | ||
399 | break; | ||
400 | case BANK_A_CTRL_LED2: | ||
401 | ret = lm3630_backlight_register(pchip, BLED_2); | ||
402 | pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; | ||
403 | break; | ||
404 | default: | ||
405 | break; | ||
406 | } | ||
407 | |||
408 | if (ret < 0) | ||
409 | goto err_bl_reg; | ||
410 | |||
411 | if (pdata->bank_b_ctrl && pchip->bled2 == NULL) { | ||
412 | ret = lm3630_backlight_register(pchip, BLED_2); | ||
413 | if (ret < 0) | ||
414 | goto err_bl_reg; | ||
415 | } | ||
416 | |||
417 | /* interrupt enable : irq 0 is not allowed for lm3630 */ | ||
418 | pchip->irq = client->irq; | ||
419 | if (pchip->irq) | ||
420 | lm3630_intr_config(pchip); | ||
421 | |||
422 | dev_info(&client->dev, "LM3630 backlight register OK.\n"); | ||
423 | return 0; | ||
424 | |||
425 | err_bl_reg: | ||
426 | dev_err(&client->dev, "fail : backlight register.\n"); | ||
427 | lm3630_backlight_unregister(pchip); | ||
428 | err_chip_init: | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | static int __devexit lm3630_remove(struct i2c_client *client) | ||
433 | { | ||
434 | int ret; | ||
435 | struct lm3630_chip_data *pchip = i2c_get_clientdata(client); | ||
436 | |||
437 | ret = regmap_write(pchip->regmap, REG_BRT_A, 0); | ||
438 | if (ret < 0) | ||
439 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
440 | |||
441 | ret = regmap_write(pchip->regmap, REG_BRT_B, 0); | ||
442 | if (ret < 0) | ||
443 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
444 | |||
445 | lm3630_backlight_unregister(pchip); | ||
446 | if (pchip->irq) { | ||
447 | free_irq(pchip->irq, pchip); | ||
448 | flush_workqueue(pchip->irqthread); | ||
449 | destroy_workqueue(pchip->irqthread); | ||
450 | } | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static const struct i2c_device_id lm3630_id[] = { | ||
455 | {LM3630_NAME, 0}, | ||
456 | {} | ||
457 | }; | ||
458 | |||
459 | MODULE_DEVICE_TABLE(i2c, lm3630_id); | ||
460 | |||
461 | static struct i2c_driver lm3630_i2c_driver = { | ||
462 | .driver = { | ||
463 | .name = LM3630_NAME, | ||
464 | }, | ||
465 | .probe = lm3630_probe, | ||
466 | .remove = __devexit_p(lm3630_remove), | ||
467 | .id_table = lm3630_id, | ||
468 | }; | ||
469 | |||
470 | module_i2c_driver(lm3630_i2c_driver); | ||
471 | |||
472 | MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630"); | ||
473 | MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); | ||
474 | MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); | ||
475 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c new file mode 100644 index 000000000000..c6915c6c3cd1 --- /dev/null +++ b/drivers/video/backlight/lm3639_bl.c | |||
@@ -0,0 +1,437 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3639 Backlight + Flash LED driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/leds.h> | ||
14 | #include <linux/backlight.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/uaccess.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/platform_data/lm3639_bl.h> | ||
21 | |||
22 | #define REG_DEV_ID 0x00 | ||
23 | #define REG_CHECKSUM 0x01 | ||
24 | #define REG_BL_CONF_1 0x02 | ||
25 | #define REG_BL_CONF_2 0x03 | ||
26 | #define REG_BL_CONF_3 0x04 | ||
27 | #define REG_BL_CONF_4 0x05 | ||
28 | #define REG_FL_CONF_1 0x06 | ||
29 | #define REG_FL_CONF_2 0x07 | ||
30 | #define REG_FL_CONF_3 0x08 | ||
31 | #define REG_IO_CTRL 0x09 | ||
32 | #define REG_ENABLE 0x0A | ||
33 | #define REG_FLAG 0x0B | ||
34 | #define REG_MAX REG_FLAG | ||
35 | |||
36 | struct lm3639_chip_data { | ||
37 | struct device *dev; | ||
38 | struct lm3639_platform_data *pdata; | ||
39 | |||
40 | struct backlight_device *bled; | ||
41 | struct led_classdev cdev_flash; | ||
42 | struct led_classdev cdev_torch; | ||
43 | struct regmap *regmap; | ||
44 | |||
45 | unsigned int bled_mode; | ||
46 | unsigned int bled_map; | ||
47 | unsigned int last_flag; | ||
48 | }; | ||
49 | |||
50 | /* initialize chip */ | ||
51 | static int __devinit lm3639_chip_init(struct lm3639_chip_data *pchip) | ||
52 | { | ||
53 | int ret; | ||
54 | unsigned int reg_val; | ||
55 | struct lm3639_platform_data *pdata = pchip->pdata; | ||
56 | |||
57 | /* input pins config. */ | ||
58 | ret = | ||
59 | regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x08, | ||
60 | pdata->pin_pwm); | ||
61 | if (ret < 0) | ||
62 | goto out; | ||
63 | |||
64 | reg_val = (pdata->pin_pwm & 0x40) | pdata->pin_strobe | pdata->pin_tx; | ||
65 | ret = regmap_update_bits(pchip->regmap, REG_IO_CTRL, 0x7C, reg_val); | ||
66 | if (ret < 0) | ||
67 | goto out; | ||
68 | |||
69 | /* init brightness */ | ||
70 | ret = regmap_write(pchip->regmap, REG_BL_CONF_4, pdata->init_brt_led); | ||
71 | if (ret < 0) | ||
72 | goto out; | ||
73 | |||
74 | ret = regmap_write(pchip->regmap, REG_BL_CONF_3, pdata->init_brt_led); | ||
75 | if (ret < 0) | ||
76 | goto out; | ||
77 | |||
78 | /* output pins config. */ | ||
79 | if (!pdata->init_brt_led) | ||
80 | reg_val = pdata->fled_pins | pdata->bled_pins; | ||
81 | else | ||
82 | reg_val = pdata->fled_pins | pdata->bled_pins | 0x01; | ||
83 | |||
84 | ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x79, reg_val); | ||
85 | if (ret < 0) | ||
86 | goto out; | ||
87 | |||
88 | return ret; | ||
89 | out: | ||
90 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | /* update and get brightness */ | ||
95 | static int lm3639_bled_update_status(struct backlight_device *bl) | ||
96 | { | ||
97 | int ret; | ||
98 | unsigned int reg_val; | ||
99 | struct lm3639_chip_data *pchip = bl_get_data(bl); | ||
100 | struct lm3639_platform_data *pdata = pchip->pdata; | ||
101 | |||
102 | ret = regmap_read(pchip->regmap, REG_FLAG, ®_val); | ||
103 | if (ret < 0) | ||
104 | goto out; | ||
105 | |||
106 | if (reg_val != 0) | ||
107 | dev_info(pchip->dev, "last flag is 0x%x\n", reg_val); | ||
108 | |||
109 | /* pwm control */ | ||
110 | if (pdata->pin_pwm) { | ||
111 | if (pdata->pwm_set_intensity) | ||
112 | pdata->pwm_set_intensity(bl->props.brightness, | ||
113 | pdata->max_brt_led); | ||
114 | else | ||
115 | dev_err(pchip->dev, | ||
116 | "No pwm control func. in plat-data\n"); | ||
117 | return bl->props.brightness; | ||
118 | } | ||
119 | |||
120 | /* i2c control and set brigtness */ | ||
121 | ret = regmap_write(pchip->regmap, REG_BL_CONF_4, bl->props.brightness); | ||
122 | if (ret < 0) | ||
123 | goto out; | ||
124 | ret = regmap_write(pchip->regmap, REG_BL_CONF_3, bl->props.brightness); | ||
125 | if (ret < 0) | ||
126 | goto out; | ||
127 | |||
128 | if (!bl->props.brightness) | ||
129 | ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x00); | ||
130 | else | ||
131 | ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x01, 0x01); | ||
132 | if (ret < 0) | ||
133 | goto out; | ||
134 | |||
135 | return bl->props.brightness; | ||
136 | out: | ||
137 | dev_err(pchip->dev, "i2c failed to access registers\n"); | ||
138 | return bl->props.brightness; | ||
139 | } | ||
140 | |||
141 | static int lm3639_bled_get_brightness(struct backlight_device *bl) | ||
142 | { | ||
143 | int ret; | ||
144 | unsigned int reg_val; | ||
145 | struct lm3639_chip_data *pchip = bl_get_data(bl); | ||
146 | struct lm3639_platform_data *pdata = pchip->pdata; | ||
147 | |||
148 | if (pdata->pin_pwm) { | ||
149 | if (pdata->pwm_get_intensity) | ||
150 | bl->props.brightness = pdata->pwm_get_intensity(); | ||
151 | else | ||
152 | dev_err(pchip->dev, | ||
153 | "No pwm control func. in plat-data\n"); | ||
154 | return bl->props.brightness; | ||
155 | } | ||
156 | |||
157 | ret = regmap_read(pchip->regmap, REG_BL_CONF_1, ®_val); | ||
158 | if (ret < 0) | ||
159 | goto out; | ||
160 | if (reg_val & 0x10) | ||
161 | ret = regmap_read(pchip->regmap, REG_BL_CONF_4, ®_val); | ||
162 | else | ||
163 | ret = regmap_read(pchip->regmap, REG_BL_CONF_3, ®_val); | ||
164 | if (ret < 0) | ||
165 | goto out; | ||
166 | bl->props.brightness = reg_val; | ||
167 | |||
168 | return bl->props.brightness; | ||
169 | out: | ||
170 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
171 | return bl->props.brightness; | ||
172 | } | ||
173 | |||
174 | static const struct backlight_ops lm3639_bled_ops = { | ||
175 | .options = BL_CORE_SUSPENDRESUME, | ||
176 | .update_status = lm3639_bled_update_status, | ||
177 | .get_brightness = lm3639_bled_get_brightness, | ||
178 | }; | ||
179 | |||
180 | /* backlight mapping mode */ | ||
181 | static ssize_t lm3639_bled_mode_store(struct device *dev, | ||
182 | struct device_attribute *devAttr, | ||
183 | const char *buf, size_t size) | ||
184 | { | ||
185 | ssize_t ret; | ||
186 | struct lm3639_chip_data *pchip = dev_get_drvdata(dev); | ||
187 | unsigned int state; | ||
188 | |||
189 | ret = kstrtouint(buf, 10, &state); | ||
190 | if (ret) | ||
191 | goto out_input; | ||
192 | |||
193 | if (!state) | ||
194 | ret = | ||
195 | regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10, | ||
196 | 0x00); | ||
197 | else | ||
198 | ret = | ||
199 | regmap_update_bits(pchip->regmap, REG_BL_CONF_1, 0x10, | ||
200 | 0x10); | ||
201 | |||
202 | if (ret < 0) | ||
203 | goto out; | ||
204 | |||
205 | return size; | ||
206 | |||
207 | out: | ||
208 | dev_err(pchip->dev, "%s:i2c access fail to register\n", __func__); | ||
209 | return size; | ||
210 | |||
211 | out_input: | ||
212 | dev_err(pchip->dev, "%s:input conversion fail\n", __func__); | ||
213 | return size; | ||
214 | |||
215 | } | ||
216 | |||
217 | static DEVICE_ATTR(bled_mode, 0666, NULL, lm3639_bled_mode_store); | ||
218 | |||
219 | /* torch */ | ||
220 | static void lm3639_torch_brightness_set(struct led_classdev *cdev, | ||
221 | enum led_brightness brightness) | ||
222 | { | ||
223 | int ret; | ||
224 | unsigned int reg_val; | ||
225 | struct lm3639_chip_data *pchip; | ||
226 | |||
227 | pchip = container_of(cdev, struct lm3639_chip_data, cdev_torch); | ||
228 | |||
229 | ret = regmap_read(pchip->regmap, REG_FLAG, ®_val); | ||
230 | if (ret < 0) | ||
231 | goto out; | ||
232 | if (reg_val != 0) | ||
233 | dev_info(pchip->dev, "last flag is 0x%x\n", reg_val); | ||
234 | |||
235 | /* brightness 0 means off state */ | ||
236 | if (!brightness) { | ||
237 | ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00); | ||
238 | if (ret < 0) | ||
239 | goto out; | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | ret = regmap_update_bits(pchip->regmap, | ||
244 | REG_FL_CONF_1, 0x70, (brightness - 1) << 4); | ||
245 | if (ret < 0) | ||
246 | goto out; | ||
247 | ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x02); | ||
248 | if (ret < 0) | ||
249 | goto out; | ||
250 | |||
251 | return; | ||
252 | out: | ||
253 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
254 | return; | ||
255 | } | ||
256 | |||
257 | /* flash */ | ||
258 | static void lm3639_flash_brightness_set(struct led_classdev *cdev, | ||
259 | enum led_brightness brightness) | ||
260 | { | ||
261 | int ret; | ||
262 | unsigned int reg_val; | ||
263 | struct lm3639_chip_data *pchip; | ||
264 | |||
265 | pchip = container_of(cdev, struct lm3639_chip_data, cdev_flash); | ||
266 | |||
267 | ret = regmap_read(pchip->regmap, REG_FLAG, ®_val); | ||
268 | if (ret < 0) | ||
269 | goto out; | ||
270 | if (reg_val != 0) | ||
271 | dev_info(pchip->dev, "last flag is 0x%x\n", reg_val); | ||
272 | |||
273 | /* torch off before flash control */ | ||
274 | ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x00); | ||
275 | if (ret < 0) | ||
276 | goto out; | ||
277 | |||
278 | /* brightness 0 means off state */ | ||
279 | if (!brightness) | ||
280 | return; | ||
281 | |||
282 | ret = regmap_update_bits(pchip->regmap, | ||
283 | REG_FL_CONF_1, 0x0F, brightness - 1); | ||
284 | if (ret < 0) | ||
285 | goto out; | ||
286 | ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x06, 0x06); | ||
287 | if (ret < 0) | ||
288 | goto out; | ||
289 | |||
290 | return; | ||
291 | out: | ||
292 | dev_err(pchip->dev, "i2c failed to access register\n"); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | static const struct regmap_config lm3639_regmap = { | ||
297 | .reg_bits = 8, | ||
298 | .val_bits = 8, | ||
299 | .max_register = REG_MAX, | ||
300 | }; | ||
301 | |||
302 | static int __devinit lm3639_probe(struct i2c_client *client, | ||
303 | const struct i2c_device_id *id) | ||
304 | { | ||
305 | int ret; | ||
306 | struct lm3639_chip_data *pchip; | ||
307 | struct lm3639_platform_data *pdata = client->dev.platform_data; | ||
308 | struct backlight_properties props; | ||
309 | |||
310 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
311 | dev_err(&client->dev, "i2c functionality check fail.\n"); | ||
312 | return -EOPNOTSUPP; | ||
313 | } | ||
314 | |||
315 | if (pdata == NULL) { | ||
316 | dev_err(&client->dev, "Needs Platform Data.\n"); | ||
317 | return -ENODATA; | ||
318 | } | ||
319 | |||
320 | pchip = devm_kzalloc(&client->dev, | ||
321 | sizeof(struct lm3639_chip_data), GFP_KERNEL); | ||
322 | if (!pchip) | ||
323 | return -ENOMEM; | ||
324 | |||
325 | pchip->pdata = pdata; | ||
326 | pchip->dev = &client->dev; | ||
327 | |||
328 | pchip->regmap = devm_regmap_init_i2c(client, &lm3639_regmap); | ||
329 | if (IS_ERR(pchip->regmap)) { | ||
330 | ret = PTR_ERR(pchip->regmap); | ||
331 | dev_err(&client->dev, "fail : allocate register map: %d\n", | ||
332 | ret); | ||
333 | return ret; | ||
334 | } | ||
335 | i2c_set_clientdata(client, pchip); | ||
336 | |||
337 | /* chip initialize */ | ||
338 | ret = lm3639_chip_init(pchip); | ||
339 | if (ret < 0) { | ||
340 | dev_err(&client->dev, "fail : chip init\n"); | ||
341 | goto err_out; | ||
342 | } | ||
343 | |||
344 | /* backlight */ | ||
345 | props.type = BACKLIGHT_RAW; | ||
346 | props.brightness = pdata->init_brt_led; | ||
347 | props.max_brightness = pdata->max_brt_led; | ||
348 | pchip->bled = | ||
349 | backlight_device_register("lm3639_bled", pchip->dev, pchip, | ||
350 | &lm3639_bled_ops, &props); | ||
351 | if (IS_ERR(pchip->bled)) { | ||
352 | dev_err(&client->dev, "fail : backlight register\n"); | ||
353 | ret = -EIO; | ||
354 | goto err_out; | ||
355 | } | ||
356 | |||
357 | ret = device_create_file(&(pchip->bled->dev), &dev_attr_bled_mode); | ||
358 | if (ret < 0) { | ||
359 | dev_err(&client->dev, "failed : add sysfs entries\n"); | ||
360 | ret = -EIO; | ||
361 | goto err_bled_mode; | ||
362 | } | ||
363 | |||
364 | /* flash */ | ||
365 | pchip->cdev_flash.name = "lm3639_flash"; | ||
366 | pchip->cdev_flash.max_brightness = 16; | ||
367 | pchip->cdev_flash.brightness_set = lm3639_flash_brightness_set; | ||
368 | ret = led_classdev_register((struct device *) | ||
369 | &client->dev, &pchip->cdev_flash); | ||
370 | if (ret < 0) { | ||
371 | dev_err(&client->dev, "fail : flash register\n"); | ||
372 | ret = -EIO; | ||
373 | goto err_flash; | ||
374 | } | ||
375 | |||
376 | /* torch */ | ||
377 | pchip->cdev_torch.name = "lm3639_torch"; | ||
378 | pchip->cdev_torch.max_brightness = 8; | ||
379 | pchip->cdev_torch.brightness_set = lm3639_torch_brightness_set; | ||
380 | ret = led_classdev_register((struct device *) | ||
381 | &client->dev, &pchip->cdev_torch); | ||
382 | if (ret < 0) { | ||
383 | dev_err(&client->dev, "fail : torch register\n"); | ||
384 | ret = -EIO; | ||
385 | goto err_torch; | ||
386 | } | ||
387 | |||
388 | return 0; | ||
389 | |||
390 | err_torch: | ||
391 | led_classdev_unregister(&pchip->cdev_flash); | ||
392 | err_flash: | ||
393 | device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode); | ||
394 | err_bled_mode: | ||
395 | backlight_device_unregister(pchip->bled); | ||
396 | err_out: | ||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | static int __devexit lm3639_remove(struct i2c_client *client) | ||
401 | { | ||
402 | struct lm3639_chip_data *pchip = i2c_get_clientdata(client); | ||
403 | |||
404 | regmap_write(pchip->regmap, REG_ENABLE, 0x00); | ||
405 | |||
406 | if (&pchip->cdev_torch) | ||
407 | led_classdev_unregister(&pchip->cdev_torch); | ||
408 | if (&pchip->cdev_flash) | ||
409 | led_classdev_unregister(&pchip->cdev_flash); | ||
410 | if (pchip->bled) { | ||
411 | device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode); | ||
412 | backlight_device_unregister(pchip->bled); | ||
413 | } | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static const struct i2c_device_id lm3639_id[] = { | ||
418 | {LM3639_NAME, 0}, | ||
419 | {} | ||
420 | }; | ||
421 | |||
422 | MODULE_DEVICE_TABLE(i2c, lm3639_id); | ||
423 | static struct i2c_driver lm3639_i2c_driver = { | ||
424 | .driver = { | ||
425 | .name = LM3639_NAME, | ||
426 | }, | ||
427 | .probe = lm3639_probe, | ||
428 | .remove = __devexit_p(lm3639_remove), | ||
429 | .id_table = lm3639_id, | ||
430 | }; | ||
431 | |||
432 | module_i2c_driver(lm3639_i2c_driver); | ||
433 | |||
434 | MODULE_DESCRIPTION("Texas Instruments Backlight+Flash LED driver for LM3639"); | ||
435 | MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); | ||
436 | MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); | ||
437 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index 6c0f1ac0d32a..4066a5bbd826 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c | |||
@@ -75,7 +75,7 @@ static int ltv350qv_power_on(struct ltv350qv *lcd) | |||
75 | /* Power On Reset Display off State */ | 75 | /* Power On Reset Display off State */ |
76 | if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000)) | 76 | if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, 0x0000)) |
77 | goto err; | 77 | goto err; |
78 | msleep(15); | 78 | usleep_range(15000, 16000); |
79 | 79 | ||
80 | /* Power Setting Function 1 */ | 80 | /* Power Setting Function 1 */ |
81 | if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE)) | 81 | if (ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE)) |
@@ -153,7 +153,7 @@ err_settings: | |||
153 | err_power2: | 153 | err_power2: |
154 | err_power1: | 154 | err_power1: |
155 | ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000); | 155 | ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000); |
156 | msleep(1); | 156 | usleep_range(1000, 1100); |
157 | err: | 157 | err: |
158 | ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE); | 158 | ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE); |
159 | return -EIO; | 159 | return -EIO; |
@@ -175,7 +175,7 @@ static int ltv350qv_power_off(struct ltv350qv *lcd) | |||
175 | ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000); | 175 | ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL2, 0x0000); |
176 | 176 | ||
177 | /* Wait at least 1 ms */ | 177 | /* Wait at least 1 ms */ |
178 | msleep(1); | 178 | usleep_range(1000, 1100); |
179 | 179 | ||
180 | /* Power down setting 2 */ | 180 | /* Power down setting 2 */ |
181 | ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE); | 181 | ret |= ltv350qv_write_reg(lcd, LTV_PWRCTL1, LTV_VCOM_DISABLE); |
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index b6672340d6c7..ca4f5d70fe10 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/fb.h> | 16 | #include <linux/fb.h> |
17 | #include <linux/backlight.h> | 17 | #include <linux/backlight.h> |
18 | #include <linux/lcd.h> | 18 | #include <linux/lcd.h> |
19 | #include <linux/of.h> | ||
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
20 | 21 | ||
21 | #include <video/platform_lcd.h> | 22 | #include <video/platform_lcd.h> |
@@ -145,6 +146,14 @@ static SIMPLE_DEV_PM_OPS(platform_lcd_pm_ops, platform_lcd_suspend, | |||
145 | platform_lcd_resume); | 146 | platform_lcd_resume); |
146 | #endif | 147 | #endif |
147 | 148 | ||
149 | #ifdef CONFIG_OF | ||
150 | static const struct of_device_id platform_lcd_of_match[] = { | ||
151 | { .compatible = "platform-lcd" }, | ||
152 | {}, | ||
153 | }; | ||
154 | MODULE_DEVICE_TABLE(of, platform_lcd_of_match); | ||
155 | #endif | ||
156 | |||
148 | static struct platform_driver platform_lcd_driver = { | 157 | static struct platform_driver platform_lcd_driver = { |
149 | .driver = { | 158 | .driver = { |
150 | .name = "platform-lcd", | 159 | .name = "platform-lcd", |
@@ -152,6 +161,7 @@ static struct platform_driver platform_lcd_driver = { | |||
152 | #ifdef CONFIG_PM | 161 | #ifdef CONFIG_PM |
153 | .pm = &platform_lcd_pm_ops, | 162 | .pm = &platform_lcd_pm_ops, |
154 | #endif | 163 | #endif |
164 | .of_match_table = of_match_ptr(platform_lcd_of_match), | ||
155 | }, | 165 | }, |
156 | .probe = platform_lcd_probe, | 166 | .probe = platform_lcd_probe, |
157 | .remove = __devexit_p(platform_lcd_remove), | 167 | .remove = __devexit_p(platform_lcd_remove), |
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c deleted file mode 100644 index 69b35f02929e..000000000000 --- a/drivers/video/backlight/progear_bl.c +++ /dev/null | |||
@@ -1,162 +0,0 @@ | |||
1 | /* | ||
2 | * Backlight Driver for Frontpath ProGear HX1050+ | ||
3 | * | ||
4 | * Copyright (c) 2006 Marcin Juszkiewicz | ||
5 | * | ||
6 | * Based on Progear LCD driver by M Schacht | ||
7 | * <mschacht at alumni dot washington dot edu> | ||
8 | * | ||
9 | * Based on Sharp's Corgi Backlight Driver | ||
10 | * Based on Backlight Driver for HP Jornada 680 | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/mutex.h> | ||
25 | #include <linux/fb.h> | ||
26 | #include <linux/backlight.h> | ||
27 | #include <linux/pci.h> | ||
28 | |||
29 | #define PMU_LPCR 0xB0 | ||
30 | #define SB_MPS1 0x61 | ||
31 | #define HW_LEVEL_MAX 0x77 | ||
32 | #define HW_LEVEL_MIN 0x4f | ||
33 | |||
34 | static struct pci_dev *pmu_dev = NULL; | ||
35 | static struct pci_dev *sb_dev = NULL; | ||
36 | |||
37 | static int progearbl_set_intensity(struct backlight_device *bd) | ||
38 | { | ||
39 | int intensity = bd->props.brightness; | ||
40 | |||
41 | if (bd->props.power != FB_BLANK_UNBLANK) | ||
42 | intensity = 0; | ||
43 | if (bd->props.fb_blank != FB_BLANK_UNBLANK) | ||
44 | intensity = 0; | ||
45 | |||
46 | pci_write_config_byte(pmu_dev, PMU_LPCR, intensity + HW_LEVEL_MIN); | ||
47 | |||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static int progearbl_get_intensity(struct backlight_device *bd) | ||
52 | { | ||
53 | u8 intensity; | ||
54 | pci_read_config_byte(pmu_dev, PMU_LPCR, &intensity); | ||
55 | |||
56 | return intensity - HW_LEVEL_MIN; | ||
57 | } | ||
58 | |||
59 | static const struct backlight_ops progearbl_ops = { | ||
60 | .get_brightness = progearbl_get_intensity, | ||
61 | .update_status = progearbl_set_intensity, | ||
62 | }; | ||
63 | |||
64 | static int progearbl_probe(struct platform_device *pdev) | ||
65 | { | ||
66 | struct backlight_properties props; | ||
67 | u8 temp; | ||
68 | struct backlight_device *progear_backlight_device; | ||
69 | int ret; | ||
70 | |||
71 | pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); | ||
72 | if (!pmu_dev) { | ||
73 | pr_err("ALI M7101 PMU not found.\n"); | ||
74 | return -ENODEV; | ||
75 | } | ||
76 | |||
77 | sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); | ||
78 | if (!sb_dev) { | ||
79 | pr_err("ALI 1533 SB not found.\n"); | ||
80 | ret = -ENODEV; | ||
81 | goto put_pmu; | ||
82 | } | ||
83 | |||
84 | /* Set SB_MPS1 to enable brightness control. */ | ||
85 | pci_read_config_byte(sb_dev, SB_MPS1, &temp); | ||
86 | pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20); | ||
87 | |||
88 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
89 | props.type = BACKLIGHT_RAW; | ||
90 | props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; | ||
91 | progear_backlight_device = backlight_device_register("progear-bl", | ||
92 | &pdev->dev, NULL, | ||
93 | &progearbl_ops, | ||
94 | &props); | ||
95 | if (IS_ERR(progear_backlight_device)) { | ||
96 | ret = PTR_ERR(progear_backlight_device); | ||
97 | goto put_sb; | ||
98 | } | ||
99 | |||
100 | platform_set_drvdata(pdev, progear_backlight_device); | ||
101 | |||
102 | progear_backlight_device->props.power = FB_BLANK_UNBLANK; | ||
103 | progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN; | ||
104 | progearbl_set_intensity(progear_backlight_device); | ||
105 | |||
106 | return 0; | ||
107 | put_sb: | ||
108 | pci_dev_put(sb_dev); | ||
109 | put_pmu: | ||
110 | pci_dev_put(pmu_dev); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | static int progearbl_remove(struct platform_device *pdev) | ||
115 | { | ||
116 | struct backlight_device *bd = platform_get_drvdata(pdev); | ||
117 | backlight_device_unregister(bd); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static struct platform_driver progearbl_driver = { | ||
123 | .probe = progearbl_probe, | ||
124 | .remove = progearbl_remove, | ||
125 | .driver = { | ||
126 | .name = "progear-bl", | ||
127 | }, | ||
128 | }; | ||
129 | |||
130 | static struct platform_device *progearbl_device; | ||
131 | |||
132 | static int __init progearbl_init(void) | ||
133 | { | ||
134 | int ret = platform_driver_register(&progearbl_driver); | ||
135 | |||
136 | if (ret) | ||
137 | return ret; | ||
138 | progearbl_device = platform_device_register_simple("progear-bl", -1, | ||
139 | NULL, 0); | ||
140 | if (IS_ERR(progearbl_device)) { | ||
141 | platform_driver_unregister(&progearbl_driver); | ||
142 | return PTR_ERR(progearbl_device); | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static void __exit progearbl_exit(void) | ||
149 | { | ||
150 | pci_dev_put(pmu_dev); | ||
151 | pci_dev_put(sb_dev); | ||
152 | |||
153 | platform_device_unregister(progearbl_device); | ||
154 | platform_driver_unregister(&progearbl_driver); | ||
155 | } | ||
156 | |||
157 | module_init(progearbl_init); | ||
158 | module_exit(progearbl_exit); | ||
159 | |||
160 | MODULE_AUTHOR("Marcin Juszkiewicz <linux@hrw.one.pl>"); | ||
161 | MODULE_DESCRIPTION("ProGear Backlight Driver"); | ||
162 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c index 5a5d0928df33..265c5ed59ade 100644 --- a/drivers/video/geode/gx1fb_core.c +++ b/drivers/video/geode/gx1fb_core.c | |||
@@ -29,7 +29,7 @@ static int crt_option = 1; | |||
29 | static char panel_option[32] = ""; | 29 | static char panel_option[32] = ""; |
30 | 30 | ||
31 | /* Modes relevant to the GX1 (taken from modedb.c) */ | 31 | /* Modes relevant to the GX1 (taken from modedb.c) */ |
32 | static const struct fb_videomode __devinitdata gx1_modedb[] = { | 32 | static const struct fb_videomode __devinitconst gx1_modedb[] = { |
33 | /* 640x480-60 VESA */ | 33 | /* 640x480-60 VESA */ |
34 | { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, | 34 | { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, |
35 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | 35 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, |
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c index 0fad23f810a3..0e9afa41d163 100644 --- a/drivers/video/gxt4500.c +++ b/drivers/video/gxt4500.c | |||
@@ -156,7 +156,7 @@ struct gxt4500_par { | |||
156 | static char *mode_option; | 156 | static char *mode_option; |
157 | 157 | ||
158 | /* default mode: 1280x1024 @ 60 Hz, 8 bpp */ | 158 | /* default mode: 1280x1024 @ 60 Hz, 8 bpp */ |
159 | static const struct fb_videomode defaultmode __devinitdata = { | 159 | static const struct fb_videomode defaultmode __devinitconst = { |
160 | .refresh = 60, | 160 | .refresh = 60, |
161 | .xres = 1280, | 161 | .xres = 1280, |
162 | .yres = 1024, | 162 | .yres = 1024, |
@@ -581,7 +581,7 @@ static int gxt4500_blank(int blank, struct fb_info *info) | |||
581 | return 0; | 581 | return 0; |
582 | } | 582 | } |
583 | 583 | ||
584 | static const struct fb_fix_screeninfo gxt4500_fix __devinitdata = { | 584 | static const struct fb_fix_screeninfo gxt4500_fix __devinitconst = { |
585 | .id = "IBM GXT4500P", | 585 | .id = "IBM GXT4500P", |
586 | .type = FB_TYPE_PACKED_PIXELS, | 586 | .type = FB_TYPE_PACKED_PIXELS, |
587 | .visual = FB_VISUAL_PSEUDOCOLOR, | 587 | .visual = FB_VISUAL_PSEUDOCOLOR, |
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index b83f36190cae..5c067816a81d 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -97,7 +97,7 @@ static int i810fb_blank (int blank_mode, struct fb_info *info); | |||
97 | static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par); | 97 | static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par); |
98 | 98 | ||
99 | /* PCI */ | 99 | /* PCI */ |
100 | static const char *i810_pci_list[] __devinitdata = { | 100 | static const char * const i810_pci_list[] __devinitconst = { |
101 | "Intel(R) 810 Framebuffer Device" , | 101 | "Intel(R) 810 Framebuffer Device" , |
102 | "Intel(R) 810-DC100 Framebuffer Device" , | 102 | "Intel(R) 810-DC100 Framebuffer Device" , |
103 | "Intel(R) 810E Framebuffer Device" , | 103 | "Intel(R) 810E Framebuffer Device" , |
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c index de366937c933..3c63fc24bb1f 100644 --- a/drivers/video/jz4740_fb.c +++ b/drivers/video/jz4740_fb.c | |||
@@ -136,7 +136,7 @@ struct jzfb { | |||
136 | uint32_t pseudo_palette[16]; | 136 | uint32_t pseudo_palette[16]; |
137 | }; | 137 | }; |
138 | 138 | ||
139 | static const struct fb_fix_screeninfo jzfb_fix __devinitdata = { | 139 | static const struct fb_fix_screeninfo jzfb_fix __devinitconst = { |
140 | .id = "JZ4740 FB", | 140 | .id = "JZ4740 FB", |
141 | .type = FB_TYPE_PACKED_PIXELS, | 141 | .type = FB_TYPE_PACKED_PIXELS, |
142 | .visual = FB_VISUAL_TRUECOLOR, | 142 | .visual = FB_VISUAL_TRUECOLOR, |
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 022574202749..0efd1524b977 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt | |||
@@ -164,3 +164,11 @@ config BINFMT_MISC | |||
164 | You may say M here for module support and later load the module when | 164 | You may say M here for module support and later load the module when |
165 | you have use for it; the module is called binfmt_misc. If you | 165 | you have use for it; the module is called binfmt_misc. If you |
166 | don't know what to answer at this point, say Y. | 166 | don't know what to answer at this point, say Y. |
167 | |||
168 | config COREDUMP | ||
169 | bool "Enable core dump support" if EXPERT | ||
170 | default y | ||
171 | help | ||
172 | This option enables support for performing core dumps. You almost | ||
173 | certainly want to say Y here. Not necessary on systems that never | ||
174 | need debugging or only ever run flawless code. | ||
diff --git a/fs/Makefile b/fs/Makefile index 8938f8250320..1d7af79288a0 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
@@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \ | |||
11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ | 11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ |
12 | seq_file.o xattr.o libfs.o fs-writeback.o \ | 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ |
13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ | 13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ |
14 | stack.o fs_struct.o statfs.o coredump.o | 14 | stack.o fs_struct.o statfs.o |
15 | 15 | ||
16 | ifeq ($(CONFIG_BLOCK),y) | 16 | ifeq ($(CONFIG_BLOCK),y) |
17 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o | 17 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o |
@@ -48,6 +48,7 @@ obj-$(CONFIG_FS_MBCACHE) += mbcache.o | |||
48 | obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o | 48 | obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o |
49 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ | 49 | obj-$(CONFIG_NFS_COMMON) += nfs_common/ |
50 | obj-$(CONFIG_GENERIC_ACL) += generic_acl.o | 50 | obj-$(CONFIG_GENERIC_ACL) += generic_acl.o |
51 | obj-$(CONFIG_COREDUMP) += coredump.o | ||
51 | 52 | ||
52 | obj-$(CONFIG_FHANDLE) += fhandle.o | 53 | obj-$(CONFIG_FHANDLE) += fhandle.o |
53 | 54 | ||
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index d146e181d10d..0e7a6f81ae36 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -32,31 +32,8 @@ | |||
32 | 32 | ||
33 | static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); | 33 | static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); |
34 | static int load_aout_library(struct file*); | 34 | static int load_aout_library(struct file*); |
35 | static int aout_core_dump(struct coredump_params *cprm); | ||
36 | |||
37 | static struct linux_binfmt aout_format = { | ||
38 | .module = THIS_MODULE, | ||
39 | .load_binary = load_aout_binary, | ||
40 | .load_shlib = load_aout_library, | ||
41 | .core_dump = aout_core_dump, | ||
42 | .min_coredump = PAGE_SIZE | ||
43 | }; | ||
44 | |||
45 | #define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) | ||
46 | |||
47 | static int set_brk(unsigned long start, unsigned long end) | ||
48 | { | ||
49 | start = PAGE_ALIGN(start); | ||
50 | end = PAGE_ALIGN(end); | ||
51 | if (end > start) { | ||
52 | unsigned long addr; | ||
53 | addr = vm_brk(start, end - start); | ||
54 | if (BAD_ADDR(addr)) | ||
55 | return addr; | ||
56 | } | ||
57 | return 0; | ||
58 | } | ||
59 | 35 | ||
36 | #ifdef CONFIG_COREDUMP | ||
60 | /* | 37 | /* |
61 | * Routine writes a core dump image in the current directory. | 38 | * Routine writes a core dump image in the current directory. |
62 | * Currently only a stub-function. | 39 | * Currently only a stub-function. |
@@ -66,7 +43,6 @@ static int set_brk(unsigned long start, unsigned long end) | |||
66 | * field, which also makes sure the core-dumps won't be recursive if the | 43 | * field, which also makes sure the core-dumps won't be recursive if the |
67 | * dumping of the process results in another error.. | 44 | * dumping of the process results in another error.. |
68 | */ | 45 | */ |
69 | |||
70 | static int aout_core_dump(struct coredump_params *cprm) | 46 | static int aout_core_dump(struct coredump_params *cprm) |
71 | { | 47 | { |
72 | struct file *file = cprm->file; | 48 | struct file *file = cprm->file; |
@@ -89,7 +65,7 @@ static int aout_core_dump(struct coredump_params *cprm) | |||
89 | current->flags |= PF_DUMPCORE; | 65 | current->flags |= PF_DUMPCORE; |
90 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); | 66 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); |
91 | dump.u_ar0 = offsetof(struct user, regs); | 67 | dump.u_ar0 = offsetof(struct user, regs); |
92 | dump.signal = cprm->signr; | 68 | dump.signal = cprm->siginfo->si_signo; |
93 | aout_dump_thread(cprm->regs, &dump); | 69 | aout_dump_thread(cprm->regs, &dump); |
94 | 70 | ||
95 | /* If the size of the dump file exceeds the rlimit, then see what would happen | 71 | /* If the size of the dump file exceeds the rlimit, then see what would happen |
@@ -135,6 +111,32 @@ end_coredump: | |||
135 | set_fs(fs); | 111 | set_fs(fs); |
136 | return has_dumped; | 112 | return has_dumped; |
137 | } | 113 | } |
114 | #else | ||
115 | #define aout_core_dump NULL | ||
116 | #endif | ||
117 | |||
118 | static struct linux_binfmt aout_format = { | ||
119 | .module = THIS_MODULE, | ||
120 | .load_binary = load_aout_binary, | ||
121 | .load_shlib = load_aout_library, | ||
122 | .core_dump = aout_core_dump, | ||
123 | .min_coredump = PAGE_SIZE | ||
124 | }; | ||
125 | |||
126 | #define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) | ||
127 | |||
128 | static int set_brk(unsigned long start, unsigned long end) | ||
129 | { | ||
130 | start = PAGE_ALIGN(start); | ||
131 | end = PAGE_ALIGN(end); | ||
132 | if (end > start) { | ||
133 | unsigned long addr; | ||
134 | addr = vm_brk(start, end - start); | ||
135 | if (BAD_ADDR(addr)) | ||
136 | return addr; | ||
137 | } | ||
138 | return 0; | ||
139 | } | ||
138 | 140 | ||
139 | /* | 141 | /* |
140 | * create_aout_tables() parses the env- and arg-strings in new user | 142 | * create_aout_tables() parses the env- and arg-strings in new user |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 0225fddf49b7..28a64e769527 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/compiler.h> | 27 | #include <linux/compiler.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
30 | #include <linux/vmalloc.h> | ||
30 | #include <linux/security.h> | 31 | #include <linux/security.h> |
31 | #include <linux/random.h> | 32 | #include <linux/random.h> |
32 | #include <linux/elf.h> | 33 | #include <linux/elf.h> |
@@ -37,6 +38,13 @@ | |||
37 | #include <asm/page.h> | 38 | #include <asm/page.h> |
38 | #include <asm/exec.h> | 39 | #include <asm/exec.h> |
39 | 40 | ||
41 | #ifndef user_long_t | ||
42 | #define user_long_t long | ||
43 | #endif | ||
44 | #ifndef user_siginfo_t | ||
45 | #define user_siginfo_t siginfo_t | ||
46 | #endif | ||
47 | |||
40 | static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); | 48 | static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); |
41 | static int load_elf_library(struct file *); | 49 | static int load_elf_library(struct file *); |
42 | static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, | 50 | static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, |
@@ -881,7 +889,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
881 | } | 889 | } |
882 | 890 | ||
883 | if (elf_interpreter) { | 891 | if (elf_interpreter) { |
884 | unsigned long uninitialized_var(interp_map_addr); | 892 | unsigned long interp_map_addr = 0; |
885 | 893 | ||
886 | elf_entry = load_elf_interp(&loc->interp_elf_ex, | 894 | elf_entry = load_elf_interp(&loc->interp_elf_ex, |
887 | interpreter, | 895 | interpreter, |
@@ -1372,6 +1380,103 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) | |||
1372 | fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); | 1380 | fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv); |
1373 | } | 1381 | } |
1374 | 1382 | ||
1383 | static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, | ||
1384 | siginfo_t *siginfo) | ||
1385 | { | ||
1386 | mm_segment_t old_fs = get_fs(); | ||
1387 | set_fs(KERNEL_DS); | ||
1388 | copy_siginfo_to_user((user_siginfo_t __user *) csigdata, siginfo); | ||
1389 | set_fs(old_fs); | ||
1390 | fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata); | ||
1391 | } | ||
1392 | |||
1393 | #define MAX_FILE_NOTE_SIZE (4*1024*1024) | ||
1394 | /* | ||
1395 | * Format of NT_FILE note: | ||
1396 | * | ||
1397 | * long count -- how many files are mapped | ||
1398 | * long page_size -- units for file_ofs | ||
1399 | * array of [COUNT] elements of | ||
1400 | * long start | ||
1401 | * long end | ||
1402 | * long file_ofs | ||
1403 | * followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL... | ||
1404 | */ | ||
1405 | static void fill_files_note(struct memelfnote *note) | ||
1406 | { | ||
1407 | struct vm_area_struct *vma; | ||
1408 | unsigned count, size, names_ofs, remaining, n; | ||
1409 | user_long_t *data; | ||
1410 | user_long_t *start_end_ofs; | ||
1411 | char *name_base, *name_curpos; | ||
1412 | |||
1413 | /* *Estimated* file count and total data size needed */ | ||
1414 | count = current->mm->map_count; | ||
1415 | size = count * 64; | ||
1416 | |||
1417 | names_ofs = (2 + 3 * count) * sizeof(data[0]); | ||
1418 | alloc: | ||
1419 | if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */ | ||
1420 | goto err; | ||
1421 | size = round_up(size, PAGE_SIZE); | ||
1422 | data = vmalloc(size); | ||
1423 | if (!data) | ||
1424 | goto err; | ||
1425 | |||
1426 | start_end_ofs = data + 2; | ||
1427 | name_base = name_curpos = ((char *)data) + names_ofs; | ||
1428 | remaining = size - names_ofs; | ||
1429 | count = 0; | ||
1430 | for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { | ||
1431 | struct file *file; | ||
1432 | const char *filename; | ||
1433 | |||
1434 | file = vma->vm_file; | ||
1435 | if (!file) | ||
1436 | continue; | ||
1437 | filename = d_path(&file->f_path, name_curpos, remaining); | ||
1438 | if (IS_ERR(filename)) { | ||
1439 | if (PTR_ERR(filename) == -ENAMETOOLONG) { | ||
1440 | vfree(data); | ||
1441 | size = size * 5 / 4; | ||
1442 | goto alloc; | ||
1443 | } | ||
1444 | continue; | ||
1445 | } | ||
1446 | |||
1447 | /* d_path() fills at the end, move name down */ | ||
1448 | /* n = strlen(filename) + 1: */ | ||
1449 | n = (name_curpos + remaining) - filename; | ||
1450 | remaining = filename - name_curpos; | ||
1451 | memmove(name_curpos, filename, n); | ||
1452 | name_curpos += n; | ||
1453 | |||
1454 | *start_end_ofs++ = vma->vm_start; | ||
1455 | *start_end_ofs++ = vma->vm_end; | ||
1456 | *start_end_ofs++ = vma->vm_pgoff; | ||
1457 | count++; | ||
1458 | } | ||
1459 | |||
1460 | /* Now we know exact count of files, can store it */ | ||
1461 | data[0] = count; | ||
1462 | data[1] = PAGE_SIZE; | ||
1463 | /* | ||
1464 | * Count usually is less than current->mm->map_count, | ||
1465 | * we need to move filenames down. | ||
1466 | */ | ||
1467 | n = current->mm->map_count - count; | ||
1468 | if (n != 0) { | ||
1469 | unsigned shift_bytes = n * 3 * sizeof(data[0]); | ||
1470 | memmove(name_base - shift_bytes, name_base, | ||
1471 | name_curpos - name_base); | ||
1472 | name_curpos -= shift_bytes; | ||
1473 | } | ||
1474 | |||
1475 | size = name_curpos - (char *)data; | ||
1476 | fill_note(note, "CORE", NT_FILE, size, data); | ||
1477 | err: ; | ||
1478 | } | ||
1479 | |||
1375 | #ifdef CORE_DUMP_USE_REGSET | 1480 | #ifdef CORE_DUMP_USE_REGSET |
1376 | #include <linux/regset.h> | 1481 | #include <linux/regset.h> |
1377 | 1482 | ||
@@ -1385,7 +1490,10 @@ struct elf_thread_core_info { | |||
1385 | struct elf_note_info { | 1490 | struct elf_note_info { |
1386 | struct elf_thread_core_info *thread; | 1491 | struct elf_thread_core_info *thread; |
1387 | struct memelfnote psinfo; | 1492 | struct memelfnote psinfo; |
1493 | struct memelfnote signote; | ||
1388 | struct memelfnote auxv; | 1494 | struct memelfnote auxv; |
1495 | struct memelfnote files; | ||
1496 | user_siginfo_t csigdata; | ||
1389 | size_t size; | 1497 | size_t size; |
1390 | int thread_notes; | 1498 | int thread_notes; |
1391 | }; | 1499 | }; |
@@ -1480,7 +1588,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, | |||
1480 | 1588 | ||
1481 | static int fill_note_info(struct elfhdr *elf, int phdrs, | 1589 | static int fill_note_info(struct elfhdr *elf, int phdrs, |
1482 | struct elf_note_info *info, | 1590 | struct elf_note_info *info, |
1483 | long signr, struct pt_regs *regs) | 1591 | siginfo_t *siginfo, struct pt_regs *regs) |
1484 | { | 1592 | { |
1485 | struct task_struct *dump_task = current; | 1593 | struct task_struct *dump_task = current; |
1486 | const struct user_regset_view *view = task_user_regset_view(dump_task); | 1594 | const struct user_regset_view *view = task_user_regset_view(dump_task); |
@@ -1550,7 +1658,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1550 | * Now fill in each thread's information. | 1658 | * Now fill in each thread's information. |
1551 | */ | 1659 | */ |
1552 | for (t = info->thread; t != NULL; t = t->next) | 1660 | for (t = info->thread; t != NULL; t = t->next) |
1553 | if (!fill_thread_core_info(t, view, signr, &info->size)) | 1661 | if (!fill_thread_core_info(t, view, siginfo->si_signo, &info->size)) |
1554 | return 0; | 1662 | return 0; |
1555 | 1663 | ||
1556 | /* | 1664 | /* |
@@ -1559,9 +1667,15 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1559 | fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm); | 1667 | fill_psinfo(psinfo, dump_task->group_leader, dump_task->mm); |
1560 | info->size += notesize(&info->psinfo); | 1668 | info->size += notesize(&info->psinfo); |
1561 | 1669 | ||
1670 | fill_siginfo_note(&info->signote, &info->csigdata, siginfo); | ||
1671 | info->size += notesize(&info->signote); | ||
1672 | |||
1562 | fill_auxv_note(&info->auxv, current->mm); | 1673 | fill_auxv_note(&info->auxv, current->mm); |
1563 | info->size += notesize(&info->auxv); | 1674 | info->size += notesize(&info->auxv); |
1564 | 1675 | ||
1676 | fill_files_note(&info->files); | ||
1677 | info->size += notesize(&info->files); | ||
1678 | |||
1565 | return 1; | 1679 | return 1; |
1566 | } | 1680 | } |
1567 | 1681 | ||
@@ -1588,8 +1702,12 @@ static int write_note_info(struct elf_note_info *info, | |||
1588 | 1702 | ||
1589 | if (first && !writenote(&info->psinfo, file, foffset)) | 1703 | if (first && !writenote(&info->psinfo, file, foffset)) |
1590 | return 0; | 1704 | return 0; |
1705 | if (first && !writenote(&info->signote, file, foffset)) | ||
1706 | return 0; | ||
1591 | if (first && !writenote(&info->auxv, file, foffset)) | 1707 | if (first && !writenote(&info->auxv, file, foffset)) |
1592 | return 0; | 1708 | return 0; |
1709 | if (first && !writenote(&info->files, file, foffset)) | ||
1710 | return 0; | ||
1593 | 1711 | ||
1594 | for (i = 1; i < info->thread_notes; ++i) | 1712 | for (i = 1; i < info->thread_notes; ++i) |
1595 | if (t->notes[i].data && | 1713 | if (t->notes[i].data && |
@@ -1616,6 +1734,7 @@ static void free_note_info(struct elf_note_info *info) | |||
1616 | kfree(t); | 1734 | kfree(t); |
1617 | } | 1735 | } |
1618 | kfree(info->psinfo.data); | 1736 | kfree(info->psinfo.data); |
1737 | vfree(info->files.data); | ||
1619 | } | 1738 | } |
1620 | 1739 | ||
1621 | #else | 1740 | #else |
@@ -1681,6 +1800,7 @@ struct elf_note_info { | |||
1681 | #ifdef ELF_CORE_COPY_XFPREGS | 1800 | #ifdef ELF_CORE_COPY_XFPREGS |
1682 | elf_fpxregset_t *xfpu; | 1801 | elf_fpxregset_t *xfpu; |
1683 | #endif | 1802 | #endif |
1803 | user_siginfo_t csigdata; | ||
1684 | int thread_status_size; | 1804 | int thread_status_size; |
1685 | int numnote; | 1805 | int numnote; |
1686 | }; | 1806 | }; |
@@ -1690,8 +1810,8 @@ static int elf_note_info_init(struct elf_note_info *info) | |||
1690 | memset(info, 0, sizeof(*info)); | 1810 | memset(info, 0, sizeof(*info)); |
1691 | INIT_LIST_HEAD(&info->thread_list); | 1811 | INIT_LIST_HEAD(&info->thread_list); |
1692 | 1812 | ||
1693 | /* Allocate space for six ELF notes */ | 1813 | /* Allocate space for ELF notes */ |
1694 | info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL); | 1814 | info->notes = kmalloc(8 * sizeof(struct memelfnote), GFP_KERNEL); |
1695 | if (!info->notes) | 1815 | if (!info->notes) |
1696 | return 0; | 1816 | return 0; |
1697 | info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); | 1817 | info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); |
@@ -1713,14 +1833,14 @@ static int elf_note_info_init(struct elf_note_info *info) | |||
1713 | 1833 | ||
1714 | static int fill_note_info(struct elfhdr *elf, int phdrs, | 1834 | static int fill_note_info(struct elfhdr *elf, int phdrs, |
1715 | struct elf_note_info *info, | 1835 | struct elf_note_info *info, |
1716 | long signr, struct pt_regs *regs) | 1836 | siginfo_t *siginfo, struct pt_regs *regs) |
1717 | { | 1837 | { |
1718 | struct list_head *t; | 1838 | struct list_head *t; |
1719 | 1839 | ||
1720 | if (!elf_note_info_init(info)) | 1840 | if (!elf_note_info_init(info)) |
1721 | return 0; | 1841 | return 0; |
1722 | 1842 | ||
1723 | if (signr) { | 1843 | if (siginfo->si_signo) { |
1724 | struct core_thread *ct; | 1844 | struct core_thread *ct; |
1725 | struct elf_thread_status *ets; | 1845 | struct elf_thread_status *ets; |
1726 | 1846 | ||
@@ -1738,13 +1858,13 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1738 | int sz; | 1858 | int sz; |
1739 | 1859 | ||
1740 | ets = list_entry(t, struct elf_thread_status, list); | 1860 | ets = list_entry(t, struct elf_thread_status, list); |
1741 | sz = elf_dump_thread_status(signr, ets); | 1861 | sz = elf_dump_thread_status(siginfo->si_signo, ets); |
1742 | info->thread_status_size += sz; | 1862 | info->thread_status_size += sz; |
1743 | } | 1863 | } |
1744 | } | 1864 | } |
1745 | /* now collect the dump for the current */ | 1865 | /* now collect the dump for the current */ |
1746 | memset(info->prstatus, 0, sizeof(*info->prstatus)); | 1866 | memset(info->prstatus, 0, sizeof(*info->prstatus)); |
1747 | fill_prstatus(info->prstatus, current, signr); | 1867 | fill_prstatus(info->prstatus, current, siginfo->si_signo); |
1748 | elf_core_copy_regs(&info->prstatus->pr_reg, regs); | 1868 | elf_core_copy_regs(&info->prstatus->pr_reg, regs); |
1749 | 1869 | ||
1750 | /* Set up header */ | 1870 | /* Set up header */ |
@@ -1761,9 +1881,11 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1761 | fill_note(info->notes + 1, "CORE", NT_PRPSINFO, | 1881 | fill_note(info->notes + 1, "CORE", NT_PRPSINFO, |
1762 | sizeof(*info->psinfo), info->psinfo); | 1882 | sizeof(*info->psinfo), info->psinfo); |
1763 | 1883 | ||
1764 | info->numnote = 2; | 1884 | fill_siginfo_note(info->notes + 2, &info->csigdata, siginfo); |
1885 | fill_auxv_note(info->notes + 3, current->mm); | ||
1886 | fill_files_note(info->notes + 4); | ||
1765 | 1887 | ||
1766 | fill_auxv_note(&info->notes[info->numnote++], current->mm); | 1888 | info->numnote = 5; |
1767 | 1889 | ||
1768 | /* Try to dump the FPU. */ | 1890 | /* Try to dump the FPU. */ |
1769 | info->prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs, | 1891 | info->prstatus->pr_fpvalid = elf_core_copy_task_fpregs(current, regs, |
@@ -1825,6 +1947,9 @@ static void free_note_info(struct elf_note_info *info) | |||
1825 | kfree(list_entry(tmp, struct elf_thread_status, list)); | 1947 | kfree(list_entry(tmp, struct elf_thread_status, list)); |
1826 | } | 1948 | } |
1827 | 1949 | ||
1950 | /* Free data allocated by fill_files_note(): */ | ||
1951 | vfree(info->notes[4].data); | ||
1952 | |||
1828 | kfree(info->prstatus); | 1953 | kfree(info->prstatus); |
1829 | kfree(info->psinfo); | 1954 | kfree(info->psinfo); |
1830 | kfree(info->notes); | 1955 | kfree(info->notes); |
@@ -1951,7 +2076,7 @@ static int elf_core_dump(struct coredump_params *cprm) | |||
1951 | * Collect all the non-memory information about the process for the | 2076 | * Collect all the non-memory information about the process for the |
1952 | * notes. This also sets up the file header. | 2077 | * notes. This also sets up the file header. |
1953 | */ | 2078 | */ |
1954 | if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs)) | 2079 | if (!fill_note_info(elf, e_phnum, &info, cprm->siginfo, cprm->regs)) |
1955 | goto cleanup; | 2080 | goto cleanup; |
1956 | 2081 | ||
1957 | has_dumped = 1; | 2082 | has_dumped = 1; |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 3d77cf81ba3c..08d812b32282 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1642,7 +1642,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) | |||
1642 | goto cleanup; | 1642 | goto cleanup; |
1643 | #endif | 1643 | #endif |
1644 | 1644 | ||
1645 | if (cprm->signr) { | 1645 | if (cprm->siginfo->si_signo) { |
1646 | struct core_thread *ct; | 1646 | struct core_thread *ct; |
1647 | struct elf_thread_status *tmp; | 1647 | struct elf_thread_status *tmp; |
1648 | 1648 | ||
@@ -1661,13 +1661,13 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) | |||
1661 | int sz; | 1661 | int sz; |
1662 | 1662 | ||
1663 | tmp = list_entry(t, struct elf_thread_status, list); | 1663 | tmp = list_entry(t, struct elf_thread_status, list); |
1664 | sz = elf_dump_thread_status(cprm->signr, tmp); | 1664 | sz = elf_dump_thread_status(cprm->siginfo->si_signo, tmp); |
1665 | thread_status_size += sz; | 1665 | thread_status_size += sz; |
1666 | } | 1666 | } |
1667 | } | 1667 | } |
1668 | 1668 | ||
1669 | /* now collect the dump for the current */ | 1669 | /* now collect the dump for the current */ |
1670 | fill_prstatus(prstatus, current, cprm->signr); | 1670 | fill_prstatus(prstatus, current, cprm->siginfo->si_signo); |
1671 | elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); | 1671 | elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); |
1672 | 1672 | ||
1673 | segs = current->mm->map_count; | 1673 | segs = current->mm->map_count; |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 178cb70acc26..e280352b28f9 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -107,7 +107,7 @@ static struct linux_binfmt flat_format = { | |||
107 | static int flat_core_dump(struct coredump_params *cprm) | 107 | static int flat_core_dump(struct coredump_params *cprm) |
108 | { | 108 | { |
109 | printk("Process %s:%d received signr %d and should have core dumped\n", | 109 | printk("Process %s:%d received signr %d and should have core dumped\n", |
110 | current->comm, current->pid, (int) cprm->signr); | 110 | current->comm, current->pid, (int) cprm->siginfo->si_signo); |
111 | return(1); | 111 | return(1); |
112 | } | 112 | } |
113 | 113 | ||
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index 112e45a17e99..a81147e2e4ef 100644 --- a/fs/compat_binfmt_elf.c +++ b/fs/compat_binfmt_elf.c | |||
@@ -38,6 +38,13 @@ | |||
38 | #define elf_addr_t Elf32_Addr | 38 | #define elf_addr_t Elf32_Addr |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Some data types as stored in coredump. | ||
42 | */ | ||
43 | #define user_long_t compat_long_t | ||
44 | #define user_siginfo_t compat_siginfo_t | ||
45 | #define copy_siginfo_to_user copy_siginfo_to_user32 | ||
46 | |||
47 | /* | ||
41 | * The machine-dependent core note format types are defined in elfcore-compat.h, | 48 | * The machine-dependent core note format types are defined in elfcore-compat.h, |
42 | * which requires asm/elf.h to define compat_elf_gregset_t et al. | 49 | * which requires asm/elf.h to define compat_elf_gregset_t et al. |
43 | */ | 50 | */ |
diff --git a/fs/coredump.c b/fs/coredump.c index f045bbad6822..fd37facac8dc 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/key.h> | 14 | #include <linux/key.h> |
15 | #include <linux/personality.h> | 15 | #include <linux/personality.h> |
16 | #include <linux/binfmts.h> | 16 | #include <linux/binfmts.h> |
17 | #include <linux/coredump.h> | ||
17 | #include <linux/utsname.h> | 18 | #include <linux/utsname.h> |
18 | #include <linux/pid_namespace.h> | 19 | #include <linux/pid_namespace.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -39,6 +40,7 @@ | |||
39 | 40 | ||
40 | #include <trace/events/task.h> | 41 | #include <trace/events/task.h> |
41 | #include "internal.h" | 42 | #include "internal.h" |
43 | #include "coredump.h" | ||
42 | 44 | ||
43 | #include <trace/events/sched.h> | 45 | #include <trace/events/sched.h> |
44 | 46 | ||
@@ -147,7 +149,7 @@ put_exe_file: | |||
147 | * name into corename, which must have space for at least | 149 | * name into corename, which must have space for at least |
148 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. | 150 | * CORENAME_MAX_SIZE bytes plus one byte for the zero terminator. |
149 | */ | 151 | */ |
150 | static int format_corename(struct core_name *cn, long signr) | 152 | static int format_corename(struct core_name *cn, struct coredump_params *cprm) |
151 | { | 153 | { |
152 | const struct cred *cred = current_cred(); | 154 | const struct cred *cred = current_cred(); |
153 | const char *pat_ptr = core_pattern; | 155 | const char *pat_ptr = core_pattern; |
@@ -192,9 +194,13 @@ static int format_corename(struct core_name *cn, long signr) | |||
192 | case 'g': | 194 | case 'g': |
193 | err = cn_printf(cn, "%d", cred->gid); | 195 | err = cn_printf(cn, "%d", cred->gid); |
194 | break; | 196 | break; |
197 | case 'd': | ||
198 | err = cn_printf(cn, "%d", | ||
199 | __get_dumpable(cprm->mm_flags)); | ||
200 | break; | ||
195 | /* signal that caused the coredump */ | 201 | /* signal that caused the coredump */ |
196 | case 's': | 202 | case 's': |
197 | err = cn_printf(cn, "%ld", signr); | 203 | err = cn_printf(cn, "%ld", cprm->siginfo->si_signo); |
198 | break; | 204 | break; |
199 | /* UNIX time of coredump */ | 205 | /* UNIX time of coredump */ |
200 | case 't': { | 206 | case 't': { |
@@ -451,7 +457,7 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) | |||
451 | return 0; | 457 | return 0; |
452 | } | 458 | } |
453 | 459 | ||
454 | void do_coredump(long signr, int exit_code, struct pt_regs *regs) | 460 | void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) |
455 | { | 461 | { |
456 | struct core_state core_state; | 462 | struct core_state core_state; |
457 | struct core_name cn; | 463 | struct core_name cn; |
@@ -466,7 +472,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
466 | bool need_nonrelative = false; | 472 | bool need_nonrelative = false; |
467 | static atomic_t core_dump_count = ATOMIC_INIT(0); | 473 | static atomic_t core_dump_count = ATOMIC_INIT(0); |
468 | struct coredump_params cprm = { | 474 | struct coredump_params cprm = { |
469 | .signr = signr, | 475 | .siginfo = siginfo, |
470 | .regs = regs, | 476 | .regs = regs, |
471 | .limit = rlimit(RLIMIT_CORE), | 477 | .limit = rlimit(RLIMIT_CORE), |
472 | /* | 478 | /* |
@@ -477,7 +483,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
477 | .mm_flags = mm->flags, | 483 | .mm_flags = mm->flags, |
478 | }; | 484 | }; |
479 | 485 | ||
480 | audit_core_dumps(signr); | 486 | audit_core_dumps(siginfo->si_signo); |
481 | 487 | ||
482 | binfmt = mm->binfmt; | 488 | binfmt = mm->binfmt; |
483 | if (!binfmt || !binfmt->core_dump) | 489 | if (!binfmt || !binfmt->core_dump) |
@@ -501,7 +507,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
501 | need_nonrelative = true; | 507 | need_nonrelative = true; |
502 | } | 508 | } |
503 | 509 | ||
504 | retval = coredump_wait(exit_code, &core_state); | 510 | retval = coredump_wait(siginfo->si_signo, &core_state); |
505 | if (retval < 0) | 511 | if (retval < 0) |
506 | goto fail_creds; | 512 | goto fail_creds; |
507 | 513 | ||
@@ -513,7 +519,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
513 | */ | 519 | */ |
514 | clear_thread_flag(TIF_SIGPENDING); | 520 | clear_thread_flag(TIF_SIGPENDING); |
515 | 521 | ||
516 | ispipe = format_corename(&cn, signr); | 522 | ispipe = format_corename(&cn, &cprm); |
517 | 523 | ||
518 | if (ispipe) { | 524 | if (ispipe) { |
519 | int dump_count; | 525 | int dump_count; |
diff --git a/fs/coredump.h b/fs/coredump.h new file mode 100644 index 000000000000..e39ff072110d --- /dev/null +++ b/fs/coredump.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _FS_COREDUMP_H | ||
2 | #define _FS_COREDUMP_H | ||
3 | |||
4 | extern int __get_dumpable(unsigned long mm_flags); | ||
5 | |||
6 | #endif | ||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index cd96649bfe62..da72250ddc1c 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -346,7 +346,7 @@ static inline struct epitem *ep_item_from_epqueue(poll_table *p) | |||
346 | /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ | 346 | /* Tells if the epoll_ctl(2) operation needs an event copy from userspace */ |
347 | static inline int ep_op_has_event(int op) | 347 | static inline int ep_op_has_event(int op) |
348 | { | 348 | { |
349 | return op != EPOLL_CTL_DEL; | 349 | return op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD; |
350 | } | 350 | } |
351 | 351 | ||
352 | /* Initialize the poll safe wake up structure */ | 352 | /* Initialize the poll safe wake up structure */ |
@@ -676,6 +676,34 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) | |||
676 | return 0; | 676 | return 0; |
677 | } | 677 | } |
678 | 678 | ||
679 | /* | ||
680 | * Disables a "struct epitem" in the eventpoll set. Returns -EBUSY if the item | ||
681 | * had no event flags set, indicating that another thread may be currently | ||
682 | * handling that item's events (in the case that EPOLLONESHOT was being | ||
683 | * used). Otherwise a zero result indicates that the item has been disabled | ||
684 | * from receiving events. A disabled item may be re-enabled via | ||
685 | * EPOLL_CTL_MOD. Must be called with "mtx" held. | ||
686 | */ | ||
687 | static int ep_disable(struct eventpoll *ep, struct epitem *epi) | ||
688 | { | ||
689 | int result = 0; | ||
690 | unsigned long flags; | ||
691 | |||
692 | spin_lock_irqsave(&ep->lock, flags); | ||
693 | if (epi->event.events & ~EP_PRIVATE_BITS) { | ||
694 | if (ep_is_linked(&epi->rdllink)) | ||
695 | list_del_init(&epi->rdllink); | ||
696 | /* Ensure ep_poll_callback will not add epi back onto ready | ||
697 | list: */ | ||
698 | epi->event.events &= EP_PRIVATE_BITS; | ||
699 | } | ||
700 | else | ||
701 | result = -EBUSY; | ||
702 | spin_unlock_irqrestore(&ep->lock, flags); | ||
703 | |||
704 | return result; | ||
705 | } | ||
706 | |||
679 | static void ep_free(struct eventpoll *ep) | 707 | static void ep_free(struct eventpoll *ep) |
680 | { | 708 | { |
681 | struct rb_node *rbp; | 709 | struct rb_node *rbp; |
@@ -1020,8 +1048,6 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi) | |||
1020 | rb_insert_color(&epi->rbn, &ep->rbr); | 1048 | rb_insert_color(&epi->rbn, &ep->rbr); |
1021 | } | 1049 | } |
1022 | 1050 | ||
1023 | |||
1024 | |||
1025 | #define PATH_ARR_SIZE 5 | 1051 | #define PATH_ARR_SIZE 5 |
1026 | /* | 1052 | /* |
1027 | * These are the number paths of length 1 to 5, that we are allowing to emanate | 1053 | * These are the number paths of length 1 to 5, that we are allowing to emanate |
@@ -1787,6 +1813,12 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, | |||
1787 | } else | 1813 | } else |
1788 | error = -ENOENT; | 1814 | error = -ENOENT; |
1789 | break; | 1815 | break; |
1816 | case EPOLL_CTL_DISABLE: | ||
1817 | if (epi) | ||
1818 | error = ep_disable(ep, epi); | ||
1819 | else | ||
1820 | error = -ENOENT; | ||
1821 | break; | ||
1790 | } | 1822 | } |
1791 | mutex_unlock(&ep->mtx); | 1823 | mutex_unlock(&ep->mtx); |
1792 | 1824 | ||
@@ -63,6 +63,7 @@ | |||
63 | 63 | ||
64 | #include <trace/events/task.h> | 64 | #include <trace/events/task.h> |
65 | #include "internal.h" | 65 | #include "internal.h" |
66 | #include "coredump.h" | ||
66 | 67 | ||
67 | #include <trace/events/sched.h> | 68 | #include <trace/events/sched.h> |
68 | 69 | ||
@@ -1096,7 +1097,7 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
1096 | current->sas_ss_sp = current->sas_ss_size = 0; | 1097 | current->sas_ss_sp = current->sas_ss_size = 0; |
1097 | 1098 | ||
1098 | if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid())) | 1099 | if (uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid())) |
1099 | set_dumpable(current->mm, 1); | 1100 | set_dumpable(current->mm, SUID_DUMPABLE_ENABLED); |
1100 | else | 1101 | else |
1101 | set_dumpable(current->mm, suid_dumpable); | 1102 | set_dumpable(current->mm, suid_dumpable); |
1102 | 1103 | ||
diff --git a/fs/fat/Makefile b/fs/fat/Makefile index e06190322c1c..964b634f6667 100644 --- a/fs/fat/Makefile +++ b/fs/fat/Makefile | |||
@@ -6,6 +6,6 @@ obj-$(CONFIG_FAT_FS) += fat.o | |||
6 | obj-$(CONFIG_VFAT_FS) += vfat.o | 6 | obj-$(CONFIG_VFAT_FS) += vfat.o |
7 | obj-$(CONFIG_MSDOS_FS) += msdos.o | 7 | obj-$(CONFIG_MSDOS_FS) += msdos.o |
8 | 8 | ||
9 | fat-y := cache.o dir.o fatent.o file.o inode.o misc.o | 9 | fat-y := cache.o dir.o fatent.o file.o inode.o misc.o nfs.o |
10 | vfat-y := namei_vfat.o | 10 | vfat-y := namei_vfat.o |
11 | msdos-y := namei_msdos.o | 11 | msdos-y := namei_msdos.o |
diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 1cc7038e273d..91ad9e1c9441 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c | |||
@@ -190,7 +190,8 @@ static void __fat_cache_inval_inode(struct inode *inode) | |||
190 | struct fat_cache *cache; | 190 | struct fat_cache *cache; |
191 | 191 | ||
192 | while (!list_empty(&i->cache_lru)) { | 192 | while (!list_empty(&i->cache_lru)) { |
193 | cache = list_entry(i->cache_lru.next, struct fat_cache, cache_list); | 193 | cache = list_entry(i->cache_lru.next, |
194 | struct fat_cache, cache_list); | ||
194 | list_del_init(&cache->cache_list); | 195 | list_del_init(&cache->cache_list); |
195 | i->nr_caches--; | 196 | i->nr_caches--; |
196 | fat_cache_free(cache); | 197 | fat_cache_free(cache); |
@@ -261,9 +262,10 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) | |||
261 | if (nr < 0) | 262 | if (nr < 0) |
262 | goto out; | 263 | goto out; |
263 | else if (nr == FAT_ENT_FREE) { | 264 | else if (nr == FAT_ENT_FREE) { |
264 | fat_fs_error_ratelimit(sb, "%s: invalid cluster chain" | 265 | fat_fs_error_ratelimit(sb, |
265 | " (i_pos %lld)", __func__, | 266 | "%s: invalid cluster chain (i_pos %lld)", |
266 | MSDOS_I(inode)->i_pos); | 267 | __func__, |
268 | MSDOS_I(inode)->i_pos); | ||
267 | nr = -EIO; | 269 | nr = -EIO; |
268 | goto out; | 270 | goto out; |
269 | } else if (nr == FAT_ENT_EOF) { | 271 | } else if (nr == FAT_ENT_EOF) { |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index dc49ed2cbffa..bca6d0a1255e 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/time.h> | 18 | #include <linux/time.h> |
19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
20 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
21 | #include <asm/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include "fat.h" | 23 | #include "fat.h" |
24 | 24 | ||
@@ -123,7 +123,8 @@ static inline int fat_get_entry(struct inode *dir, loff_t *pos, | |||
123 | { | 123 | { |
124 | /* Fast stuff first */ | 124 | /* Fast stuff first */ |
125 | if (*bh && *de && | 125 | if (*bh && *de && |
126 | (*de - (struct msdos_dir_entry *)(*bh)->b_data) < MSDOS_SB(dir->i_sb)->dir_per_block - 1) { | 126 | (*de - (struct msdos_dir_entry *)(*bh)->b_data) < |
127 | MSDOS_SB(dir->i_sb)->dir_per_block - 1) { | ||
127 | *pos += sizeof(struct msdos_dir_entry); | 128 | *pos += sizeof(struct msdos_dir_entry); |
128 | (*de)++; | 129 | (*de)++; |
129 | return 0; | 130 | return 0; |
@@ -155,7 +156,8 @@ static int uni16_to_x8(struct super_block *sb, unsigned char *ascii, | |||
155 | 156 | ||
156 | while (*ip && ((len - NLS_MAX_CHARSET_SIZE) > 0)) { | 157 | while (*ip && ((len - NLS_MAX_CHARSET_SIZE) > 0)) { |
157 | ec = *ip++; | 158 | ec = *ip++; |
158 | if ((charlen = nls->uni2char(ec, op, NLS_MAX_CHARSET_SIZE)) > 0) { | 159 | charlen = nls->uni2char(ec, op, NLS_MAX_CHARSET_SIZE); |
160 | if (charlen > 0) { | ||
159 | op += charlen; | 161 | op += charlen; |
160 | len -= charlen; | 162 | len -= charlen; |
161 | } else { | 163 | } else { |
@@ -172,12 +174,12 @@ static int uni16_to_x8(struct super_block *sb, unsigned char *ascii, | |||
172 | } | 174 | } |
173 | 175 | ||
174 | if (unlikely(*ip)) { | 176 | if (unlikely(*ip)) { |
175 | fat_msg(sb, KERN_WARNING, "filename was truncated while " | 177 | fat_msg(sb, KERN_WARNING, |
176 | "converting."); | 178 | "filename was truncated while converting."); |
177 | } | 179 | } |
178 | 180 | ||
179 | *op = 0; | 181 | *op = 0; |
180 | return (op - ascii); | 182 | return op - ascii; |
181 | } | 183 | } |
182 | 184 | ||
183 | static inline int fat_uni_to_x8(struct super_block *sb, const wchar_t *uni, | 185 | static inline int fat_uni_to_x8(struct super_block *sb, const wchar_t *uni, |
@@ -205,7 +207,8 @@ fat_short2uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni) | |||
205 | } | 207 | } |
206 | 208 | ||
207 | static inline int | 209 | static inline int |
208 | fat_short2lower_uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *uni) | 210 | fat_short2lower_uni(struct nls_table *t, unsigned char *c, |
211 | int clen, wchar_t *uni) | ||
209 | { | 212 | { |
210 | int charlen; | 213 | int charlen; |
211 | wchar_t wc; | 214 | wchar_t wc; |
@@ -220,7 +223,8 @@ fat_short2lower_uni(struct nls_table *t, unsigned char *c, int clen, wchar_t *un | |||
220 | if (!nc) | 223 | if (!nc) |
221 | nc = *c; | 224 | nc = *c; |
222 | 225 | ||
223 | if ( (charlen = t->char2uni(&nc, 1, uni)) < 0) { | 226 | charlen = t->char2uni(&nc, 1, uni); |
227 | if (charlen < 0) { | ||
224 | *uni = 0x003f; /* a question mark */ | 228 | *uni = 0x003f; /* a question mark */ |
225 | charlen = 1; | 229 | charlen = 1; |
226 | } | 230 | } |
@@ -537,7 +541,6 @@ end_of_dir: | |||
537 | 541 | ||
538 | return err; | 542 | return err; |
539 | } | 543 | } |
540 | |||
541 | EXPORT_SYMBOL_GPL(fat_search_long); | 544 | EXPORT_SYMBOL_GPL(fat_search_long); |
542 | 545 | ||
543 | struct fat_ioctl_filldir_callback { | 546 | struct fat_ioctl_filldir_callback { |
@@ -574,7 +577,8 @@ static int __fat_readdir(struct inode *inode, struct file *filp, void *dirent, | |||
574 | /* Fake . and .. for the root directory. */ | 577 | /* Fake . and .. for the root directory. */ |
575 | if (inode->i_ino == MSDOS_ROOT_INO) { | 578 | if (inode->i_ino == MSDOS_ROOT_INO) { |
576 | while (cpos < 2) { | 579 | while (cpos < 2) { |
577 | if (filldir(dirent, "..", cpos+1, cpos, MSDOS_ROOT_INO, DT_DIR) < 0) | 580 | if (filldir(dirent, "..", cpos+1, cpos, |
581 | MSDOS_ROOT_INO, DT_DIR) < 0) | ||
578 | goto out; | 582 | goto out; |
579 | cpos++; | 583 | cpos++; |
580 | filp->f_pos++; | 584 | filp->f_pos++; |
@@ -872,25 +876,26 @@ static int fat_get_short_entry(struct inode *dir, loff_t *pos, | |||
872 | } | 876 | } |
873 | 877 | ||
874 | /* | 878 | /* |
875 | * The ".." entry can not provide the "struct fat_slot_info" informations | 879 | * The ".." entry can not provide the "struct fat_slot_info" information |
876 | * for inode. So, this function provide the some informations only. | 880 | * for inode, nor a usable i_pos. So, this function provides some information |
881 | * only. | ||
882 | * | ||
883 | * Since this function walks through the on-disk inodes within a directory, | ||
884 | * callers are responsible for taking any locks necessary to prevent the | ||
885 | * directory from changing. | ||
877 | */ | 886 | */ |
878 | int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, | 887 | int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, |
879 | struct msdos_dir_entry **de, loff_t *i_pos) | 888 | struct msdos_dir_entry **de) |
880 | { | 889 | { |
881 | loff_t offset; | 890 | loff_t offset = 0; |
882 | 891 | ||
883 | offset = 0; | 892 | *de = NULL; |
884 | *bh = NULL; | ||
885 | while (fat_get_short_entry(dir, &offset, bh, de) >= 0) { | 893 | while (fat_get_short_entry(dir, &offset, bh, de) >= 0) { |
886 | if (!strncmp((*de)->name, MSDOS_DOTDOT, MSDOS_NAME)) { | 894 | if (!strncmp((*de)->name, MSDOS_DOTDOT, MSDOS_NAME)) |
887 | *i_pos = fat_make_i_pos(dir->i_sb, *bh, *de); | ||
888 | return 0; | 895 | return 0; |
889 | } | ||
890 | } | 896 | } |
891 | return -ENOENT; | 897 | return -ENOENT; |
892 | } | 898 | } |
893 | |||
894 | EXPORT_SYMBOL_GPL(fat_get_dotdot_entry); | 899 | EXPORT_SYMBOL_GPL(fat_get_dotdot_entry); |
895 | 900 | ||
896 | /* See if directory is empty */ | 901 | /* See if directory is empty */ |
@@ -913,7 +918,6 @@ int fat_dir_empty(struct inode *dir) | |||
913 | brelse(bh); | 918 | brelse(bh); |
914 | return result; | 919 | return result; |
915 | } | 920 | } |
916 | |||
917 | EXPORT_SYMBOL_GPL(fat_dir_empty); | 921 | EXPORT_SYMBOL_GPL(fat_dir_empty); |
918 | 922 | ||
919 | /* | 923 | /* |
@@ -959,7 +963,6 @@ int fat_scan(struct inode *dir, const unsigned char *name, | |||
959 | } | 963 | } |
960 | return -ENOENT; | 964 | return -ENOENT; |
961 | } | 965 | } |
962 | |||
963 | EXPORT_SYMBOL_GPL(fat_scan); | 966 | EXPORT_SYMBOL_GPL(fat_scan); |
964 | 967 | ||
965 | static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) | 968 | static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots) |
@@ -1047,7 +1050,6 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) | |||
1047 | 1050 | ||
1048 | return 0; | 1051 | return 0; |
1049 | } | 1052 | } |
1050 | |||
1051 | EXPORT_SYMBOL_GPL(fat_remove_entries); | 1053 | EXPORT_SYMBOL_GPL(fat_remove_entries); |
1052 | 1054 | ||
1053 | static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, | 1055 | static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used, |
@@ -1141,10 +1143,8 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec *ts) | |||
1141 | de[0].ctime_cs = de[1].ctime_cs = 0; | 1143 | de[0].ctime_cs = de[1].ctime_cs = 0; |
1142 | de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = 0; | 1144 | de[0].adate = de[0].cdate = de[1].adate = de[1].cdate = 0; |
1143 | } | 1145 | } |
1144 | de[0].start = cpu_to_le16(cluster); | 1146 | fat_set_start(&de[0], cluster); |
1145 | de[0].starthi = cpu_to_le16(cluster >> 16); | 1147 | fat_set_start(&de[1], MSDOS_I(dir)->i_logstart); |
1146 | de[1].start = cpu_to_le16(MSDOS_I(dir)->i_logstart); | ||
1147 | de[1].starthi = cpu_to_le16(MSDOS_I(dir)->i_logstart >> 16); | ||
1148 | de[0].size = de[1].size = 0; | 1148 | de[0].size = de[1].size = 0; |
1149 | memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); | 1149 | memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de)); |
1150 | set_buffer_uptodate(bhs[0]); | 1150 | set_buffer_uptodate(bhs[0]); |
@@ -1161,7 +1161,6 @@ error_free: | |||
1161 | error: | 1161 | error: |
1162 | return err; | 1162 | return err; |
1163 | } | 1163 | } |
1164 | |||
1165 | EXPORT_SYMBOL_GPL(fat_alloc_new_dir); | 1164 | EXPORT_SYMBOL_GPL(fat_alloc_new_dir); |
1166 | 1165 | ||
1167 | static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots, | 1166 | static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots, |
@@ -1377,5 +1376,4 @@ error_remove: | |||
1377 | __fat_remove_entries(dir, pos, free_slots); | 1376 | __fat_remove_entries(dir, pos, free_slots); |
1378 | return err; | 1377 | return err; |
1379 | } | 1378 | } |
1380 | |||
1381 | EXPORT_SYMBOL_GPL(fat_add_entries); | 1379 | EXPORT_SYMBOL_GPL(fat_add_entries); |
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 7d8e0dcac5d5..ca7e8f8bad7c 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/string.h> | 5 | #include <linux/string.h> |
6 | #include <linux/nls.h> | 6 | #include <linux/nls.h> |
7 | #include <linux/fs.h> | 7 | #include <linux/fs.h> |
8 | #include <linux/hash.h> | ||
8 | #include <linux/mutex.h> | 9 | #include <linux/mutex.h> |
9 | #include <linux/ratelimit.h> | 10 | #include <linux/ratelimit.h> |
10 | #include <linux/msdos_fs.h> | 11 | #include <linux/msdos_fs.h> |
@@ -27,26 +28,27 @@ struct fat_mount_options { | |||
27 | kgid_t fs_gid; | 28 | kgid_t fs_gid; |
28 | unsigned short fs_fmask; | 29 | unsigned short fs_fmask; |
29 | unsigned short fs_dmask; | 30 | unsigned short fs_dmask; |
30 | unsigned short codepage; /* Codepage for shortname conversions */ | 31 | unsigned short codepage; /* Codepage for shortname conversions */ |
31 | char *iocharset; /* Charset used for filename input/display */ | 32 | char *iocharset; /* Charset used for filename input/display */ |
32 | unsigned short shortname; /* flags for shortname display/create rule */ | 33 | unsigned short shortname; /* flags for shortname display/create rule */ |
33 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ | 34 | unsigned char name_check; /* r = relaxed, n = normal, s = strict */ |
34 | unsigned char errors; /* On error: continue, panic, remount-ro */ | 35 | unsigned char errors; /* On error: continue, panic, remount-ro */ |
35 | unsigned short allow_utime;/* permission for setting the [am]time */ | 36 | unsigned short allow_utime;/* permission for setting the [am]time */ |
36 | unsigned quiet:1, /* set = fake successful chmods and chowns */ | 37 | unsigned quiet:1, /* set = fake successful chmods and chowns */ |
37 | showexec:1, /* set = only set x bit for com/exe/bat */ | 38 | showexec:1, /* set = only set x bit for com/exe/bat */ |
38 | sys_immutable:1, /* set = system files are immutable */ | 39 | sys_immutable:1, /* set = system files are immutable */ |
39 | dotsOK:1, /* set = hidden and system files are named '.filename' */ | 40 | dotsOK:1, /* set = hidden and system files are named '.filename' */ |
40 | isvfat:1, /* 0=no vfat long filename support, 1=vfat support */ | 41 | isvfat:1, /* 0=no vfat long filename support, 1=vfat support */ |
41 | utf8:1, /* Use of UTF-8 character set (Default) */ | 42 | utf8:1, /* Use of UTF-8 character set (Default) */ |
42 | unicode_xlate:1, /* create escape sequences for unhandled Unicode */ | 43 | unicode_xlate:1, /* create escape sequences for unhandled Unicode */ |
43 | numtail:1, /* Does first alias have a numeric '~1' type tail? */ | 44 | numtail:1, /* Does first alias have a numeric '~1' type tail? */ |
44 | flush:1, /* write things quickly */ | 45 | flush:1, /* write things quickly */ |
45 | nocase:1, /* Does this need case conversion? 0=need case conversion*/ | 46 | nocase:1, /* Does this need case conversion? 0=need case conversion*/ |
46 | usefree:1, /* Use free_clusters for FAT32 */ | 47 | usefree:1, /* Use free_clusters for FAT32 */ |
47 | tz_utc:1, /* Filesystem timestamps are in UTC */ | 48 | tz_utc:1, /* Filesystem timestamps are in UTC */ |
48 | rodir:1, /* allow ATTR_RO for directory */ | 49 | rodir:1, /* allow ATTR_RO for directory */ |
49 | discard:1; /* Issue discard requests on deletions */ | 50 | discard:1, /* Issue discard requests on deletions */ |
51 | nfs:1; /* Do extra work needed for NFS export */ | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | #define FAT_HASH_BITS 8 | 54 | #define FAT_HASH_BITS 8 |
@@ -56,28 +58,28 @@ struct fat_mount_options { | |||
56 | * MS-DOS file system in-core superblock data | 58 | * MS-DOS file system in-core superblock data |
57 | */ | 59 | */ |
58 | struct msdos_sb_info { | 60 | struct msdos_sb_info { |
59 | unsigned short sec_per_clus; /* sectors/cluster */ | 61 | unsigned short sec_per_clus; /* sectors/cluster */ |
60 | unsigned short cluster_bits; /* log2(cluster_size) */ | 62 | unsigned short cluster_bits; /* log2(cluster_size) */ |
61 | unsigned int cluster_size; /* cluster size */ | 63 | unsigned int cluster_size; /* cluster size */ |
62 | unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ | 64 | unsigned char fats, fat_bits; /* number of FATs, FAT bits (12 or 16) */ |
63 | unsigned short fat_start; | 65 | unsigned short fat_start; |
64 | unsigned long fat_length; /* FAT start & length (sec.) */ | 66 | unsigned long fat_length; /* FAT start & length (sec.) */ |
65 | unsigned long dir_start; | 67 | unsigned long dir_start; |
66 | unsigned short dir_entries; /* root dir start & entries */ | 68 | unsigned short dir_entries; /* root dir start & entries */ |
67 | unsigned long data_start; /* first data sector */ | 69 | unsigned long data_start; /* first data sector */ |
68 | unsigned long max_cluster; /* maximum cluster number */ | 70 | unsigned long max_cluster; /* maximum cluster number */ |
69 | unsigned long root_cluster; /* first cluster of the root directory */ | 71 | unsigned long root_cluster; /* first cluster of the root directory */ |
70 | unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ | 72 | unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ |
71 | struct mutex fat_lock; | 73 | struct mutex fat_lock; |
72 | unsigned int prev_free; /* previously allocated cluster number */ | 74 | unsigned int prev_free; /* previously allocated cluster number */ |
73 | unsigned int free_clusters; /* -1 if undefined */ | 75 | unsigned int free_clusters; /* -1 if undefined */ |
74 | unsigned int free_clus_valid; /* is free_clusters valid? */ | 76 | unsigned int free_clus_valid; /* is free_clusters valid? */ |
75 | struct fat_mount_options options; | 77 | struct fat_mount_options options; |
76 | struct nls_table *nls_disk; /* Codepage used on disk */ | 78 | struct nls_table *nls_disk; /* Codepage used on disk */ |
77 | struct nls_table *nls_io; /* Charset used for input and display */ | 79 | struct nls_table *nls_io; /* Charset used for input and display */ |
78 | const void *dir_ops; /* Opaque; default directory operations */ | 80 | const void *dir_ops; /* Opaque; default directory operations */ |
79 | int dir_per_block; /* dir entries per block */ | 81 | int dir_per_block; /* dir entries per block */ |
80 | int dir_per_block_bits; /* log2(dir_per_block) */ | 82 | int dir_per_block_bits; /* log2(dir_per_block) */ |
81 | 83 | ||
82 | int fatent_shift; | 84 | int fatent_shift; |
83 | struct fatent_operations *fatent_ops; | 85 | struct fatent_operations *fatent_ops; |
@@ -88,6 +90,9 @@ struct msdos_sb_info { | |||
88 | 90 | ||
89 | spinlock_t inode_hash_lock; | 91 | spinlock_t inode_hash_lock; |
90 | struct hlist_head inode_hashtable[FAT_HASH_SIZE]; | 92 | struct hlist_head inode_hashtable[FAT_HASH_SIZE]; |
93 | |||
94 | spinlock_t dir_hash_lock; | ||
95 | struct hlist_head dir_hashtable[FAT_HASH_SIZE]; | ||
91 | }; | 96 | }; |
92 | 97 | ||
93 | #define FAT_CACHE_VALID 0 /* special case for valid cache */ | 98 | #define FAT_CACHE_VALID 0 /* special case for valid cache */ |
@@ -110,6 +115,7 @@ struct msdos_inode_info { | |||
110 | int i_attrs; /* unused attribute bits */ | 115 | int i_attrs; /* unused attribute bits */ |
111 | loff_t i_pos; /* on-disk position of directory entry or 0 */ | 116 | loff_t i_pos; /* on-disk position of directory entry or 0 */ |
112 | struct hlist_node i_fat_hash; /* hash by i_location */ | 117 | struct hlist_node i_fat_hash; /* hash by i_location */ |
118 | struct hlist_node i_dir_hash; /* hash by i_logstart */ | ||
113 | struct rw_semaphore truncate_lock; /* protect bmap against truncate */ | 119 | struct rw_semaphore truncate_lock; /* protect bmap against truncate */ |
114 | struct inode vfs_inode; | 120 | struct inode vfs_inode; |
115 | }; | 121 | }; |
@@ -262,7 +268,7 @@ extern int fat_subdirs(struct inode *dir); | |||
262 | extern int fat_scan(struct inode *dir, const unsigned char *name, | 268 | extern int fat_scan(struct inode *dir, const unsigned char *name, |
263 | struct fat_slot_info *sinfo); | 269 | struct fat_slot_info *sinfo); |
264 | extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, | 270 | extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, |
265 | struct msdos_dir_entry **de, loff_t *i_pos); | 271 | struct msdos_dir_entry **de); |
266 | extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); | 272 | extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); |
267 | extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots, | 273 | extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots, |
268 | struct fat_slot_info *sinfo); | 274 | struct fat_slot_info *sinfo); |
@@ -322,7 +328,7 @@ extern long fat_generic_ioctl(struct file *filp, unsigned int cmd, | |||
322 | unsigned long arg); | 328 | unsigned long arg); |
323 | extern const struct file_operations fat_file_operations; | 329 | extern const struct file_operations fat_file_operations; |
324 | extern const struct inode_operations fat_file_inode_operations; | 330 | extern const struct inode_operations fat_file_inode_operations; |
325 | extern int fat_setattr(struct dentry * dentry, struct iattr * attr); | 331 | extern int fat_setattr(struct dentry *dentry, struct iattr *attr); |
326 | extern void fat_truncate_blocks(struct inode *inode, loff_t offset); | 332 | extern void fat_truncate_blocks(struct inode *inode, loff_t offset); |
327 | extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, | 333 | extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, |
328 | struct kstat *stat); | 334 | struct kstat *stat); |
@@ -340,7 +346,12 @@ extern int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
340 | int isvfat, void (*setup)(struct super_block *)); | 346 | int isvfat, void (*setup)(struct super_block *)); |
341 | 347 | ||
342 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, | 348 | extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, |
343 | struct inode *i2); | 349 | struct inode *i2); |
350 | static inline unsigned long fat_dir_hash(int logstart) | ||
351 | { | ||
352 | return hash_32(logstart, FAT_HASH_BITS); | ||
353 | } | ||
354 | |||
344 | /* fat/misc.c */ | 355 | /* fat/misc.c */ |
345 | extern __printf(3, 4) __cold | 356 | extern __printf(3, 4) __cold |
346 | void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...); | 357 | void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...); |
@@ -366,6 +377,14 @@ extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); | |||
366 | int fat_cache_init(void); | 377 | int fat_cache_init(void); |
367 | void fat_cache_destroy(void); | 378 | void fat_cache_destroy(void); |
368 | 379 | ||
380 | /* fat/nfs.c */ | ||
381 | struct fid; | ||
382 | extern struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, | ||
383 | int fh_len, int fh_type); | ||
384 | extern struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, | ||
385 | int fh_len, int fh_type); | ||
386 | extern struct dentry *fat_get_parent(struct dentry *child_dir); | ||
387 | |||
369 | /* helper for printk */ | 388 | /* helper for printk */ |
370 | typedef unsigned long long llu; | 389 | typedef unsigned long long llu; |
371 | 390 | ||
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 31f08ab62c56..260705c58062 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c | |||
@@ -186,9 +186,6 @@ static void fat16_ent_put(struct fat_entry *fatent, int new) | |||
186 | 186 | ||
187 | static void fat32_ent_put(struct fat_entry *fatent, int new) | 187 | static void fat32_ent_put(struct fat_entry *fatent, int new) |
188 | { | 188 | { |
189 | if (new == FAT_ENT_EOF) | ||
190 | new = EOF_FAT32; | ||
191 | |||
192 | WARN_ON(new & 0xf0000000); | 189 | WARN_ON(new & 0xf0000000); |
193 | new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff; | 190 | new |= le32_to_cpu(*fatent->u.ent32_p) & ~0x0fffffff; |
194 | *fatent->u.ent32_p = cpu_to_le32(new); | 191 | *fatent->u.ent32_p = cpu_to_le32(new); |
@@ -203,15 +200,18 @@ static int fat12_ent_next(struct fat_entry *fatent) | |||
203 | 200 | ||
204 | fatent->entry++; | 201 | fatent->entry++; |
205 | if (fatent->nr_bhs == 1) { | 202 | if (fatent->nr_bhs == 1) { |
206 | WARN_ON(ent12_p[0] > (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 2))); | 203 | WARN_ON(ent12_p[0] > (u8 *)(bhs[0]->b_data + |
207 | WARN_ON(ent12_p[1] > (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1))); | 204 | (bhs[0]->b_size - 2))); |
205 | WARN_ON(ent12_p[1] > (u8 *)(bhs[0]->b_data + | ||
206 | (bhs[0]->b_size - 1))); | ||
208 | if (nextp < (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1))) { | 207 | if (nextp < (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1))) { |
209 | ent12_p[0] = nextp - 1; | 208 | ent12_p[0] = nextp - 1; |
210 | ent12_p[1] = nextp; | 209 | ent12_p[1] = nextp; |
211 | return 1; | 210 | return 1; |
212 | } | 211 | } |
213 | } else { | 212 | } else { |
214 | WARN_ON(ent12_p[0] != (u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1))); | 213 | WARN_ON(ent12_p[0] != (u8 *)(bhs[0]->b_data + |
214 | (bhs[0]->b_size - 1))); | ||
215 | WARN_ON(ent12_p[1] != (u8 *)bhs[1]->b_data); | 215 | WARN_ON(ent12_p[1] != (u8 *)bhs[1]->b_data); |
216 | ent12_p[0] = nextp - 1; | 216 | ent12_p[0] = nextp - 1; |
217 | ent12_p[1] = nextp; | 217 | ent12_p[1] = nextp; |
@@ -631,7 +631,6 @@ error: | |||
631 | 631 | ||
632 | return err; | 632 | return err; |
633 | } | 633 | } |
634 | |||
635 | EXPORT_SYMBOL_GPL(fat_free_clusters); | 634 | EXPORT_SYMBOL_GPL(fat_free_clusters); |
636 | 635 | ||
637 | /* 128kb is the whole sectors for FAT12 and FAT16 */ | 636 | /* 128kb is the whole sectors for FAT12 and FAT16 */ |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 4e5a6ac54ebd..76f60c642c06 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -281,15 +281,42 @@ static inline unsigned long fat_hash(loff_t i_pos) | |||
281 | return hash_32(i_pos, FAT_HASH_BITS); | 281 | return hash_32(i_pos, FAT_HASH_BITS); |
282 | } | 282 | } |
283 | 283 | ||
284 | static void dir_hash_init(struct super_block *sb) | ||
285 | { | ||
286 | struct msdos_sb_info *sbi = MSDOS_SB(sb); | ||
287 | int i; | ||
288 | |||
289 | spin_lock_init(&sbi->dir_hash_lock); | ||
290 | for (i = 0; i < FAT_HASH_SIZE; i++) | ||
291 | INIT_HLIST_HEAD(&sbi->dir_hashtable[i]); | ||
292 | } | ||
293 | |||
284 | void fat_attach(struct inode *inode, loff_t i_pos) | 294 | void fat_attach(struct inode *inode, loff_t i_pos) |
285 | { | 295 | { |
286 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | 296 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); |
287 | struct hlist_head *head = sbi->inode_hashtable + fat_hash(i_pos); | ||
288 | 297 | ||
289 | spin_lock(&sbi->inode_hash_lock); | 298 | if (inode->i_ino != MSDOS_ROOT_INO) { |
290 | MSDOS_I(inode)->i_pos = i_pos; | 299 | struct hlist_head *head = sbi->inode_hashtable |
291 | hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head); | 300 | + fat_hash(i_pos); |
292 | spin_unlock(&sbi->inode_hash_lock); | 301 | |
302 | spin_lock(&sbi->inode_hash_lock); | ||
303 | MSDOS_I(inode)->i_pos = i_pos; | ||
304 | hlist_add_head(&MSDOS_I(inode)->i_fat_hash, head); | ||
305 | spin_unlock(&sbi->inode_hash_lock); | ||
306 | } | ||
307 | |||
308 | /* If NFS support is enabled, cache the mapping of start cluster | ||
309 | * to directory inode. This is used during reconnection of | ||
310 | * dentries to the filesystem root. | ||
311 | */ | ||
312 | if (S_ISDIR(inode->i_mode) && sbi->options.nfs) { | ||
313 | struct hlist_head *d_head = sbi->dir_hashtable; | ||
314 | d_head += fat_dir_hash(MSDOS_I(inode)->i_logstart); | ||
315 | |||
316 | spin_lock(&sbi->dir_hash_lock); | ||
317 | hlist_add_head(&MSDOS_I(inode)->i_dir_hash, d_head); | ||
318 | spin_unlock(&sbi->dir_hash_lock); | ||
319 | } | ||
293 | } | 320 | } |
294 | EXPORT_SYMBOL_GPL(fat_attach); | 321 | EXPORT_SYMBOL_GPL(fat_attach); |
295 | 322 | ||
@@ -300,6 +327,12 @@ void fat_detach(struct inode *inode) | |||
300 | MSDOS_I(inode)->i_pos = 0; | 327 | MSDOS_I(inode)->i_pos = 0; |
301 | hlist_del_init(&MSDOS_I(inode)->i_fat_hash); | 328 | hlist_del_init(&MSDOS_I(inode)->i_fat_hash); |
302 | spin_unlock(&sbi->inode_hash_lock); | 329 | spin_unlock(&sbi->inode_hash_lock); |
330 | |||
331 | if (S_ISDIR(inode->i_mode) && sbi->options.nfs) { | ||
332 | spin_lock(&sbi->dir_hash_lock); | ||
333 | hlist_del_init(&MSDOS_I(inode)->i_dir_hash); | ||
334 | spin_unlock(&sbi->dir_hash_lock); | ||
335 | } | ||
303 | } | 336 | } |
304 | EXPORT_SYMBOL_GPL(fat_detach); | 337 | EXPORT_SYMBOL_GPL(fat_detach); |
305 | 338 | ||
@@ -504,6 +537,7 @@ static void init_once(void *foo) | |||
504 | ei->cache_valid_id = FAT_CACHE_VALID + 1; | 537 | ei->cache_valid_id = FAT_CACHE_VALID + 1; |
505 | INIT_LIST_HEAD(&ei->cache_lru); | 538 | INIT_LIST_HEAD(&ei->cache_lru); |
506 | INIT_HLIST_NODE(&ei->i_fat_hash); | 539 | INIT_HLIST_NODE(&ei->i_fat_hash); |
540 | INIT_HLIST_NODE(&ei->i_dir_hash); | ||
507 | inode_init_once(&ei->vfs_inode); | 541 | inode_init_once(&ei->vfs_inode); |
508 | } | 542 | } |
509 | 543 | ||
@@ -668,125 +702,9 @@ static const struct super_operations fat_sops = { | |||
668 | .show_options = fat_show_options, | 702 | .show_options = fat_show_options, |
669 | }; | 703 | }; |
670 | 704 | ||
671 | /* | ||
672 | * a FAT file handle with fhtype 3 is | ||
673 | * 0/ i_ino - for fast, reliable lookup if still in the cache | ||
674 | * 1/ i_generation - to see if i_ino is still valid | ||
675 | * bit 0 == 0 iff directory | ||
676 | * 2/ i_pos(8-39) - if ino has changed, but still in cache | ||
677 | * 3/ i_pos(4-7)|i_logstart - to semi-verify inode found at i_pos | ||
678 | * 4/ i_pos(0-3)|parent->i_logstart - maybe used to hunt for the file on disc | ||
679 | * | ||
680 | * Hack for NFSv2: Maximum FAT entry number is 28bits and maximum | ||
681 | * i_pos is 40bits (blocknr(32) + dir offset(8)), so two 4bits | ||
682 | * of i_logstart is used to store the directory entry offset. | ||
683 | */ | ||
684 | |||
685 | static struct dentry *fat_fh_to_dentry(struct super_block *sb, | ||
686 | struct fid *fid, int fh_len, int fh_type) | ||
687 | { | ||
688 | struct inode *inode = NULL; | ||
689 | u32 *fh = fid->raw; | ||
690 | |||
691 | if (fh_len < 5 || fh_type != 3) | ||
692 | return NULL; | ||
693 | |||
694 | inode = ilookup(sb, fh[0]); | ||
695 | if (!inode || inode->i_generation != fh[1]) { | ||
696 | if (inode) | ||
697 | iput(inode); | ||
698 | inode = NULL; | ||
699 | } | ||
700 | if (!inode) { | ||
701 | loff_t i_pos; | ||
702 | int i_logstart = fh[3] & 0x0fffffff; | ||
703 | |||
704 | i_pos = (loff_t)fh[2] << 8; | ||
705 | i_pos |= ((fh[3] >> 24) & 0xf0) | (fh[4] >> 28); | ||
706 | |||
707 | /* try 2 - see if i_pos is in F-d-c | ||
708 | * require i_logstart to be the same | ||
709 | * Will fail if you truncate and then re-write | ||
710 | */ | ||
711 | |||
712 | inode = fat_iget(sb, i_pos); | ||
713 | if (inode && MSDOS_I(inode)->i_logstart != i_logstart) { | ||
714 | iput(inode); | ||
715 | inode = NULL; | ||
716 | } | ||
717 | } | ||
718 | |||
719 | /* | ||
720 | * For now, do nothing if the inode is not found. | ||
721 | * | ||
722 | * What we could do is: | ||
723 | * | ||
724 | * - follow the file starting at fh[4], and record the ".." entry, | ||
725 | * and the name of the fh[2] entry. | ||
726 | * - then follow the ".." file finding the next step up. | ||
727 | * | ||
728 | * This way we build a path to the root of the tree. If this works, we | ||
729 | * lookup the path and so get this inode into the cache. Finally try | ||
730 | * the fat_iget lookup again. If that fails, then we are totally out | ||
731 | * of luck. But all that is for another day | ||
732 | */ | ||
733 | return d_obtain_alias(inode); | ||
734 | } | ||
735 | |||
736 | static int | ||
737 | fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent) | ||
738 | { | ||
739 | int len = *lenp; | ||
740 | struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); | ||
741 | loff_t i_pos; | ||
742 | |||
743 | if (len < 5) { | ||
744 | *lenp = 5; | ||
745 | return 255; /* no room */ | ||
746 | } | ||
747 | |||
748 | i_pos = fat_i_pos_read(sbi, inode); | ||
749 | *lenp = 5; | ||
750 | fh[0] = inode->i_ino; | ||
751 | fh[1] = inode->i_generation; | ||
752 | fh[2] = i_pos >> 8; | ||
753 | fh[3] = ((i_pos & 0xf0) << 24) | MSDOS_I(inode)->i_logstart; | ||
754 | fh[4] = (i_pos & 0x0f) << 28; | ||
755 | if (parent) | ||
756 | fh[4] |= MSDOS_I(parent)->i_logstart; | ||
757 | return 3; | ||
758 | } | ||
759 | |||
760 | static struct dentry *fat_get_parent(struct dentry *child) | ||
761 | { | ||
762 | struct super_block *sb = child->d_sb; | ||
763 | struct buffer_head *bh; | ||
764 | struct msdos_dir_entry *de; | ||
765 | loff_t i_pos; | ||
766 | struct dentry *parent; | ||
767 | struct inode *inode; | ||
768 | int err; | ||
769 | |||
770 | lock_super(sb); | ||
771 | |||
772 | err = fat_get_dotdot_entry(child->d_inode, &bh, &de, &i_pos); | ||
773 | if (err) { | ||
774 | parent = ERR_PTR(err); | ||
775 | goto out; | ||
776 | } | ||
777 | inode = fat_build_inode(sb, de, i_pos); | ||
778 | brelse(bh); | ||
779 | |||
780 | parent = d_obtain_alias(inode); | ||
781 | out: | ||
782 | unlock_super(sb); | ||
783 | |||
784 | return parent; | ||
785 | } | ||
786 | |||
787 | static const struct export_operations fat_export_ops = { | 705 | static const struct export_operations fat_export_ops = { |
788 | .encode_fh = fat_encode_fh, | ||
789 | .fh_to_dentry = fat_fh_to_dentry, | 706 | .fh_to_dentry = fat_fh_to_dentry, |
707 | .fh_to_parent = fat_fh_to_parent, | ||
790 | .get_parent = fat_get_parent, | 708 | .get_parent = fat_get_parent, |
791 | }; | 709 | }; |
792 | 710 | ||
@@ -836,6 +754,8 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) | |||
836 | seq_puts(m, ",usefree"); | 754 | seq_puts(m, ",usefree"); |
837 | if (opts->quiet) | 755 | if (opts->quiet) |
838 | seq_puts(m, ",quiet"); | 756 | seq_puts(m, ",quiet"); |
757 | if (opts->nfs) | ||
758 | seq_puts(m, ",nfs"); | ||
839 | if (opts->showexec) | 759 | if (opts->showexec) |
840 | seq_puts(m, ",showexec"); | 760 | seq_puts(m, ",showexec"); |
841 | if (opts->sys_immutable) | 761 | if (opts->sys_immutable) |
@@ -880,7 +800,7 @@ enum { | |||
880 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, | 800 | Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, |
881 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 801 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, |
882 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, | 802 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, |
883 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_err, | 803 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_err, |
884 | }; | 804 | }; |
885 | 805 | ||
886 | static const match_table_t fat_tokens = { | 806 | static const match_table_t fat_tokens = { |
@@ -909,6 +829,7 @@ static const match_table_t fat_tokens = { | |||
909 | {Opt_err_panic, "errors=panic"}, | 829 | {Opt_err_panic, "errors=panic"}, |
910 | {Opt_err_ro, "errors=remount-ro"}, | 830 | {Opt_err_ro, "errors=remount-ro"}, |
911 | {Opt_discard, "discard"}, | 831 | {Opt_discard, "discard"}, |
832 | {Opt_nfs, "nfs"}, | ||
912 | {Opt_obsolete, "conv=binary"}, | 833 | {Opt_obsolete, "conv=binary"}, |
913 | {Opt_obsolete, "conv=text"}, | 834 | {Opt_obsolete, "conv=text"}, |
914 | {Opt_obsolete, "conv=auto"}, | 835 | {Opt_obsolete, "conv=auto"}, |
@@ -989,6 +910,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
989 | opts->numtail = 1; | 910 | opts->numtail = 1; |
990 | opts->usefree = opts->nocase = 0; | 911 | opts->usefree = opts->nocase = 0; |
991 | opts->tz_utc = 0; | 912 | opts->tz_utc = 0; |
913 | opts->nfs = 0; | ||
992 | opts->errors = FAT_ERRORS_RO; | 914 | opts->errors = FAT_ERRORS_RO; |
993 | *debug = 0; | 915 | *debug = 0; |
994 | 916 | ||
@@ -1153,6 +1075,9 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
1153 | case Opt_discard: | 1075 | case Opt_discard: |
1154 | opts->discard = 1; | 1076 | opts->discard = 1; |
1155 | break; | 1077 | break; |
1078 | case Opt_nfs: | ||
1079 | opts->nfs = 1; | ||
1080 | break; | ||
1156 | 1081 | ||
1157 | /* obsolete mount options */ | 1082 | /* obsolete mount options */ |
1158 | case Opt_obsolete: | 1083 | case Opt_obsolete: |
@@ -1443,6 +1368,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1443 | 1368 | ||
1444 | /* set up enough so that it can read an inode */ | 1369 | /* set up enough so that it can read an inode */ |
1445 | fat_hash_init(sb); | 1370 | fat_hash_init(sb); |
1371 | dir_hash_init(sb); | ||
1446 | fat_ent_access_init(sb); | 1372 | fat_ent_access_init(sb); |
1447 | 1373 | ||
1448 | /* | 1374 | /* |
@@ -1497,6 +1423,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1497 | } | 1423 | } |
1498 | error = -ENOMEM; | 1424 | error = -ENOMEM; |
1499 | insert_inode_hash(root_inode); | 1425 | insert_inode_hash(root_inode); |
1426 | fat_attach(root_inode, 0); | ||
1500 | sb->s_root = d_make_root(root_inode); | 1427 | sb->s_root = d_make_root(root_inode); |
1501 | if (!sb->s_root) { | 1428 | if (!sb->s_root) { |
1502 | fat_msg(sb, KERN_ERR, "get root inode failed"); | 1429 | fat_msg(sb, KERN_ERR, "get root inode failed"); |
@@ -1536,18 +1463,14 @@ static int writeback_inode(struct inode *inode) | |||
1536 | { | 1463 | { |
1537 | 1464 | ||
1538 | int ret; | 1465 | int ret; |
1539 | struct address_space *mapping = inode->i_mapping; | 1466 | |
1540 | struct writeback_control wbc = { | 1467 | /* if we used wait=1, sync_inode_metadata waits for the io for the |
1541 | .sync_mode = WB_SYNC_NONE, | 1468 | * inode to finish. So wait=0 is sent down to sync_inode_metadata |
1542 | .nr_to_write = 0, | ||
1543 | }; | ||
1544 | /* if we used WB_SYNC_ALL, sync_inode waits for the io for the | ||
1545 | * inode to finish. So WB_SYNC_NONE is sent down to sync_inode | ||
1546 | * and filemap_fdatawrite is used for the data blocks | 1469 | * and filemap_fdatawrite is used for the data blocks |
1547 | */ | 1470 | */ |
1548 | ret = sync_inode(inode, &wbc); | 1471 | ret = sync_inode_metadata(inode, 0); |
1549 | if (!ret) | 1472 | if (!ret) |
1550 | ret = filemap_fdatawrite(mapping); | 1473 | ret = filemap_fdatawrite(inode->i_mapping); |
1551 | return ret; | 1474 | return ret; |
1552 | } | 1475 | } |
1553 | 1476 | ||
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index b0e12bf9f4a1..c1055e778fff 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -407,7 +407,7 @@ out: | |||
407 | static int msdos_unlink(struct inode *dir, struct dentry *dentry) | 407 | static int msdos_unlink(struct inode *dir, struct dentry *dentry) |
408 | { | 408 | { |
409 | struct inode *inode = dentry->d_inode; | 409 | struct inode *inode = dentry->d_inode; |
410 | struct super_block *sb= inode->i_sb; | 410 | struct super_block *sb = inode->i_sb; |
411 | struct fat_slot_info sinfo; | 411 | struct fat_slot_info sinfo; |
412 | int err; | 412 | int err; |
413 | 413 | ||
@@ -440,7 +440,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
440 | struct inode *old_inode, *new_inode; | 440 | struct inode *old_inode, *new_inode; |
441 | struct fat_slot_info old_sinfo, sinfo; | 441 | struct fat_slot_info old_sinfo, sinfo; |
442 | struct timespec ts; | 442 | struct timespec ts; |
443 | loff_t dotdot_i_pos, new_i_pos; | 443 | loff_t new_i_pos; |
444 | int err, old_attrs, is_dir, update_dotdot, corrupt = 0; | 444 | int err, old_attrs, is_dir, update_dotdot, corrupt = 0; |
445 | 445 | ||
446 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; | 446 | old_sinfo.bh = sinfo.bh = dotdot_bh = NULL; |
@@ -456,8 +456,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, | |||
456 | is_dir = S_ISDIR(old_inode->i_mode); | 456 | is_dir = S_ISDIR(old_inode->i_mode); |
457 | update_dotdot = (is_dir && old_dir != new_dir); | 457 | update_dotdot = (is_dir && old_dir != new_dir); |
458 | if (update_dotdot) { | 458 | if (update_dotdot) { |
459 | if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de, | 459 | if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de)) { |
460 | &dotdot_i_pos) < 0) { | ||
461 | err = -EIO; | 460 | err = -EIO; |
462 | goto out; | 461 | goto out; |
463 | } | 462 | } |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 6a6d8c0715a1..e535dd75b986 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -914,7 +914,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
914 | struct inode *old_inode, *new_inode; | 914 | struct inode *old_inode, *new_inode; |
915 | struct fat_slot_info old_sinfo, sinfo; | 915 | struct fat_slot_info old_sinfo, sinfo; |
916 | struct timespec ts; | 916 | struct timespec ts; |
917 | loff_t dotdot_i_pos, new_i_pos; | 917 | loff_t new_i_pos; |
918 | int err, is_dir, update_dotdot, corrupt = 0; | 918 | int err, is_dir, update_dotdot, corrupt = 0; |
919 | struct super_block *sb = old_dir->i_sb; | 919 | struct super_block *sb = old_dir->i_sb; |
920 | 920 | ||
@@ -929,8 +929,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
929 | is_dir = S_ISDIR(old_inode->i_mode); | 929 | is_dir = S_ISDIR(old_inode->i_mode); |
930 | update_dotdot = (is_dir && old_dir != new_dir); | 930 | update_dotdot = (is_dir && old_dir != new_dir); |
931 | if (update_dotdot) { | 931 | if (update_dotdot) { |
932 | if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de, | 932 | if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de)) { |
933 | &dotdot_i_pos) < 0) { | ||
934 | err = -EIO; | 933 | err = -EIO; |
935 | goto out; | 934 | goto out; |
936 | } | 935 | } |
diff --git a/fs/fat/nfs.c b/fs/fat/nfs.c new file mode 100644 index 000000000000..ef4b5faba87b --- /dev/null +++ b/fs/fat/nfs.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* fs/fat/nfs.c | ||
2 | * | ||
3 | * This software is licensed under the terms of the GNU General Public | ||
4 | * License version 2, as published by the Free Software Foundation, and | ||
5 | * may be copied, distributed, and modified under those terms. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/exportfs.h> | ||
15 | #include "fat.h" | ||
16 | |||
17 | /** | ||
18 | * Look up a directory inode given its starting cluster. | ||
19 | */ | ||
20 | static struct inode *fat_dget(struct super_block *sb, int i_logstart) | ||
21 | { | ||
22 | struct msdos_sb_info *sbi = MSDOS_SB(sb); | ||
23 | struct hlist_head *head; | ||
24 | struct hlist_node *_p; | ||
25 | struct msdos_inode_info *i; | ||
26 | struct inode *inode = NULL; | ||
27 | |||
28 | head = sbi->dir_hashtable + fat_dir_hash(i_logstart); | ||
29 | spin_lock(&sbi->dir_hash_lock); | ||
30 | hlist_for_each_entry(i, _p, head, i_dir_hash) { | ||
31 | BUG_ON(i->vfs_inode.i_sb != sb); | ||
32 | if (i->i_logstart != i_logstart) | ||
33 | continue; | ||
34 | inode = igrab(&i->vfs_inode); | ||
35 | if (inode) | ||
36 | break; | ||
37 | } | ||
38 | spin_unlock(&sbi->dir_hash_lock); | ||
39 | return inode; | ||
40 | } | ||
41 | |||
42 | static struct inode *fat_nfs_get_inode(struct super_block *sb, | ||
43 | u64 ino, u32 generation) | ||
44 | { | ||
45 | struct inode *inode; | ||
46 | |||
47 | if ((ino < MSDOS_ROOT_INO) || (ino == MSDOS_FSINFO_INO)) | ||
48 | return NULL; | ||
49 | |||
50 | inode = ilookup(sb, ino); | ||
51 | if (inode && generation && (inode->i_generation != generation)) { | ||
52 | iput(inode); | ||
53 | inode = NULL; | ||
54 | } | ||
55 | |||
56 | return inode; | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Map a NFS file handle to a corresponding dentry. | ||
61 | * The dentry may or may not be connected to the filesystem root. | ||
62 | */ | ||
63 | struct dentry *fat_fh_to_dentry(struct super_block *sb, struct fid *fid, | ||
64 | int fh_len, int fh_type) | ||
65 | { | ||
66 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, | ||
67 | fat_nfs_get_inode); | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * Find the parent for a file specified by NFS handle. | ||
72 | * This requires that the handle contain the i_ino of the parent. | ||
73 | */ | ||
74 | struct dentry *fat_fh_to_parent(struct super_block *sb, struct fid *fid, | ||
75 | int fh_len, int fh_type) | ||
76 | { | ||
77 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, | ||
78 | fat_nfs_get_inode); | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Find the parent for a directory that is not currently connected to | ||
83 | * the filesystem root. | ||
84 | * | ||
85 | * On entry, the caller holds child_dir->d_inode->i_mutex. | ||
86 | */ | ||
87 | struct dentry *fat_get_parent(struct dentry *child_dir) | ||
88 | { | ||
89 | struct super_block *sb = child_dir->d_sb; | ||
90 | struct buffer_head *bh = NULL; | ||
91 | struct msdos_dir_entry *de; | ||
92 | struct inode *parent_inode = NULL; | ||
93 | |||
94 | if (!fat_get_dotdot_entry(child_dir->d_inode, &bh, &de)) { | ||
95 | int parent_logstart = fat_get_start(MSDOS_SB(sb), de); | ||
96 | parent_inode = fat_dget(sb, parent_logstart); | ||
97 | } | ||
98 | brelse(bh); | ||
99 | |||
100 | return d_obtain_alias(parent_inode); | ||
101 | } | ||
diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c index 4bae4a4a60b1..2d5b254ad9e2 100644 --- a/fs/hpfs/anode.c +++ b/fs/hpfs/anode.c | |||
@@ -102,7 +102,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
102 | return -1; | 102 | return -1; |
103 | } | 103 | } |
104 | if (hpfs_alloc_if_possible(s, se = le32_to_cpu(btree->u.external[n].disk_secno) + le32_to_cpu(btree->u.external[n].length))) { | 104 | if (hpfs_alloc_if_possible(s, se = le32_to_cpu(btree->u.external[n].disk_secno) + le32_to_cpu(btree->u.external[n].length))) { |
105 | btree->u.external[n].length = cpu_to_le32(le32_to_cpu(btree->u.external[n].length) + 1); | 105 | le32_add_cpu(&btree->u.external[n].length, 1); |
106 | mark_buffer_dirty(bh); | 106 | mark_buffer_dirty(bh); |
107 | brelse(bh); | 107 | brelse(bh); |
108 | return se; | 108 | return se; |
@@ -153,7 +153,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
153 | btree = &anode->btree; | 153 | btree = &anode->btree; |
154 | } | 154 | } |
155 | btree->n_free_nodes--; n = btree->n_used_nodes++; | 155 | btree->n_free_nodes--; n = btree->n_used_nodes++; |
156 | btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 12); | 156 | le16_add_cpu(&btree->first_free, 12); |
157 | btree->u.external[n].disk_secno = cpu_to_le32(se); | 157 | btree->u.external[n].disk_secno = cpu_to_le32(se); |
158 | btree->u.external[n].file_secno = cpu_to_le32(fs); | 158 | btree->u.external[n].file_secno = cpu_to_le32(fs); |
159 | btree->u.external[n].length = cpu_to_le32(1); | 159 | btree->u.external[n].length = cpu_to_le32(1); |
@@ -174,7 +174,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
174 | } | 174 | } |
175 | if (btree->n_free_nodes) { | 175 | if (btree->n_free_nodes) { |
176 | btree->n_free_nodes--; n = btree->n_used_nodes++; | 176 | btree->n_free_nodes--; n = btree->n_used_nodes++; |
177 | btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 8); | 177 | le16_add_cpu(&btree->first_free, 8); |
178 | btree->u.internal[n].file_secno = cpu_to_le32(-1); | 178 | btree->u.internal[n].file_secno = cpu_to_le32(-1); |
179 | btree->u.internal[n].down = cpu_to_le32(na); | 179 | btree->u.internal[n].down = cpu_to_le32(na); |
180 | btree->u.internal[n-1].file_secno = cpu_to_le32(fs); | 180 | btree->u.internal[n-1].file_secno = cpu_to_le32(fs); |
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c index 3228c524ebe5..4364b2a02c5d 100644 --- a/fs/hpfs/dnode.c +++ b/fs/hpfs/dnode.c | |||
@@ -145,10 +145,10 @@ static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno | |||
145 | } | 145 | } |
146 | } | 146 | } |
147 | if (ptr) { | 147 | if (ptr) { |
148 | d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) + 4); | 148 | le32_add_cpu(&d->first_free, 4); |
149 | if (le32_to_cpu(d->first_free) > 2048) { | 149 | if (le32_to_cpu(d->first_free) > 2048) { |
150 | hpfs_error(s, "set_last_pointer: too long dnode %08x", le32_to_cpu(d->self)); | 150 | hpfs_error(s, "set_last_pointer: too long dnode %08x", le32_to_cpu(d->self)); |
151 | d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) - 4); | 151 | le32_add_cpu(&d->first_free, -4); |
152 | return; | 152 | return; |
153 | } | 153 | } |
154 | de->length = cpu_to_le16(36); | 154 | de->length = cpu_to_le16(36); |
@@ -184,7 +184,7 @@ struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d, | |||
184 | de->not_8x3 = hpfs_is_name_long(name, namelen); | 184 | de->not_8x3 = hpfs_is_name_long(name, namelen); |
185 | de->namelen = namelen; | 185 | de->namelen = namelen; |
186 | memcpy(de->name, name, namelen); | 186 | memcpy(de->name, name, namelen); |
187 | d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) + d_size); | 187 | le32_add_cpu(&d->first_free, d_size); |
188 | return de; | 188 | return de; |
189 | } | 189 | } |
190 | 190 | ||
@@ -314,7 +314,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, | |||
314 | set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0); | 314 | set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0); |
315 | de = de_next_de(de); | 315 | de = de_next_de(de); |
316 | memmove((char *)nd + 20, de, le32_to_cpu(nd->first_free) + (char *)nd - (char *)de); | 316 | memmove((char *)nd + 20, de, le32_to_cpu(nd->first_free) + (char *)nd - (char *)de); |
317 | nd->first_free = cpu_to_le32(le32_to_cpu(nd->first_free) - ((char *)de - (char *)nd - 20)); | 317 | le32_add_cpu(&nd->first_free, -((char *)de - (char *)nd - 20)); |
318 | memcpy(d, nd, le32_to_cpu(nd->first_free)); | 318 | memcpy(d, nd, le32_to_cpu(nd->first_free)); |
319 | for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos); | 319 | for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos); |
320 | fix_up_ptrs(i->i_sb, ad); | 320 | fix_up_ptrs(i->i_sb, ad); |
@@ -474,8 +474,8 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to) | |||
474 | hpfs_brelse4(&qbh); | 474 | hpfs_brelse4(&qbh); |
475 | return 0; | 475 | return 0; |
476 | } | 476 | } |
477 | dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4); | 477 | le32_add_cpu(&dnode->first_free, -4); |
478 | de->length = cpu_to_le16(le16_to_cpu(de->length) - 4); | 478 | le16_add_cpu(&de->length, -4); |
479 | de->down = 0; | 479 | de->down = 0; |
480 | hpfs_mark_4buffers_dirty(&qbh); | 480 | hpfs_mark_4buffers_dirty(&qbh); |
481 | dno = up; | 481 | dno = up; |
@@ -570,8 +570,8 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) | |||
570 | for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p); | 570 | for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p); |
571 | if (!down) { | 571 | if (!down) { |
572 | de->down = 0; | 572 | de->down = 0; |
573 | de->length = cpu_to_le16(le16_to_cpu(de->length) - 4); | 573 | le16_add_cpu(&de->length, -4); |
574 | dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) - 4); | 574 | le32_add_cpu(&dnode->first_free, -4); |
575 | memmove(de_next_de(de), (char *)de_next_de(de) + 4, | 575 | memmove(de_next_de(de), (char *)de_next_de(de) + 4, |
576 | (char *)dnode + le32_to_cpu(dnode->first_free) - (char *)de_next_de(de)); | 576 | (char *)dnode + le32_to_cpu(dnode->first_free) - (char *)de_next_de(de)); |
577 | } else { | 577 | } else { |
@@ -647,14 +647,14 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) | |||
647 | printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n"); | 647 | printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n"); |
648 | printk("HPFS: warning: goin'on\n"); | 648 | printk("HPFS: warning: goin'on\n"); |
649 | } | 649 | } |
650 | del->length = cpu_to_le16(le16_to_cpu(del->length) + 4); | 650 | le16_add_cpu(&del->length, 4); |
651 | del->down = 1; | 651 | del->down = 1; |
652 | d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) + 4); | 652 | le32_add_cpu(&d1->first_free, 4); |
653 | } | 653 | } |
654 | if (dlp && !down) { | 654 | if (dlp && !down) { |
655 | del->length = cpu_to_le16(le16_to_cpu(del->length) - 4); | 655 | le16_add_cpu(&del->length, -4); |
656 | del->down = 0; | 656 | del->down = 0; |
657 | d1->first_free = cpu_to_le32(le32_to_cpu(d1->first_free) - 4); | 657 | le32_add_cpu(&d1->first_free, -4); |
658 | } else if (down) | 658 | } else if (down) |
659 | *(__le32 *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down); | 659 | *(__le32 *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down); |
660 | } else goto endm; | 660 | } else goto endm; |
@@ -668,9 +668,9 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) | |||
668 | memcpy(de_cp, de_prev, le16_to_cpu(de_prev->length)); | 668 | memcpy(de_cp, de_prev, le16_to_cpu(de_prev->length)); |
669 | hpfs_delete_de(i->i_sb, dnode, de_prev); | 669 | hpfs_delete_de(i->i_sb, dnode, de_prev); |
670 | if (!de_prev->down) { | 670 | if (!de_prev->down) { |
671 | de_prev->length = cpu_to_le16(le16_to_cpu(de_prev->length) + 4); | 671 | le16_add_cpu(&de_prev->length, 4); |
672 | de_prev->down = 1; | 672 | de_prev->down = 1; |
673 | dnode->first_free = cpu_to_le32(le32_to_cpu(dnode->first_free) + 4); | 673 | le32_add_cpu(&dnode->first_free, 4); |
674 | } | 674 | } |
675 | *(__le32 *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown); | 675 | *(__le32 *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown); |
676 | hpfs_mark_4buffers_dirty(&qbh); | 676 | hpfs_mark_4buffers_dirty(&qbh); |
diff --git a/fs/omfs/file.c b/fs/omfs/file.c index 2c6d95257a4d..77e3cb2962b4 100644 --- a/fs/omfs/file.c +++ b/fs/omfs/file.c | |||
@@ -146,8 +146,7 @@ static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe, | |||
146 | be64_to_cpu(entry->e_blocks); | 146 | be64_to_cpu(entry->e_blocks); |
147 | 147 | ||
148 | if (omfs_allocate_block(inode->i_sb, new_block)) { | 148 | if (omfs_allocate_block(inode->i_sb, new_block)) { |
149 | entry->e_blocks = | 149 | be64_add_cpu(&entry->e_blocks, 1); |
150 | cpu_to_be64(be64_to_cpu(entry->e_blocks) + 1); | ||
151 | terminator->e_blocks = ~(cpu_to_be64( | 150 | terminator->e_blocks = ~(cpu_to_be64( |
152 | be64_to_cpu(~terminator->e_blocks) + 1)); | 151 | be64_to_cpu(~terminator->e_blocks) + 1)); |
153 | goto out; | 152 | goto out; |
@@ -177,7 +176,7 @@ static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe, | |||
177 | be64_to_cpu(~terminator->e_blocks) + (u64) new_count)); | 176 | be64_to_cpu(~terminator->e_blocks) + (u64) new_count)); |
178 | 177 | ||
179 | /* write in new entry */ | 178 | /* write in new entry */ |
180 | oe->e_extent_count = cpu_to_be32(1 + be32_to_cpu(oe->e_extent_count)); | 179 | be32_add_cpu(&oe->e_extent_count, 1); |
181 | 180 | ||
182 | out: | 181 | out: |
183 | *ret_block = new_block; | 182 | *ret_block = new_block; |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index b3647fe6a608..0d80cef4cfb9 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -427,7 +427,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
427 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { | 427 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
428 | pde_get(de); | 428 | pde_get(de); |
429 | spin_unlock(&proc_subdir_lock); | 429 | spin_unlock(&proc_subdir_lock); |
430 | error = -EINVAL; | 430 | error = -ENOMEM; |
431 | inode = proc_get_inode(dir->i_sb, de); | 431 | inode = proc_get_inode(dir->i_sb, de); |
432 | goto out_unlock; | 432 | goto out_unlock; |
433 | } | 433 | } |
@@ -605,7 +605,8 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, | |||
605 | unsigned int len; | 605 | unsigned int len; |
606 | 606 | ||
607 | /* make sure name is valid */ | 607 | /* make sure name is valid */ |
608 | if (!name || !strlen(name)) goto out; | 608 | if (!name || !strlen(name)) |
609 | goto out; | ||
609 | 610 | ||
610 | if (xlate_proc_name(name, parent, &fn) != 0) | 611 | if (xlate_proc_name(name, parent, &fn) != 0) |
611 | goto out; | 612 | goto out; |
@@ -616,20 +617,18 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, | |||
616 | 617 | ||
617 | len = strlen(fn); | 618 | len = strlen(fn); |
618 | 619 | ||
619 | ent = kmalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL); | 620 | ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL); |
620 | if (!ent) goto out; | 621 | if (!ent) |
622 | goto out; | ||
621 | 623 | ||
622 | memset(ent, 0, sizeof(struct proc_dir_entry)); | ||
623 | memcpy(ent->name, fn, len + 1); | 624 | memcpy(ent->name, fn, len + 1); |
624 | ent->namelen = len; | 625 | ent->namelen = len; |
625 | ent->mode = mode; | 626 | ent->mode = mode; |
626 | ent->nlink = nlink; | 627 | ent->nlink = nlink; |
627 | atomic_set(&ent->count, 1); | 628 | atomic_set(&ent->count, 1); |
628 | ent->pde_users = 0; | ||
629 | spin_lock_init(&ent->pde_unload_lock); | 629 | spin_lock_init(&ent->pde_unload_lock); |
630 | ent->pde_unload_completion = NULL; | ||
631 | INIT_LIST_HEAD(&ent->pde_openers); | 630 | INIT_LIST_HEAD(&ent->pde_openers); |
632 | out: | 631 | out: |
633 | return ent; | 632 | return ent; |
634 | } | 633 | } |
635 | 634 | ||
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 7ac817b64a71..3b22bbdee9ec 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -450,7 +450,6 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) | |||
450 | return NULL; | 450 | return NULL; |
451 | if (inode->i_state & I_NEW) { | 451 | if (inode->i_state & I_NEW) { |
452 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 452 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
453 | PROC_I(inode)->fd = 0; | ||
454 | PROC_I(inode)->pde = de; | 453 | PROC_I(inode)->pde = de; |
455 | 454 | ||
456 | if (de->mode) { | 455 | if (de->mode) { |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 67925a7bd8cb..cceaab07ad54 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -103,7 +103,7 @@ static inline int task_dumpable(struct task_struct *task) | |||
103 | if (mm) | 103 | if (mm) |
104 | dumpable = get_dumpable(mm); | 104 | dumpable = get_dumpable(mm); |
105 | task_unlock(task); | 105 | task_unlock(task); |
106 | if(dumpable == 1) | 106 | if (dumpable == SUID_DUMPABLE_ENABLED) |
107 | return 1; | 107 | return 1; |
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index eb7cc91b7258..dcd56f84db7e 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -266,8 +266,7 @@ void sysctl_head_put(struct ctl_table_header *head) | |||
266 | 266 | ||
267 | static struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head) | 267 | static struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head) |
268 | { | 268 | { |
269 | if (!head) | 269 | BUG_ON(!head); |
270 | BUG(); | ||
271 | spin_lock(&sysctl_lock); | 270 | spin_lock(&sysctl_lock); |
272 | if (!use_table(head)) | 271 | if (!use_table(head)) |
273 | head = ERR_PTR(-ENOENT); | 272 | head = ERR_PTR(-ENOENT); |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 9a2d9fd7cadd..9889a92d2e01 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -61,7 +61,7 @@ static int proc_parse_options(char *options, struct pid_namespace *pid) | |||
61 | if (!*p) | 61 | if (!*p) |
62 | continue; | 62 | continue; |
63 | 63 | ||
64 | args[0].to = args[0].from = 0; | 64 | args[0].to = args[0].from = NULL; |
65 | token = match_token(p, tokens, args); | 65 | token = match_token(p, tokens, args); |
66 | switch (token) { | 66 | switch (token) { |
67 | case Opt_gid: | 67 | case Opt_gid: |
diff --git a/fs/super.c b/fs/super.c index 5fdf7ff32c4e..a3bc935069d9 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -865,7 +865,7 @@ int get_anon_bdev(dev_t *p) | |||
865 | else if (error) | 865 | else if (error) |
866 | return -EAGAIN; | 866 | return -EAGAIN; |
867 | 867 | ||
868 | if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) { | 868 | if ((dev & MAX_IDR_MASK) == (1 << MINORBITS)) { |
869 | spin_lock(&unnamed_dev_lock); | 869 | spin_lock(&unnamed_dev_lock); |
870 | ida_remove(&unnamed_dev_ida, dev); | 870 | ida_remove(&unnamed_dev_ida, dev); |
871 | if (unnamed_dev_start > dev) | 871 | if (unnamed_dev_start > dev) |
diff --git a/include/asm-generic/bitops/le.h b/include/asm-generic/bitops/le.h index f95c663a6a41..61731543c00e 100644 --- a/include/asm-generic/bitops/le.h +++ b/include/asm-generic/bitops/le.h | |||
@@ -54,6 +54,16 @@ static inline int test_bit_le(int nr, const void *addr) | |||
54 | return test_bit(nr ^ BITOP_LE_SWIZZLE, addr); | 54 | return test_bit(nr ^ BITOP_LE_SWIZZLE, addr); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline void set_bit_le(int nr, void *addr) | ||
58 | { | ||
59 | set_bit(nr ^ BITOP_LE_SWIZZLE, addr); | ||
60 | } | ||
61 | |||
62 | static inline void clear_bit_le(int nr, void *addr) | ||
63 | { | ||
64 | clear_bit(nr ^ BITOP_LE_SWIZZLE, addr); | ||
65 | } | ||
66 | |||
57 | static inline void __set_bit_le(int nr, void *addr) | 67 | static inline void __set_bit_le(int nr, void *addr) |
58 | { | 68 | { |
59 | __set_bit(nr ^ BITOP_LE_SWIZZLE, addr); | 69 | __set_bit(nr ^ BITOP_LE_SWIZZLE, addr); |
diff --git a/include/linux/audit.h b/include/linux/audit.h index e7c836d961ea..2c83e5f7edb1 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -527,9 +527,18 @@ static inline void audit_ptrace(struct task_struct *t) | |||
527 | extern unsigned int audit_serial(void); | 527 | extern unsigned int audit_serial(void); |
528 | extern int auditsc_get_stamp(struct audit_context *ctx, | 528 | extern int auditsc_get_stamp(struct audit_context *ctx, |
529 | struct timespec *t, unsigned int *serial); | 529 | struct timespec *t, unsigned int *serial); |
530 | extern int audit_set_loginuid(kuid_t loginuid); | 530 | extern int audit_set_loginuid(kuid_t loginuid); |
531 | #define audit_get_loginuid(t) ((t)->loginuid) | 531 | |
532 | #define audit_get_sessionid(t) ((t)->sessionid) | 532 | static inline kuid_t audit_get_loginuid(struct task_struct *tsk) |
533 | { | ||
534 | return tsk->loginuid; | ||
535 | } | ||
536 | |||
537 | static inline int audit_get_sessionid(struct task_struct *tsk) | ||
538 | { | ||
539 | return tsk->sessionid; | ||
540 | } | ||
541 | |||
533 | extern void audit_log_task_context(struct audit_buffer *ab); | 542 | extern void audit_log_task_context(struct audit_buffer *ab); |
534 | extern void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk); | 543 | extern void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk); |
535 | extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); | 544 | extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); |
@@ -626,38 +635,101 @@ static inline void audit_mmap_fd(int fd, int flags) | |||
626 | extern int audit_n_rules; | 635 | extern int audit_n_rules; |
627 | extern int audit_signals; | 636 | extern int audit_signals; |
628 | #else /* CONFIG_AUDITSYSCALL */ | 637 | #else /* CONFIG_AUDITSYSCALL */ |
629 | #define audit_alloc(t) ({ 0; }) | 638 | static inline int audit_alloc(struct task_struct *task) |
630 | #define audit_free(t) do { ; } while (0) | 639 | { |
631 | #define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0) | 640 | return 0; |
632 | #define audit_syscall_exit(r) do { ; } while (0) | 641 | } |
633 | #define audit_dummy_context() 1 | 642 | static inline void audit_free(struct task_struct *task) |
634 | #define audit_getname(n) do { ; } while (0) | 643 | { } |
635 | #define audit_putname(n) do { ; } while (0) | 644 | static inline void audit_syscall_entry(int arch, int major, unsigned long a0, |
636 | #define __audit_inode(n,d) do { ; } while (0) | 645 | unsigned long a1, unsigned long a2, |
637 | #define __audit_inode_child(i,p) do { ; } while (0) | 646 | unsigned long a3) |
638 | #define audit_inode(n,d) do { (void)(d); } while (0) | 647 | { } |
639 | #define audit_inode_child(i,p) do { ; } while (0) | 648 | static inline void audit_syscall_exit(void *pt_regs) |
640 | #define audit_core_dumps(i) do { ; } while (0) | 649 | { } |
641 | #define audit_seccomp(i,s,c) do { ; } while (0) | 650 | static inline int audit_dummy_context(void) |
642 | #define auditsc_get_stamp(c,t,s) (0) | 651 | { |
643 | #define audit_get_loginuid(t) (INVALID_UID) | 652 | return 1; |
644 | #define audit_get_sessionid(t) (-1) | 653 | } |
645 | #define audit_log_task_context(b) do { ; } while (0) | 654 | static inline void audit_getname(const char *name) |
646 | #define audit_log_task_info(b, t) do { ; } while (0) | 655 | { } |
647 | #define audit_ipc_obj(i) ((void)0) | 656 | static inline void audit_putname(const char *name) |
648 | #define audit_ipc_set_perm(q,u,g,m) ((void)0) | 657 | { } |
649 | #define audit_bprm(p) ({ 0; }) | 658 | static inline void __audit_inode(const char *name, const struct dentry *dentry) |
650 | #define audit_socketcall(n,a) ((void)0) | 659 | { } |
651 | #define audit_fd_pair(n,a) ((void)0) | 660 | static inline void __audit_inode_child(const struct dentry *dentry, |
652 | #define audit_sockaddr(len, addr) ({ 0; }) | 661 | const struct inode *parent) |
653 | #define audit_mq_open(o,m,a) ((void)0) | 662 | { } |
654 | #define audit_mq_sendrecv(d,l,p,t) ((void)0) | 663 | static inline void audit_inode(const char *name, const struct dentry *dentry) |
655 | #define audit_mq_notify(d,n) ((void)0) | 664 | { } |
656 | #define audit_mq_getsetattr(d,s) ((void)0) | 665 | static inline void audit_inode_child(const struct dentry *dentry, |
657 | #define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; }) | 666 | const struct inode *parent) |
658 | #define audit_log_capset(pid, ncr, ocr) ((void)0) | 667 | { } |
659 | #define audit_mmap_fd(fd, flags) ((void)0) | 668 | static inline void audit_core_dumps(long signr) |
660 | #define audit_ptrace(t) ((void)0) | 669 | { } |
670 | static inline void __audit_seccomp(unsigned long syscall, long signr, int code) | ||
671 | { } | ||
672 | static inline void audit_seccomp(unsigned long syscall, long signr, int code) | ||
673 | { } | ||
674 | static inline int auditsc_get_stamp(struct audit_context *ctx, | ||
675 | struct timespec *t, unsigned int *serial) | ||
676 | { | ||
677 | return 0; | ||
678 | } | ||
679 | static inline kuid_t audit_get_loginuid(struct task_struct *tsk) | ||
680 | { | ||
681 | return INVALID_UID; | ||
682 | } | ||
683 | static inline int audit_get_sessionid(struct task_struct *tsk) | ||
684 | { | ||
685 | return -1; | ||
686 | } | ||
687 | static inline void audit_log_task_context(struct audit_buffer *ab) | ||
688 | { } | ||
689 | static inline void audit_log_task_info(struct audit_buffer *ab, | ||
690 | struct task_struct *tsk) | ||
691 | { } | ||
692 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) | ||
693 | { } | ||
694 | static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, | ||
695 | gid_t gid, umode_t mode) | ||
696 | { } | ||
697 | static inline int audit_bprm(struct linux_binprm *bprm) | ||
698 | { | ||
699 | return 0; | ||
700 | } | ||
701 | static inline void audit_socketcall(int nargs, unsigned long *args) | ||
702 | { } | ||
703 | static inline void audit_fd_pair(int fd1, int fd2) | ||
704 | { } | ||
705 | static inline int audit_sockaddr(int len, void *addr) | ||
706 | { | ||
707 | return 0; | ||
708 | } | ||
709 | static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr) | ||
710 | { } | ||
711 | static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, | ||
712 | unsigned int msg_prio, | ||
713 | const struct timespec *abs_timeout) | ||
714 | { } | ||
715 | static inline void audit_mq_notify(mqd_t mqdes, | ||
716 | const struct sigevent *notification) | ||
717 | { } | ||
718 | static inline void audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) | ||
719 | { } | ||
720 | static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm, | ||
721 | const struct cred *new, | ||
722 | const struct cred *old) | ||
723 | { | ||
724 | return 0; | ||
725 | } | ||
726 | static inline void audit_log_capset(pid_t pid, const struct cred *new, | ||
727 | const struct cred *old) | ||
728 | { } | ||
729 | static inline void audit_mmap_fd(int fd, int flags) | ||
730 | { } | ||
731 | static inline void audit_ptrace(struct task_struct *t) | ||
732 | { } | ||
661 | #define audit_n_rules 0 | 733 | #define audit_n_rules 0 |
662 | #define audit_signals 0 | 734 | #define audit_signals 0 |
663 | #endif /* CONFIG_AUDITSYSCALL */ | 735 | #endif /* CONFIG_AUDITSYSCALL */ |
@@ -681,7 +753,6 @@ extern void audit_log_n_hex(struct audit_buffer *ab, | |||
681 | extern void audit_log_n_string(struct audit_buffer *ab, | 753 | extern void audit_log_n_string(struct audit_buffer *ab, |
682 | const char *buf, | 754 | const char *buf, |
683 | size_t n); | 755 | size_t n); |
684 | #define audit_log_string(a,b) audit_log_n_string(a, b, strlen(b)); | ||
685 | extern void audit_log_n_untrustedstring(struct audit_buffer *ab, | 756 | extern void audit_log_n_untrustedstring(struct audit_buffer *ab, |
686 | const char *string, | 757 | const char *string, |
687 | size_t n); | 758 | size_t n); |
@@ -698,7 +769,8 @@ extern void audit_log_lost(const char *message); | |||
698 | #ifdef CONFIG_SECURITY | 769 | #ifdef CONFIG_SECURITY |
699 | extern void audit_log_secctx(struct audit_buffer *ab, u32 secid); | 770 | extern void audit_log_secctx(struct audit_buffer *ab, u32 secid); |
700 | #else | 771 | #else |
701 | #define audit_log_secctx(b,s) do { ; } while (0) | 772 | static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) |
773 | { } | ||
702 | #endif | 774 | #endif |
703 | 775 | ||
704 | extern int audit_update_lsm_rules(void); | 776 | extern int audit_update_lsm_rules(void); |
@@ -710,22 +782,50 @@ extern int audit_receive_filter(int type, int pid, int seq, | |||
710 | void *data, size_t datasz, kuid_t loginuid, | 782 | void *data, size_t datasz, kuid_t loginuid, |
711 | u32 sessionid, u32 sid); | 783 | u32 sessionid, u32 sid); |
712 | extern int audit_enabled; | 784 | extern int audit_enabled; |
713 | #else | 785 | #else /* CONFIG_AUDIT */ |
714 | #define audit_log(c,g,t,f,...) do { ; } while (0) | 786 | static inline __printf(4, 5) |
715 | #define audit_log_start(c,g,t) ({ NULL; }) | 787 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, |
716 | #define audit_log_vformat(b,f,a) do { ; } while (0) | 788 | const char *fmt, ...) |
717 | #define audit_log_format(b,f,...) do { ; } while (0) | 789 | { } |
718 | #define audit_log_end(b) do { ; } while (0) | 790 | static inline struct audit_buffer *audit_log_start(struct audit_context *ctx, |
719 | #define audit_log_n_hex(a,b,l) do { ; } while (0) | 791 | gfp_t gfp_mask, int type) |
720 | #define audit_log_n_string(a,c,l) do { ; } while (0) | 792 | { |
721 | #define audit_log_string(a,c) do { ; } while (0) | 793 | return NULL; |
722 | #define audit_log_n_untrustedstring(a,n,s) do { ; } while (0) | 794 | } |
723 | #define audit_log_untrustedstring(a,s) do { ; } while (0) | 795 | static inline __printf(2, 3) |
724 | #define audit_log_d_path(b, p, d) do { ; } while (0) | 796 | void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) |
725 | #define audit_log_key(b, k) do { ; } while (0) | 797 | { } |
726 | #define audit_log_link_denied(o, l) do { ; } while (0) | 798 | static inline void audit_log_end(struct audit_buffer *ab) |
727 | #define audit_log_secctx(b,s) do { ; } while (0) | 799 | { } |
800 | static inline void audit_log_n_hex(struct audit_buffer *ab, | ||
801 | const unsigned char *buf, size_t len) | ||
802 | { } | ||
803 | static inline void audit_log_n_string(struct audit_buffer *ab, | ||
804 | const char *buf, size_t n) | ||
805 | { } | ||
806 | static inline void audit_log_n_untrustedstring(struct audit_buffer *ab, | ||
807 | const char *string, size_t n) | ||
808 | { } | ||
809 | static inline void audit_log_untrustedstring(struct audit_buffer *ab, | ||
810 | const char *string) | ||
811 | { } | ||
812 | static inline void audit_log_d_path(struct audit_buffer *ab, | ||
813 | const char *prefix, | ||
814 | const struct path *path) | ||
815 | { } | ||
816 | static inline void audit_log_key(struct audit_buffer *ab, char *key) | ||
817 | { } | ||
818 | static inline void audit_log_link_denied(const char *string, | ||
819 | const struct path *link) | ||
820 | { } | ||
821 | static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) | ||
822 | { } | ||
728 | #define audit_enabled 0 | 823 | #define audit_enabled 0 |
729 | #endif | 824 | #endif /* CONFIG_AUDIT */ |
825 | static inline void audit_log_string(struct audit_buffer *ab, const char *buf) | ||
826 | { | ||
827 | audit_log_n_string(ab, buf, strlen(buf)); | ||
828 | } | ||
829 | |||
730 | #endif | 830 | #endif |
731 | #endif | 831 | #endif |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 366422bc1633..37935c2d2e8f 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h | |||
@@ -72,7 +72,7 @@ struct linux_binprm { | |||
72 | 72 | ||
73 | /* Function parameter for binfmt->coredump */ | 73 | /* Function parameter for binfmt->coredump */ |
74 | struct coredump_params { | 74 | struct coredump_params { |
75 | long signr; | 75 | siginfo_t *siginfo; |
76 | struct pt_regs *regs; | 76 | struct pt_regs *regs; |
77 | struct file *file; | 77 | struct file *file; |
78 | unsigned long limit; | 78 | unsigned long limit; |
@@ -132,7 +132,6 @@ extern int copy_strings_kernel(int argc, const char *const *argv, | |||
132 | struct linux_binprm *bprm); | 132 | struct linux_binprm *bprm); |
133 | extern int prepare_bprm_creds(struct linux_binprm *bprm); | 133 | extern int prepare_bprm_creds(struct linux_binprm *bprm); |
134 | extern void install_exec_creds(struct linux_binprm *bprm); | 134 | extern void install_exec_creds(struct linux_binprm *bprm); |
135 | extern void do_coredump(long signr, int exit_code, struct pt_regs *regs); | ||
136 | extern void set_binfmt(struct linux_binfmt *new); | 135 | extern void set_binfmt(struct linux_binfmt *new); |
137 | extern void free_bprm(struct linux_binprm *); | 136 | extern void free_bprm(struct linux_binprm *); |
138 | 137 | ||
diff --git a/include/linux/compat.h b/include/linux/compat.h index fd4e29956d1c..3f53d002c7c5 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -160,11 +160,6 @@ struct compat_ustat { | |||
160 | char f_fpack[6]; | 160 | char f_fpack[6]; |
161 | }; | 161 | }; |
162 | 162 | ||
163 | typedef union compat_sigval { | ||
164 | compat_int_t sival_int; | ||
165 | compat_uptr_t sival_ptr; | ||
166 | } compat_sigval_t; | ||
167 | |||
168 | #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) | 163 | #define COMPAT_SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) |
169 | 164 | ||
170 | typedef struct compat_sigevent { | 165 | typedef struct compat_sigevent { |
diff --git a/include/linux/coredump.h b/include/linux/coredump.h index ba4b85a6d9b8..1775eb8acc03 100644 --- a/include/linux/coredump.h +++ b/include/linux/coredump.h | |||
@@ -11,5 +11,10 @@ | |||
11 | */ | 11 | */ |
12 | extern int dump_write(struct file *file, const void *addr, int nr); | 12 | extern int dump_write(struct file *file, const void *addr, int nr); |
13 | extern int dump_seek(struct file *file, loff_t off); | 13 | extern int dump_seek(struct file *file, loff_t off); |
14 | #ifdef CONFIG_COREDUMP | ||
15 | extern void do_coredump(siginfo_t *siginfo, struct pt_regs *regs); | ||
16 | #else | ||
17 | static inline void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) {} | ||
18 | #endif | ||
14 | 19 | ||
15 | #endif /* _LINUX_COREDUMP_H */ | 20 | #endif /* _LINUX_COREDUMP_H */ |
diff --git a/include/linux/elf.h b/include/linux/elf.h index 0a05051a8924..59ef40650e1e 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h | |||
@@ -372,6 +372,12 @@ typedef struct elf64_shdr { | |||
372 | #define NT_PRPSINFO 3 | 372 | #define NT_PRPSINFO 3 |
373 | #define NT_TASKSTRUCT 4 | 373 | #define NT_TASKSTRUCT 4 |
374 | #define NT_AUXV 6 | 374 | #define NT_AUXV 6 |
375 | /* | ||
376 | * Note to userspace developers: size of NT_SIGINFO note may increase | ||
377 | * in the future to accomodate more fields, don't assume it is fixed! | ||
378 | */ | ||
379 | #define NT_SIGINFO 0x53494749 | ||
380 | #define NT_FILE 0x46494c45 | ||
375 | #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ | 381 | #define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */ |
376 | #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ | 382 | #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ |
377 | #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ | 383 | #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ |
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index f4bb378ccf6a..41085d0f3955 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define EPOLL_CTL_ADD 1 | 25 | #define EPOLL_CTL_ADD 1 |
26 | #define EPOLL_CTL_DEL 2 | 26 | #define EPOLL_CTL_DEL 2 |
27 | #define EPOLL_CTL_MOD 3 | 27 | #define EPOLL_CTL_MOD 3 |
28 | #define EPOLL_CTL_DISABLE 4 | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Request the handling of system wakeup events so as to prevent system suspends | 31 | * Request the handling of system wakeup events so as to prevent system suspends |
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 5e98eeb2af3b..dd7c569aacad 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h | |||
@@ -29,6 +29,20 @@ | |||
29 | 29 | ||
30 | #ifndef __GENALLOC_H__ | 30 | #ifndef __GENALLOC_H__ |
31 | #define __GENALLOC_H__ | 31 | #define __GENALLOC_H__ |
32 | /** | ||
33 | * Allocation callback function type definition | ||
34 | * @map: Pointer to bitmap | ||
35 | * @size: The bitmap size in bits | ||
36 | * @start: The bitnumber to start searching at | ||
37 | * @nr: The number of zeroed bits we're looking for | ||
38 | * @data: optional additional data used by @genpool_algo_t | ||
39 | */ | ||
40 | typedef unsigned long (*genpool_algo_t)(unsigned long *map, | ||
41 | unsigned long size, | ||
42 | unsigned long start, | ||
43 | unsigned int nr, | ||
44 | void *data); | ||
45 | |||
32 | /* | 46 | /* |
33 | * General purpose special memory pool descriptor. | 47 | * General purpose special memory pool descriptor. |
34 | */ | 48 | */ |
@@ -36,6 +50,9 @@ struct gen_pool { | |||
36 | spinlock_t lock; | 50 | spinlock_t lock; |
37 | struct list_head chunks; /* list of chunks in this pool */ | 51 | struct list_head chunks; /* list of chunks in this pool */ |
38 | int min_alloc_order; /* minimum allocation order */ | 52 | int min_alloc_order; /* minimum allocation order */ |
53 | |||
54 | genpool_algo_t algo; /* allocation function */ | ||
55 | void *data; | ||
39 | }; | 56 | }; |
40 | 57 | ||
41 | /* | 58 | /* |
@@ -78,4 +95,14 @@ extern void gen_pool_for_each_chunk(struct gen_pool *, | |||
78 | void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); | 95 | void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); |
79 | extern size_t gen_pool_avail(struct gen_pool *); | 96 | extern size_t gen_pool_avail(struct gen_pool *); |
80 | extern size_t gen_pool_size(struct gen_pool *); | 97 | extern size_t gen_pool_size(struct gen_pool *); |
98 | |||
99 | extern void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, | ||
100 | void *data); | ||
101 | |||
102 | extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, | ||
103 | unsigned long start, unsigned int nr, void *data); | ||
104 | |||
105 | extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, | ||
106 | unsigned long start, unsigned int nr, void *data); | ||
107 | |||
81 | #endif /* __GENALLOC_H__ */ | 108 | #endif /* __GENALLOC_H__ */ |
diff --git a/include/linux/idr.h b/include/linux/idr.h index 255491cf522e..87259a44c251 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h | |||
@@ -38,15 +38,15 @@ | |||
38 | #define IDR_SIZE (1 << IDR_BITS) | 38 | #define IDR_SIZE (1 << IDR_BITS) |
39 | #define IDR_MASK ((1 << IDR_BITS)-1) | 39 | #define IDR_MASK ((1 << IDR_BITS)-1) |
40 | 40 | ||
41 | #define MAX_ID_SHIFT (sizeof(int)*8 - 1) | 41 | #define MAX_IDR_SHIFT (sizeof(int)*8 - 1) |
42 | #define MAX_ID_BIT (1U << MAX_ID_SHIFT) | 42 | #define MAX_IDR_BIT (1U << MAX_IDR_SHIFT) |
43 | #define MAX_ID_MASK (MAX_ID_BIT - 1) | 43 | #define MAX_IDR_MASK (MAX_IDR_BIT - 1) |
44 | 44 | ||
45 | /* Leave the possibility of an incomplete final layer */ | 45 | /* Leave the possibility of an incomplete final layer */ |
46 | #define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS | 46 | #define MAX_IDR_LEVEL ((MAX_IDR_SHIFT + IDR_BITS - 1) / IDR_BITS) |
47 | 47 | ||
48 | /* Number of id_layer structs to leave in free list */ | 48 | /* Number of id_layer structs to leave in free list */ |
49 | #define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL | 49 | #define MAX_IDR_FREE (MAX_IDR_LEVEL * 2) |
50 | 50 | ||
51 | struct idr_layer { | 51 | struct idr_layer { |
52 | unsigned long bitmap; /* A zero bit means "space here" */ | 52 | unsigned long bitmap; /* A zero bit means "space here" */ |
diff --git a/include/linux/init.h b/include/linux/init.h index 5e664f671615..e59041e21df3 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -43,11 +43,22 @@ | |||
43 | discard it in modules) */ | 43 | discard it in modules) */ |
44 | #define __init __section(.init.text) __cold notrace | 44 | #define __init __section(.init.text) __cold notrace |
45 | #define __initdata __section(.init.data) | 45 | #define __initdata __section(.init.data) |
46 | #define __initconst __section(.init.rodata) | 46 | #define __initconst __constsection(.init.rodata) |
47 | #define __exitdata __section(.exit.data) | 47 | #define __exitdata __section(.exit.data) |
48 | #define __exit_call __used __section(.exitcall.exit) | 48 | #define __exit_call __used __section(.exitcall.exit) |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * Some architecture have tool chains which do not handle rodata attributes | ||
52 | * correctly. For those disable special sections for const, so that other | ||
53 | * architectures can annotate correctly. | ||
54 | */ | ||
55 | #ifdef CONFIG_BROKEN_RODATA | ||
56 | #define __constsection(x) | ||
57 | #else | ||
58 | #define __constsection(x) __section(x) | ||
59 | #endif | ||
60 | |||
61 | /* | ||
51 | * modpost check for section mismatches during the kernel build. | 62 | * modpost check for section mismatches during the kernel build. |
52 | * A section mismatch happens when there are references from a | 63 | * A section mismatch happens when there are references from a |
53 | * code or data section to an init section (both code or data). | 64 | * code or data section to an init section (both code or data). |
@@ -66,7 +77,7 @@ | |||
66 | */ | 77 | */ |
67 | #define __ref __section(.ref.text) noinline | 78 | #define __ref __section(.ref.text) noinline |
68 | #define __refdata __section(.ref.data) | 79 | #define __refdata __section(.ref.data) |
69 | #define __refconst __section(.ref.rodata) | 80 | #define __refconst __constsection(.ref.rodata) |
70 | 81 | ||
71 | /* compatibility defines */ | 82 | /* compatibility defines */ |
72 | #define __init_refok __ref | 83 | #define __init_refok __ref |
@@ -85,26 +96,26 @@ | |||
85 | /* Used for HOTPLUG */ | 96 | /* Used for HOTPLUG */ |
86 | #define __devinit __section(.devinit.text) __cold notrace | 97 | #define __devinit __section(.devinit.text) __cold notrace |
87 | #define __devinitdata __section(.devinit.data) | 98 | #define __devinitdata __section(.devinit.data) |
88 | #define __devinitconst __section(.devinit.rodata) | 99 | #define __devinitconst __constsection(.devinit.rodata) |
89 | #define __devexit __section(.devexit.text) __exitused __cold notrace | 100 | #define __devexit __section(.devexit.text) __exitused __cold notrace |
90 | #define __devexitdata __section(.devexit.data) | 101 | #define __devexitdata __section(.devexit.data) |
91 | #define __devexitconst __section(.devexit.rodata) | 102 | #define __devexitconst __constsection(.devexit.rodata) |
92 | 103 | ||
93 | /* Used for HOTPLUG_CPU */ | 104 | /* Used for HOTPLUG_CPU */ |
94 | #define __cpuinit __section(.cpuinit.text) __cold notrace | 105 | #define __cpuinit __section(.cpuinit.text) __cold notrace |
95 | #define __cpuinitdata __section(.cpuinit.data) | 106 | #define __cpuinitdata __section(.cpuinit.data) |
96 | #define __cpuinitconst __section(.cpuinit.rodata) | 107 | #define __cpuinitconst __constsection(.cpuinit.rodata) |
97 | #define __cpuexit __section(.cpuexit.text) __exitused __cold notrace | 108 | #define __cpuexit __section(.cpuexit.text) __exitused __cold notrace |
98 | #define __cpuexitdata __section(.cpuexit.data) | 109 | #define __cpuexitdata __section(.cpuexit.data) |
99 | #define __cpuexitconst __section(.cpuexit.rodata) | 110 | #define __cpuexitconst __constsection(.cpuexit.rodata) |
100 | 111 | ||
101 | /* Used for MEMORY_HOTPLUG */ | 112 | /* Used for MEMORY_HOTPLUG */ |
102 | #define __meminit __section(.meminit.text) __cold notrace | 113 | #define __meminit __section(.meminit.text) __cold notrace |
103 | #define __meminitdata __section(.meminit.data) | 114 | #define __meminitdata __section(.meminit.data) |
104 | #define __meminitconst __section(.meminit.rodata) | 115 | #define __meminitconst __constsection(.meminit.rodata) |
105 | #define __memexit __section(.memexit.text) __exitused __cold notrace | 116 | #define __memexit __section(.memexit.text) __exitused __cold notrace |
106 | #define __memexitdata __section(.memexit.data) | 117 | #define __memexitdata __section(.memexit.data) |
107 | #define __memexitconst __section(.memexit.rodata) | 118 | #define __memexitconst __constsection(.memexit.rodata) |
108 | 119 | ||
109 | /* For assembly routines */ | 120 | /* For assembly routines */ |
110 | #define __HEAD .section ".head.text","ax" | 121 | #define __HEAD .section ".head.text","ax" |
diff --git a/include/linux/mfd/rc5t583.h b/include/linux/mfd/rc5t583.h index 3661c59aa1e9..36c242e52ef1 100644 --- a/include/linux/mfd/rc5t583.h +++ b/include/linux/mfd/rc5t583.h | |||
@@ -146,6 +146,28 @@ | |||
146 | #define RC5T583_GPIO_MON_IOIN 0xAB | 146 | #define RC5T583_GPIO_MON_IOIN 0xAB |
147 | #define RC5T583_GPIO_GPOFUNC 0xAC | 147 | #define RC5T583_GPIO_GPOFUNC 0xAC |
148 | 148 | ||
149 | /* RTC registers */ | ||
150 | #define RC5T583_RTC_SEC 0xE0 | ||
151 | #define RC5T583_RTC_MIN 0xE1 | ||
152 | #define RC5T583_RTC_HOUR 0xE2 | ||
153 | #define RC5T583_RTC_WDAY 0xE3 | ||
154 | #define RC5T583_RTC_DAY 0xE4 | ||
155 | #define RC5T583_RTC_MONTH 0xE5 | ||
156 | #define RC5T583_RTC_YEAR 0xE6 | ||
157 | #define RC5T583_RTC_ADJ 0xE7 | ||
158 | #define RC5T583_RTC_AW_MIN 0xE8 | ||
159 | #define RC5T583_RTC_AW_HOUR 0xE9 | ||
160 | #define RC5T583_RTC_AW_WEEK 0xEA | ||
161 | #define RC5T583_RTC_AD_MIN 0xEB | ||
162 | #define RC5T583_RTC_AD_HOUR 0xEC | ||
163 | #define RC5T583_RTC_CTL1 0xED | ||
164 | #define RC5T583_RTC_CTL2 0xEE | ||
165 | #define RC5T583_RTC_AY_MIN 0xF0 | ||
166 | #define RC5T583_RTC_AY_HOUR 0xF1 | ||
167 | #define RC5T583_RTC_AY_DAY 0xF2 | ||
168 | #define RC5T583_RTC_AY_MONTH 0xF3 | ||
169 | #define RC5T583_RTC_AY_YEAR 0xF4 | ||
170 | |||
149 | /* RICOH_RC5T583 IRQ definitions */ | 171 | /* RICOH_RC5T583 IRQ definitions */ |
150 | enum { | 172 | enum { |
151 | RC5T583_IRQ_ONKEY, | 173 | RC5T583_IRQ_ONKEY, |
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index ac772b36a1b1..02e894f3ff45 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h | |||
@@ -132,6 +132,16 @@ | |||
132 | * | 132 | * |
133 | */ | 133 | */ |
134 | 134 | ||
135 | /* RTC_CTRL_REG bitfields */ | ||
136 | #define TPS65910_RTC_CTRL_STOP_RTC 0x01 /*0=stop, 1=run */ | ||
137 | #define TPS65910_RTC_CTRL_GET_TIME 0x40 | ||
138 | |||
139 | /* RTC_STATUS_REG bitfields */ | ||
140 | #define TPS65910_RTC_STATUS_ALARM 0x40 | ||
141 | |||
142 | /* RTC_INTERRUPTS_REG bitfields */ | ||
143 | #define TPS65910_RTC_INTERRUPTS_EVERY 0x03 | ||
144 | #define TPS65910_RTC_INTERRUPTS_IT_ALARM 0x08 | ||
135 | 145 | ||
136 | /*Register BCK1 (0x80) register.RegisterDescription */ | 146 | /*Register BCK1 (0x80) register.RegisterDescription */ |
137 | #define BCK1_BCKUP_MASK 0xFF | 147 | #define BCK1_BCKUP_MASK 0xFF |
diff --git a/include/linux/nbd.h b/include/linux/nbd.h index d146ca10c0f5..5c86e2b33e2d 100644 --- a/include/linux/nbd.h +++ b/include/linux/nbd.h | |||
@@ -27,13 +27,22 @@ | |||
27 | #define NBD_SET_SIZE_BLOCKS _IO( 0xab, 7 ) | 27 | #define NBD_SET_SIZE_BLOCKS _IO( 0xab, 7 ) |
28 | #define NBD_DISCONNECT _IO( 0xab, 8 ) | 28 | #define NBD_DISCONNECT _IO( 0xab, 8 ) |
29 | #define NBD_SET_TIMEOUT _IO( 0xab, 9 ) | 29 | #define NBD_SET_TIMEOUT _IO( 0xab, 9 ) |
30 | #define NBD_SET_FLAGS _IO( 0xab, 10) | ||
30 | 31 | ||
31 | enum { | 32 | enum { |
32 | NBD_CMD_READ = 0, | 33 | NBD_CMD_READ = 0, |
33 | NBD_CMD_WRITE = 1, | 34 | NBD_CMD_WRITE = 1, |
34 | NBD_CMD_DISC = 2 | 35 | NBD_CMD_DISC = 2, |
36 | /* there is a gap here to match userspace */ | ||
37 | NBD_CMD_TRIM = 4 | ||
35 | }; | 38 | }; |
36 | 39 | ||
40 | /* values for flags field */ | ||
41 | #define NBD_FLAG_HAS_FLAGS (1 << 0) /* nbd-server supports flags */ | ||
42 | #define NBD_FLAG_READ_ONLY (1 << 1) /* device is read-only */ | ||
43 | /* there is a gap here to match userspace */ | ||
44 | #define NBD_FLAG_SEND_TRIM (1 << 5) /* send trim/discard */ | ||
45 | |||
37 | #define nbd_cmd(req) ((req)->cmd[0]) | 46 | #define nbd_cmd(req) ((req)->cmd[0]) |
38 | 47 | ||
39 | /* userspace doesn't need the nbd_device structure */ | 48 | /* userspace doesn't need the nbd_device structure */ |
@@ -42,10 +51,6 @@ enum { | |||
42 | #include <linux/wait.h> | 51 | #include <linux/wait.h> |
43 | #include <linux/mutex.h> | 52 | #include <linux/mutex.h> |
44 | 53 | ||
45 | /* values for flags field */ | ||
46 | #define NBD_READ_ONLY 0x0001 | ||
47 | #define NBD_WRITE_NOCHK 0x0002 | ||
48 | |||
49 | struct request; | 54 | struct request; |
50 | 55 | ||
51 | struct nbd_device { | 56 | struct nbd_device { |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 2b9f82c037c9..cc88172c7d9a 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -107,7 +107,7 @@ enum pcpu_fc { | |||
107 | 107 | ||
108 | PCPU_FC_NR, | 108 | PCPU_FC_NR, |
109 | }; | 109 | }; |
110 | extern const char *pcpu_fc_names[PCPU_FC_NR]; | 110 | extern const char * const pcpu_fc_names[PCPU_FC_NR]; |
111 | 111 | ||
112 | extern enum pcpu_fc pcpu_chosen_fc; | 112 | extern enum pcpu_fc pcpu_chosen_fc; |
113 | 113 | ||
diff --git a/include/linux/platform_data/lm3630_bl.h b/include/linux/platform_data/lm3630_bl.h new file mode 100644 index 000000000000..9176dd3f2d63 --- /dev/null +++ b/include/linux/platform_data/lm3630_bl.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3630 LED Flash driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef __LINUX_LM3630_H | ||
12 | #define __LINUX_LM3630_H | ||
13 | |||
14 | #define LM3630_NAME "lm3630_bl" | ||
15 | |||
16 | enum lm3630_pwm_ctrl { | ||
17 | PWM_CTRL_DISABLE = 0, | ||
18 | PWM_CTRL_BANK_A, | ||
19 | PWM_CTRL_BANK_B, | ||
20 | PWM_CTRL_BANK_ALL, | ||
21 | }; | ||
22 | |||
23 | enum lm3630_pwm_active { | ||
24 | PWM_ACTIVE_HIGH = 0, | ||
25 | PWM_ACTIVE_LOW, | ||
26 | }; | ||
27 | |||
28 | enum lm3630_bank_a_ctrl { | ||
29 | BANK_A_CTRL_DISABLE = 0x0, | ||
30 | BANK_A_CTRL_LED1 = 0x4, | ||
31 | BANK_A_CTRL_LED2 = 0x1, | ||
32 | BANK_A_CTRL_ALL = 0x5, | ||
33 | }; | ||
34 | |||
35 | enum lm3630_bank_b_ctrl { | ||
36 | BANK_B_CTRL_DISABLE = 0, | ||
37 | BANK_B_CTRL_LED2, | ||
38 | }; | ||
39 | |||
40 | struct lm3630_platform_data { | ||
41 | |||
42 | /* maximum brightness */ | ||
43 | int max_brt_led1; | ||
44 | int max_brt_led2; | ||
45 | |||
46 | /* initial on brightness */ | ||
47 | int init_brt_led1; | ||
48 | int init_brt_led2; | ||
49 | enum lm3630_pwm_ctrl pwm_ctrl; | ||
50 | enum lm3630_pwm_active pwm_active; | ||
51 | enum lm3630_bank_a_ctrl bank_a_ctrl; | ||
52 | enum lm3630_bank_b_ctrl bank_b_ctrl; | ||
53 | unsigned int pwm_period; | ||
54 | void (*pwm_set_intensity) (int brightness, int max_brightness); | ||
55 | }; | ||
56 | |||
57 | #endif /* __LINUX_LM3630_H */ | ||
diff --git a/include/linux/platform_data/lm3639_bl.h b/include/linux/platform_data/lm3639_bl.h new file mode 100644 index 000000000000..5234cd5ed166 --- /dev/null +++ b/include/linux/platform_data/lm3639_bl.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Simple driver for Texas Instruments LM3630 LED Flash driver chip | ||
3 | * Copyright (C) 2012 Texas Instruments | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef __LINUX_LM3639_H | ||
12 | #define __LINUX_LM3639_H | ||
13 | |||
14 | #define LM3639_NAME "lm3639_bl" | ||
15 | |||
16 | enum lm3639_pwm { | ||
17 | LM3639_PWM_DISABLE = 0x00, | ||
18 | LM3639_PWM_EN_ACTLOW = 0x48, | ||
19 | LM3639_PWM_EN_ACTHIGH = 0x40, | ||
20 | }; | ||
21 | |||
22 | enum lm3639_strobe { | ||
23 | LM3639_STROBE_DISABLE = 0x00, | ||
24 | LM3639_STROBE_EN_ACTLOW = 0x10, | ||
25 | LM3639_STROBE_EN_ACTHIGH = 0x30, | ||
26 | }; | ||
27 | |||
28 | enum lm3639_txpin { | ||
29 | LM3639_TXPIN_DISABLE = 0x00, | ||
30 | LM3639_TXPIN_EN_ACTLOW = 0x04, | ||
31 | LM3639_TXPIN_EN_ACTHIGH = 0x0C, | ||
32 | }; | ||
33 | |||
34 | enum lm3639_fleds { | ||
35 | LM3639_FLED_DIASBLE_ALL = 0x00, | ||
36 | LM3639_FLED_EN_1 = 0x40, | ||
37 | LM3639_FLED_EN_2 = 0x20, | ||
38 | LM3639_FLED_EN_ALL = 0x60, | ||
39 | }; | ||
40 | |||
41 | enum lm3639_bleds { | ||
42 | LM3639_BLED_DIASBLE_ALL = 0x00, | ||
43 | LM3639_BLED_EN_1 = 0x10, | ||
44 | LM3639_BLED_EN_2 = 0x08, | ||
45 | LM3639_BLED_EN_ALL = 0x18, | ||
46 | }; | ||
47 | enum lm3639_bled_mode { | ||
48 | LM3639_BLED_MODE_EXPONETIAL = 0x00, | ||
49 | LM3639_BLED_MODE_LINEAR = 0x10, | ||
50 | }; | ||
51 | |||
52 | struct lm3639_platform_data { | ||
53 | unsigned int max_brt_led; | ||
54 | unsigned int init_brt_led; | ||
55 | |||
56 | /* input pins */ | ||
57 | enum lm3639_pwm pin_pwm; | ||
58 | enum lm3639_strobe pin_strobe; | ||
59 | enum lm3639_txpin pin_tx; | ||
60 | |||
61 | /* output pins */ | ||
62 | enum lm3639_fleds fled_pins; | ||
63 | enum lm3639_bleds bled_pins; | ||
64 | enum lm3639_bled_mode bled_mode; | ||
65 | |||
66 | void (*pwm_set_intensity) (int brightness, int max_brightness); | ||
67 | int (*pwm_get_intensity) (void); | ||
68 | }; | ||
69 | #endif /* __LINUX_LM3639_H */ | ||
diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h index cc76f1f18f18..761f31752367 100644 --- a/include/linux/platform_data/lp855x.h +++ b/include/linux/platform_data/lp855x.h | |||
@@ -46,6 +46,8 @@ | |||
46 | #define LP8556_I2C_CONFIG ((ENABLE_BL << BL_CTL_SHFT) | \ | 46 | #define LP8556_I2C_CONFIG ((ENABLE_BL << BL_CTL_SHFT) | \ |
47 | (LP8556_I2C_ONLY << BRT_MODE_SHFT)) | 47 | (LP8556_I2C_ONLY << BRT_MODE_SHFT)) |
48 | #define LP8556_COMB2_CONFIG (LP8556_COMBINED2 << BRT_MODE_SHFT) | 48 | #define LP8556_COMB2_CONFIG (LP8556_COMBINED2 << BRT_MODE_SHFT) |
49 | #define LP8556_FAST_CONFIG BIT(7) /* use it if EPROMs should be maintained | ||
50 | when exiting the low power mode */ | ||
49 | 51 | ||
50 | enum lp855x_chip_id { | 52 | enum lp855x_chip_id { |
51 | LP8550, | 53 | LP8550, |
diff --git a/include/linux/rio.h b/include/linux/rio.h index a90ebadd9da0..d2dff22cf681 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define RIO_MAX_MPORTS 8 | 30 | #define RIO_MAX_MPORTS 8 |
31 | #define RIO_MAX_MPORT_RESOURCES 16 | 31 | #define RIO_MAX_MPORT_RESOURCES 16 |
32 | #define RIO_MAX_DEV_RESOURCES 16 | 32 | #define RIO_MAX_DEV_RESOURCES 16 |
33 | #define RIO_MAX_MPORT_NAME 40 | ||
33 | 34 | ||
34 | #define RIO_GLOBAL_TABLE 0xff /* Indicates access of a switch's | 35 | #define RIO_GLOBAL_TABLE 0xff /* Indicates access of a switch's |
35 | global routing table if it | 36 | global routing table if it |
@@ -235,6 +236,7 @@ enum rio_phy_type { | |||
235 | * @phys_efptr: RIO port extended features pointer | 236 | * @phys_efptr: RIO port extended features pointer |
236 | * @name: Port name string | 237 | * @name: Port name string |
237 | * @priv: Master port private data | 238 | * @priv: Master port private data |
239 | * @dma: DMA device associated with mport | ||
238 | */ | 240 | */ |
239 | struct rio_mport { | 241 | struct rio_mport { |
240 | struct list_head dbells; /* list of doorbell events */ | 242 | struct list_head dbells; /* list of doorbell events */ |
@@ -255,13 +257,21 @@ struct rio_mport { | |||
255 | */ | 257 | */ |
256 | enum rio_phy_type phy_type; /* RapidIO phy type */ | 258 | enum rio_phy_type phy_type; /* RapidIO phy type */ |
257 | u32 phys_efptr; | 259 | u32 phys_efptr; |
258 | unsigned char name[40]; | 260 | unsigned char name[RIO_MAX_MPORT_NAME]; |
259 | void *priv; /* Master port private data */ | 261 | void *priv; /* Master port private data */ |
260 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | 262 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE |
261 | struct dma_device dma; | 263 | struct dma_device dma; |
262 | #endif | 264 | #endif |
263 | }; | 265 | }; |
264 | 266 | ||
267 | struct rio_id_table { | ||
268 | u16 start; /* logical minimal id */ | ||
269 | u16 next; /* hint for find */ | ||
270 | u32 max; /* max number of IDs in table */ | ||
271 | spinlock_t lock; | ||
272 | unsigned long *table; | ||
273 | }; | ||
274 | |||
265 | /** | 275 | /** |
266 | * struct rio_net - RIO network info | 276 | * struct rio_net - RIO network info |
267 | * @node: Node in global list of RIO networks | 277 | * @node: Node in global list of RIO networks |
@@ -273,9 +283,11 @@ struct rio_mport { | |||
273 | struct rio_net { | 283 | struct rio_net { |
274 | struct list_head node; /* node in list of networks */ | 284 | struct list_head node; /* node in list of networks */ |
275 | struct list_head devices; /* list of devices in this net */ | 285 | struct list_head devices; /* list of devices in this net */ |
286 | struct list_head switches; /* list of switches in this net */ | ||
276 | struct list_head mports; /* list of ports accessing net */ | 287 | struct list_head mports; /* list of ports accessing net */ |
277 | struct rio_mport *hport; /* primary port for accessing net */ | 288 | struct rio_mport *hport; /* primary port for accessing net */ |
278 | unsigned char id; /* RIO network ID */ | 289 | unsigned char id; /* RIO network ID */ |
290 | struct rio_id_table destid_table; /* destID allocation table */ | ||
279 | }; | 291 | }; |
280 | 292 | ||
281 | /* Definitions used by switch sysfs initialization callback */ | 293 | /* Definitions used by switch sysfs initialization callback */ |
@@ -299,6 +311,8 @@ struct rio_net { | |||
299 | * @add_outb_message: Callback to add a message to an outbound mailbox queue. | 311 | * @add_outb_message: Callback to add a message to an outbound mailbox queue. |
300 | * @add_inb_buffer: Callback to add a buffer to an inbound mailbox queue. | 312 | * @add_inb_buffer: Callback to add a buffer to an inbound mailbox queue. |
301 | * @get_inb_message: Callback to get a message from an inbound mailbox queue. | 313 | * @get_inb_message: Callback to get a message from an inbound mailbox queue. |
314 | * @map_inb: Callback to map RapidIO address region into local memory space. | ||
315 | * @unmap_inb: Callback to unmap RapidIO address region mapped with map_inb(). | ||
302 | */ | 316 | */ |
303 | struct rio_ops { | 317 | struct rio_ops { |
304 | int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len, | 318 | int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len, |
@@ -321,6 +335,9 @@ struct rio_ops { | |||
321 | int mbox, void *buffer, size_t len); | 335 | int mbox, void *buffer, size_t len); |
322 | int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf); | 336 | int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf); |
323 | void *(*get_inb_message)(struct rio_mport *mport, int mbox); | 337 | void *(*get_inb_message)(struct rio_mport *mport, int mbox); |
338 | int (*map_inb)(struct rio_mport *mport, dma_addr_t lstart, | ||
339 | u64 rstart, u32 size, u32 flags); | ||
340 | void (*unmap_inb)(struct rio_mport *mport, dma_addr_t lstart); | ||
324 | }; | 341 | }; |
325 | 342 | ||
326 | #define RIO_RESOURCE_MEM 0x00000100 | 343 | #define RIO_RESOURCE_MEM 0x00000100 |
@@ -403,7 +420,7 @@ union rio_pw_msg { | |||
403 | 420 | ||
404 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | 421 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE |
405 | 422 | ||
406 | /** | 423 | /* |
407 | * enum rio_write_type - RIO write transaction types used in DMA transfers | 424 | * enum rio_write_type - RIO write transaction types used in DMA transfers |
408 | * | 425 | * |
409 | * Note: RapidIO specification defines write (NWRITE) and | 426 | * Note: RapidIO specification defines write (NWRITE) and |
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h index 31ad146be316..b75c05920ab5 100644 --- a/include/linux/rio_drv.h +++ b/include/linux/rio_drv.h | |||
@@ -365,6 +365,11 @@ void rio_release_regions(struct rio_dev *); | |||
365 | int rio_request_region(struct rio_dev *, int, char *); | 365 | int rio_request_region(struct rio_dev *, int, char *); |
366 | void rio_release_region(struct rio_dev *, int); | 366 | void rio_release_region(struct rio_dev *, int); |
367 | 367 | ||
368 | /* Memory mapping functions */ | ||
369 | extern int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local, | ||
370 | u64 rbase, u32 size, u32 rflags); | ||
371 | extern void rio_unmap_inb_region(struct rio_mport *mport, dma_addr_t lstart); | ||
372 | |||
368 | /* Port-Write management */ | 373 | /* Port-Write management */ |
369 | extern int rio_request_inb_pwrite(struct rio_dev *, | 374 | extern int rio_request_inb_pwrite(struct rio_dev *, |
370 | int (*)(struct rio_dev *, union rio_pw_msg*, int)); | 375 | int (*)(struct rio_dev *, union rio_pw_msg*, int)); |
diff --git a/include/linux/rtc-ds2404.h b/include/linux/rtc-ds2404.h new file mode 100644 index 000000000000..22c53825528f --- /dev/null +++ b/include/linux/rtc-ds2404.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * ds2404.h - platform data structure for the DS2404 RTC. | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2012 Sven Schnelle <svens@stackframe.org> | ||
9 | */ | ||
10 | |||
11 | #ifndef __LINUX_DS2404_H | ||
12 | #define __LINUX_DS2404_H | ||
13 | |||
14 | struct ds2404_platform_data { | ||
15 | |||
16 | unsigned int gpio_rst; | ||
17 | unsigned int gpio_clk; | ||
18 | unsigned int gpio_dq; | ||
19 | }; | ||
20 | #endif | ||
diff --git a/include/linux/rtc.h b/include/linux/rtc.h index f071b3922c67..20ec4d3bed73 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h | |||
@@ -276,7 +276,7 @@ static inline bool is_leap_year(unsigned int year) | |||
276 | return (!(year % 4) && (year % 100)) || !(year % 400); | 276 | return (!(year % 4) && (year % 100)) || !(year % 400); |
277 | } | 277 | } |
278 | 278 | ||
279 | #ifdef CONFIG_RTC_HCTOSYS | 279 | #ifdef CONFIG_RTC_HCTOSYS_DEVICE |
280 | extern int rtc_hctosys_ret; | 280 | extern int rtc_hctosys_ret; |
281 | #else | 281 | #else |
282 | #define rtc_hctosys_ret -ENODEV | 282 | #define rtc_hctosys_ret -ENODEV |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 9d51e260bde0..9c5612f0374b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -405,7 +405,6 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) {} | |||
405 | 405 | ||
406 | extern void set_dumpable(struct mm_struct *mm, int value); | 406 | extern void set_dumpable(struct mm_struct *mm, int value); |
407 | extern int get_dumpable(struct mm_struct *mm); | 407 | extern int get_dumpable(struct mm_struct *mm); |
408 | extern int __get_dumpable(unsigned long mm_flags); | ||
409 | 408 | ||
410 | /* get/set_dumpable() values */ | 409 | /* get/set_dumpable() values */ |
411 | #define SUID_DUMPABLE_DISABLED 0 | 410 | #define SUID_DUMPABLE_DISABLED 0 |
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 4faf6612ecac..95e646641184 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
@@ -257,10 +257,12 @@ static inline struct net *read_pnet(struct net * const *pnet) | |||
257 | #define __net_init | 257 | #define __net_init |
258 | #define __net_exit | 258 | #define __net_exit |
259 | #define __net_initdata | 259 | #define __net_initdata |
260 | #define __net_initconst | ||
260 | #else | 261 | #else |
261 | #define __net_init __init | 262 | #define __net_init __init |
262 | #define __net_exit __exit_refok | 263 | #define __net_exit __exit_refok |
263 | #define __net_initdata __initdata | 264 | #define __net_initdata __initdata |
265 | #define __net_initconst __initconst | ||
264 | #endif | 266 | #endif |
265 | 267 | ||
266 | struct pernet_operations { | 268 | struct pernet_operations { |
diff --git a/init/Kconfig b/init/Kconfig index cb003a3c9122..ed6334dd5e71 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1199,6 +1199,7 @@ config BUG | |||
1199 | Just say Y. | 1199 | Just say Y. |
1200 | 1200 | ||
1201 | config ELF_CORE | 1201 | config ELF_CORE |
1202 | depends on COREDUMP | ||
1202 | default y | 1203 | default y |
1203 | bool "Enable ELF core dumps" if EXPERT | 1204 | bool "Enable ELF core dumps" if EXPERT |
1204 | help | 1205 | help |
@@ -1581,4 +1582,10 @@ config PADATA | |||
1581 | depends on SMP | 1582 | depends on SMP |
1582 | bool | 1583 | bool |
1583 | 1584 | ||
1585 | # Can be selected by architectures with broken toolchains | ||
1586 | # that get confused by correct const<->read_only section | ||
1587 | # mappings | ||
1588 | config BROKEN_RODATA | ||
1589 | bool | ||
1590 | |||
1584 | source "kernel/Kconfig.locks" | 1591 | source "kernel/Kconfig.locks" |
diff --git a/kernel/kexec.c b/kernel/kexec.c index 0668d58d6413..5e4bd7864c5d 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/hardirq.h> | 21 | #include <linux/hardirq.h> |
22 | #include <linux/elf.h> | 22 | #include <linux/elf.h> |
23 | #include <linux/elfcore.h> | 23 | #include <linux/elfcore.h> |
24 | #include <generated/utsrelease.h> | ||
25 | #include <linux/utsname.h> | 24 | #include <linux/utsname.h> |
26 | #include <linux/numa.h> | 25 | #include <linux/numa.h> |
27 | #include <linux/suspend.h> | 26 | #include <linux/suspend.h> |
diff --git a/kernel/resource.c b/kernel/resource.c index 34d45886ee84..73f35d4b30b9 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -763,6 +763,7 @@ static void __init __reserve_region_with_split(struct resource *root, | |||
763 | struct resource *parent = root; | 763 | struct resource *parent = root; |
764 | struct resource *conflict; | 764 | struct resource *conflict; |
765 | struct resource *res = kzalloc(sizeof(*res), GFP_ATOMIC); | 765 | struct resource *res = kzalloc(sizeof(*res), GFP_ATOMIC); |
766 | struct resource *next_res = NULL; | ||
766 | 767 | ||
767 | if (!res) | 768 | if (!res) |
768 | return; | 769 | return; |
@@ -772,21 +773,46 @@ static void __init __reserve_region_with_split(struct resource *root, | |||
772 | res->end = end; | 773 | res->end = end; |
773 | res->flags = IORESOURCE_BUSY; | 774 | res->flags = IORESOURCE_BUSY; |
774 | 775 | ||
775 | conflict = __request_resource(parent, res); | 776 | while (1) { |
776 | if (!conflict) | ||
777 | return; | ||
778 | 777 | ||
779 | /* failed, split and try again */ | 778 | conflict = __request_resource(parent, res); |
780 | kfree(res); | 779 | if (!conflict) { |
780 | if (!next_res) | ||
781 | break; | ||
782 | res = next_res; | ||
783 | next_res = NULL; | ||
784 | continue; | ||
785 | } | ||
781 | 786 | ||
782 | /* conflict covered whole area */ | 787 | /* conflict covered whole area */ |
783 | if (conflict->start <= start && conflict->end >= end) | 788 | if (conflict->start <= res->start && |
784 | return; | 789 | conflict->end >= res->end) { |
790 | kfree(res); | ||
791 | WARN_ON(next_res); | ||
792 | break; | ||
793 | } | ||
794 | |||
795 | /* failed, split and try again */ | ||
796 | if (conflict->start > res->start) { | ||
797 | end = res->end; | ||
798 | res->end = conflict->start - 1; | ||
799 | if (conflict->end < end) { | ||
800 | next_res = kzalloc(sizeof(*next_res), | ||
801 | GFP_ATOMIC); | ||
802 | if (!next_res) { | ||
803 | kfree(res); | ||
804 | break; | ||
805 | } | ||
806 | next_res->name = name; | ||
807 | next_res->start = conflict->end + 1; | ||
808 | next_res->end = end; | ||
809 | next_res->flags = IORESOURCE_BUSY; | ||
810 | } | ||
811 | } else { | ||
812 | res->start = conflict->end + 1; | ||
813 | } | ||
814 | } | ||
785 | 815 | ||
786 | if (conflict->start > start) | ||
787 | __reserve_region_with_split(root, start, conflict->start-1, name); | ||
788 | if (conflict->end < end) | ||
789 | __reserve_region_with_split(root, conflict->end+1, end, name); | ||
790 | } | 816 | } |
791 | 817 | ||
792 | void __init reserve_region_with_split(struct resource *root, | 818 | void __init reserve_region_with_split(struct resource *root, |
diff --git a/kernel/signal.c b/kernel/signal.c index 2c681f11b7d2..0af8868525d6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/binfmts.h> | 19 | #include <linux/binfmts.h> |
20 | #include <linux/coredump.h> | ||
20 | #include <linux/security.h> | 21 | #include <linux/security.h> |
21 | #include <linux/syscalls.h> | 22 | #include <linux/syscalls.h> |
22 | #include <linux/ptrace.h> | 23 | #include <linux/ptrace.h> |
@@ -2359,7 +2360,7 @@ relock: | |||
2359 | * first and our do_group_exit call below will use | 2360 | * first and our do_group_exit call below will use |
2360 | * that value and ignore the one we pass it. | 2361 | * that value and ignore the one we pass it. |
2361 | */ | 2362 | */ |
2362 | do_coredump(info->si_signo, info->si_signo, regs); | 2363 | do_coredump(info, regs); |
2363 | } | 2364 | } |
2364 | 2365 | ||
2365 | /* | 2366 | /* |
diff --git a/kernel/sys.c b/kernel/sys.c index f9492284e5d2..c5cb5b99cb81 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -368,6 +368,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); | |||
368 | void kernel_restart(char *cmd) | 368 | void kernel_restart(char *cmd) |
369 | { | 369 | { |
370 | kernel_restart_prepare(cmd); | 370 | kernel_restart_prepare(cmd); |
371 | disable_nonboot_cpus(); | ||
371 | if (!cmd) | 372 | if (!cmd) |
372 | printk(KERN_EMERG "Restarting system.\n"); | 373 | printk(KERN_EMERG "Restarting system.\n"); |
373 | else | 374 | else |
@@ -2204,7 +2205,7 @@ static int __orderly_poweroff(void) | |||
2204 | return -ENOMEM; | 2205 | return -ENOMEM; |
2205 | } | 2206 | } |
2206 | 2207 | ||
2207 | ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT, | 2208 | ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_WAIT_EXEC, |
2208 | NULL, argv_cleanup, NULL); | 2209 | NULL, argv_cleanup, NULL); |
2209 | if (ret == -ENOMEM) | 2210 | if (ret == -ENOMEM) |
2210 | argv_free(argv); | 2211 | argv_free(argv); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 84c76a34e41c..c2a2f8084bad 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -97,10 +97,12 @@ | |||
97 | extern int sysctl_overcommit_memory; | 97 | extern int sysctl_overcommit_memory; |
98 | extern int sysctl_overcommit_ratio; | 98 | extern int sysctl_overcommit_ratio; |
99 | extern int max_threads; | 99 | extern int max_threads; |
100 | extern int core_uses_pid; | ||
101 | extern int suid_dumpable; | 100 | extern int suid_dumpable; |
101 | #ifdef CONFIG_COREDUMP | ||
102 | extern int core_uses_pid; | ||
102 | extern char core_pattern[]; | 103 | extern char core_pattern[]; |
103 | extern unsigned int core_pipe_limit; | 104 | extern unsigned int core_pipe_limit; |
105 | #endif | ||
104 | extern int pid_max; | 106 | extern int pid_max; |
105 | extern int min_free_kbytes; | 107 | extern int min_free_kbytes; |
106 | extern int pid_max_min, pid_max_max; | 108 | extern int pid_max_min, pid_max_max; |
@@ -177,8 +179,10 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, | |||
177 | 179 | ||
178 | static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, | 180 | static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, |
179 | void __user *buffer, size_t *lenp, loff_t *ppos); | 181 | void __user *buffer, size_t *lenp, loff_t *ppos); |
182 | #ifdef CONFIG_COREDUMP | ||
180 | static int proc_dostring_coredump(struct ctl_table *table, int write, | 183 | static int proc_dostring_coredump(struct ctl_table *table, int write, |
181 | void __user *buffer, size_t *lenp, loff_t *ppos); | 184 | void __user *buffer, size_t *lenp, loff_t *ppos); |
185 | #endif | ||
182 | 186 | ||
183 | #ifdef CONFIG_MAGIC_SYSRQ | 187 | #ifdef CONFIG_MAGIC_SYSRQ |
184 | /* Note: sysrq code uses it's own private copy */ | 188 | /* Note: sysrq code uses it's own private copy */ |
@@ -404,6 +408,7 @@ static struct ctl_table kern_table[] = { | |||
404 | .mode = 0644, | 408 | .mode = 0644, |
405 | .proc_handler = proc_dointvec, | 409 | .proc_handler = proc_dointvec, |
406 | }, | 410 | }, |
411 | #ifdef CONFIG_COREDUMP | ||
407 | { | 412 | { |
408 | .procname = "core_uses_pid", | 413 | .procname = "core_uses_pid", |
409 | .data = &core_uses_pid, | 414 | .data = &core_uses_pid, |
@@ -425,6 +430,7 @@ static struct ctl_table kern_table[] = { | |||
425 | .mode = 0644, | 430 | .mode = 0644, |
426 | .proc_handler = proc_dointvec, | 431 | .proc_handler = proc_dointvec, |
427 | }, | 432 | }, |
433 | #endif | ||
428 | #ifdef CONFIG_PROC_SYSCTL | 434 | #ifdef CONFIG_PROC_SYSCTL |
429 | { | 435 | { |
430 | .procname = "tainted", | 436 | .procname = "tainted", |
@@ -2036,12 +2042,14 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, | |||
2036 | 2042 | ||
2037 | static void validate_coredump_safety(void) | 2043 | static void validate_coredump_safety(void) |
2038 | { | 2044 | { |
2045 | #ifdef CONFIG_COREDUMP | ||
2039 | if (suid_dumpable == SUID_DUMPABLE_SAFE && | 2046 | if (suid_dumpable == SUID_DUMPABLE_SAFE && |
2040 | core_pattern[0] != '/' && core_pattern[0] != '|') { | 2047 | core_pattern[0] != '/' && core_pattern[0] != '|') { |
2041 | printk(KERN_WARNING "Unsafe core_pattern used with "\ | 2048 | printk(KERN_WARNING "Unsafe core_pattern used with "\ |
2042 | "suid_dumpable=2. Pipe handler or fully qualified "\ | 2049 | "suid_dumpable=2. Pipe handler or fully qualified "\ |
2043 | "core dump path required.\n"); | 2050 | "core dump path required.\n"); |
2044 | } | 2051 | } |
2052 | #endif | ||
2045 | } | 2053 | } |
2046 | 2054 | ||
2047 | static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, | 2055 | static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, |
@@ -2053,6 +2061,7 @@ static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, | |||
2053 | return error; | 2061 | return error; |
2054 | } | 2062 | } |
2055 | 2063 | ||
2064 | #ifdef CONFIG_COREDUMP | ||
2056 | static int proc_dostring_coredump(struct ctl_table *table, int write, | 2065 | static int proc_dostring_coredump(struct ctl_table *table, int write, |
2057 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2066 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2058 | { | 2067 | { |
@@ -2061,6 +2070,7 @@ static int proc_dostring_coredump(struct ctl_table *table, int write, | |||
2061 | validate_coredump_safety(); | 2070 | validate_coredump_safety(); |
2062 | return error; | 2071 | return error; |
2063 | } | 2072 | } |
2073 | #endif | ||
2064 | 2074 | ||
2065 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, | 2075 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, |
2066 | void __user *buffer, | 2076 | void __user *buffer, |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 610f0838d555..145bb4d3bd4d 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -445,6 +445,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) | |||
445 | na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, | 445 | na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, |
446 | sizeof(struct cgroupstats)); | 446 | sizeof(struct cgroupstats)); |
447 | if (na == NULL) { | 447 | if (na == NULL) { |
448 | nlmsg_free(rep_skb); | ||
448 | rc = -EMSGSIZE; | 449 | rc = -EMSGSIZE; |
449 | goto err; | 450 | goto err; |
450 | } | 451 | } |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 35c4565ee8fa..7fba3a98967f 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -196,12 +196,13 @@ config LOCKUP_DETECTOR | |||
196 | thresholds can be controlled through the sysctl watchdog_thresh. | 196 | thresholds can be controlled through the sysctl watchdog_thresh. |
197 | 197 | ||
198 | config HARDLOCKUP_DETECTOR | 198 | config HARDLOCKUP_DETECTOR |
199 | def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI && \ | 199 | def_bool y |
200 | !HAVE_NMI_WATCHDOG | 200 | depends on LOCKUP_DETECTOR && !HAVE_NMI_WATCHDOG |
201 | depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI | ||
201 | 202 | ||
202 | config BOOTPARAM_HARDLOCKUP_PANIC | 203 | config BOOTPARAM_HARDLOCKUP_PANIC |
203 | bool "Panic (Reboot) On Hard Lockups" | 204 | bool "Panic (Reboot) On Hard Lockups" |
204 | depends on LOCKUP_DETECTOR | 205 | depends on HARDLOCKUP_DETECTOR |
205 | help | 206 | help |
206 | Say Y here to enable the kernel to panic on "hard lockups", | 207 | Say Y here to enable the kernel to panic on "hard lockups", |
207 | which are bugs that cause the kernel to loop in kernel | 208 | which are bugs that cause the kernel to loop in kernel |
@@ -212,7 +213,7 @@ config BOOTPARAM_HARDLOCKUP_PANIC | |||
212 | 213 | ||
213 | config BOOTPARAM_HARDLOCKUP_PANIC_VALUE | 214 | config BOOTPARAM_HARDLOCKUP_PANIC_VALUE |
214 | int | 215 | int |
215 | depends on LOCKUP_DETECTOR | 216 | depends on HARDLOCKUP_DETECTOR |
216 | range 0 1 | 217 | range 0 1 |
217 | default 0 if !BOOTPARAM_HARDLOCKUP_PANIC | 218 | default 0 if !BOOTPARAM_HARDLOCKUP_PANIC |
218 | default 1 if BOOTPARAM_HARDLOCKUP_PANIC | 219 | default 1 if BOOTPARAM_HARDLOCKUP_PANIC |
diff --git a/lib/crc32.c b/lib/crc32.c index 61774b8db4de..072fbd8234d5 100644 --- a/lib/crc32.c +++ b/lib/crc32.c | |||
@@ -188,11 +188,13 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) | |||
188 | #else | 188 | #else |
189 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | 189 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) |
190 | { | 190 | { |
191 | return crc32_le_generic(crc, p, len, crc32table_le, CRCPOLY_LE); | 191 | return crc32_le_generic(crc, p, len, |
192 | (const u32 (*)[256])crc32table_le, CRCPOLY_LE); | ||
192 | } | 193 | } |
193 | u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) | 194 | u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len) |
194 | { | 195 | { |
195 | return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE); | 196 | return crc32_le_generic(crc, p, len, |
197 | (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE); | ||
196 | } | 198 | } |
197 | #endif | 199 | #endif |
198 | EXPORT_SYMBOL(crc32_le); | 200 | EXPORT_SYMBOL(crc32_le); |
@@ -253,7 +255,8 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | |||
253 | #else | 255 | #else |
254 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | 256 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) |
255 | { | 257 | { |
256 | return crc32_be_generic(crc, p, len, crc32table_be, CRCPOLY_BE); | 258 | return crc32_be_generic(crc, p, len, |
259 | (const u32 (*)[256])crc32table_be, CRCPOLY_BE); | ||
257 | } | 260 | } |
258 | #endif | 261 | #endif |
259 | EXPORT_SYMBOL(crc32_be); | 262 | EXPORT_SYMBOL(crc32_be); |
diff --git a/lib/decompress.c b/lib/decompress.c index 3d766b7f60ab..31a804277282 100644 --- a/lib/decompress.c +++ b/lib/decompress.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/init.h> | ||
17 | 18 | ||
18 | #ifndef CONFIG_DECOMPRESS_GZIP | 19 | #ifndef CONFIG_DECOMPRESS_GZIP |
19 | # define gunzip NULL | 20 | # define gunzip NULL |
@@ -31,11 +32,13 @@ | |||
31 | # define unlzo NULL | 32 | # define unlzo NULL |
32 | #endif | 33 | #endif |
33 | 34 | ||
34 | static const struct compress_format { | 35 | struct compress_format { |
35 | unsigned char magic[2]; | 36 | unsigned char magic[2]; |
36 | const char *name; | 37 | const char *name; |
37 | decompress_fn decompressor; | 38 | decompress_fn decompressor; |
38 | } compressed_formats[] = { | 39 | }; |
40 | |||
41 | static const struct compress_format compressed_formats[] __initdata = { | ||
39 | { {037, 0213}, "gzip", gunzip }, | 42 | { {037, 0213}, "gzip", gunzip }, |
40 | { {037, 0236}, "gzip", gunzip }, | 43 | { {037, 0236}, "gzip", gunzip }, |
41 | { {0x42, 0x5a}, "bzip2", bunzip2 }, | 44 | { {0x42, 0x5a}, "bzip2", bunzip2 }, |
@@ -45,7 +48,7 @@ static const struct compress_format { | |||
45 | { {0, 0}, NULL, NULL } | 48 | { {0, 0}, NULL, NULL } |
46 | }; | 49 | }; |
47 | 50 | ||
48 | decompress_fn decompress_method(const unsigned char *inbuf, int len, | 51 | decompress_fn __init decompress_method(const unsigned char *inbuf, int len, |
49 | const char **name) | 52 | const char **name) |
50 | { | 53 | { |
51 | const struct compress_format *cf; | 54 | const struct compress_format *cf; |
@@ -9,6 +9,9 @@ unsigned long gcd(unsigned long a, unsigned long b) | |||
9 | 9 | ||
10 | if (a < b) | 10 | if (a < b) |
11 | swap(a, b); | 11 | swap(a, b); |
12 | |||
13 | if (!b) | ||
14 | return a; | ||
12 | while ((r = a % b) != 0) { | 15 | while ((r = a % b) != 0) { |
13 | a = b; | 16 | a = b; |
14 | b = r; | 17 | b = r; |
diff --git a/lib/gen_crc32table.c b/lib/gen_crc32table.c index 8f8d5439e2d9..71fcfcd96410 100644 --- a/lib/gen_crc32table.c +++ b/lib/gen_crc32table.c | |||
@@ -109,7 +109,7 @@ int main(int argc, char** argv) | |||
109 | 109 | ||
110 | if (CRC_LE_BITS > 1) { | 110 | if (CRC_LE_BITS > 1) { |
111 | crc32init_le(); | 111 | crc32init_le(); |
112 | printf("static const u32 __cacheline_aligned " | 112 | printf("static u32 __cacheline_aligned " |
113 | "crc32table_le[%d][%d] = {", | 113 | "crc32table_le[%d][%d] = {", |
114 | LE_TABLE_ROWS, LE_TABLE_SIZE); | 114 | LE_TABLE_ROWS, LE_TABLE_SIZE); |
115 | output_table(crc32table_le, LE_TABLE_ROWS, | 115 | output_table(crc32table_le, LE_TABLE_ROWS, |
@@ -119,7 +119,7 @@ int main(int argc, char** argv) | |||
119 | 119 | ||
120 | if (CRC_BE_BITS > 1) { | 120 | if (CRC_BE_BITS > 1) { |
121 | crc32init_be(); | 121 | crc32init_be(); |
122 | printf("static const u32 __cacheline_aligned " | 122 | printf("static u32 __cacheline_aligned " |
123 | "crc32table_be[%d][%d] = {", | 123 | "crc32table_be[%d][%d] = {", |
124 | BE_TABLE_ROWS, BE_TABLE_SIZE); | 124 | BE_TABLE_ROWS, BE_TABLE_SIZE); |
125 | output_table(crc32table_be, LE_TABLE_ROWS, | 125 | output_table(crc32table_be, LE_TABLE_ROWS, |
@@ -128,7 +128,7 @@ int main(int argc, char** argv) | |||
128 | } | 128 | } |
129 | if (CRC_LE_BITS > 1) { | 129 | if (CRC_LE_BITS > 1) { |
130 | crc32cinit_le(); | 130 | crc32cinit_le(); |
131 | printf("static const u32 __cacheline_aligned " | 131 | printf("static u32 __cacheline_aligned " |
132 | "crc32ctable_le[%d][%d] = {", | 132 | "crc32ctable_le[%d][%d] = {", |
133 | LE_TABLE_ROWS, LE_TABLE_SIZE); | 133 | LE_TABLE_ROWS, LE_TABLE_SIZE); |
134 | output_table(crc32ctable_le, LE_TABLE_ROWS, | 134 | output_table(crc32ctable_le, LE_TABLE_ROWS, |
diff --git a/lib/genalloc.c b/lib/genalloc.c index 6bc04aab6ec7..ca208a92628c 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c | |||
@@ -152,6 +152,8 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) | |||
152 | spin_lock_init(&pool->lock); | 152 | spin_lock_init(&pool->lock); |
153 | INIT_LIST_HEAD(&pool->chunks); | 153 | INIT_LIST_HEAD(&pool->chunks); |
154 | pool->min_alloc_order = min_alloc_order; | 154 | pool->min_alloc_order = min_alloc_order; |
155 | pool->algo = gen_pool_first_fit; | ||
156 | pool->data = NULL; | ||
155 | } | 157 | } |
156 | return pool; | 158 | return pool; |
157 | } | 159 | } |
@@ -255,8 +257,9 @@ EXPORT_SYMBOL(gen_pool_destroy); | |||
255 | * @size: number of bytes to allocate from the pool | 257 | * @size: number of bytes to allocate from the pool |
256 | * | 258 | * |
257 | * Allocate the requested number of bytes from the specified pool. | 259 | * Allocate the requested number of bytes from the specified pool. |
258 | * Uses a first-fit algorithm. Can not be used in NMI handler on | 260 | * Uses the pool allocation function (with first-fit algorithm by default). |
259 | * architectures without NMI-safe cmpxchg implementation. | 261 | * Can not be used in NMI handler on architectures without |
262 | * NMI-safe cmpxchg implementation. | ||
260 | */ | 263 | */ |
261 | unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) | 264 | unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) |
262 | { | 265 | { |
@@ -280,8 +283,8 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) | |||
280 | 283 | ||
281 | end_bit = (chunk->end_addr - chunk->start_addr) >> order; | 284 | end_bit = (chunk->end_addr - chunk->start_addr) >> order; |
282 | retry: | 285 | retry: |
283 | start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, | 286 | start_bit = pool->algo(chunk->bits, end_bit, start_bit, nbits, |
284 | start_bit, nbits, 0); | 287 | pool->data); |
285 | if (start_bit >= end_bit) | 288 | if (start_bit >= end_bit) |
286 | continue; | 289 | continue; |
287 | remain = bitmap_set_ll(chunk->bits, start_bit, nbits); | 290 | remain = bitmap_set_ll(chunk->bits, start_bit, nbits); |
@@ -400,3 +403,80 @@ size_t gen_pool_size(struct gen_pool *pool) | |||
400 | return size; | 403 | return size; |
401 | } | 404 | } |
402 | EXPORT_SYMBOL_GPL(gen_pool_size); | 405 | EXPORT_SYMBOL_GPL(gen_pool_size); |
406 | |||
407 | /** | ||
408 | * gen_pool_set_algo - set the allocation algorithm | ||
409 | * @pool: pool to change allocation algorithm | ||
410 | * @algo: custom algorithm function | ||
411 | * @data: additional data used by @algo | ||
412 | * | ||
413 | * Call @algo for each memory allocation in the pool. | ||
414 | * If @algo is NULL use gen_pool_first_fit as default | ||
415 | * memory allocation function. | ||
416 | */ | ||
417 | void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, void *data) | ||
418 | { | ||
419 | rcu_read_lock(); | ||
420 | |||
421 | pool->algo = algo; | ||
422 | if (!pool->algo) | ||
423 | pool->algo = gen_pool_first_fit; | ||
424 | |||
425 | pool->data = data; | ||
426 | |||
427 | rcu_read_unlock(); | ||
428 | } | ||
429 | EXPORT_SYMBOL(gen_pool_set_algo); | ||
430 | |||
431 | /** | ||
432 | * gen_pool_first_fit - find the first available region | ||
433 | * of memory matching the size requirement (no alignment constraint) | ||
434 | * @map: The address to base the search on | ||
435 | * @size: The bitmap size in bits | ||
436 | * @start: The bitnumber to start searching at | ||
437 | * @nr: The number of zeroed bits we're looking for | ||
438 | * @data: additional data - unused | ||
439 | */ | ||
440 | unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, | ||
441 | unsigned long start, unsigned int nr, void *data) | ||
442 | { | ||
443 | return bitmap_find_next_zero_area(map, size, start, nr, 0); | ||
444 | } | ||
445 | EXPORT_SYMBOL(gen_pool_first_fit); | ||
446 | |||
447 | /** | ||
448 | * gen_pool_best_fit - find the best fitting region of memory | ||
449 | * macthing the size requirement (no alignment constraint) | ||
450 | * @map: The address to base the search on | ||
451 | * @size: The bitmap size in bits | ||
452 | * @start: The bitnumber to start searching at | ||
453 | * @nr: The number of zeroed bits we're looking for | ||
454 | * @data: additional data - unused | ||
455 | * | ||
456 | * Iterate over the bitmap to find the smallest free region | ||
457 | * which we can allocate the memory. | ||
458 | */ | ||
459 | unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, | ||
460 | unsigned long start, unsigned int nr, void *data) | ||
461 | { | ||
462 | unsigned long start_bit = size; | ||
463 | unsigned long len = size + 1; | ||
464 | unsigned long index; | ||
465 | |||
466 | index = bitmap_find_next_zero_area(map, size, start, nr, 0); | ||
467 | |||
468 | while (index < size) { | ||
469 | int next_bit = find_next_bit(map, size, index + nr); | ||
470 | if ((next_bit - index) < len) { | ||
471 | len = next_bit - index; | ||
472 | start_bit = index; | ||
473 | if (len == nr) | ||
474 | return start_bit; | ||
475 | } | ||
476 | index = bitmap_find_next_zero_area(map, size, | ||
477 | next_bit + 1, nr, 0); | ||
478 | } | ||
479 | |||
480 | return start_bit; | ||
481 | } | ||
482 | EXPORT_SYMBOL(gen_pool_best_fit); | ||
@@ -20,7 +20,7 @@ | |||
20 | * that id to this code and it returns your pointer. | 20 | * that id to this code and it returns your pointer. |
21 | 21 | ||
22 | * You can release ids at any time. When all ids are released, most of | 22 | * You can release ids at any time. When all ids are released, most of |
23 | * the memory is returned (we keep IDR_FREE_MAX) in a local pool so we | 23 | * the memory is returned (we keep MAX_IDR_FREE) in a local pool so we |
24 | * don't need to go to the memory "store" during an id allocate, just | 24 | * don't need to go to the memory "store" during an id allocate, just |
25 | * so you don't need to be too concerned about locking and conflicts | 25 | * so you don't need to be too concerned about locking and conflicts |
26 | * with the slab allocator. | 26 | * with the slab allocator. |
@@ -122,7 +122,7 @@ static void idr_mark_full(struct idr_layer **pa, int id) | |||
122 | */ | 122 | */ |
123 | int idr_pre_get(struct idr *idp, gfp_t gfp_mask) | 123 | int idr_pre_get(struct idr *idp, gfp_t gfp_mask) |
124 | { | 124 | { |
125 | while (idp->id_free_cnt < IDR_FREE_MAX) { | 125 | while (idp->id_free_cnt < MAX_IDR_FREE) { |
126 | struct idr_layer *new; | 126 | struct idr_layer *new; |
127 | new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); | 127 | new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); |
128 | if (new == NULL) | 128 | if (new == NULL) |
@@ -179,7 +179,7 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa) | |||
179 | sh = IDR_BITS*l; | 179 | sh = IDR_BITS*l; |
180 | id = ((id >> sh) ^ n ^ m) << sh; | 180 | id = ((id >> sh) ^ n ^ m) << sh; |
181 | } | 181 | } |
182 | if ((id >= MAX_ID_BIT) || (id < 0)) | 182 | if ((id >= MAX_IDR_BIT) || (id < 0)) |
183 | return IDR_NOMORE_SPACE; | 183 | return IDR_NOMORE_SPACE; |
184 | if (l == 0) | 184 | if (l == 0) |
185 | break; | 185 | break; |
@@ -223,7 +223,7 @@ build_up: | |||
223 | * Add a new layer to the top of the tree if the requested | 223 | * Add a new layer to the top of the tree if the requested |
224 | * id is larger than the currently allocated space. | 224 | * id is larger than the currently allocated space. |
225 | */ | 225 | */ |
226 | while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { | 226 | while ((layers < (MAX_IDR_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { |
227 | layers++; | 227 | layers++; |
228 | if (!p->count) { | 228 | if (!p->count) { |
229 | /* special case: if the tree is currently empty, | 229 | /* special case: if the tree is currently empty, |
@@ -265,7 +265,7 @@ build_up: | |||
265 | 265 | ||
266 | static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) | 266 | static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) |
267 | { | 267 | { |
268 | struct idr_layer *pa[MAX_LEVEL]; | 268 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
269 | int id; | 269 | int id; |
270 | 270 | ||
271 | id = idr_get_empty_slot(idp, starting_id, pa); | 271 | id = idr_get_empty_slot(idp, starting_id, pa); |
@@ -357,7 +357,7 @@ static void idr_remove_warning(int id) | |||
357 | static void sub_remove(struct idr *idp, int shift, int id) | 357 | static void sub_remove(struct idr *idp, int shift, int id) |
358 | { | 358 | { |
359 | struct idr_layer *p = idp->top; | 359 | struct idr_layer *p = idp->top; |
360 | struct idr_layer **pa[MAX_LEVEL]; | 360 | struct idr_layer **pa[MAX_IDR_LEVEL]; |
361 | struct idr_layer ***paa = &pa[0]; | 361 | struct idr_layer ***paa = &pa[0]; |
362 | struct idr_layer *to_free; | 362 | struct idr_layer *to_free; |
363 | int n; | 363 | int n; |
@@ -402,7 +402,7 @@ void idr_remove(struct idr *idp, int id) | |||
402 | struct idr_layer *to_free; | 402 | struct idr_layer *to_free; |
403 | 403 | ||
404 | /* Mask off upper bits we don't use for the search. */ | 404 | /* Mask off upper bits we don't use for the search. */ |
405 | id &= MAX_ID_MASK; | 405 | id &= MAX_IDR_MASK; |
406 | 406 | ||
407 | sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); | 407 | sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); |
408 | if (idp->top && idp->top->count == 1 && (idp->layers > 1) && | 408 | if (idp->top && idp->top->count == 1 && (idp->layers > 1) && |
@@ -420,7 +420,7 @@ void idr_remove(struct idr *idp, int id) | |||
420 | to_free->bitmap = to_free->count = 0; | 420 | to_free->bitmap = to_free->count = 0; |
421 | free_layer(to_free); | 421 | free_layer(to_free); |
422 | } | 422 | } |
423 | while (idp->id_free_cnt >= IDR_FREE_MAX) { | 423 | while (idp->id_free_cnt >= MAX_IDR_FREE) { |
424 | p = get_from_free_list(idp); | 424 | p = get_from_free_list(idp); |
425 | /* | 425 | /* |
426 | * Note: we don't call the rcu callback here, since the only | 426 | * Note: we don't call the rcu callback here, since the only |
@@ -451,7 +451,7 @@ void idr_remove_all(struct idr *idp) | |||
451 | int n, id, max; | 451 | int n, id, max; |
452 | int bt_mask; | 452 | int bt_mask; |
453 | struct idr_layer *p; | 453 | struct idr_layer *p; |
454 | struct idr_layer *pa[MAX_LEVEL]; | 454 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
455 | struct idr_layer **paa = &pa[0]; | 455 | struct idr_layer **paa = &pa[0]; |
456 | 456 | ||
457 | n = idp->layers * IDR_BITS; | 457 | n = idp->layers * IDR_BITS; |
@@ -517,7 +517,7 @@ void *idr_find(struct idr *idp, int id) | |||
517 | n = (p->layer+1) * IDR_BITS; | 517 | n = (p->layer+1) * IDR_BITS; |
518 | 518 | ||
519 | /* Mask off upper bits we don't use for the search. */ | 519 | /* Mask off upper bits we don't use for the search. */ |
520 | id &= MAX_ID_MASK; | 520 | id &= MAX_IDR_MASK; |
521 | 521 | ||
522 | if (id >= (1 << n)) | 522 | if (id >= (1 << n)) |
523 | return NULL; | 523 | return NULL; |
@@ -555,7 +555,7 @@ int idr_for_each(struct idr *idp, | |||
555 | { | 555 | { |
556 | int n, id, max, error = 0; | 556 | int n, id, max, error = 0; |
557 | struct idr_layer *p; | 557 | struct idr_layer *p; |
558 | struct idr_layer *pa[MAX_LEVEL]; | 558 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
559 | struct idr_layer **paa = &pa[0]; | 559 | struct idr_layer **paa = &pa[0]; |
560 | 560 | ||
561 | n = idp->layers * IDR_BITS; | 561 | n = idp->layers * IDR_BITS; |
@@ -601,7 +601,7 @@ EXPORT_SYMBOL(idr_for_each); | |||
601 | */ | 601 | */ |
602 | void *idr_get_next(struct idr *idp, int *nextidp) | 602 | void *idr_get_next(struct idr *idp, int *nextidp) |
603 | { | 603 | { |
604 | struct idr_layer *p, *pa[MAX_LEVEL]; | 604 | struct idr_layer *p, *pa[MAX_IDR_LEVEL]; |
605 | struct idr_layer **paa = &pa[0]; | 605 | struct idr_layer **paa = &pa[0]; |
606 | int id = *nextidp; | 606 | int id = *nextidp; |
607 | int n, max; | 607 | int n, max; |
@@ -659,7 +659,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) | |||
659 | 659 | ||
660 | n = (p->layer+1) * IDR_BITS; | 660 | n = (p->layer+1) * IDR_BITS; |
661 | 661 | ||
662 | id &= MAX_ID_MASK; | 662 | id &= MAX_IDR_MASK; |
663 | 663 | ||
664 | if (id >= (1 << n)) | 664 | if (id >= (1 << n)) |
665 | return ERR_PTR(-EINVAL); | 665 | return ERR_PTR(-EINVAL); |
@@ -780,7 +780,7 @@ EXPORT_SYMBOL(ida_pre_get); | |||
780 | */ | 780 | */ |
781 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | 781 | int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) |
782 | { | 782 | { |
783 | struct idr_layer *pa[MAX_LEVEL]; | 783 | struct idr_layer *pa[MAX_IDR_LEVEL]; |
784 | struct ida_bitmap *bitmap; | 784 | struct ida_bitmap *bitmap; |
785 | unsigned long flags; | 785 | unsigned long flags; |
786 | int idr_id = starting_id / IDA_BITMAP_BITS; | 786 | int idr_id = starting_id / IDA_BITMAP_BITS; |
@@ -793,7 +793,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | |||
793 | if (t < 0) | 793 | if (t < 0) |
794 | return _idr_rc_to_errno(t); | 794 | return _idr_rc_to_errno(t); |
795 | 795 | ||
796 | if (t * IDA_BITMAP_BITS >= MAX_ID_BIT) | 796 | if (t * IDA_BITMAP_BITS >= MAX_IDR_BIT) |
797 | return -ENOSPC; | 797 | return -ENOSPC; |
798 | 798 | ||
799 | if (t != idr_id) | 799 | if (t != idr_id) |
@@ -827,7 +827,7 @@ int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) | |||
827 | } | 827 | } |
828 | 828 | ||
829 | id = idr_id * IDA_BITMAP_BITS + t; | 829 | id = idr_id * IDA_BITMAP_BITS + t; |
830 | if (id >= MAX_ID_BIT) | 830 | if (id >= MAX_IDR_BIT) |
831 | return -ENOSPC; | 831 | return -ENOSPC; |
832 | 832 | ||
833 | __set_bit(t, bitmap->bitmap); | 833 | __set_bit(t, bitmap->bitmap); |
diff --git a/lib/parser.c b/lib/parser.c index c43410084838..52cfa69f73df 100644 --- a/lib/parser.c +++ b/lib/parser.c | |||
@@ -122,13 +122,14 @@ int match_token(char *s, const match_table_t table, substring_t args[]) | |||
122 | * | 122 | * |
123 | * Description: Given a &substring_t and a base, attempts to parse the substring | 123 | * Description: Given a &substring_t and a base, attempts to parse the substring |
124 | * as a number in that base. On success, sets @result to the integer represented | 124 | * as a number in that base. On success, sets @result to the integer represented |
125 | * by the string and returns 0. Returns either -ENOMEM or -EINVAL on failure. | 125 | * by the string and returns 0. Returns -ENOMEM, -EINVAL, or -ERANGE on failure. |
126 | */ | 126 | */ |
127 | static int match_number(substring_t *s, int *result, int base) | 127 | static int match_number(substring_t *s, int *result, int base) |
128 | { | 128 | { |
129 | char *endp; | 129 | char *endp; |
130 | char *buf; | 130 | char *buf; |
131 | int ret; | 131 | int ret; |
132 | long val; | ||
132 | size_t len = s->to - s->from; | 133 | size_t len = s->to - s->from; |
133 | 134 | ||
134 | buf = kmalloc(len + 1, GFP_KERNEL); | 135 | buf = kmalloc(len + 1, GFP_KERNEL); |
@@ -136,10 +137,15 @@ static int match_number(substring_t *s, int *result, int base) | |||
136 | return -ENOMEM; | 137 | return -ENOMEM; |
137 | memcpy(buf, s->from, len); | 138 | memcpy(buf, s->from, len); |
138 | buf[len] = '\0'; | 139 | buf[len] = '\0'; |
139 | *result = simple_strtol(buf, &endp, base); | 140 | |
140 | ret = 0; | 141 | ret = 0; |
142 | val = simple_strtol(buf, &endp, base); | ||
141 | if (endp == buf) | 143 | if (endp == buf) |
142 | ret = -EINVAL; | 144 | ret = -EINVAL; |
145 | else if (val < (long)INT_MIN || val > (long)INT_MAX) | ||
146 | ret = -ERANGE; | ||
147 | else | ||
148 | *result = (int) val; | ||
143 | kfree(buf); | 149 | kfree(buf); |
144 | return ret; | 150 | return ret; |
145 | } | 151 | } |
diff --git a/lib/plist.c b/lib/plist.c index 6ab0e521c48b..1ebc95f7a46f 100644 --- a/lib/plist.c +++ b/lib/plist.c | |||
@@ -175,7 +175,7 @@ static int __init plist_test(void) | |||
175 | int nr_expect = 0, i, loop; | 175 | int nr_expect = 0, i, loop; |
176 | unsigned int r = local_clock(); | 176 | unsigned int r = local_clock(); |
177 | 177 | ||
178 | printk(KERN_INFO "start plist test\n"); | 178 | pr_debug("start plist test\n"); |
179 | plist_head_init(&test_head); | 179 | plist_head_init(&test_head); |
180 | for (i = 0; i < ARRAY_SIZE(test_node); i++) | 180 | for (i = 0; i < ARRAY_SIZE(test_node); i++) |
181 | plist_node_init(test_node + i, 0); | 181 | plist_node_init(test_node + i, 0); |
@@ -203,7 +203,7 @@ static int __init plist_test(void) | |||
203 | plist_test_check(nr_expect); | 203 | plist_test_check(nr_expect); |
204 | } | 204 | } |
205 | 205 | ||
206 | printk(KERN_INFO "end plist test\n"); | 206 | pr_debug("end plist test\n"); |
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index fadae774a20c..e76d85cf3175 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
@@ -404,14 +404,13 @@ EXPORT_SYMBOL(sg_miter_start); | |||
404 | * @miter: sg mapping iter to proceed | 404 | * @miter: sg mapping iter to proceed |
405 | * | 405 | * |
406 | * Description: | 406 | * Description: |
407 | * Proceeds @miter@ to the next mapping. @miter@ should have been | 407 | * Proceeds @miter to the next mapping. @miter should have been started |
408 | * started using sg_miter_start(). On successful return, | 408 | * using sg_miter_start(). On successful return, @miter->page, |
409 | * @miter@->page, @miter@->addr and @miter@->length point to the | 409 | * @miter->addr and @miter->length point to the current mapping. |
410 | * current mapping. | ||
411 | * | 410 | * |
412 | * Context: | 411 | * Context: |
413 | * IRQ disabled if SG_MITER_ATOMIC. IRQ must stay disabled till | 412 | * Preemption disabled if SG_MITER_ATOMIC. Preemption must stay disabled |
414 | * @miter@ is stopped. May sleep if !SG_MITER_ATOMIC. | 413 | * till @miter is stopped. May sleep if !SG_MITER_ATOMIC. |
415 | * | 414 | * |
416 | * Returns: | 415 | * Returns: |
417 | * true if @miter contains the next mapping. false if end of sg | 416 | * true if @miter contains the next mapping. false if end of sg |
@@ -465,7 +464,8 @@ EXPORT_SYMBOL(sg_miter_next); | |||
465 | * resources (kmap) need to be released during iteration. | 464 | * resources (kmap) need to be released during iteration. |
466 | * | 465 | * |
467 | * Context: | 466 | * Context: |
468 | * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise. | 467 | * Preemption disabled if the SG_MITER_ATOMIC is set. Don't care |
468 | * otherwise. | ||
469 | */ | 469 | */ |
470 | void sg_miter_stop(struct sg_mapping_iter *miter) | 470 | void sg_miter_stop(struct sg_mapping_iter *miter) |
471 | { | 471 | { |
@@ -479,7 +479,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter) | |||
479 | flush_kernel_dcache_page(miter->page); | 479 | flush_kernel_dcache_page(miter->page); |
480 | 480 | ||
481 | if (miter->__flags & SG_MITER_ATOMIC) { | 481 | if (miter->__flags & SG_MITER_ATOMIC) { |
482 | WARN_ON(!irqs_disabled()); | 482 | WARN_ON_ONCE(preemptible()); |
483 | kunmap_atomic(miter->addr); | 483 | kunmap_atomic(miter->addr); |
484 | } else | 484 | } else |
485 | kunmap(miter->page); | 485 | kunmap(miter->page); |
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index eb10578ae055..0374a596cffa 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c | |||
@@ -107,23 +107,27 @@ static void __spin_lock_debug(raw_spinlock_t *lock) | |||
107 | { | 107 | { |
108 | u64 i; | 108 | u64 i; |
109 | u64 loops = loops_per_jiffy * HZ; | 109 | u64 loops = loops_per_jiffy * HZ; |
110 | int print_once = 1; | ||
111 | 110 | ||
112 | for (;;) { | 111 | for (i = 0; i < loops; i++) { |
113 | for (i = 0; i < loops; i++) { | 112 | if (arch_spin_trylock(&lock->raw_lock)) |
114 | if (arch_spin_trylock(&lock->raw_lock)) | 113 | return; |
115 | return; | 114 | __delay(1); |
116 | __delay(1); | 115 | } |
117 | } | 116 | /* lockup suspected: */ |
118 | /* lockup suspected: */ | 117 | spin_dump(lock, "lockup suspected"); |
119 | if (print_once) { | ||
120 | print_once = 0; | ||
121 | spin_dump(lock, "lockup suspected"); | ||
122 | #ifdef CONFIG_SMP | 118 | #ifdef CONFIG_SMP |
123 | trigger_all_cpu_backtrace(); | 119 | trigger_all_cpu_backtrace(); |
124 | #endif | 120 | #endif |
125 | } | 121 | |
126 | } | 122 | /* |
123 | * The trylock above was causing a livelock. Give the lower level arch | ||
124 | * specific lock code a chance to acquire the lock. We have already | ||
125 | * printed a warning/backtrace at this point. The non-debug arch | ||
126 | * specific code might actually succeed in acquiring the lock. If it is | ||
127 | * not successful, the end-result is the same - there is no forward | ||
128 | * progress. | ||
129 | */ | ||
130 | arch_spin_lock(&lock->raw_lock); | ||
127 | } | 131 | } |
128 | 132 | ||
129 | void do_raw_spin_lock(raw_spinlock_t *lock) | 133 | void do_raw_spin_lock(raw_spinlock_t *lock) |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 0e337541f005..39c99fea7c03 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -174,35 +174,25 @@ char *put_dec_trunc8(char *buf, unsigned r) | |||
174 | unsigned q; | 174 | unsigned q; |
175 | 175 | ||
176 | /* Copy of previous function's body with added early returns */ | 176 | /* Copy of previous function's body with added early returns */ |
177 | q = (r * (uint64_t)0x1999999a) >> 32; | 177 | while (r >= 10000) { |
178 | *buf++ = (r - 10 * q) + '0'; /* 2 */ | 178 | q = r + '0'; |
179 | if (q == 0) | 179 | r = (r * (uint64_t)0x1999999a) >> 32; |
180 | return buf; | 180 | *buf++ = q - 10*r; |
181 | r = (q * (uint64_t)0x1999999a) >> 32; | 181 | } |
182 | *buf++ = (q - 10 * r) + '0'; /* 3 */ | 182 | |
183 | if (r == 0) | 183 | q = (r * 0x199a) >> 16; /* r <= 9999 */ |
184 | return buf; | 184 | *buf++ = (r - 10 * q) + '0'; |
185 | q = (r * (uint64_t)0x1999999a) >> 32; | ||
186 | *buf++ = (r - 10 * q) + '0'; /* 4 */ | ||
187 | if (q == 0) | ||
188 | return buf; | ||
189 | r = (q * (uint64_t)0x1999999a) >> 32; | ||
190 | *buf++ = (q - 10 * r) + '0'; /* 5 */ | ||
191 | if (r == 0) | ||
192 | return buf; | ||
193 | q = (r * 0x199a) >> 16; | ||
194 | *buf++ = (r - 10 * q) + '0'; /* 6 */ | ||
195 | if (q == 0) | 185 | if (q == 0) |
196 | return buf; | 186 | return buf; |
197 | r = (q * 0xcd) >> 11; | 187 | r = (q * 0xcd) >> 11; /* q <= 999 */ |
198 | *buf++ = (q - 10 * r) + '0'; /* 7 */ | 188 | *buf++ = (q - 10 * r) + '0'; |
199 | if (r == 0) | 189 | if (r == 0) |
200 | return buf; | 190 | return buf; |
201 | q = (r * 0xcd) >> 11; | 191 | q = (r * 0xcd) >> 11; /* r <= 99 */ |
202 | *buf++ = (r - 10 * q) + '0'; /* 8 */ | 192 | *buf++ = (r - 10 * q) + '0'; |
203 | if (q == 0) | 193 | if (q == 0) |
204 | return buf; | 194 | return buf; |
205 | *buf++ = q + '0'; /* 9 */ | 195 | *buf++ = q + '0'; /* q <= 9 */ |
206 | return buf; | 196 | return buf; |
207 | } | 197 | } |
208 | 198 | ||
@@ -243,18 +233,34 @@ char *put_dec(char *buf, unsigned long long n) | |||
243 | 233 | ||
244 | /* Second algorithm: valid only for 64-bit long longs */ | 234 | /* Second algorithm: valid only for 64-bit long longs */ |
245 | 235 | ||
236 | /* See comment in put_dec_full9 for choice of constants */ | ||
246 | static noinline_for_stack | 237 | static noinline_for_stack |
247 | char *put_dec_full4(char *buf, unsigned q) | 238 | void put_dec_full4(char *buf, unsigned q) |
248 | { | 239 | { |
249 | unsigned r; | 240 | unsigned r; |
250 | r = (q * 0xcccd) >> 19; | 241 | r = (q * 0xccd) >> 15; |
251 | *buf++ = (q - 10 * r) + '0'; | 242 | buf[0] = (q - 10 * r) + '0'; |
252 | q = (r * 0x199a) >> 16; | 243 | q = (r * 0xcd) >> 11; |
253 | *buf++ = (r - 10 * q) + '0'; | 244 | buf[1] = (r - 10 * q) + '0'; |
254 | r = (q * 0xcd) >> 11; | 245 | r = (q * 0xcd) >> 11; |
255 | *buf++ = (q - 10 * r) + '0'; | 246 | buf[2] = (q - 10 * r) + '0'; |
256 | *buf++ = r + '0'; | 247 | buf[3] = r + '0'; |
257 | return buf; | 248 | } |
249 | |||
250 | /* | ||
251 | * Call put_dec_full4 on x % 10000, return x / 10000. | ||
252 | * The approximation x/10000 == (x * 0x346DC5D7) >> 43 | ||
253 | * holds for all x < 1,128,869,999. The largest value this | ||
254 | * helper will ever be asked to convert is 1,125,520,955. | ||
255 | * (d1 in the put_dec code, assuming n is all-ones). | ||
256 | */ | ||
257 | static | ||
258 | unsigned put_dec_helper4(char *buf, unsigned x) | ||
259 | { | ||
260 | uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43; | ||
261 | |||
262 | put_dec_full4(buf, x - q * 10000); | ||
263 | return q; | ||
258 | } | 264 | } |
259 | 265 | ||
260 | /* Based on code by Douglas W. Jones found at | 266 | /* Based on code by Douglas W. Jones found at |
@@ -276,28 +282,19 @@ char *put_dec(char *buf, unsigned long long n) | |||
276 | d3 = (h >> 16); /* implicit "& 0xffff" */ | 282 | d3 = (h >> 16); /* implicit "& 0xffff" */ |
277 | 283 | ||
278 | q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); | 284 | q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); |
285 | q = put_dec_helper4(buf, q); | ||
286 | |||
287 | q += 7671 * d3 + 9496 * d2 + 6 * d1; | ||
288 | q = put_dec_helper4(buf+4, q); | ||
289 | |||
290 | q += 4749 * d3 + 42 * d2; | ||
291 | q = put_dec_helper4(buf+8, q); | ||
279 | 292 | ||
280 | buf = put_dec_full4(buf, q % 10000); | 293 | q += 281 * d3; |
281 | q = q / 10000; | 294 | buf += 12; |
282 | 295 | if (q) | |
283 | d1 = q + 7671 * d3 + 9496 * d2 + 6 * d1; | 296 | buf = put_dec_trunc8(buf, q); |
284 | buf = put_dec_full4(buf, d1 % 10000); | 297 | else while (buf[-1] == '0') |
285 | q = d1 / 10000; | ||
286 | |||
287 | d2 = q + 4749 * d3 + 42 * d2; | ||
288 | buf = put_dec_full4(buf, d2 % 10000); | ||
289 | q = d2 / 10000; | ||
290 | |||
291 | d3 = q + 281 * d3; | ||
292 | if (!d3) | ||
293 | goto done; | ||
294 | buf = put_dec_full4(buf, d3 % 10000); | ||
295 | q = d3 / 10000; | ||
296 | if (!q) | ||
297 | goto done; | ||
298 | buf = put_dec_full4(buf, q); | ||
299 | done: | ||
300 | while (buf[-1] == '0') | ||
301 | --buf; | 298 | --buf; |
302 | 299 | ||
303 | return buf; | 300 | return buf; |
@@ -990,7 +987,7 @@ int kptr_restrict __read_mostly; | |||
990 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons | 987 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons |
991 | * - 'MF' For a 6-byte MAC FDDI address, it prints the address | 988 | * - 'MF' For a 6-byte MAC FDDI address, it prints the address |
992 | * with a dash-separated hex notation | 989 | * with a dash-separated hex notation |
993 | * - '[mM]R For a 6-byte MAC address, Reverse order (Bluetooth) | 990 | * - '[mM]R' For a 6-byte MAC address, Reverse order (Bluetooth) |
994 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way | 991 | * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way |
995 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) | 992 | * IPv4 uses dot-separated decimal without leading 0's (1.2.3.4) |
996 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's | 993 | * IPv6 uses colon separated network-order 16 bit hex with leading 0's |
@@ -1341,7 +1338,10 @@ qualifier: | |||
1341 | * %pR output the address range in a struct resource with decoded flags | 1338 | * %pR output the address range in a struct resource with decoded flags |
1342 | * %pr output the address range in a struct resource with raw flags | 1339 | * %pr output the address range in a struct resource with raw flags |
1343 | * %pM output a 6-byte MAC address with colons | 1340 | * %pM output a 6-byte MAC address with colons |
1341 | * %pMR output a 6-byte MAC address with colons in reversed order | ||
1342 | * %pMF output a 6-byte MAC address with dashes | ||
1344 | * %pm output a 6-byte MAC address without colons | 1343 | * %pm output a 6-byte MAC address without colons |
1344 | * %pmR output a 6-byte MAC address without colons in reversed order | ||
1345 | * %pI4 print an IPv4 address without leading zeros | 1345 | * %pI4 print an IPv4 address without leading zeros |
1346 | * %pi4 print an IPv4 address with leading zeros | 1346 | * %pi4 print an IPv4 address with leading zeros |
1347 | * %pI6 print an IPv6 address with colons | 1347 | * %pI6 print an IPv6 address with colons |
@@ -2017,7 +2017,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2017 | s16 field_width; | 2017 | s16 field_width; |
2018 | bool is_sign; | 2018 | bool is_sign; |
2019 | 2019 | ||
2020 | while (*fmt && *str) { | 2020 | while (*fmt) { |
2021 | /* skip any white space in format */ | 2021 | /* skip any white space in format */ |
2022 | /* white space in format matchs any amount of | 2022 | /* white space in format matchs any amount of |
2023 | * white space, including none, in the input. | 2023 | * white space, including none, in the input. |
@@ -2042,6 +2042,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2042 | * advance both strings to next white space | 2042 | * advance both strings to next white space |
2043 | */ | 2043 | */ |
2044 | if (*fmt == '*') { | 2044 | if (*fmt == '*') { |
2045 | if (!*str) | ||
2046 | break; | ||
2045 | while (!isspace(*fmt) && *fmt != '%' && *fmt) | 2047 | while (!isspace(*fmt) && *fmt != '%' && *fmt) |
2046 | fmt++; | 2048 | fmt++; |
2047 | while (!isspace(*str) && *str) | 2049 | while (!isspace(*str) && *str) |
@@ -2070,7 +2072,17 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2070 | } | 2072 | } |
2071 | } | 2073 | } |
2072 | 2074 | ||
2073 | if (!*fmt || !*str) | 2075 | if (!*fmt) |
2076 | break; | ||
2077 | |||
2078 | if (*fmt == 'n') { | ||
2079 | /* return number of characters read so far */ | ||
2080 | *va_arg(args, int *) = str - buf; | ||
2081 | ++fmt; | ||
2082 | continue; | ||
2083 | } | ||
2084 | |||
2085 | if (!*str) | ||
2074 | break; | 2086 | break; |
2075 | 2087 | ||
2076 | base = 10; | 2088 | base = 10; |
@@ -2103,13 +2115,6 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2103 | num++; | 2115 | num++; |
2104 | } | 2116 | } |
2105 | continue; | 2117 | continue; |
2106 | case 'n': | ||
2107 | /* return number of characters read so far */ | ||
2108 | { | ||
2109 | int *i = (int *)va_arg(args, int*); | ||
2110 | *i = str - buf; | ||
2111 | } | ||
2112 | continue; | ||
2113 | case 'o': | 2118 | case 'o': |
2114 | base = 8; | 2119 | base = 8; |
2115 | break; | 2120 | break; |
@@ -2210,16 +2215,6 @@ int vsscanf(const char *buf, const char *fmt, va_list args) | |||
2210 | str = next; | 2215 | str = next; |
2211 | } | 2216 | } |
2212 | 2217 | ||
2213 | /* | ||
2214 | * Now we've come all the way through so either the input string or the | ||
2215 | * format ended. In the former case, there can be a %n at the current | ||
2216 | * position in the format that needs to be filled. | ||
2217 | */ | ||
2218 | if (*fmt == '%' && *(fmt + 1) == 'n') { | ||
2219 | int *p = (int *)va_arg(args, int *); | ||
2220 | *p = str - buf; | ||
2221 | } | ||
2222 | |||
2223 | return num; | 2218 | return num; |
2224 | } | 2219 | } |
2225 | EXPORT_SYMBOL(vsscanf); | 2220 | EXPORT_SYMBOL(vsscanf); |
diff --git a/mm/percpu.c b/mm/percpu.c index bb4be7435ce3..ddc5efb9c5bb 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -1370,7 +1370,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, | |||
1370 | 1370 | ||
1371 | #ifdef CONFIG_SMP | 1371 | #ifdef CONFIG_SMP |
1372 | 1372 | ||
1373 | const char *pcpu_fc_names[PCPU_FC_NR] __initdata = { | 1373 | const char * const pcpu_fc_names[PCPU_FC_NR] __initconst = { |
1374 | [PCPU_FC_AUTO] = "auto", | 1374 | [PCPU_FC_AUTO] = "auto", |
1375 | [PCPU_FC_EMBED] = "embed", | 1375 | [PCPU_FC_EMBED] = "embed", |
1376 | [PCPU_FC_PAGE] = "page", | 1376 | [PCPU_FC_PAGE] = "page", |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 821022a7214f..ddac1ee2ed20 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -63,7 +63,7 @@ | |||
63 | 63 | ||
64 | #include "af_can.h" | 64 | #include "af_can.h" |
65 | 65 | ||
66 | static __initdata const char banner[] = KERN_INFO | 66 | static __initconst const char banner[] = KERN_INFO |
67 | "can: controller area network core (" CAN_VERSION_STRING ")\n"; | 67 | "can: controller area network core (" CAN_VERSION_STRING ")\n"; |
68 | 68 | ||
69 | MODULE_DESCRIPTION("Controller Area Network PF_CAN core"); | 69 | MODULE_DESCRIPTION("Controller Area Network PF_CAN core"); |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 151b7730c12c..6f747582718e 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -77,7 +77,7 @@ | |||
77 | (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG)) | 77 | (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG)) |
78 | 78 | ||
79 | #define CAN_BCM_VERSION CAN_VERSION | 79 | #define CAN_BCM_VERSION CAN_VERSION |
80 | static __initdata const char banner[] = KERN_INFO | 80 | static __initconst const char banner[] = KERN_INFO |
81 | "can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n"; | 81 | "can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n"; |
82 | 82 | ||
83 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); | 83 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); |
diff --git a/net/can/gw.c b/net/can/gw.c index 127879c55fb6..1f5c9785a262 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -58,7 +58,7 @@ | |||
58 | #include <net/sock.h> | 58 | #include <net/sock.h> |
59 | 59 | ||
60 | #define CAN_GW_VERSION "20101209" | 60 | #define CAN_GW_VERSION "20101209" |
61 | static __initdata const char banner[] = | 61 | static __initconst const char banner[] = |
62 | KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n"; | 62 | KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n"; |
63 | 63 | ||
64 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); | 64 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); |
diff --git a/net/can/raw.c b/net/can/raw.c index 3e9c89356a93..5b0e3e330d97 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <net/net_namespace.h> | 55 | #include <net/net_namespace.h> |
56 | 56 | ||
57 | #define CAN_RAW_VERSION CAN_VERSION | 57 | #define CAN_RAW_VERSION CAN_VERSION |
58 | static __initdata const char banner[] = | 58 | static __initconst const char banner[] = |
59 | KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n"; | 59 | KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n"; |
60 | 60 | ||
61 | MODULE_DESCRIPTION("PF_CAN raw protocol"); | 61 | MODULE_DESCRIPTION("PF_CAN raw protocol"); |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index e65f2c856e06..faf7cc3483fe 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -220,7 +220,7 @@ static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops) | |||
220 | dn_rt_cache_flush(-1); | 220 | dn_rt_cache_flush(-1); |
221 | } | 221 | } |
222 | 222 | ||
223 | static const struct fib_rules_ops __net_initdata dn_fib_rules_ops_template = { | 223 | static const struct fib_rules_ops __net_initconst dn_fib_rules_ops_template = { |
224 | .family = AF_DECnet, | 224 | .family = AF_DECnet, |
225 | .rule_size = sizeof(struct dn_fib_rule), | 225 | .rule_size = sizeof(struct dn_fib_rule), |
226 | .addr_size = sizeof(u16), | 226 | .addr_size = sizeof(u16), |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 274309d3aded..26aa65d1fce4 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -262,7 +262,7 @@ static void fib4_rule_flush_cache(struct fib_rules_ops *ops) | |||
262 | rt_cache_flush(ops->fro_net); | 262 | rt_cache_flush(ops->fro_net); |
263 | } | 263 | } |
264 | 264 | ||
265 | static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { | 265 | static const struct fib_rules_ops __net_initconst fib4_rules_ops_template = { |
266 | .family = AF_INET, | 266 | .family = AF_INET, |
267 | .rule_size = sizeof(struct fib4_rule), | 267 | .rule_size = sizeof(struct fib4_rule), |
268 | .addr_size = sizeof(u32), | 268 | .addr_size = sizeof(u32), |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 1daa95c2a0ba..6168c4dc58b1 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -221,7 +221,7 @@ static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | 223 | ||
224 | static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = { | 224 | static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { |
225 | .family = RTNL_FAMILY_IPMR, | 225 | .family = RTNL_FAMILY_IPMR, |
226 | .rule_size = sizeof(struct ipmr_rule), | 226 | .rule_size = sizeof(struct ipmr_rule), |
227 | .addr_size = sizeof(u32), | 227 | .addr_size = sizeof(u32), |
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 4be23da32b89..ff76eecfd622 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -79,7 +79,7 @@ struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl) | |||
79 | 79 | ||
80 | #define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL | 80 | #define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL |
81 | 81 | ||
82 | static const __net_initdata struct ip6addrlbl_init_table | 82 | static const __net_initconst struct ip6addrlbl_init_table |
83 | { | 83 | { |
84 | const struct in6_addr *prefix; | 84 | const struct in6_addr *prefix; |
85 | int prefixlen; | 85 | int prefixlen; |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 0ff1cfd55bc4..d9fb9110f607 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -238,7 +238,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | |||
238 | + nla_total_size(16); /* src */ | 238 | + nla_total_size(16); /* src */ |
239 | } | 239 | } |
240 | 240 | ||
241 | static const struct fib_rules_ops __net_initdata fib6_rules_ops_template = { | 241 | static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = { |
242 | .family = AF_INET6, | 242 | .family = AF_INET6, |
243 | .rule_size = sizeof(struct fib6_rule), | 243 | .rule_size = sizeof(struct fib6_rule), |
244 | .addr_size = sizeof(struct in6_addr), | 244 | .addr_size = sizeof(struct in6_addr), |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 08ea3f0b6e55..f7c7c6319720 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -205,7 +205,7 @@ static int ip6mr_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
205 | return 0; | 205 | return 0; |
206 | } | 206 | } |
207 | 207 | ||
208 | static const struct fib_rules_ops __net_initdata ip6mr_rules_ops_template = { | 208 | static const struct fib_rules_ops __net_initconst ip6mr_rules_ops_template = { |
209 | .family = RTNL_FAMILY_IP6MR, | 209 | .family = RTNL_FAMILY_IP6MR, |
210 | .rule_size = sizeof(struct ip6mr_rule), | 210 | .rule_size = sizeof(struct ip6mr_rule), |
211 | .addr_size = sizeof(struct in6_addr), | 211 | .addr_size = sizeof(struct in6_addr), |
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 6a3ee981931d..afa44595f348 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include | |||
@@ -209,7 +209,7 @@ endif | |||
209 | # >$< substitution to preserve $ when reloading .cmd file | 209 | # >$< substitution to preserve $ when reloading .cmd file |
210 | # note: when using inline perl scripts [perl -e '...$$t=1;...'] | 210 | # note: when using inline perl scripts [perl -e '...$$t=1;...'] |
211 | # in $(cmd_xxx) double $$ your perl vars | 211 | # in $(cmd_xxx) double $$ your perl vars |
212 | make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))) | 212 | make-cmd = $(subst \\,\\\\,$(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))) |
213 | 213 | ||
214 | # Find any prerequisites that is newer than target or that does not exist. | 214 | # Find any prerequisites that is newer than target or that does not exist. |
215 | # PHONY targets skipped in both cases. | 215 | # PHONY targets skipped in both cases. |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index ca05ba217f5f..21a9f5de0a21 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -421,7 +421,7 @@ sub top_of_kernel_tree { | |||
421 | } | 421 | } |
422 | } | 422 | } |
423 | return 1; | 423 | return 1; |
424 | } | 424 | } |
425 | 425 | ||
426 | sub parse_email { | 426 | sub parse_email { |
427 | my ($formatted_email) = @_; | 427 | my ($formatted_email) = @_; |
@@ -1386,6 +1386,8 @@ sub process { | |||
1386 | my $in_header_lines = 1; | 1386 | my $in_header_lines = 1; |
1387 | my $in_commit_log = 0; #Scanning lines before patch | 1387 | my $in_commit_log = 0; #Scanning lines before patch |
1388 | 1388 | ||
1389 | my $non_utf8_charset = 0; | ||
1390 | |||
1389 | our @report = (); | 1391 | our @report = (); |
1390 | our $cnt_lines = 0; | 1392 | our $cnt_lines = 0; |
1391 | our $cnt_error = 0; | 1393 | our $cnt_error = 0; |
@@ -1686,10 +1688,17 @@ sub process { | |||
1686 | $in_commit_log = 1; | 1688 | $in_commit_log = 1; |
1687 | } | 1689 | } |
1688 | 1690 | ||
1689 | # Still not yet in a patch, check for any UTF-8 | 1691 | # Check if there is UTF-8 in a commit log when a mail header has explicitly |
1690 | if ($in_commit_log && $realfile =~ /^$/ && | 1692 | # declined it, i.e defined some charset where it is missing. |
1693 | if ($in_header_lines && | ||
1694 | $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && | ||
1695 | $1 !~ /utf-8/i) { | ||
1696 | $non_utf8_charset = 1; | ||
1697 | } | ||
1698 | |||
1699 | if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && | ||
1691 | $rawline =~ /$NON_ASCII_UTF8/) { | 1700 | $rawline =~ /$NON_ASCII_UTF8/) { |
1692 | CHK("UTF8_BEFORE_PATCH", | 1701 | WARN("UTF8_BEFORE_PATCH", |
1693 | "8-bit UTF-8 used in possible commit log\n" . $herecurr); | 1702 | "8-bit UTF-8 used in possible commit log\n" . $herecurr); |
1694 | } | 1703 | } |
1695 | 1704 | ||
@@ -1873,6 +1882,20 @@ sub process { | |||
1873 | "No space is necessary after a cast\n" . $hereprev); | 1882 | "No space is necessary after a cast\n" . $hereprev); |
1874 | } | 1883 | } |
1875 | 1884 | ||
1885 | if ($realfile =~ m@^(drivers/net/|net/)@ && | ||
1886 | $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && | ||
1887 | $prevrawline =~ /^\+[ \t]*$/) { | ||
1888 | WARN("NETWORKING_BLOCK_COMMENT_STYLE", | ||
1889 | "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); | ||
1890 | } | ||
1891 | |||
1892 | if ($realfile =~ m@^(drivers/net/|net/)@ && | ||
1893 | $rawline !~ m@^\+[ \t]*(\/\*|\*\/)@ && | ||
1894 | $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { | ||
1895 | WARN("NETWORKING_BLOCK_COMMENT_STYLE", | ||
1896 | "networking block comments put the trailing */ on a separate line\n" . $herecurr); | ||
1897 | } | ||
1898 | |||
1876 | # check for spaces at the beginning of a line. | 1899 | # check for spaces at the beginning of a line. |
1877 | # Exceptions: | 1900 | # Exceptions: |
1878 | # 1) within comments | 1901 | # 1) within comments |
@@ -2390,8 +2413,10 @@ sub process { | |||
2390 | my $orig = $1; | 2413 | my $orig = $1; |
2391 | my $level = lc($orig); | 2414 | my $level = lc($orig); |
2392 | $level = "warn" if ($level eq "warning"); | 2415 | $level = "warn" if ($level eq "warning"); |
2416 | my $level2 = $level; | ||
2417 | $level2 = "dbg" if ($level eq "debug"); | ||
2393 | WARN("PREFER_PR_LEVEL", | 2418 | WARN("PREFER_PR_LEVEL", |
2394 | "Prefer pr_$level(... to printk(KERN_$1, ...\n" . $herecurr); | 2419 | "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); |
2395 | } | 2420 | } |
2396 | 2421 | ||
2397 | if ($line =~ /\bpr_warning\s*\(/) { | 2422 | if ($line =~ /\bpr_warning\s*\(/) { |
@@ -2947,7 +2972,7 @@ sub process { | |||
2947 | my $exceptions = qr{ | 2972 | my $exceptions = qr{ |
2948 | $Declare| | 2973 | $Declare| |
2949 | module_param_named| | 2974 | module_param_named| |
2950 | MODULE_PARAM_DESC| | 2975 | MODULE_PARM_DESC| |
2951 | DECLARE_PER_CPU| | 2976 | DECLARE_PER_CPU| |
2952 | DEFINE_PER_CPU| | 2977 | DEFINE_PER_CPU| |
2953 | __typeof__\(| | 2978 | __typeof__\(| |
diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 8fd107a3fac4..01e8a8e22602 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc | |||
@@ -230,6 +230,7 @@ my $dohighlight = ""; | |||
230 | 230 | ||
231 | my $verbose = 0; | 231 | my $verbose = 0; |
232 | my $output_mode = "man"; | 232 | my $output_mode = "man"; |
233 | my $output_preformatted = 0; | ||
233 | my $no_doc_sections = 0; | 234 | my $no_doc_sections = 0; |
234 | my %highlights = %highlights_man; | 235 | my %highlights = %highlights_man; |
235 | my $blankline = $blankline_man; | 236 | my $blankline = $blankline_man; |
@@ -280,9 +281,10 @@ my $doc_special = "\@\%\$\&"; | |||
280 | my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. | 281 | my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. |
281 | my $doc_end = '\*/'; | 282 | my $doc_end = '\*/'; |
282 | my $doc_com = '\s*\*\s*'; | 283 | my $doc_com = '\s*\*\s*'; |
284 | my $doc_com_body = '\s*\* ?'; | ||
283 | my $doc_decl = $doc_com . '(\w+)'; | 285 | my $doc_decl = $doc_com . '(\w+)'; |
284 | my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)'; | 286 | my $doc_sect = $doc_com . '([' . $doc_special . ']?[\w\s]+):(.*)'; |
285 | my $doc_content = $doc_com . '(.*)'; | 287 | my $doc_content = $doc_com_body . '(.*)'; |
286 | my $doc_block = $doc_com . 'DOC:\s*(.*)?'; | 288 | my $doc_block = $doc_com . 'DOC:\s*(.*)?'; |
287 | 289 | ||
288 | my %constants; | 290 | my %constants; |
@@ -459,8 +461,13 @@ sub output_highlight { | |||
459 | # print STDERR "contents af:$contents\n"; | 461 | # print STDERR "contents af:$contents\n"; |
460 | 462 | ||
461 | foreach $line (split "\n", $contents) { | 463 | foreach $line (split "\n", $contents) { |
464 | if (! $output_preformatted) { | ||
465 | $line =~ s/^\s*//; | ||
466 | } | ||
462 | if ($line eq ""){ | 467 | if ($line eq ""){ |
463 | print $lineprefix, local_unescape($blankline); | 468 | if (! $output_preformatted) { |
469 | print $lineprefix, local_unescape($blankline); | ||
470 | } | ||
464 | } else { | 471 | } else { |
465 | $line =~ s/\\\\\\/\&/g; | 472 | $line =~ s/\\\\\\/\&/g; |
466 | if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { | 473 | if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { |
@@ -643,10 +650,12 @@ sub output_section_xml(%) { | |||
643 | print "<title>$section</title>\n"; | 650 | print "<title>$section</title>\n"; |
644 | if ($section =~ m/EXAMPLE/i) { | 651 | if ($section =~ m/EXAMPLE/i) { |
645 | print "<informalexample><programlisting>\n"; | 652 | print "<informalexample><programlisting>\n"; |
653 | $output_preformatted = 1; | ||
646 | } else { | 654 | } else { |
647 | print "<para>\n"; | 655 | print "<para>\n"; |
648 | } | 656 | } |
649 | output_highlight($args{'sections'}{$section}); | 657 | output_highlight($args{'sections'}{$section}); |
658 | $output_preformatted = 0; | ||
650 | if ($section =~ m/EXAMPLE/i) { | 659 | if ($section =~ m/EXAMPLE/i) { |
651 | print "</programlisting></informalexample>\n"; | 660 | print "</programlisting></informalexample>\n"; |
652 | } else { | 661 | } else { |
@@ -949,10 +958,12 @@ sub output_blockhead_xml(%) { | |||
949 | } | 958 | } |
950 | if ($section =~ m/EXAMPLE/i) { | 959 | if ($section =~ m/EXAMPLE/i) { |
951 | print "<example><para>\n"; | 960 | print "<example><para>\n"; |
961 | $output_preformatted = 1; | ||
952 | } else { | 962 | } else { |
953 | print "<para>\n"; | 963 | print "<para>\n"; |
954 | } | 964 | } |
955 | output_highlight($args{'sections'}{$section}); | 965 | output_highlight($args{'sections'}{$section}); |
966 | $output_preformatted = 0; | ||
956 | if ($section =~ m/EXAMPLE/i) { | 967 | if ($section =~ m/EXAMPLE/i) { |
957 | print "</para></example>\n"; | 968 | print "</para></example>\n"; |
958 | } else { | 969 | } else { |
@@ -1028,10 +1039,12 @@ sub output_function_gnome { | |||
1028 | print "<simplesect>\n <title>$section</title>\n"; | 1039 | print "<simplesect>\n <title>$section</title>\n"; |
1029 | if ($section =~ m/EXAMPLE/i) { | 1040 | if ($section =~ m/EXAMPLE/i) { |
1030 | print "<example><programlisting>\n"; | 1041 | print "<example><programlisting>\n"; |
1042 | $output_preformatted = 1; | ||
1031 | } else { | 1043 | } else { |
1032 | } | 1044 | } |
1033 | print "<para>\n"; | 1045 | print "<para>\n"; |
1034 | output_highlight($args{'sections'}{$section}); | 1046 | output_highlight($args{'sections'}{$section}); |
1047 | $output_preformatted = 0; | ||
1035 | print "</para>\n"; | 1048 | print "</para>\n"; |
1036 | if ($section =~ m/EXAMPLE/i) { | 1049 | if ($section =~ m/EXAMPLE/i) { |
1037 | print "</programlisting></example>\n"; | 1050 | print "</programlisting></example>\n"; |
@@ -2046,6 +2059,9 @@ sub process_file($) { | |||
2046 | 2059 | ||
2047 | $section_counter = 0; | 2060 | $section_counter = 0; |
2048 | while (<IN>) { | 2061 | while (<IN>) { |
2062 | while (s/\\\s*$//) { | ||
2063 | $_ .= <IN>; | ||
2064 | } | ||
2049 | if ($state == 0) { | 2065 | if ($state == 0) { |
2050 | if (/$doc_start/o) { | 2066 | if (/$doc_start/o) { |
2051 | $state = 1; # next line is always the function name | 2067 | $state = 1; # next line is always the function name |
@@ -2073,7 +2089,7 @@ sub process_file($) { | |||
2073 | $descr= $1; | 2089 | $descr= $1; |
2074 | $descr =~ s/^\s*//; | 2090 | $descr =~ s/^\s*//; |
2075 | $descr =~ s/\s*$//; | 2091 | $descr =~ s/\s*$//; |
2076 | $descr =~ s/\s+/ /; | 2092 | $descr =~ s/\s+/ /g; |
2077 | $declaration_purpose = xml_escape($descr); | 2093 | $declaration_purpose = xml_escape($descr); |
2078 | $in_purpose = 1; | 2094 | $in_purpose = 1; |
2079 | } else { | 2095 | } else { |
@@ -2165,6 +2181,7 @@ sub process_file($) { | |||
2165 | # Continued declaration purpose | 2181 | # Continued declaration purpose |
2166 | chomp($declaration_purpose); | 2182 | chomp($declaration_purpose); |
2167 | $declaration_purpose .= " " . xml_escape($1); | 2183 | $declaration_purpose .= " " . xml_escape($1); |
2184 | $declaration_purpose =~ s/\s+/ /g; | ||
2168 | } else { | 2185 | } else { |
2169 | $contents .= $1 . "\n"; | 2186 | $contents .= $1 . "\n"; |
2170 | } | 2187 | } |
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 4b877a92a7ea..44dfc415a379 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -26,12 +26,12 @@ | |||
26 | static DEFINE_MUTEX(devcgroup_mutex); | 26 | static DEFINE_MUTEX(devcgroup_mutex); |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * whitelist locking rules: | 29 | * exception list locking rules: |
30 | * hold devcgroup_mutex for update/read. | 30 | * hold devcgroup_mutex for update/read. |
31 | * hold rcu_read_lock() for read. | 31 | * hold rcu_read_lock() for read. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | struct dev_whitelist_item { | 34 | struct dev_exception_item { |
35 | u32 major, minor; | 35 | u32 major, minor; |
36 | short type; | 36 | short type; |
37 | short access; | 37 | short access; |
@@ -41,7 +41,8 @@ struct dev_whitelist_item { | |||
41 | 41 | ||
42 | struct dev_cgroup { | 42 | struct dev_cgroup { |
43 | struct cgroup_subsys_state css; | 43 | struct cgroup_subsys_state css; |
44 | struct list_head whitelist; | 44 | struct list_head exceptions; |
45 | bool deny_all; | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) | 48 | static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) |
@@ -74,12 +75,12 @@ static int devcgroup_can_attach(struct cgroup *new_cgrp, | |||
74 | /* | 75 | /* |
75 | * called under devcgroup_mutex | 76 | * called under devcgroup_mutex |
76 | */ | 77 | */ |
77 | static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig) | 78 | static int dev_exceptions_copy(struct list_head *dest, struct list_head *orig) |
78 | { | 79 | { |
79 | struct dev_whitelist_item *wh, *tmp, *new; | 80 | struct dev_exception_item *ex, *tmp, *new; |
80 | 81 | ||
81 | list_for_each_entry(wh, orig, list) { | 82 | list_for_each_entry(ex, orig, list) { |
82 | new = kmemdup(wh, sizeof(*wh), GFP_KERNEL); | 83 | new = kmemdup(ex, sizeof(*ex), GFP_KERNEL); |
83 | if (!new) | 84 | if (!new) |
84 | goto free_and_exit; | 85 | goto free_and_exit; |
85 | list_add_tail(&new->list, dest); | 86 | list_add_tail(&new->list, dest); |
@@ -88,64 +89,60 @@ static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig) | |||
88 | return 0; | 89 | return 0; |
89 | 90 | ||
90 | free_and_exit: | 91 | free_and_exit: |
91 | list_for_each_entry_safe(wh, tmp, dest, list) { | 92 | list_for_each_entry_safe(ex, tmp, dest, list) { |
92 | list_del(&wh->list); | 93 | list_del(&ex->list); |
93 | kfree(wh); | 94 | kfree(ex); |
94 | } | 95 | } |
95 | return -ENOMEM; | 96 | return -ENOMEM; |
96 | } | 97 | } |
97 | 98 | ||
98 | /* Stupid prototype - don't bother combining existing entries */ | ||
99 | /* | 99 | /* |
100 | * called under devcgroup_mutex | 100 | * called under devcgroup_mutex |
101 | */ | 101 | */ |
102 | static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, | 102 | static int dev_exception_add(struct dev_cgroup *dev_cgroup, |
103 | struct dev_whitelist_item *wh) | 103 | struct dev_exception_item *ex) |
104 | { | 104 | { |
105 | struct dev_whitelist_item *whcopy, *walk; | 105 | struct dev_exception_item *excopy, *walk; |
106 | 106 | ||
107 | whcopy = kmemdup(wh, sizeof(*wh), GFP_KERNEL); | 107 | excopy = kmemdup(ex, sizeof(*ex), GFP_KERNEL); |
108 | if (!whcopy) | 108 | if (!excopy) |
109 | return -ENOMEM; | 109 | return -ENOMEM; |
110 | 110 | ||
111 | list_for_each_entry(walk, &dev_cgroup->whitelist, list) { | 111 | list_for_each_entry(walk, &dev_cgroup->exceptions, list) { |
112 | if (walk->type != wh->type) | 112 | if (walk->type != ex->type) |
113 | continue; | 113 | continue; |
114 | if (walk->major != wh->major) | 114 | if (walk->major != ex->major) |
115 | continue; | 115 | continue; |
116 | if (walk->minor != wh->minor) | 116 | if (walk->minor != ex->minor) |
117 | continue; | 117 | continue; |
118 | 118 | ||
119 | walk->access |= wh->access; | 119 | walk->access |= ex->access; |
120 | kfree(whcopy); | 120 | kfree(excopy); |
121 | whcopy = NULL; | 121 | excopy = NULL; |
122 | } | 122 | } |
123 | 123 | ||
124 | if (whcopy != NULL) | 124 | if (excopy != NULL) |
125 | list_add_tail_rcu(&whcopy->list, &dev_cgroup->whitelist); | 125 | list_add_tail_rcu(&excopy->list, &dev_cgroup->exceptions); |
126 | return 0; | 126 | return 0; |
127 | } | 127 | } |
128 | 128 | ||
129 | /* | 129 | /* |
130 | * called under devcgroup_mutex | 130 | * called under devcgroup_mutex |
131 | */ | 131 | */ |
132 | static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup, | 132 | static void dev_exception_rm(struct dev_cgroup *dev_cgroup, |
133 | struct dev_whitelist_item *wh) | 133 | struct dev_exception_item *ex) |
134 | { | 134 | { |
135 | struct dev_whitelist_item *walk, *tmp; | 135 | struct dev_exception_item *walk, *tmp; |
136 | 136 | ||
137 | list_for_each_entry_safe(walk, tmp, &dev_cgroup->whitelist, list) { | 137 | list_for_each_entry_safe(walk, tmp, &dev_cgroup->exceptions, list) { |
138 | if (walk->type == DEV_ALL) | 138 | if (walk->type != ex->type) |
139 | goto remove; | ||
140 | if (walk->type != wh->type) | ||
141 | continue; | 139 | continue; |
142 | if (walk->major != ~0 && walk->major != wh->major) | 140 | if (walk->major != ex->major) |
143 | continue; | 141 | continue; |
144 | if (walk->minor != ~0 && walk->minor != wh->minor) | 142 | if (walk->minor != ex->minor) |
145 | continue; | 143 | continue; |
146 | 144 | ||
147 | remove: | 145 | walk->access &= ~ex->access; |
148 | walk->access &= ~wh->access; | ||
149 | if (!walk->access) { | 146 | if (!walk->access) { |
150 | list_del_rcu(&walk->list); | 147 | list_del_rcu(&walk->list); |
151 | kfree_rcu(walk, rcu); | 148 | kfree_rcu(walk, rcu); |
@@ -153,6 +150,22 @@ remove: | |||
153 | } | 150 | } |
154 | } | 151 | } |
155 | 152 | ||
153 | /** | ||
154 | * dev_exception_clean - frees all entries of the exception list | ||
155 | * @dev_cgroup: dev_cgroup with the exception list to be cleaned | ||
156 | * | ||
157 | * called under devcgroup_mutex | ||
158 | */ | ||
159 | static void dev_exception_clean(struct dev_cgroup *dev_cgroup) | ||
160 | { | ||
161 | struct dev_exception_item *ex, *tmp; | ||
162 | |||
163 | list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { | ||
164 | list_del(&ex->list); | ||
165 | kfree(ex); | ||
166 | } | ||
167 | } | ||
168 | |||
156 | /* | 169 | /* |
157 | * called from kernel/cgroup.c with cgroup_lock() held. | 170 | * called from kernel/cgroup.c with cgroup_lock() held. |
158 | */ | 171 | */ |
@@ -165,25 +178,17 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup) | |||
165 | dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL); | 178 | dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL); |
166 | if (!dev_cgroup) | 179 | if (!dev_cgroup) |
167 | return ERR_PTR(-ENOMEM); | 180 | return ERR_PTR(-ENOMEM); |
168 | INIT_LIST_HEAD(&dev_cgroup->whitelist); | 181 | INIT_LIST_HEAD(&dev_cgroup->exceptions); |
169 | parent_cgroup = cgroup->parent; | 182 | parent_cgroup = cgroup->parent; |
170 | 183 | ||
171 | if (parent_cgroup == NULL) { | 184 | if (parent_cgroup == NULL) |
172 | struct dev_whitelist_item *wh; | 185 | dev_cgroup->deny_all = false; |
173 | wh = kmalloc(sizeof(*wh), GFP_KERNEL); | 186 | else { |
174 | if (!wh) { | ||
175 | kfree(dev_cgroup); | ||
176 | return ERR_PTR(-ENOMEM); | ||
177 | } | ||
178 | wh->minor = wh->major = ~0; | ||
179 | wh->type = DEV_ALL; | ||
180 | wh->access = ACC_MASK; | ||
181 | list_add(&wh->list, &dev_cgroup->whitelist); | ||
182 | } else { | ||
183 | parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); | 187 | parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); |
184 | mutex_lock(&devcgroup_mutex); | 188 | mutex_lock(&devcgroup_mutex); |
185 | ret = dev_whitelist_copy(&dev_cgroup->whitelist, | 189 | ret = dev_exceptions_copy(&dev_cgroup->exceptions, |
186 | &parent_dev_cgroup->whitelist); | 190 | &parent_dev_cgroup->exceptions); |
191 | dev_cgroup->deny_all = parent_dev_cgroup->deny_all; | ||
187 | mutex_unlock(&devcgroup_mutex); | 192 | mutex_unlock(&devcgroup_mutex); |
188 | if (ret) { | 193 | if (ret) { |
189 | kfree(dev_cgroup); | 194 | kfree(dev_cgroup); |
@@ -197,13 +202,9 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup) | |||
197 | static void devcgroup_destroy(struct cgroup *cgroup) | 202 | static void devcgroup_destroy(struct cgroup *cgroup) |
198 | { | 203 | { |
199 | struct dev_cgroup *dev_cgroup; | 204 | struct dev_cgroup *dev_cgroup; |
200 | struct dev_whitelist_item *wh, *tmp; | ||
201 | 205 | ||
202 | dev_cgroup = cgroup_to_devcgroup(cgroup); | 206 | dev_cgroup = cgroup_to_devcgroup(cgroup); |
203 | list_for_each_entry_safe(wh, tmp, &dev_cgroup->whitelist, list) { | 207 | dev_exception_clean(dev_cgroup); |
204 | list_del(&wh->list); | ||
205 | kfree(wh); | ||
206 | } | ||
207 | kfree(dev_cgroup); | 208 | kfree(dev_cgroup); |
208 | } | 209 | } |
209 | 210 | ||
@@ -249,59 +250,87 @@ static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, | |||
249 | struct seq_file *m) | 250 | struct seq_file *m) |
250 | { | 251 | { |
251 | struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup); | 252 | struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup); |
252 | struct dev_whitelist_item *wh; | 253 | struct dev_exception_item *ex; |
253 | char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; | 254 | char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; |
254 | 255 | ||
255 | rcu_read_lock(); | 256 | rcu_read_lock(); |
256 | list_for_each_entry_rcu(wh, &devcgroup->whitelist, list) { | 257 | /* |
257 | set_access(acc, wh->access); | 258 | * To preserve the compatibility: |
258 | set_majmin(maj, wh->major); | 259 | * - Only show the "all devices" when the default policy is to allow |
259 | set_majmin(min, wh->minor); | 260 | * - List the exceptions in case the default policy is to deny |
260 | seq_printf(m, "%c %s:%s %s\n", type_to_char(wh->type), | 261 | * This way, the file remains as a "whitelist of devices" |
262 | */ | ||
263 | if (devcgroup->deny_all == false) { | ||
264 | set_access(acc, ACC_MASK); | ||
265 | set_majmin(maj, ~0); | ||
266 | set_majmin(min, ~0); | ||
267 | seq_printf(m, "%c %s:%s %s\n", type_to_char(DEV_ALL), | ||
261 | maj, min, acc); | 268 | maj, min, acc); |
269 | } else { | ||
270 | list_for_each_entry_rcu(ex, &devcgroup->exceptions, list) { | ||
271 | set_access(acc, ex->access); | ||
272 | set_majmin(maj, ex->major); | ||
273 | set_majmin(min, ex->minor); | ||
274 | seq_printf(m, "%c %s:%s %s\n", type_to_char(ex->type), | ||
275 | maj, min, acc); | ||
276 | } | ||
262 | } | 277 | } |
263 | rcu_read_unlock(); | 278 | rcu_read_unlock(); |
264 | 279 | ||
265 | return 0; | 280 | return 0; |
266 | } | 281 | } |
267 | 282 | ||
268 | /* | 283 | /** |
269 | * may_access_whitelist: | 284 | * may_access - verifies if a new exception is part of what is allowed |
270 | * does the access granted to dev_cgroup c contain the access | 285 | * by a dev cgroup based on the default policy + |
271 | * requested in whitelist item refwh. | 286 | * exceptions. This is used to make sure a child cgroup |
272 | * return 1 if yes, 0 if no. | 287 | * won't have more privileges than its parent or to |
273 | * call with devcgroup_mutex held | 288 | * verify if a certain access is allowed. |
289 | * @dev_cgroup: dev cgroup to be tested against | ||
290 | * @refex: new exception | ||
274 | */ | 291 | */ |
275 | static int may_access_whitelist(struct dev_cgroup *c, | 292 | static int may_access(struct dev_cgroup *dev_cgroup, |
276 | struct dev_whitelist_item *refwh) | 293 | struct dev_exception_item *refex) |
277 | { | 294 | { |
278 | struct dev_whitelist_item *whitem; | 295 | struct dev_exception_item *ex; |
296 | bool match = false; | ||
279 | 297 | ||
280 | list_for_each_entry(whitem, &c->whitelist, list) { | 298 | list_for_each_entry(ex, &dev_cgroup->exceptions, list) { |
281 | if (whitem->type & DEV_ALL) | 299 | if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) |
282 | return 1; | ||
283 | if ((refwh->type & DEV_BLOCK) && !(whitem->type & DEV_BLOCK)) | ||
284 | continue; | 300 | continue; |
285 | if ((refwh->type & DEV_CHAR) && !(whitem->type & DEV_CHAR)) | 301 | if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) |
286 | continue; | 302 | continue; |
287 | if (whitem->major != ~0 && whitem->major != refwh->major) | 303 | if (ex->major != ~0 && ex->major != refex->major) |
288 | continue; | 304 | continue; |
289 | if (whitem->minor != ~0 && whitem->minor != refwh->minor) | 305 | if (ex->minor != ~0 && ex->minor != refex->minor) |
290 | continue; | 306 | continue; |
291 | if (refwh->access & (~whitem->access)) | 307 | if (refex->access & (~ex->access)) |
292 | continue; | 308 | continue; |
293 | return 1; | 309 | match = true; |
310 | break; | ||
294 | } | 311 | } |
312 | |||
313 | /* | ||
314 | * In two cases we'll consider this new exception valid: | ||
315 | * - the dev cgroup has its default policy to allow + exception list: | ||
316 | * the new exception should *not* match any of the exceptions | ||
317 | * (!deny_all, !match) | ||
318 | * - the dev cgroup has its default policy to deny + exception list: | ||
319 | * the new exception *should* match the exceptions | ||
320 | * (deny_all, match) | ||
321 | */ | ||
322 | if (dev_cgroup->deny_all == match) | ||
323 | return 1; | ||
295 | return 0; | 324 | return 0; |
296 | } | 325 | } |
297 | 326 | ||
298 | /* | 327 | /* |
299 | * parent_has_perm: | 328 | * parent_has_perm: |
300 | * when adding a new allow rule to a device whitelist, the rule | 329 | * when adding a new allow rule to a device exception list, the rule |
301 | * must be allowed in the parent device | 330 | * must be allowed in the parent device |
302 | */ | 331 | */ |
303 | static int parent_has_perm(struct dev_cgroup *childcg, | 332 | static int parent_has_perm(struct dev_cgroup *childcg, |
304 | struct dev_whitelist_item *wh) | 333 | struct dev_exception_item *ex) |
305 | { | 334 | { |
306 | struct cgroup *pcg = childcg->css.cgroup->parent; | 335 | struct cgroup *pcg = childcg->css.cgroup->parent; |
307 | struct dev_cgroup *parent; | 336 | struct dev_cgroup *parent; |
@@ -309,17 +338,17 @@ static int parent_has_perm(struct dev_cgroup *childcg, | |||
309 | if (!pcg) | 338 | if (!pcg) |
310 | return 1; | 339 | return 1; |
311 | parent = cgroup_to_devcgroup(pcg); | 340 | parent = cgroup_to_devcgroup(pcg); |
312 | return may_access_whitelist(parent, wh); | 341 | return may_access(parent, ex); |
313 | } | 342 | } |
314 | 343 | ||
315 | /* | 344 | /* |
316 | * Modify the whitelist using allow/deny rules. | 345 | * Modify the exception list using allow/deny rules. |
317 | * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD | 346 | * CAP_SYS_ADMIN is needed for this. It's at least separate from CAP_MKNOD |
318 | * so we can give a container CAP_MKNOD to let it create devices but not | 347 | * so we can give a container CAP_MKNOD to let it create devices but not |
319 | * modify the whitelist. | 348 | * modify the exception list. |
320 | * It seems likely we'll want to add a CAP_CONTAINER capability to allow | 349 | * It seems likely we'll want to add a CAP_CONTAINER capability to allow |
321 | * us to also grant CAP_SYS_ADMIN to containers without giving away the | 350 | * us to also grant CAP_SYS_ADMIN to containers without giving away the |
322 | * device whitelist controls, but for now we'll stick with CAP_SYS_ADMIN | 351 | * device exception list controls, but for now we'll stick with CAP_SYS_ADMIN |
323 | * | 352 | * |
324 | * Taking rules away is always allowed (given CAP_SYS_ADMIN). Granting | 353 | * Taking rules away is always allowed (given CAP_SYS_ADMIN). Granting |
325 | * new access is only allowed if you're in the top-level cgroup, or your | 354 | * new access is only allowed if you're in the top-level cgroup, or your |
@@ -331,26 +360,36 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
331 | const char *b; | 360 | const char *b; |
332 | char *endp; | 361 | char *endp; |
333 | int count; | 362 | int count; |
334 | struct dev_whitelist_item wh; | 363 | struct dev_exception_item ex; |
335 | 364 | ||
336 | if (!capable(CAP_SYS_ADMIN)) | 365 | if (!capable(CAP_SYS_ADMIN)) |
337 | return -EPERM; | 366 | return -EPERM; |
338 | 367 | ||
339 | memset(&wh, 0, sizeof(wh)); | 368 | memset(&ex, 0, sizeof(ex)); |
340 | b = buffer; | 369 | b = buffer; |
341 | 370 | ||
342 | switch (*b) { | 371 | switch (*b) { |
343 | case 'a': | 372 | case 'a': |
344 | wh.type = DEV_ALL; | 373 | switch (filetype) { |
345 | wh.access = ACC_MASK; | 374 | case DEVCG_ALLOW: |
346 | wh.major = ~0; | 375 | if (!parent_has_perm(devcgroup, &ex)) |
347 | wh.minor = ~0; | 376 | return -EPERM; |
348 | goto handle; | 377 | dev_exception_clean(devcgroup); |
378 | devcgroup->deny_all = false; | ||
379 | break; | ||
380 | case DEVCG_DENY: | ||
381 | dev_exception_clean(devcgroup); | ||
382 | devcgroup->deny_all = true; | ||
383 | break; | ||
384 | default: | ||
385 | return -EINVAL; | ||
386 | } | ||
387 | return 0; | ||
349 | case 'b': | 388 | case 'b': |
350 | wh.type = DEV_BLOCK; | 389 | ex.type = DEV_BLOCK; |
351 | break; | 390 | break; |
352 | case 'c': | 391 | case 'c': |
353 | wh.type = DEV_CHAR; | 392 | ex.type = DEV_CHAR; |
354 | break; | 393 | break; |
355 | default: | 394 | default: |
356 | return -EINVAL; | 395 | return -EINVAL; |
@@ -360,10 +399,10 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
360 | return -EINVAL; | 399 | return -EINVAL; |
361 | b++; | 400 | b++; |
362 | if (*b == '*') { | 401 | if (*b == '*') { |
363 | wh.major = ~0; | 402 | ex.major = ~0; |
364 | b++; | 403 | b++; |
365 | } else if (isdigit(*b)) { | 404 | } else if (isdigit(*b)) { |
366 | wh.major = simple_strtoul(b, &endp, 10); | 405 | ex.major = simple_strtoul(b, &endp, 10); |
367 | b = endp; | 406 | b = endp; |
368 | } else { | 407 | } else { |
369 | return -EINVAL; | 408 | return -EINVAL; |
@@ -374,10 +413,10 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
374 | 413 | ||
375 | /* read minor */ | 414 | /* read minor */ |
376 | if (*b == '*') { | 415 | if (*b == '*') { |
377 | wh.minor = ~0; | 416 | ex.minor = ~0; |
378 | b++; | 417 | b++; |
379 | } else if (isdigit(*b)) { | 418 | } else if (isdigit(*b)) { |
380 | wh.minor = simple_strtoul(b, &endp, 10); | 419 | ex.minor = simple_strtoul(b, &endp, 10); |
381 | b = endp; | 420 | b = endp; |
382 | } else { | 421 | } else { |
383 | return -EINVAL; | 422 | return -EINVAL; |
@@ -387,13 +426,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
387 | for (b++, count = 0; count < 3; count++, b++) { | 426 | for (b++, count = 0; count < 3; count++, b++) { |
388 | switch (*b) { | 427 | switch (*b) { |
389 | case 'r': | 428 | case 'r': |
390 | wh.access |= ACC_READ; | 429 | ex.access |= ACC_READ; |
391 | break; | 430 | break; |
392 | case 'w': | 431 | case 'w': |
393 | wh.access |= ACC_WRITE; | 432 | ex.access |= ACC_WRITE; |
394 | break; | 433 | break; |
395 | case 'm': | 434 | case 'm': |
396 | wh.access |= ACC_MKNOD; | 435 | ex.access |= ACC_MKNOD; |
397 | break; | 436 | break; |
398 | case '\n': | 437 | case '\n': |
399 | case '\0': | 438 | case '\0': |
@@ -404,15 +443,31 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
404 | } | 443 | } |
405 | } | 444 | } |
406 | 445 | ||
407 | handle: | ||
408 | switch (filetype) { | 446 | switch (filetype) { |
409 | case DEVCG_ALLOW: | 447 | case DEVCG_ALLOW: |
410 | if (!parent_has_perm(devcgroup, &wh)) | 448 | if (!parent_has_perm(devcgroup, &ex)) |
411 | return -EPERM; | 449 | return -EPERM; |
412 | return dev_whitelist_add(devcgroup, &wh); | 450 | /* |
451 | * If the default policy is to allow by default, try to remove | ||
452 | * an matching exception instead. And be silent about it: we | ||
453 | * don't want to break compatibility | ||
454 | */ | ||
455 | if (devcgroup->deny_all == false) { | ||
456 | dev_exception_rm(devcgroup, &ex); | ||
457 | return 0; | ||
458 | } | ||
459 | return dev_exception_add(devcgroup, &ex); | ||
413 | case DEVCG_DENY: | 460 | case DEVCG_DENY: |
414 | dev_whitelist_rm(devcgroup, &wh); | 461 | /* |
415 | break; | 462 | * If the default policy is to deny by default, try to remove |
463 | * an matching exception instead. And be silent about it: we | ||
464 | * don't want to break compatibility | ||
465 | */ | ||
466 | if (devcgroup->deny_all == true) { | ||
467 | dev_exception_rm(devcgroup, &ex); | ||
468 | return 0; | ||
469 | } | ||
470 | return dev_exception_add(devcgroup, &ex); | ||
416 | default: | 471 | default: |
417 | return -EINVAL; | 472 | return -EINVAL; |
418 | } | 473 | } |
@@ -468,73 +523,71 @@ struct cgroup_subsys devices_subsys = { | |||
468 | .broken_hierarchy = true, | 523 | .broken_hierarchy = true, |
469 | }; | 524 | }; |
470 | 525 | ||
471 | int __devcgroup_inode_permission(struct inode *inode, int mask) | 526 | /** |
527 | * __devcgroup_check_permission - checks if an inode operation is permitted | ||
528 | * @dev_cgroup: the dev cgroup to be tested against | ||
529 | * @type: device type | ||
530 | * @major: device major number | ||
531 | * @minor: device minor number | ||
532 | * @access: combination of ACC_WRITE, ACC_READ and ACC_MKNOD | ||
533 | * | ||
534 | * returns 0 on success, -EPERM case the operation is not permitted | ||
535 | */ | ||
536 | static int __devcgroup_check_permission(struct dev_cgroup *dev_cgroup, | ||
537 | short type, u32 major, u32 minor, | ||
538 | short access) | ||
472 | { | 539 | { |
473 | struct dev_cgroup *dev_cgroup; | 540 | struct dev_exception_item ex; |
474 | struct dev_whitelist_item *wh; | 541 | int rc; |
475 | |||
476 | rcu_read_lock(); | ||
477 | 542 | ||
478 | dev_cgroup = task_devcgroup(current); | 543 | memset(&ex, 0, sizeof(ex)); |
544 | ex.type = type; | ||
545 | ex.major = major; | ||
546 | ex.minor = minor; | ||
547 | ex.access = access; | ||
479 | 548 | ||
480 | list_for_each_entry_rcu(wh, &dev_cgroup->whitelist, list) { | 549 | rcu_read_lock(); |
481 | if (wh->type & DEV_ALL) | 550 | rc = may_access(dev_cgroup, &ex); |
482 | goto found; | 551 | rcu_read_unlock(); |
483 | if ((wh->type & DEV_BLOCK) && !S_ISBLK(inode->i_mode)) | ||
484 | continue; | ||
485 | if ((wh->type & DEV_CHAR) && !S_ISCHR(inode->i_mode)) | ||
486 | continue; | ||
487 | if (wh->major != ~0 && wh->major != imajor(inode)) | ||
488 | continue; | ||
489 | if (wh->minor != ~0 && wh->minor != iminor(inode)) | ||
490 | continue; | ||
491 | 552 | ||
492 | if ((mask & MAY_WRITE) && !(wh->access & ACC_WRITE)) | 553 | if (!rc) |
493 | continue; | 554 | return -EPERM; |
494 | if ((mask & MAY_READ) && !(wh->access & ACC_READ)) | ||
495 | continue; | ||
496 | found: | ||
497 | rcu_read_unlock(); | ||
498 | return 0; | ||
499 | } | ||
500 | 555 | ||
501 | rcu_read_unlock(); | 556 | return 0; |
557 | } | ||
502 | 558 | ||
503 | return -EPERM; | 559 | int __devcgroup_inode_permission(struct inode *inode, int mask) |
560 | { | ||
561 | struct dev_cgroup *dev_cgroup = task_devcgroup(current); | ||
562 | short type, access = 0; | ||
563 | |||
564 | if (S_ISBLK(inode->i_mode)) | ||
565 | type = DEV_BLOCK; | ||
566 | if (S_ISCHR(inode->i_mode)) | ||
567 | type = DEV_CHAR; | ||
568 | if (mask & MAY_WRITE) | ||
569 | access |= ACC_WRITE; | ||
570 | if (mask & MAY_READ) | ||
571 | access |= ACC_READ; | ||
572 | |||
573 | return __devcgroup_check_permission(dev_cgroup, type, imajor(inode), | ||
574 | iminor(inode), access); | ||
504 | } | 575 | } |
505 | 576 | ||
506 | int devcgroup_inode_mknod(int mode, dev_t dev) | 577 | int devcgroup_inode_mknod(int mode, dev_t dev) |
507 | { | 578 | { |
508 | struct dev_cgroup *dev_cgroup; | 579 | struct dev_cgroup *dev_cgroup = task_devcgroup(current); |
509 | struct dev_whitelist_item *wh; | 580 | short type; |
510 | 581 | ||
511 | if (!S_ISBLK(mode) && !S_ISCHR(mode)) | 582 | if (!S_ISBLK(mode) && !S_ISCHR(mode)) |
512 | return 0; | 583 | return 0; |
513 | 584 | ||
514 | rcu_read_lock(); | 585 | if (S_ISBLK(mode)) |
515 | 586 | type = DEV_BLOCK; | |
516 | dev_cgroup = task_devcgroup(current); | 587 | else |
517 | 588 | type = DEV_CHAR; | |
518 | list_for_each_entry_rcu(wh, &dev_cgroup->whitelist, list) { | ||
519 | if (wh->type & DEV_ALL) | ||
520 | goto found; | ||
521 | if ((wh->type & DEV_BLOCK) && !S_ISBLK(mode)) | ||
522 | continue; | ||
523 | if ((wh->type & DEV_CHAR) && !S_ISCHR(mode)) | ||
524 | continue; | ||
525 | if (wh->major != ~0 && wh->major != MAJOR(dev)) | ||
526 | continue; | ||
527 | if (wh->minor != ~0 && wh->minor != MINOR(dev)) | ||
528 | continue; | ||
529 | |||
530 | if (!(wh->access & ACC_MKNOD)) | ||
531 | continue; | ||
532 | found: | ||
533 | rcu_read_unlock(); | ||
534 | return 0; | ||
535 | } | ||
536 | 589 | ||
537 | rcu_read_unlock(); | 590 | return __devcgroup_check_permission(dev_cgroup, type, MAJOR(dev), |
591 | MINOR(dev), ACC_MKNOD); | ||
538 | 592 | ||
539 | return -EPERM; | ||
540 | } | 593 | } |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index f4817292ef45..aa62c0e44cb6 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -1233,7 +1233,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { | |||
1233 | { "PWM2", NULL, "PWM2 Driver" }, | 1233 | { "PWM2", NULL, "PWM2 Driver" }, |
1234 | }; | 1234 | }; |
1235 | 1235 | ||
1236 | static const __devinitdata struct reg_default wm5100_reva_patches[] = { | 1236 | static const __devinitconst struct reg_default wm5100_reva_patches[] = { |
1237 | { WM5100_AUDIO_IF_1_10, 0 }, | 1237 | { WM5100_AUDIO_IF_1_10, 0 }, |
1238 | { WM5100_AUDIO_IF_1_11, 1 }, | 1238 | { WM5100_AUDIO_IF_1_11, 1 }, |
1239 | { WM5100_AUDIO_IF_1_12, 2 }, | 1239 | { WM5100_AUDIO_IF_1_12, 2 }, |
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 85baf11e2acd..43480149119e 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug | 1 | TARGETS = breakpoints kcmp mqueue vm cpu-hotplug memory-hotplug epoll |
2 | 2 | ||
3 | all: | 3 | all: |
4 | for TARGET in $(TARGETS); do \ | 4 | for TARGET in $(TARGETS); do \ |
diff --git a/tools/testing/selftests/epoll/Makefile b/tools/testing/selftests/epoll/Makefile new file mode 100644 index 000000000000..19806ed62f50 --- /dev/null +++ b/tools/testing/selftests/epoll/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # Makefile for epoll selftests | ||
2 | |||
3 | all: test_epoll | ||
4 | %: %.c | ||
5 | gcc -pthread -g -o $@ $^ | ||
6 | |||
7 | run_tests: all | ||
8 | ./test_epoll | ||
9 | |||
10 | clean: | ||
11 | $(RM) test_epoll | ||
diff --git a/tools/testing/selftests/epoll/test_epoll.c b/tools/testing/selftests/epoll/test_epoll.c new file mode 100644 index 000000000000..e0fcff1e8331 --- /dev/null +++ b/tools/testing/selftests/epoll/test_epoll.c | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * tools/testing/selftests/epoll/test_epoll.c | ||
3 | * | ||
4 | * Copyright 2012 Adobe Systems Incorporated | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * Paton J. Lewis <palewis@adobe.com> | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include <errno.h> | ||
16 | #include <fcntl.h> | ||
17 | #include <pthread.h> | ||
18 | #include <stdio.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <unistd.h> | ||
21 | #include <sys/epoll.h> | ||
22 | #include <sys/socket.h> | ||
23 | |||
24 | /* | ||
25 | * A pointer to an epoll_item_private structure will be stored in the epoll | ||
26 | * item's event structure so that we can get access to the epoll_item_private | ||
27 | * data after calling epoll_wait: | ||
28 | */ | ||
29 | struct epoll_item_private { | ||
30 | int index; /* Position of this struct within the epoll_items array. */ | ||
31 | int fd; | ||
32 | uint32_t events; | ||
33 | pthread_mutex_t mutex; /* Guards the following variables... */ | ||
34 | int stop; | ||
35 | int status; /* Stores any error encountered while handling item. */ | ||
36 | /* The following variable allows us to test whether we have encountered | ||
37 | a problem while attempting to cancel and delete the associated | ||
38 | event. When the test program exits, 'deleted' should be exactly | ||
39 | one. If it is greater than one, then the failed test reflects a real | ||
40 | world situation where we would have tried to access the epoll item's | ||
41 | private data after deleting it: */ | ||
42 | int deleted; | ||
43 | }; | ||
44 | |||
45 | struct epoll_item_private *epoll_items; | ||
46 | |||
47 | /* | ||
48 | * Delete the specified item from the epoll set. In a real-world secneario this | ||
49 | * is where we would free the associated data structure, but in this testing | ||
50 | * environment we retain the structure so that we can test for double-deletion: | ||
51 | */ | ||
52 | void delete_item(int index) | ||
53 | { | ||
54 | __sync_fetch_and_add(&epoll_items[index].deleted, 1); | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * A pointer to a read_thread_data structure will be passed as the argument to | ||
59 | * each read thread: | ||
60 | */ | ||
61 | struct read_thread_data { | ||
62 | int stop; | ||
63 | int status; /* Indicates any error encountered by the read thread. */ | ||
64 | int epoll_set; | ||
65 | }; | ||
66 | |||
67 | /* | ||
68 | * The function executed by the read threads: | ||
69 | */ | ||
70 | void *read_thread_function(void *function_data) | ||
71 | { | ||
72 | struct read_thread_data *thread_data = | ||
73 | (struct read_thread_data *)function_data; | ||
74 | struct epoll_event event_data; | ||
75 | struct epoll_item_private *item_data; | ||
76 | char socket_data; | ||
77 | |||
78 | /* Handle events until we encounter an error or this thread's 'stop' | ||
79 | condition is set: */ | ||
80 | while (1) { | ||
81 | int result = epoll_wait(thread_data->epoll_set, | ||
82 | &event_data, | ||
83 | 1, /* Number of desired events */ | ||
84 | 1000); /* Timeout in ms */ | ||
85 | if (result < 0) { | ||
86 | /* Breakpoints signal all threads. Ignore that while | ||
87 | debugging: */ | ||
88 | if (errno == EINTR) | ||
89 | continue; | ||
90 | thread_data->status = errno; | ||
91 | return 0; | ||
92 | } else if (thread_data->stop) | ||
93 | return 0; | ||
94 | else if (result == 0) /* Timeout */ | ||
95 | continue; | ||
96 | |||
97 | /* We need the mutex here because checking for the stop | ||
98 | condition and re-enabling the epoll item need to be done | ||
99 | together as one atomic operation when EPOLL_CTL_DISABLE is | ||
100 | available: */ | ||
101 | item_data = (struct epoll_item_private *)event_data.data.ptr; | ||
102 | pthread_mutex_lock(&item_data->mutex); | ||
103 | |||
104 | /* Remove the item from the epoll set if we want to stop | ||
105 | handling that event: */ | ||
106 | if (item_data->stop) | ||
107 | delete_item(item_data->index); | ||
108 | else { | ||
109 | /* Clear the data that was written to the other end of | ||
110 | our non-blocking socket: */ | ||
111 | do { | ||
112 | if (read(item_data->fd, &socket_data, 1) < 1) { | ||
113 | if ((errno == EAGAIN) || | ||
114 | (errno == EWOULDBLOCK)) | ||
115 | break; | ||
116 | else | ||
117 | goto error_unlock; | ||
118 | } | ||
119 | } while (item_data->events & EPOLLET); | ||
120 | |||
121 | /* The item was one-shot, so re-enable it: */ | ||
122 | event_data.events = item_data->events; | ||
123 | if (epoll_ctl(thread_data->epoll_set, | ||
124 | EPOLL_CTL_MOD, | ||
125 | item_data->fd, | ||
126 | &event_data) < 0) | ||
127 | goto error_unlock; | ||
128 | } | ||
129 | |||
130 | pthread_mutex_unlock(&item_data->mutex); | ||
131 | } | ||
132 | |||
133 | error_unlock: | ||
134 | thread_data->status = item_data->status = errno; | ||
135 | pthread_mutex_unlock(&item_data->mutex); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * A pointer to a write_thread_data structure will be passed as the argument to | ||
141 | * the write thread: | ||
142 | */ | ||
143 | struct write_thread_data { | ||
144 | int stop; | ||
145 | int status; /* Indicates any error encountered by the write thread. */ | ||
146 | int n_fds; | ||
147 | int *fds; | ||
148 | }; | ||
149 | |||
150 | /* | ||
151 | * The function executed by the write thread. It writes a single byte to each | ||
152 | * socket in turn until the stop condition for this thread is set. If writing to | ||
153 | * a socket would block (i.e. errno was EAGAIN), we leave that socket alone for | ||
154 | * the moment and just move on to the next socket in the list. We don't care | ||
155 | * about the order in which we deliver events to the epoll set. In fact we don't | ||
156 | * care about the data we're writing to the pipes at all; we just want to | ||
157 | * trigger epoll events: | ||
158 | */ | ||
159 | void *write_thread_function(void *function_data) | ||
160 | { | ||
161 | const char data = 'X'; | ||
162 | int index; | ||
163 | struct write_thread_data *thread_data = | ||
164 | (struct write_thread_data *)function_data; | ||
165 | while (!write_thread_data->stop) | ||
166 | for (index = 0; | ||
167 | !thread_data->stop && (index < thread_data->n_fds); | ||
168 | ++index) | ||
169 | if ((write(thread_data->fds[index], &data, 1) < 1) && | ||
170 | (errno != EAGAIN) && | ||
171 | (errno != EWOULDBLOCK)) { | ||
172 | write_thread_data->status = errno; | ||
173 | return; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Arguments are currently ignored: | ||
179 | */ | ||
180 | int main(int argc, char **argv) | ||
181 | { | ||
182 | const int n_read_threads = 100; | ||
183 | const int n_epoll_items = 500; | ||
184 | int index; | ||
185 | int epoll_set = epoll_create1(0); | ||
186 | struct write_thread_data write_thread_data = { | ||
187 | 0, 0, n_epoll_items, malloc(n_epoll_items * sizeof(int)) | ||
188 | }; | ||
189 | struct read_thread_data *read_thread_data = | ||
190 | malloc(n_read_threads * sizeof(struct read_thread_data)); | ||
191 | pthread_t *read_threads = malloc(n_read_threads * sizeof(pthread_t)); | ||
192 | pthread_t write_thread; | ||
193 | |||
194 | printf("-----------------\n"); | ||
195 | printf("Runing test_epoll\n"); | ||
196 | printf("-----------------\n"); | ||
197 | |||
198 | epoll_items = malloc(n_epoll_items * sizeof(struct epoll_item_private)); | ||
199 | |||
200 | if (epoll_set < 0 || epoll_items == 0 || write_thread_data.fds == 0 || | ||
201 | read_thread_data == 0 || read_threads == 0) | ||
202 | goto error; | ||
203 | |||
204 | if (sysconf(_SC_NPROCESSORS_ONLN) < 2) { | ||
205 | printf("Error: please run this test on a multi-core system.\n"); | ||
206 | goto error; | ||
207 | } | ||
208 | |||
209 | /* Create the socket pairs and epoll items: */ | ||
210 | for (index = 0; index < n_epoll_items; ++index) { | ||
211 | int socket_pair[2]; | ||
212 | struct epoll_event event_data; | ||
213 | if (socketpair(AF_UNIX, | ||
214 | SOCK_STREAM | SOCK_NONBLOCK, | ||
215 | 0, | ||
216 | socket_pair) < 0) | ||
217 | goto error; | ||
218 | write_thread_data.fds[index] = socket_pair[0]; | ||
219 | epoll_items[index].index = index; | ||
220 | epoll_items[index].fd = socket_pair[1]; | ||
221 | if (pthread_mutex_init(&epoll_items[index].mutex, NULL) != 0) | ||
222 | goto error; | ||
223 | /* We always use EPOLLONESHOT because this test is currently | ||
224 | structured to demonstrate the need for EPOLL_CTL_DISABLE, | ||
225 | which only produces useful information in the EPOLLONESHOT | ||
226 | case (without EPOLLONESHOT, calling epoll_ctl with | ||
227 | EPOLL_CTL_DISABLE will never return EBUSY). If support for | ||
228 | testing events without EPOLLONESHOT is desired, it should | ||
229 | probably be implemented in a separate unit test. */ | ||
230 | epoll_items[index].events = EPOLLIN | EPOLLONESHOT; | ||
231 | if (index < n_epoll_items / 2) | ||
232 | epoll_items[index].events |= EPOLLET; | ||
233 | epoll_items[index].stop = 0; | ||
234 | epoll_items[index].status = 0; | ||
235 | epoll_items[index].deleted = 0; | ||
236 | event_data.events = epoll_items[index].events; | ||
237 | event_data.data.ptr = &epoll_items[index]; | ||
238 | if (epoll_ctl(epoll_set, | ||
239 | EPOLL_CTL_ADD, | ||
240 | epoll_items[index].fd, | ||
241 | &event_data) < 0) | ||
242 | goto error; | ||
243 | } | ||
244 | |||
245 | /* Create and start the read threads: */ | ||
246 | for (index = 0; index < n_read_threads; ++index) { | ||
247 | read_thread_data[index].stop = 0; | ||
248 | read_thread_data[index].status = 0; | ||
249 | read_thread_data[index].epoll_set = epoll_set; | ||
250 | if (pthread_create(&read_threads[index], | ||
251 | NULL, | ||
252 | read_thread_function, | ||
253 | &read_thread_data[index]) != 0) | ||
254 | goto error; | ||
255 | } | ||
256 | |||
257 | if (pthread_create(&write_thread, | ||
258 | NULL, | ||
259 | write_thread_function, | ||
260 | &write_thread_data) != 0) | ||
261 | goto error; | ||
262 | |||
263 | /* Cancel all event pollers: */ | ||
264 | #ifdef EPOLL_CTL_DISABLE | ||
265 | for (index = 0; index < n_epoll_items; ++index) { | ||
266 | pthread_mutex_lock(&epoll_items[index].mutex); | ||
267 | ++epoll_items[index].stop; | ||
268 | if (epoll_ctl(epoll_set, | ||
269 | EPOLL_CTL_DISABLE, | ||
270 | epoll_items[index].fd, | ||
271 | NULL) == 0) | ||
272 | delete_item(index); | ||
273 | else if (errno != EBUSY) { | ||
274 | pthread_mutex_unlock(&epoll_items[index].mutex); | ||
275 | goto error; | ||
276 | } | ||
277 | /* EBUSY means events were being handled; allow the other thread | ||
278 | to delete the item. */ | ||
279 | pthread_mutex_unlock(&epoll_items[index].mutex); | ||
280 | } | ||
281 | #else | ||
282 | for (index = 0; index < n_epoll_items; ++index) { | ||
283 | pthread_mutex_lock(&epoll_items[index].mutex); | ||
284 | ++epoll_items[index].stop; | ||
285 | pthread_mutex_unlock(&epoll_items[index].mutex); | ||
286 | /* Wait in case a thread running read_thread_function is | ||
287 | currently executing code between epoll_wait and | ||
288 | pthread_mutex_lock with this item. Note that a longer delay | ||
289 | would make double-deletion less likely (at the expense of | ||
290 | performance), but there is no guarantee that any delay would | ||
291 | ever be sufficient. Note also that we delete all event | ||
292 | pollers at once for testing purposes, but in a real-world | ||
293 | environment we are likely to want to be able to cancel event | ||
294 | pollers at arbitrary times. Therefore we can't improve this | ||
295 | situation by just splitting this loop into two loops | ||
296 | (i.e. signal 'stop' for all items, sleep, and then delete all | ||
297 | items). We also can't fix the problem via EPOLL_CTL_DEL | ||
298 | because that command can't prevent the case where some other | ||
299 | thread is executing read_thread_function within the region | ||
300 | mentioned above: */ | ||
301 | usleep(1); | ||
302 | pthread_mutex_lock(&epoll_items[index].mutex); | ||
303 | if (!epoll_items[index].deleted) | ||
304 | delete_item(index); | ||
305 | pthread_mutex_unlock(&epoll_items[index].mutex); | ||
306 | } | ||
307 | #endif | ||
308 | |||
309 | /* Shut down the read threads: */ | ||
310 | for (index = 0; index < n_read_threads; ++index) | ||
311 | __sync_fetch_and_add(&read_thread_data[index].stop, 1); | ||
312 | for (index = 0; index < n_read_threads; ++index) { | ||
313 | if (pthread_join(read_threads[index], NULL) != 0) | ||
314 | goto error; | ||
315 | if (read_thread_data[index].status) | ||
316 | goto error; | ||
317 | } | ||
318 | |||
319 | /* Shut down the write thread: */ | ||
320 | __sync_fetch_and_add(&write_thread_data.stop, 1); | ||
321 | if ((pthread_join(write_thread, NULL) != 0) || write_thread_data.status) | ||
322 | goto error; | ||
323 | |||
324 | /* Check for final error conditions: */ | ||
325 | for (index = 0; index < n_epoll_items; ++index) { | ||
326 | if (epoll_items[index].status != 0) | ||
327 | goto error; | ||
328 | if (pthread_mutex_destroy(&epoll_items[index].mutex) < 0) | ||
329 | goto error; | ||
330 | } | ||
331 | for (index = 0; index < n_epoll_items; ++index) | ||
332 | if (epoll_items[index].deleted != 1) { | ||
333 | printf("Error: item data deleted %1d times.\n", | ||
334 | epoll_items[index].deleted); | ||
335 | goto error; | ||
336 | } | ||
337 | |||
338 | printf("[PASS]\n"); | ||
339 | return 0; | ||
340 | |||
341 | error: | ||
342 | printf("[FAIL]\n"); | ||
343 | return errno; | ||
344 | } | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c353b4599cec..e59bb63cb089 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -1568,8 +1568,7 @@ void mark_page_dirty_in_slot(struct kvm *kvm, struct kvm_memory_slot *memslot, | |||
1568 | if (memslot && memslot->dirty_bitmap) { | 1568 | if (memslot && memslot->dirty_bitmap) { |
1569 | unsigned long rel_gfn = gfn - memslot->base_gfn; | 1569 | unsigned long rel_gfn = gfn - memslot->base_gfn; |
1570 | 1570 | ||
1571 | /* TODO: introduce set_bit_le() and use it */ | 1571 | set_bit_le(rel_gfn, memslot->dirty_bitmap); |
1572 | test_and_set_bit_le(rel_gfn, memslot->dirty_bitmap); | ||
1573 | } | 1572 | } |
1574 | } | 1573 | } |
1575 | 1574 | ||