diff options
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 | ||
